diff --git a/Engine/modules/Verve/Core/ITreeNode.h b/Engine/modules/Verve/Core/ITreeNode.h new file mode 100644 index 000000000..943dd554d --- /dev/null +++ b/Engine/modules/Verve/Core/ITreeNode.h @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// 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_ITREENODE_H_ +#define _VT_ITREENODE_H_ + +//----------------------------------------------------------------------------- + +class ITreeNode +{ +public: + + ITreeNode *mParentNode; + ITreeNode *mChildNode; + + ITreeNode *mSiblingPrevNode; + ITreeNode *mSiblingNextNode; + +public: + + ITreeNode( void ) : + mParentNode( 0 ), + mChildNode( 0 ), + mSiblingPrevNode( 0 ), + mSiblingNextNode( 0 ) + { + // Void. + }; + + virtual ~ITreeNode( void ) + { + // Void. + }; + + virtual void clear( void ) = 0; // Clear the Node. + + virtual ITreeNode *getRoot( void ) = 0; // Get Root Node. + virtual ITreeNode *getParent( void ) = 0; // Get Parent Node. + virtual ITreeNode *getChild( void ) = 0; // Get Child Node. + virtual ITreeNode *getLastChild( void ) = 0; // Get Last Child Node. + + virtual ITreeNode *getPrevSibling( void ) = 0; // Get Previous Sibling Node. + virtual ITreeNode *getNextSibling( void ) = 0; // Get Next Sibling Node. + + virtual void addTo( ITreeNode *pNode ) = 0; // Add Node to target node. + virtual void remove( void ) = 0; // Remove this Node from the tree. + virtual void moveTo( ITreeNode* node ) = 0; // Move to specified Node. + + virtual void onAttach( void ) = 0; // Attach Callback. + virtual void onDetach( void ) = 0; // Detach Callback. + + virtual bool inTree( void ) = 0; // Is Node in a tree? +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_ITREENODE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/Persistence/VPersistence.cpp b/Engine/modules/Verve/Core/Persistence/VPersistence.cpp new file mode 100644 index 000000000..daf3336a9 --- /dev/null +++ b/Engine/modules/Verve/Core/Persistence/VPersistence.cpp @@ -0,0 +1,137 @@ +//----------------------------------------------------------------------------- +// 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/Persistence/VPersistence.h" + +#include "Verve/Core/VController.h" +#include "Verve/Core/VObject.h" + +namespace VPersistence +{ + //----------------------------------------------------------------------------- + // + // VController + // + //----------------------------------------------------------------------------- + + template <> + bool write( TiXmlElement *pElement, VController *pObject ) + { + // Write Properties. + if ( !writeProperties( pElement, pObject ) ) + { + return false; + } + + // Write Data Table. + if ( !pObject->writeDataTable( pElement ) ) + { + return false; + } + + // Write Objects. + return writeObjects( pElement, pObject ); + } + + template <> + bool read( TiXmlElement *pElement, VController *pObject ) + { + // Read Properties. + if ( !readProperties( pElement, pObject ) ) + { + // Invalid Properties. + return false; + } + + // Read Data Table. + if ( !pObject->readDataTable( pElement ) ) + { + // Invalid Data Table. + return false; + } + + // Read Objects. + if ( !readObjects( pElement, pObject ) ) + { + // Invalid Read. + return false; + } + + // Valid Read. + return true; + } + + //----------------------------------------------------------------------------- + // + // VObject + // + //----------------------------------------------------------------------------- + + template <> + bool write( TiXmlElement *pElement, VObject *pObject ) + { + // Create Element. + TiXmlElement *objectElement = new TiXmlElement( "VObject" ); + pElement->LinkEndChild( objectElement ); + + // Attributes. + objectElement->SetAttribute( "Type", pObject->getClassName() ); + + // Write Properties. + if ( !writeProperties( objectElement, pObject ) ) + { + return false; + } + + // Write Objects. + return writeObjects( objectElement, pObject ); + } + + template <> + bool read( TiXmlElement *pElement, VObject *pObject ) + { + // Read Properties. + if ( !readProperties( pElement, pObject ) ) + { + // Invalid Properties. + return false; + } + + // Set Name Unique. + pObject->setLabelUnique( pObject->getLabel() ); + + // Read Objects. + if ( !readObjects( pElement, pObject ) ) + { + // Invalid Objects. + return false; + } + +#ifdef VT_EDITOR + // Callback. + Con::executef( pObject, "onRead" ); +#endif + + // Valid Read. + return true; + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Core/Persistence/VPersistence.h b/Engine/modules/Verve/Core/Persistence/VPersistence.h new file mode 100644 index 000000000..6c357681d --- /dev/null +++ b/Engine/modules/Verve/Core/Persistence/VPersistence.h @@ -0,0 +1,286 @@ +//----------------------------------------------------------------------------- +// 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_VPERSISTENCE_H_ +#define _VT_VPERSISTENCE_H_ + +#ifndef TINYXML_INCLUDED +#include "tinyxml/tinyxml.h" +#endif + +#ifndef _SIMOBJECT_H_ +#include "console/simObject.h" +#endif + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- + +namespace VPersistence +{ + static const char *VSFVersionString = "0.0.0a"; + + // This object is used to filter fields which belong to SimObject's. + // There is no need to serialize these fields, so they are skipped + // entirely. + static SimObject DummySimObject; + + //------------------------------------------------------------------------- + + template bool writeFile( const char* pFileName, T *pObject ) + { + // Create Doc. + TiXmlDocument xmlDocument; + TiXmlDeclaration *xmlDeclaration = new TiXmlDeclaration( "1.0", "", "" ); + xmlDocument.LinkEndChild( xmlDeclaration ); + + // Create Root. + TiXmlElement *xmlRoot = new TiXmlElement( "VerveControllerSequence" ); + xmlDocument.LinkEndChild( xmlRoot ); + + // Write Version. + xmlRoot->SetAttribute( "Version", VSFVersionString ); + + // Write Object. + if ( !write( xmlRoot, pObject ) ) + { + Con::errorf( "VPersistence::writeFile() - Unable to Write Object." ); + return false; + } + + // Save File. + return xmlDocument.SaveFile( pFileName ); + }; + + template bool write( TiXmlElement *pElement, T *pObject ); + + template bool writeProperties( TiXmlElement *pElement, T *pObject ) + { + const AbstractClassRep::FieldList &fieldList = pObject->getFieldList(); + const AbstractClassRep::Field *field = NULL; + + // Create Property Root. + TiXmlElement *propertyRoot = new TiXmlElement( "Properties" ); + pElement->LinkEndChild( propertyRoot ); + + const S32 fieldCount = fieldList.size(); + for ( S32 i = 0; i < fieldCount; i++ ) + { + field = &fieldList[i]; + + if ( field->type >= AbstractClassRep::ARCFirstCustomField ) + { + // Ignore Special Fields. + continue; + } + + // Fetch the Field Name. + const char *fieldName = field->pFieldname; + // SimObject Field? + if ( DummySimObject.findField( fieldName ) != NULL ) + { + // Skip SimObject Fields. + continue; + } + + // Fetch the Field Value. + const char *fieldValue = ( *field->getDataFn )( pObject, Con::getData( field->type, ( void * ) ( ( ( const char * )pObject ) + field->offset ), 0, field->table, field->flag ) ); + + if ( fieldValue ) + { + // Create Element. + TiXmlElement *propertyElement = new TiXmlElement( fieldName ); + + // Apply Value. + propertyElement->InsertEndChild( TiXmlText( fieldValue ) ); + + // Add. + propertyRoot->LinkEndChild( propertyElement ); + } + } + + // Valid Write. + return true; + }; + + template bool writeObjects( TiXmlElement *pElement, T *pObject ) + { + for ( ITreeNode *node = pObject->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + // Write Group. + if ( !write( pElement, ( VObject* )node ) ) + { + // Invalid Write. + return false; + } + } + + // Valid Write. + return true; + } + + //------------------------------------------------------------------------- + + template bool readFile( const char* pFileName, T *pObject ) + { + TiXmlDocument xmlDocument; + if ( !xmlDocument.LoadFile( pFileName ) ) + { + Con::errorf( "VPersistence::readFile() - Unable to load file '%s'.", pFileName ); + return false; + } + + TiXmlElement *rootElement = xmlDocument.RootElement(); + if ( !rootElement ) + { + Con::errorf( "VPersistence::readFile() - Invalid Document '%s'.", pFileName ); + return false; + } + + const char *docVersion = rootElement->Attribute( "Version" ); + if ( !docVersion || dStrcmp( VSFVersionString, docVersion ) != 0 ) + { + Con::errorf( "VPersistence::readFile() - Invalid file version." ); + return false; + } + + // Read Object. + if ( !read( rootElement, pObject ) ) + { + // Invalid Read. + return false; + } + + // Valid. + return true; + }; + + template bool read( TiXmlElement *pElement, T *pObject ); + + template bool readProperties( TiXmlElement *pElement, T *pObject ) + { + TiXmlElement *propertyRoot = pElement->FirstChildElement( "Properties" ); + if ( propertyRoot ) + { + for ( TiXmlElement *child = propertyRoot->FirstChildElement(); child != NULL; child = child->NextSiblingElement() ) + { + // Get Field Data. + const char *fieldName = child->Value(); + const char *fieldValue = child->GetText(); + + if ( !fieldValue ) + { + // Clear Value. + pObject->setField( fieldName, "" ); + } + else + { + // Apply Field Value. + if ( !pObject->setField( fieldName, fieldValue ) ) + { + // Invalid. + Con::warnf( "VPersistence::readProperties() - Invalid property '%s'", fieldName ); + } + } + } + } + + // Valid Read. + return true; + }; + + template bool readObjects( TiXmlElement *pElement, T *pObject ) + { + for ( TiXmlElement *child = pElement->FirstChildElement( "VObject" ); child != NULL; child = child->NextSiblingElement( "VObject" ) ) + { + // Get Object Type. + const char *type = child->Attribute( "Type" ); + if ( !type || !AbstractClassRep::findClassRep( type ) ) + { + // Invalid Type. + Con::errorf( "VController::readObjects() - Invalid object type specified '%s'.", ( ( type ) ? type : "NULL" ) ); + + // Invalid Read. + return false; + } + + // Create Object. + VObject *object = dynamic_cast( ConsoleObject::create( type ) ); + +#ifdef VT_EDITOR + // Register SimObject. + if ( !object->registerObject() ) + { + // Delete. + delete object; + + // Invalid Read. + return false; + } +#endif + + // Add Reference. + object->addTo( pObject ); + +#ifdef VT_EDITOR + // Valid Method? + if ( object->isMethod( "onAdd" ) ) + { + // Callback. + const char *retValue = Con::executef( object, "onAdd" ); + if ( !dAtob( retValue ) ) + { + // Delete. + object->deleteObject(); + + // Invalid Read. + return false; + } + } +#endif + + // Read Object. + if ( !read( child, object ) ) + { +#ifdef VT_EDITOR + // Delete. + object->deleteObject(); +#else + // Delete. + delete object; +#endif + + // Invalid Read. + return false; + } + } + + // Valid Read. + return true; + }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPERSISTENCE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/Util/VSharedEnum.cpp b/Engine/modules/Verve/Core/Util/VSharedEnum.cpp new file mode 100644 index 000000000..b4825de3f --- /dev/null +++ b/Engine/modules/Verve/Core/Util/VSharedEnum.cpp @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// 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 "VSharedEnum.h" + +//----------------------------------------------------------------------------- + +// Implement the Action enum list. +ImplementEnumType( VActionToggle, "" ) + { VSharedEnum::k_ActionTurnOn, "ON" }, + { VSharedEnum::k_ActionTurnOff, "OFF" }, +EndImplementEnumType; \ No newline at end of file diff --git a/Engine/modules/Verve/Core/Util/VSharedEnum.h b/Engine/modules/Verve/Core/Util/VSharedEnum.h new file mode 100644 index 000000000..73df682d8 --- /dev/null +++ b/Engine/modules/Verve/Core/Util/VSharedEnum.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// 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_VSHAREDENUM_H_ +#define _VT_VSHAREDENUM_H_ + +#ifndef _DYNAMIC_CONSOLETYPES_H_ +#include "console/dynamicTypes.h" +#endif + +namespace VSharedEnum +{ + enum eActionToggle + { + k_ActionTurnOn, + k_ActionTurnOff, + }; +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VSharedEnum::eActionToggle VActionToggle; + +// Declare Enum Types. +DefineEnumType( VActionToggle ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAREDENUM_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VController.cpp b/Engine/modules/Verve/Core/VController.cpp new file mode 100644 index 000000000..5352f64cd --- /dev/null +++ b/Engine/modules/Verve/Core/VController.cpp @@ -0,0 +1,1160 @@ +//----------------------------------------------------------------------------- +// 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/VObject.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VTrack.h" + +#include "Verve/Extension/Director/VDirectorGroup.h" + +#include "console/consoleObject.h" +#include "console/consoleTypes.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VController ); +//----------------------------------------------------------------------------- + +VController::VController( void ) : + mStatus( ( k_StatusInit | k_StatusStopped ) ), + mTime( 0 ), + mLastTime( 0 ), + mTimeScale( 1.f ), + mDuration( 5000 ), + mLoop( false ), + mLoopBackwards( false ), + mLoopCount( -1 ), + mLoopIndex( 0 ), + mLoopDelay( 0 ), + mLoopDelayTime( 0 ), + mJump( k_JumpInvalid ), + mJumpTime( 0 ), + mResetOnCompletion( true ) +{ + // Don't Process Ticks. + setProcessTicks( false ); +} + +VController::~VController( void ) +{ + // Void. +} + +void VController::initPersistFields( void ) +{ + addGroup( "Controller" ); + addProtectedField( "Time", TypeS32, Offset( mTime, VController ), &setTime, &defaultProtectedGetFn, "Current position of the Controller (in milliseconds)." ); + addProtectedField( "Duration", TypeS32, Offset( mDuration, VController ), &setDuration, &defaultProtectedGetFn, "Total length of the sequence (in milliseconds)." ); + addProtectedField( "TimeScale", TypeF32, Offset( mTimeScale, VController ), &setTimeScale, &defaultProtectedGetFn, "Speed of playback. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |TimeScale| > 1.0, then playback will be faster than normal, while |TimeScale| < 1.0 will be slower." ); + + addField( "Loop", TypeBool, Offset( mLoop, VController ), "Instead of stopping once playback is complete, the Controller will reset and resume play." ); + addField( "LoopBackwards", TypeBool, Offset( mLoopBackwards, VController ), "When the sequence loops, reverse the direction of play." ); + addField( "LoopCount", TypeS32, Offset( mLoopCount, VController ), "The number of times the sequence loops before stopping. -1 will cause the sequence to loop indefinitely." ); + addField( "LoopDelay", TypeS32, Offset( mLoopDelay, VController ), "When the sequence loops, delay playback by this value (in milliseconds)." ); + + addField( "ResetOnCompletion", TypeBool, Offset( mResetOnCompletion, VController ), "When the sequence is completed, reset the state of the Controller." ); + endGroup( "Controller" ); + + // Parent Call. + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// ITickable Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::processTick(); +// +// This method controls the playback of the entire sequence. It integrates all +// of the groups and handles sequence looping and jumping. +// +//----------------------------------------------------------------------------- +void VController::processTick( void ) +{ + if ( mTimeScale == 0.f ) + { + // Pause. + pause(); + + // Exit. + return; + } + + // Calculate Delta. + const S32 time = Sim::getCurrentTime(); + S32 delta = ( time - mLastTime ); + mLastTime = time; + + // Reverse? + if ( mTimeScale < 0.f ) + { + // Negative Delta. + delta *= -1; + } + + if ( mLoopDelayTime > 0 ) + { + // Update Delay Time. + mLoopDelayTime -= getMin( mAbs( delta ), mLoopDelayTime ); + + // Exit. + return; + } + + // Jump Delta? + if ( mJump == k_JumpDelta ) + { + // Jump. + delta = mJumpTime; + + // Clear. + mJump = k_JumpInvalid; + mJumpTime = 0; + } + + if ( ( isPlayingForward() && ( mTime + delta ) > mDuration ) + || ( !isPlayingForward() && ( mTime + delta ) < 0 ) ) + { + // Clamp Delta. + delta = ( ( mTimeScale > 0.f ) * mDuration ) - mTime; + + // Note: If we are playing forwards, we're at the end of the + // sequence and we want to loop/reset the Controller, then we + // need to handle that now. + if ( delta == 0 ) + { + onPostTick(); + } + } + + // Valid Delta? + if ( delta == 0 ) + { + // Exit. + return; + } + + // Trigger Update. + mControllerUpdateSignal.trigger( mTime, delta ); + + // Update Time. + mTime += delta; + + // Perform Post Tick. + onPostTick(); +} + +//----------------------------------------------------------------------------- +// +// VController::onPostTick(); +// +// This method is called onces a tick has been processed. It will perform the +// the right checks to see if the Controller has finished playing. It also +// handles special cases like Looping or Resetting the Controller. +// +//----------------------------------------------------------------------------- +void VController::onPostTick( void ) +{ + // Jump Time? + if ( mJump == k_JumpTime ) + { + // Jump Post Update. + reset( mJumpTime ); + + // Clear. + mJump = k_JumpInvalid; + mJumpTime = 0; + } + + // Sequence Completed? + if ( isPlayingForward() && mTime >= mDuration + || !isPlayingForward() && mTime <= 0 ) + { + bool stopPlaying = true; + if ( mLoop ) + { + // Don't Stop. + stopPlaying = false; + + if ( mLoopBackwards ) + { + // Change Direction. + setTimeScale( -1.f * mTimeScale ); + } + else + { + // Reset Time. + reset(); + } + + if ( mLoopDelay > 0 ) + { + // Resume After Delay. + mLoopDelayTime = mLoopDelay; + } + + // At the Start of the Sequence? + if ( mTime <= 0 && mLoopCount >= 0 ) + { + // Stop Looping? + stopPlaying = ( ++mLoopIndex >= mLoopCount ); + } + + // Callback. + Con::executef( this, "onLoop" ); + + // Loop Signal. + postEvent( k_EventLoop ); + } + + // Stop? + if ( stopPlaying ) + { + // Stop Only. + stop( mResetOnCompletion ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::reset(); +// +// Reset the Controller to the start of the sequence. +// +//----------------------------------------------------------------------------- +void VController::reset( void ) +{ + // Reset. + reset( ( isPlayingForward() ) ? 0 : mDuration ); +} + +//----------------------------------------------------------------------------- +// +// VController::reset( pTime ); +// +// Reset the Controller to the target time. This is a very important method as +// it allows tracks and events to reset their state as well as prepare +// themselves for playback. +// +//----------------------------------------------------------------------------- +void VController::reset( const S32 &pTime ) +{ + // Reset Time. + mTime = pTime; + mLastTime = Sim::getCurrentTime(); + + // Reset Delay Time. + mLoopDelayTime = 0; + + // Post Event. + postEvent( k_EventReset ); +} + +//----------------------------------------------------------------------------- +// +// VController::play(); +// +// Start playing the sequence from the current time and execute a number of +// callbacks. +// +//----------------------------------------------------------------------------- +void VController::play( void ) +{ + if ( isPlaying() || mTime < 0 || mTime > mDuration ) + { + // Sanity! + return; + } + + // Reset Time. + mLastTime = Sim::getCurrentTime(); + + // Start Updating. + setProcessTicks( true ); + + if ( mStatus & k_StatusInit ) + { + // Init Signal. + postEvent( k_EventInit ); + + // Clear Init Status. + mStatus &= ~k_StatusInit; + } + + // Update Status. + updateStatus( k_StatusPlaying ); + + // Play Signal. + postEvent( k_EventPlay ); + + // Callback. + Con::executef( this, "onPlay" ); +} + +//----------------------------------------------------------------------------- +// +// VController::play( pTime ); +// +// Start playing the sequence from the desired time. +// +//----------------------------------------------------------------------------- +void VController::play( const S32 &pTime ) +{ + // Reset. + reset( pTime ); + + // Play. + play(); +} + +//----------------------------------------------------------------------------- +// +// VController::pause(); +// +// Cease playback of the sequence, but maintain the current time. +// +//----------------------------------------------------------------------------- +void VController::pause( void ) +{ + // Stop Updating. + setProcessTicks( false ); + + // Update Status. + updateStatus( k_StatusPaused ); + + // Pause Signal. + postEvent( k_EventPause ); + + // Callback. + Con::executef( this, "onPause" ); +} + +//----------------------------------------------------------------------------- +// +// VController::stop( pReset ); +// +// Stop playback altogether and reset the Controller to the start of the +// sequence. +// +//----------------------------------------------------------------------------- +void VController::stop( const bool &pReset ) +{ + // Stop Updating. + setProcessTicks( false ); + + // Reset Loop Index. + mLoopIndex = 0; + + // Update Status. + updateStatus( ( k_StatusInit | k_StatusStopped ) ); + + // Reset? + if ( pReset ) + { + // Reset. + reset(); + } + + // Stop Signal. + postEvent( k_EventStop ); + + // Callback. + Con::executef( this, "onStop" ); +} + +//----------------------------------------------------------------------------- +// +// VController::jump(); +// +// Jump the Controller time forward 1 tick (32ms). +// +//----------------------------------------------------------------------------- +void VController::jump( void ) +{ + // Jump 1 tick. + jump( k_JumpDelta, ( isPlayingForward() ) ? TickMs : -TickMs ); +} + +//----------------------------------------------------------------------------- +// +// VController::jump( pType, pDelta ); +// +// Jump the Controller time by the target Delta. +// +//----------------------------------------------------------------------------- +void VController::jump( const eControllerJumpType &pType, const S32 &pDelta ) +{ + // Jump. + mJump = pType; + mJumpTime = pDelta; +} + +//----------------------------------------------------------------------------- +// +// VController::updateStatus( pStatus ); +// +// Clear the regular playback states and add the updated state. +// +//----------------------------------------------------------------------------- +void VController::updateStatus( const S32 &pStatus ) +{ + // Clear Playback Status. + mStatus &= ~( k_StatusPlaying | k_StatusPaused | k_StatusStopped ); + + // Add New Status. + mStatus |= pStatus; +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::getObject( pLabel ); +// +// Returns the group with the given name. If no group belongs to the Controller +// with that name, then a NULL value is returned. +// +//----------------------------------------------------------------------------- +VGroup *VController::getObject( const String &pLabel ) +{ + VGroup *node = ( VGroup* )mChildNode; + while ( node ) + { + // Compare Names. + if ( node->getLabel().equal( pLabel, String::NoCase ) ) + { + // Valid. + return node; + } + + // Next Sibling. + node = ( VGroup* )node->mSiblingNextNode; + } + + // Invalid. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VController::getDirectorGroup(); +// +// Returns the DirectorGroup reference if the Controller has a one. +// +//----------------------------------------------------------------------------- +VDirectorGroup *VController::getDirectorGroup( void ) +{ + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + if ( VDirectorGroup *group = dynamic_cast( node ) ) + { + // Return Group. + return group; + } + } + + // Invalid Group. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VController::getDirectorTrack(); +// +// Returns the DirectorTrack reference if the DirectorGroup has one. +// +//----------------------------------------------------------------------------- +VDirectorTrack *VController::getDirectorTrack( void ) +{ + VDirectorGroup *group = getDirectorGroup(); + if ( !group ) + { + // Invalid Track. + return NULL; + } + + // Return Track. + return group->getDirectorTrack(); +} + +//----------------------------------------------------------------------------- +// +// VController::getDataValue( pFieldName, *pValue ); +// +// Returns true if the field is a DataTable member and can be correctly +// evaluated. If this is the case, then pValue will contain the result. +// +//----------------------------------------------------------------------------- +bool VController::getDataValue( const String &pFieldName, String &pValue ) +{ + return mDataTable.getValue( this, pFieldName, pValue ); +} + +//----------------------------------------------------------------------------- +// +// VController::clearData(); +// +// Clear the contents of the DataTable entirely. +// +//----------------------------------------------------------------------------- +void VController::clearData( void ) +{ + while ( mDataTable.getCount() > 0 ) + { + // Clear Item. + clearData( 0 ); + } +} + +//----------------------------------------------------------------------------- +// +// VController::clearData( pIndex ); +// +// Clear the DataTable entry with the given index. +// +//----------------------------------------------------------------------------- +void VController::clearData( const S32 &pIndex ) +{ + VDataTable::sDataItem data; + if ( mDataTable.getItem( pIndex, &data ) ) + { + // Clear Data. + clearData( data.FieldName ); + } +} + +//----------------------------------------------------------------------------- +// +// VController::clearData( pIndex ); +// +// Clear the DataTable entry with the given field name. +// +//----------------------------------------------------------------------------- +void VController::clearData( const String &pFieldName ) +{ + // Clear Dynamic Field. + setDataField( pFieldName, NULL, "" ); + + // Clear Item. + mDataTable.clear( pFieldName ); +} + +//----------------------------------------------------------------------------- +// +// VController::sort(); +// +// Sort each track in each of the child groups. +// +//----------------------------------------------------------------------------- +void VController::sort( void ) +{ + for ( ITreeNode *group = mChildNode; group != NULL; group = group->mSiblingNextNode ) + { + for ( ITreeNode *track = group->mChildNode; track != NULL; track = track->mSiblingNextNode ) + { + // Sort Track. + ( ( VTrack* )track )->sort(); + } + } +} + +//----------------------------------------------------------------------------- +// +// Write Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::writeDataTable( pElement ); +// +// Write the DataTable out to a TinyXML document. +// +//----------------------------------------------------------------------------- +bool VController::writeDataTable( TiXmlElement *pElement ) +{ + // Create Data Table Root. + TiXmlElement *dataTableRoot = new TiXmlElement( "DataTable" ); + pElement->LinkEndChild( dataTableRoot ); + + for ( VDataTable::VDataMap::Iterator itr = mDataTable.mDataMap.begin(); itr != mDataTable.mDataMap.end(); ++itr ) + { + // Fetch Data. + VDataTable::sDataItem *data = &itr->value; + + // Create Element. + TiXmlElement *dataElement = new TiXmlElement( "DataItem" ); + + // Apply Attributes. + dataElement->SetAttribute( "Type", VDataTable::getDataTypeDescription( data->Type ) ); + dataElement->SetAttribute( "Name", data->FieldName ); + dataElement->SetAttribute( "Value", getDataField( StringTable->insert( data->FieldName.c_str() ), NULL ) ); + + // Add. + dataTableRoot->LinkEndChild( dataElement ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Read Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::readDataTable( pElement ); +// +// Read the DataTable from a TinyXML document. +// +//----------------------------------------------------------------------------- +bool VController::readDataTable( TiXmlElement *pElement ) +{ + TiXmlElement *dataTableRoot = pElement->FirstChildElement( "DataTable" ); + if ( dataTableRoot ) + { + for ( TiXmlElement *child = dataTableRoot->FirstChildElement(); child != NULL; child = child->NextSiblingElement() ) + { + // Get Field Data. + const char *fieldType = child->Attribute( "Type" ); + const char *fieldName = child->Attribute( "Name" ); + const char *fieldValue = child->Attribute( "Value" ); + + // Add Data Item. + mDataTable.insert( VDataTable::getDataTypeEnum( fieldType ), fieldName ); + + // Set Field Value. + setDataField( StringTable->insert( fieldName ), NULL, fieldValue ); + } + } + + // Valid Read. + return true; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::postEvent( pEvent ); +// +// Process an event signal to all event subscribers. This method is used to +// signal changes in the Controller's status. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +void VController::postEvent( const eControllerEventType &pEvent ) +{ + // Signal Event. + mControllerEventSignal.trigger( pEvent ); +} + +//----------------------------------------------------------------------------- +// +// VController::setTimeScale( pTimeScale ); +// +// Set the speed of playback. In effect, a value of 0.5 will double the real +// time taken to complete the playback of the sequence, while a value of 2.0 +// will halve the time needed. +// +//----------------------------------------------------------------------------- +void VController::setTimeScale( const F32 &pTimeScale ) +{ + // Need an Update? + const bool update = ( pTimeScale != 0.f && ( mTimeScale == 0.f || ( ( mTimeScale > 0.f ) != ( pTimeScale > 0.f ) ) ) ); + + // Store. + mTimeScale = pTimeScale; + + // Update $timeScale Variable. + Con::setFloatVariable( "timeScale", mFabs( mTimeScale ) ); + + if ( update ) + { + // Reset. + reset( mTime ); + } +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VController, readFile, bool, 3, 3, "( string pFileName ) - Clears the object and loads the new data from the given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Buffer the FileName. + // Note: This is done because the arg variables can be altered during any + // Callbacks or Console Methods called while clearing the Controller. + char fileName[1024]; + dStrcpy( fileName, argv[2] ); + + // Clear Sequence Lists. + object->clear(); + + // Clear Data Table. + object->clearData(); + + // Read Target File. + if ( !VPersistence::readFile( fileName, object ) ) + { + // Re-Clear. + object->clear(); + + // Invalid Read. + return false; + } + + // Initial Sort. + object->sort(); + + // Reset. + object->reset(); + + // Valid Read. + return true; +} + +ConsoleMethod( VController, clear, void, 2, 2, "( void ) - Detaches and deletes all of the child objects.\n" + "@return No return value." ) +{ + // Clear Sequence Lists. + object->clear(); + + // Clear Data Table. + object->clearData(); +} + +ConsoleMethod( VController, reset, void, 2, 3, "( [int pTime] ) - Reset the Controller's and child object's state.\n" + "@param pTime The target time to reset to.\n" + "@return No return value." ) +{ + if ( argc >= 3 ) + { + // Reset Sequence. + object->reset( dAtoi( argv[2] ) ); + return; + } + + // Default Reset. + object->reset(); +} + +ConsoleMethod( VController, isPlaying, bool, 2, 2, "( void ) - Is the sequence currently playing?\n" + "@return Returns true if the Controller is playing." ) +{ + // Is Playing? + return ( object->isPlaying() ); +} + +ConsoleMethod( VController, play, void, 2, 3, "( [int pTime] ) - Play the sequence. If a value for pTime is specified, the Controller is reset and played from that time.\n" + "@param pTime The time to start playing the sequence from.\n" + "@return No return value." ) +{ + S32 startTime = object->getTime(); + if ( argc >= 3 ) + { + startTime = dAtoi( argv[2] ); + } + + // Play From Specified Time. + object->play( startTime ); +} + +ConsoleMethod( VController, step, void, 2, 2, "( void ) - Step forward one frame.\n" + "@return No return value." ) +{ + if ( object->isPlaying() ) + { + // Sanity! + return; + } + + // Play. + object->play( object->getTime() ); + + // Jump. + object->jump(); + + // Step Forward One Frame. + object->processTick(); + + // Stop. + object->stop( false ); +} + +ConsoleMethod( VController, isPaused, bool, 2, 2, "( void ) - Is the sequence currently paused?\n" + "@return Returns true if the Controller is paused." ) +{ + // Is Paused? + return ( object->isPaused() ); +} + +ConsoleMethod( VController, pause, void, 2, 2, "( void ) - Pause the sequence. Playback can resume by calling VController::play().\n" + "@return No return value." ) +{ + // Pause Sequence. + object->pause(); +} + +ConsoleMethod( VController, isStopped, bool, 2, 2, "( void ) - Is the sequence currently stopped?\n" + "@return Returns true if the Controller is stopped." ) +{ + // Is Stopped? + return ( object->isStopped() ); +} + +ConsoleMethod( VController, stop, void, 2, 3, "( [bool pReset] ) - Stop the sequence and optionally reset it.\n" + "@param pReset Reset the Controller after stopping.\n" + "@return No return value." ) +{ + // Stop Sequence. + object->stop( ( argc == 3 ) ? dAtob( argv[2] ) : true ); +} + +ConsoleMethod( VController, getTimeScale, F32, 2, 2, "( void ) - Get the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards.\n" + "@return Playback Speed." ) +{ + // Get Time Scale. + return object->getTimeScale(); +} + +ConsoleMethod( VController, setTimeScale, void, 3, 3, "( float pTimeScale ) - Set the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |pTimeScale| > 1.0, then playback will be faster than normal, while |pTimeScale| < 1.0 will be slower.\n" + "@param pTimeScale Playback speed.\n" + "@return No return value." ) +{ + // Set Time Scale. + object->setTimeScale( dAtof( argv[2] ) ); +} + +ConsoleMethod( VController, isDataField, bool, 3, 3, "( string pFieldName ) - Is the field a member of the Data Table?\n" + "@param pFieldName The name of the dynamic field you wish to check.\n" + "@return Returns true if the field is a member of the Data Table." ) +{ + if ( argv[2][0] == '\0' ) + { + return false; + } + + // Is Field. + return object->getDataTable().getItem( argv[2] ); +} + +ConsoleMethod( VController, getDataFieldCount, S32, 2, 2, "( void ) - Get the number of data elements in the Data Table.\n" + "@return Returns the size of the Data Table." ) +{ + // Return Count. + return object->getDataTable().getCount(); +} + +ConsoleMethod( VController, getDataFieldName, const char *, 3, 3, "( int pIndex ) - Get the name of the field given by the passed index.\n" + "@param pIndex The index of the data field you wish to check.\n" + "@return Returns the name of the field corresponding to the given index." ) +{ + VDataTable::sDataItem data; + if ( !object->getDataTable().getItem( dAtoi( argv[2] ), &data ) || data.Type == VDataTable::k_TypeInvalid ) + { + // Invalid Field. + return ""; + } + + // Return Field Name. + return data.FieldName; +} + +ConsoleMethod( VController, getDataFieldValue, const char *, 3, 3, "( string pFieldName ) - Get the evaluated data from the data field.\n" + "@param pFieldName The name of the field you wish to evaluate.\n" + "@return Returns the evaluated data from the field." ) +{ + String fieldValue; + if ( object->getDataValue( argv[2], fieldValue ) ) + { + // Create Buffer. + char *buffer = Con::getReturnBuffer( 256 ); + dStrcpy( buffer, fieldValue.c_str() ); + + // Return Value. + return buffer; + } + + // Return NULL. + return "0"; +} + +ConsoleMethod( VController, getDataFieldType, const char *, 3, 3, "( string pFieldName ) - Get the type of data for the given field.\n" + "@param pFieldName The name of the field you wish to check.\n" + "@return Returns the data type." ) +{ + VDataTable::sDataItem data; + if ( !object->getDataTable().getItem( argv[2], &data ) || data.Type == VDataTable::k_TypeInvalid ) + { + // Invalid Field. + return ""; + } + + // Return Field Type. + return VDataTable::getDataTypeDescription( data.Type ); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VController, writeFile, bool, 3, 3, "( string pFileName ) - Save to a given filename.\n" + "@param pFileName The target file to write to.\n" + "@return Returns true if the write was successful." ) +{ + // Write Target File. + return VPersistence::writeFile( argv[2], object ); +} + +ConsoleMethod( VController, readTemplate, bool, 3, 3, "( string pFileName ) - Load data from given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Read Target File. + return VPersistence::readFile( argv[2], object ); +} + +ConsoleMethod( VController, getCount, S32, 2, 2, "( void ) - Get the number of child objects.\n" + "@return Returns the number of child objects." ) +{ + // Size. + return object->size(); +} + +ConsoleMethod( VController, getObject, S32, 3, 3, "( int pIndex ) - Get the object corresponding to the given index.\n" + "@param pIndex The index of the object you wish to retrieve.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->at( dAtoi( argv[2] ) ); + + // Return Group ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +ConsoleMethod( VController, addObject, void, 3, 3, "( SimObject pObject ) - Add a child object to this node.\n" + "@param pObject The SimObjectID of the object to be added to this node.\n" + "@return No return value." ) +{ + VObject *child = dynamic_cast( Sim::findObject( argv[2] ) ); + if ( child ) + { + // Add Child. + child->addTo( object ); + } +} + +ConsoleMethod( VController, removeObject, void, 3, 3, "( SimObject pObject ) - Remove the target object from this node.\n" + "@param pObject The SimObjectID of the object to be removed from this node.\n" + "@return No return value." ) +{ + VObject *child = dynamic_cast( Sim::findObject( argv[2] ) ); + if ( child && child->getParent() == object ) + { + child->remove(); + } +} + +ConsoleMethod( VController, sortGroups, void, 2, 2, "( void ) - Sort Groups by their Labels.\n" + "@return No return value." ) +{ + // Ensure that the Director Group is the First Group. + VDirectorGroup *directorGroup = object->getDirectorGroup(); + if ( directorGroup && directorGroup != object->mChildNode ) + { + // Detach. + directorGroup->remove(); + + // Add to the Front of the Controller. + directorGroup->addToFront( object ); + } + + const S32 count = object->size(); + for ( S32 j = 0; j < count; j++ ) + { + ITreeNode *node = object->mChildNode; + if ( dynamic_cast( node ) != NULL ) + { + // Skip Director Group. + node = node->mSiblingNextNode; + } + + for ( ; node != NULL; node = node->mSiblingNextNode ) + { + VGroup *groupA = ( VGroup* )node; + VGroup *groupB = ( VGroup* )node->mSiblingNextNode; + if ( !groupB ) + { + // No Node. + break; + } + + // Swap? + if ( dStrcmp( groupA->getLabel(), groupB->getLabel() ) > 0 ) + { + // Get Outer Siblings. + ITreeNode *prevNode = groupA->mSiblingPrevNode; + ITreeNode *nextNode = groupB->mSiblingNextNode; + + if ( groupA->mParentNode && groupA->mParentNode->mChildNode == groupA ) + { + // New Child Node. + groupA->mParentNode->mChildNode = groupB; + } + + // + // Move A. + + groupA->mSiblingPrevNode = groupB; + groupA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = groupA; + } + + // + // Move B. + + groupB->mSiblingPrevNode = prevNode; + groupB->mSiblingNextNode = groupA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = groupB; + } + } + } + } +} + +ConsoleMethod( VController, sortTracks, void, 2, 2, "( void ) - Sort Tracks by their Labels.\n" + "@return No return value." ) +{ + for ( ITreeNode *group = object->mChildNode; group != NULL; group = group->mSiblingNextNode ) + { + const S32 count = ( ( VGroup* )group )->size(); + for ( S32 j = 0; j < count; j++ ) + { + for ( ITreeNode *node = group->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VTrack *trackA = ( VTrack* )node; + VTrack *trackB = ( VTrack* )node->mSiblingNextNode; + if ( !trackB ) + { + // No Node. + break; + } + + // Swap? + if ( dStrcmp( trackA->getLabel(), trackB->getLabel() ) > 0 ) + { + // Get Outer Siblings. + ITreeNode *prevNode = trackA->mSiblingPrevNode; + ITreeNode *nextNode = trackB->mSiblingNextNode; + + if ( trackA->mParentNode && trackA->mParentNode->mChildNode == trackA ) + { + // New Child Node. + trackA->mParentNode->mChildNode = trackB; + } + + // + // Move A. + + trackA->mSiblingPrevNode = trackB; + trackA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = trackA; + } + + // + // Move B. + + trackB->mSiblingPrevNode = prevNode; + trackB->mSiblingNextNode = trackA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = trackB; + } + } + } + } + } +} + +ConsoleMethod( VController, addDataField, void, 4, 4, "( string pFieldType, string pFieldName ) - Add a new data entry to the Data Table.\n" + "@param pFieldType The method of evaluating the field's data.\n" + "@param pFieldName The name of the field to be added to the Data Table.\n" + "@return No return value." ) +{ + // Insert Data. + object->getDataTable().insert( VDataTable::getDataTypeEnum( argv[2] ), argv[3] ); +} + +ConsoleMethod( VController, removeDataField, void, 3, 3, "( string pFieldName ) - Remove a data entry from the Data Table.\n" + "@param pFieldName The name of the field to be removed from the Data Table.\n" + "@return No return value." ) +{ + // Clear Data Item. + object->clearData( argv[2] ); +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VController.h b/Engine/modules/Verve/Core/VController.h new file mode 100644 index 000000000..f38a1cdf0 --- /dev/null +++ b/Engine/modules/Verve/Core/VController.h @@ -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_VCONTROLLER_H_ +#define _VT_VCONTROLLER_H_ + +#ifndef _VT_VERVECONFIG_H_ +#include "Verve/VerveConfig.h" +#endif + +#ifndef _PLATFORM_H_ +#include "platform/platform.h" +#endif + +#ifndef _PROCESSLIST_H_ +#include "T3D/gameBase/processList.h" +#endif + +#ifndef _ITICKABLE_H_ +#include "core/iTickable.h" +#endif + +#ifndef _VT_VPERSISTENCE_H_ +#include "Verve/Core/Persistence/VPersistence.h" +#endif + +#ifndef _VT_VTREENODE_H_ +#include "Verve/Core/VTreeNode.h" +#endif + +#ifndef _VT_VDATATABLE_H_ +#include "Verve/Core/VDataTable.h" +#endif + +#ifndef _VT_TORQUE_CAMERA_H_ +#include "Verve/Torque/TCamera.h" +#endif + +//----------------------------------------------------------------------------- +class VObject; + +class VTrack; +class VEvent; +class VGroup; + +class VDirectorGroup; +class VDirectorTrack; + +typedef VectorPtr VTrackVector; +typedef VTrackVector::iterator VTrackIterator; + +typedef VectorPtr VEventVector; +typedef VEventVector::iterator VEventIterator; + +typedef VectorPtr VGroupVector; +typedef VGroupVector::iterator VGroupIterator; +//----------------------------------------------------------------------------- + +class VController : public SimObject, + public virtual ITickable, + public VTreeNode +{ + typedef SimObject Parent; + +public: + + enum eControllerStatus + { + k_StatusInit = BIT( 0 ), + + k_StatusPlaying = BIT( 1 ), + k_StatusPaused = BIT( 2 ), + k_StatusStopped = BIT( 3 ), + }; + + enum eControllerEventType + { + k_EventInit, + k_EventReset, + + k_EventPlay, + k_EventPause, + k_EventStop, + + k_EventLoop, + }; + + enum eControllerJumpType + { + k_JumpTime, + k_JumpDelta, + + k_JumpInvalid, + }; + + typedef Signal ControllerUpdateSignal; + typedef Signal ControllerEventSignal; + +private: + + // Data. + + VDataTable mDataTable; + + // Event Signal. + + ControllerUpdateSignal mControllerUpdateSignal; + ControllerEventSignal mControllerEventSignal; + + // Properties. + + S32 mStatus; + + S32 mTime; + U32 mLastTime; + S32 mDuration; + F32 mTimeScale; + + bool mLoop; + bool mLoopBackwards; + S32 mLoopCount; + S32 mLoopIndex; + S32 mLoopDelay; + S32 mLoopDelayTime; + + eControllerJumpType mJump; + S32 mJumpTime; + + bool mResetOnCompletion; + +public: + + VController(); + ~VController(); + + static void initPersistFields( void ); + + // ITickable. + + void interpolateTick( F32 pDelta ) { }; + void advanceTime( F32 pDelta ) { }; + void processTick( void ); + void onPostTick( void ); + + // Controller. + + void reset( void ); + void reset( const S32 &pTime ); + + void play( void ); + void play( const S32 &pTime ); + + void pause( void ); + void stop( const bool &pReset = true ); + + void jump( void ); + void jump( const eControllerJumpType &pType, const S32 &pDelta ); + + void updateStatus( const S32 &pStatus ); + + // Reference. + + VGroup *getObject( const String &pLabel ); + template inline bool getObject( const String &pLabel, T *&pObject ) + { + // Reference Group. + pObject = dynamic_cast( getObject( pLabel ) ); + + // Valid? + return ( pObject != NULL ); + } + + bool getDataValue( const String &pFieldName, String &pValue ); + void clearData( void ); + void clearData( const S32 &pIndex ); + void clearData( const String &pFieldName ); + + void sort( void ); + + // Saving. + + bool writeDataTable( TiXmlElement *pElement ); + + // Reading. + + bool readDataTable( TiXmlElement *pElement ); + + // Console Declaration. + + DECLARE_CONOBJECT( VController ); + +public: + + inline VDataTable &getDataTable( void ) { return mDataTable; }; + + inline ControllerUpdateSignal &getControllerUpdateSignal( void ) { return mControllerUpdateSignal; }; + inline ControllerEventSignal &getControllerEventSignal( void ) { return mControllerEventSignal; }; + void postEvent( const eControllerEventType &pEvent ); + + VDirectorGroup *getDirectorGroup( void ); + VDirectorTrack *getDirectorTrack( void ); + + inline void setTime( const S32 &pTime ) { mTime = pTime; }; + inline void setDuration( const S32 &pDuration ) { mDuration = pDuration; }; + void setTimeScale( const F32 &pTimeScale ); + + inline bool isLooping( void ) { return mLoop; }; + inline bool isPlaying( void ) { return ( mStatus & k_StatusPlaying ); }; + inline bool isPaused( void ) { return ( mStatus & k_StatusPaused ); }; + inline bool isStopped( void ) { return ( mStatus & k_StatusStopped ); }; + inline bool isPlayingForward( void ) { return ( mTimeScale > 0.f ); }; + + inline S32 getTime( void ) { return mTime; }; + inline S32 getDuration( void ) { return mDuration; }; + inline F32 getTimeScale( void ) { return mTimeScale; }; + inline S32 getLoopDelayTime( void ) { return mLoopDelayTime; }; + +protected: + + static bool setTime( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setTime( dAtoi( pData ) ); return false; }; + static bool setDuration( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setDuration( dAtoi( pData ) ); return false; }; + static bool setTimeScale( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setTimeScale( dAtof( pData ) ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VDataTable.cpp b/Engine/modules/Verve/Core/VDataTable.cpp new file mode 100644 index 000000000..5f9046428 --- /dev/null +++ b/Engine/modules/Verve/Core/VDataTable.cpp @@ -0,0 +1,254 @@ +//----------------------------------------------------------------------------- +// 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/VDataTable.h" + +#include "console/simObject.h" + +//----------------------------------------------------------------------------- + +// Implement the DataType enum list. +ImplementEnumType( VDataTableDataType, "" ) + { VDataTable::k_TypeExpression, "EXPRESSION" }, + { VDataTable::k_TypeStatic, "STATIC" }, + { VDataTable::k_TypeVariable, "VARIABLE" }, +EndImplementEnumType; + +VDataTable::eDataType VDataTable::getDataTypeEnum( const char *pLabel ) +{ + VDataTable::eDataType out; + if ( !castConsoleTypeFromString( out, pLabel ) ) + { + // Bah! + return VDataTable::k_TypeInvalid; + } + + // Return. + return out; +} + +const char *VDataTable::getDataTypeDescription( const VDataTable::eDataType pEnum ) +{ + // Return. + return castConsoleTypeToString( pEnum ); +} + +//----------------------------------------------------------------------------- + +VDataTable::VDataTable( void ) +{ + mDataMap.clear(); +} + +VDataTable::~VDataTable( void ) +{ + mDataMap.clear(); +} + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDataTable::insert( pType, pFieldName ); +// +// Add a DataTable entry, referencing the field name and assign it the given +// data type. +// +// For a full list of possible data types, see the 'eDataType' declaration in +// VDataTable.h. +// +//----------------------------------------------------------------------------- +void VDataTable::insert( eDataType pType, const String &pFieldName ) +{ + if ( mDataMap.contains( pFieldName ) ) + { + // Change Field Type. + mDataMap.find( pFieldName )->value.Type = pType; + + // Return. + return; + } + + // Insert Item. + mDataMap.insert( pFieldName, sDataItem( pType, pFieldName ) ); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::clear( pFieldName ); +// +// Clear the DataTable entry with the given field name. +// +//----------------------------------------------------------------------------- +void VDataTable::clear( const String &pFieldName ) +{ + // Clear Item. + mDataMap.erase( pFieldName ); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::clear(); +// +// Clear the contents of the DataTable entirely. +// +//----------------------------------------------------------------------------- +void VDataTable::clear( void ) +{ + // Clear. + mDataMap.clear(); +} + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDataTable::getCount(); +// +// Return the number of DataTable entries. +// +//----------------------------------------------------------------------------- +S32 VDataTable::getCount( void ) +{ + return mDataMap.size(); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getItem( pIndex, *pDataItem ); +// +// Return the item with the given index. This method will return false if there +// is no valid data entry with that index. +// +//----------------------------------------------------------------------------- +bool VDataTable::getItem( const S32 &pIndex, sDataItem *pDataItem ) +{ + if ( pIndex < 0 || pIndex >= mDataMap.size() ) + { + // Invalid Field. + return false; + } + + S32 index = 0; + for ( VDataMap::Iterator itr = mDataMap.begin(); itr != mDataMap.end(); ++itr ) + { + if ( index == pIndex ) + { + if ( pDataItem ) + { + // Store Reference. + *pDataItem = ( itr->value ); + } + + // Valid Field. + return true; + } + + // Increment. + ++index; + } + + // Invalid Field. + return false; +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getItem( pFieldName, *pDataItem ); +// +// Return the item with the given field name. This method will return false if +// there is no valid data entry with that name. +// +//----------------------------------------------------------------------------- +bool VDataTable::getItem( const String &pFieldName, sDataItem *pDataItem ) +{ + if ( mDataMap.contains( pFieldName ) ) + { + if ( pDataItem ) + { + // Fetch Item + *pDataItem = mDataMap.find( pFieldName )->value; + } + + // Valid Field. + return true; + } + + // Invalid Field. + return false; +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getValue( pObject, pFieldName, *pValue ); +// +// Evaluate and return the expression provided in the data field. +// +//----------------------------------------------------------------------------- +bool VDataTable::getValue( SimObject *pObject, const String &pFieldName, String &pValue ) +{ + if ( !pObject || pFieldName.isEmpty() ) + { + // Sanity! + return false; + } + + // Fetch Data. + sDataItem *data = &( mDataMap.find( pFieldName )->value ); + if ( !data ) + { + // No Field. + return false; + } + + // Field Value. + const char *fieldValue = pObject->getDataField( StringTable->insert( data->FieldName ), NULL ); + + switch ( data->Type ) + { + case VDataTable::k_TypeExpression : + { + + // Evaluate. + pValue = Con::evaluate( fieldValue, false ); + + } break; + + case VDataTable::k_TypeStatic : + { + // Use Value. + pValue = fieldValue; + + } break; + + case VDataTable::k_TypeVariable : + { + + // Fetch Variable. + pValue = Con::getVariable( fieldValue ); + + } break; + } + + // Valid Field. + return true; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VDataTable.h b/Engine/modules/Verve/Core/VDataTable.h new file mode 100644 index 000000000..6b4cba90a --- /dev/null +++ b/Engine/modules/Verve/Core/VDataTable.h @@ -0,0 +1,118 @@ +//----------------------------------------------------------------------------- +// 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_VDATATABLE_H_ +#define _VT_VDATATABLE_H_ + +#ifndef CORE_TDICTIONARY_H +#include "core/util/tDictionary.h" +#endif + +#ifndef _CONSOLE_H_ +#include "console/console.h" +#endif + +#ifndef _DYNAMIC_CONSOLETYPES_H_ +#include "console/dynamicTypes.h" +#endif + +#ifndef _STRINGTABLE_H_ +#include "core/stringTable.h" +#endif + +//----------------------------------------------------------------------------- + +class VDataTable +{ +public: + + enum eDataType + { + k_TypeExpression, + k_TypeStatic, + k_TypeVariable, + + k_TypeInvalid, + }; + + struct sDataItem + { + eDataType Type; + String FieldName; + + sDataItem( void ) : + Type( k_TypeInvalid ), + FieldName( String::EmptyString ) + { + // Void. + }; + + sDataItem( eDataType pType, const String &pFieldName ) : + Type( pType ), + FieldName( pFieldName ) + { + // Void. + }; + }; + + // Enum Lookup. + static VDataTable::eDataType getDataTypeEnum( const char *pLabel ); + static const char *getDataTypeDescription( const VDataTable::eDataType pEnum ); + + // Map Type. + typedef Map VDataMap; + +public: + + VDataMap mDataMap; + +public: + + VDataTable( void ); + ~VDataTable( void ); + + // Data. + + void insert( eDataType pType, const String &pFieldName ); + void clear( const String &pFieldName ); + void clear( void ); + + // Reference. + + S32 getCount( void ); + bool getItem( const S32 &pIndex, sDataItem *pDataItem = NULL ); + bool getItem( const String &pFieldName, sDataItem *pDataItem = NULL ); + + bool getValue( SimObject *pObject, const String &pFieldName, String &pValue ); +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VDataTable::eDataType VDataTableDataType; + +// Declare Enum Types. +DefineEnumType( VDataTableDataType ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VDATATABLE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VEvent.cpp b/Engine/modules/Verve/Core/VEvent.cpp new file mode 100644 index 000000000..6b4e8ed54 --- /dev/null +++ b/Engine/modules/Verve/Core/VEvent.cpp @@ -0,0 +1,406 @@ +//----------------------------------------------------------------------------- +// 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/VEvent.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VTrack.h" + +#include "console/consoleTypes.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEvent ); +//----------------------------------------------------------------------------- + +VEvent::VEvent( void ) : + mIsPlaying( false ), + mTriggered( false ), + mTriggerTime( 0 ), + mDuration( 0 ) +{ + setLabel( "DefaultEvent" ); +} + +void VEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "TriggerTime", TypeS32, Offset( mTriggerTime, VEvent ), &setTriggerTime, &defaultProtectedGetFn, "The time that this event is triggered." ); + addProtectedField( "Duration", TypeS32, Offset( mDuration, VEvent ), &setDuration, &defaultProtectedGetFn, "The total duration that this event plays for." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::onControllerReset( pTime, pForward ); +// +// Reset the status of the event. If the given time is between the event's +// start and finish times, then the isPlaying flag will be true. This means +// that the event is free to be triggered upon playback. +// +//----------------------------------------------------------------------------- +void VEvent::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Reset Status. + mIsPlaying = ( pTime > mTriggerTime && pTime < ( mTriggerTime + mDuration ) ); + mTriggered = false; +} + +//----------------------------------------------------------------------------- +// +// VEvent::onControllerUpdate( pTime, pDelta ) +// +// Integrate is only called when this event is the Next Event for the parent +// track. For each track, there is only ever *one* event being integrated - the +// event that needs to be triggered next. +// +// If the event has a duration greater than 0, then this event will continue to +// integrate until its time is up, or the controller finishes playing +// (whichever happens first). +// +// If a value of true is returned, then this event will continue to integrate +// until a value of false is returned to the parent track. When this happens, +// this event ceases to be the track's Next Event and will not continue +// updating. +// +//----------------------------------------------------------------------------- +bool VEvent::onControllerUpdate( const S32 &pTime, const S32 &pDelta ) +{ + if ( !isEnabled() ) + { + return false; + } + + const S32 newTime = ( pTime + pDelta ); + const S32 &startTime = getStartTime(); + const S32 &finishTime = getFinishTime(); + + if ( !mIsPlaying || !mTriggered ) + { + if ( !mIsPlaying ) + { + if ( ( pDelta > 0 && newTime < startTime ) + || ( pDelta < 0 && newTime > startTime ) ) + { + // Not Time to Trigger. + return true; + } + + if ( ( pDelta > 0 && pTime > startTime ) + || ( pDelta < 0 && pTime < startTime ) ) + { + //AssertFatal( false, "VEvent::onControllerUpdate() - Event has been skipped." ); + return false; + } + } + + if ( !mTriggered ) + { + // Play and Trigger. + mIsPlaying = ( mDuration > 0 ); + mTriggered = true; + + // Callback. + onTrigger( pTime, pDelta ); + + if ( mDuration == 0 ) + { + // Stop Integrating. + return false; + } + + // Return Here. + // Note: If Duration is non-zero this event will continue to update + // so that VEvent:: onUpdate is processed for the full event + // duration. + return ( mDuration != 0 ); + } + } + + // Complete? + const bool isComplete = ( ( pDelta > 0 && newTime > finishTime ) + || ( pDelta < 0 && newTime < finishTime ) ); + + if ( !isComplete ) + { + // Callback. + onUpdate( pTime, pDelta ); + } + else + { + // Complete. + mIsPlaying = false; + + // Callback. + onComplete( pTime, pDelta ); + } + + // Continue? + return !isComplete; +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::onTrigger( pTime, pDelta ); +// +// This method is called when an event is due to be triggered. This method is +// meant to be overloaded by derived classes. +// +// For examples of what an event might do, please refer to some of the included +// events with Verve. +// +//----------------------------------------------------------------------------- +void VEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// VEvent::onUpdate( pTime, pDelta ); +// +// This method is called each tick once an event has been triggered and ceases +// to be called when it is completed. This method is meant to be overloaded by +// derived classes. +// +//----------------------------------------------------------------------------- +void VEvent::onUpdate( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// VEvent::onComplete( pTime, pDelta ); +// +// This method is called once an event has finished being updated. It is not +// called on events that have a duration of 0. This method is meant to be +// overloaded by derived classes. +// +//----------------------------------------------------------------------------- +void VEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::getGroup(); +// +// Returns the parent group. +// +//----------------------------------------------------------------------------- +VGroup *VEvent::getGroup( void ) +{ + VTrack *track = getTrack(); + if ( track ) + { + return track->getGroup(); + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VEvent::getTrack(); +// +// Returns the parent track. +// +//----------------------------------------------------------------------------- +VTrack *VEvent::getTrack( void ) +{ + return dynamic_cast( mParentNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getNextEvent(); +// +// Returns the next event. +// +//----------------------------------------------------------------------------- +VEvent *VEvent::getNextEvent( void ) +{ + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( mSiblingPrevNode ); + } + + return dynamic_cast( mSiblingNextNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getPreviousEvent(); +// +// Returns the previous event. +// +//----------------------------------------------------------------------------- +VEvent *VEvent::getPreviousEvent( void ) +{ + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( mSiblingNextNode ); + } + + return dynamic_cast( mSiblingPrevNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getStartTime(); +// +// Returns the time, in milliseconds, that the event is due to trigger. +// +//----------------------------------------------------------------------------- +S32 VEvent::getStartTime( void ) +{ + return ( mTriggerTime + ( !isControllerPlayingForward() * mDuration ) ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getFinishTime(); +// +// Returns the time, in milliseconds, that the event will cease updating. +// +//----------------------------------------------------------------------------- +S32 VEvent::getFinishTime( void ) +{ + return ( mTriggerTime + ( isControllerPlayingForward() * mDuration ) ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::setTriggerTime( pTime ); +// +// Apply the given trigger time to the object. +// +// If the project was built using the VT_EDITOR preprocessor argument, then +// the validity of the passed value is verified. It also cannot be changed +// while the controller is playing. +// +//----------------------------------------------------------------------------- +void VEvent::setTriggerTime( const S32 &pTime ) +{ +#ifdef VT_EDITOR + + VTrack *track = getTrack(); + if ( !track ) + { + // Apply Time. + mTriggerTime = pTime; + + return; + } + + if ( track->isControllerPlaying() ) + { + // Don't Change While Playing. + return; + } + + /* + // Check For Overlap. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *event = ( VEvent* )node; + if ( event == this ) + { + // Skip. + continue; + } + + const U32 startTime = getStartTime(); + const U32 finishTime = getFinishTime(); + + if ( ( pTime > startTime && pTime < finishTime ) + || ( ( pTime + mDuration ) > startTime && ( pTime + mDuration ) < finishTime ) + || ( pTime < startTime && ( pTime + mDuration ) > finishTime ) ) + { + // Overlap! + return; + } + } + */ + + // Apply Time. + mTriggerTime = mClamp( pTime, 0, getControllerDuration() ); + + // Sort Events. + track->sort(); + + // Reset Track. + track->onControllerReset( getControllerTime(), isControllerPlayingForward() ); + +#else + + // Apply Time. + mTriggerTime = pTime; + +#endif +} + +//----------------------------------------------------------------------------- +// +// VEvent::setDuration( pDuration ); +// +// Apply the given duration time to the object. +// +// If the project was built using the VT_EDITOR preprocessor argument, then +// the validity of the passed value is verified. It also cannot be changed +// while the controller is playing. +// +//----------------------------------------------------------------------------- +void VEvent::setDuration( const S32 &pDuration ) +{ +#ifdef VT_EDITOR + + if ( isControllerPlaying() ) + { + // Don't Change While Playing. + return; + } + +#endif + + // Apply Duration. + mDuration = pDuration; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VEvent.h b/Engine/modules/Verve/Core/VEvent.h new file mode 100644 index 000000000..7a1914f04 --- /dev/null +++ b/Engine/modules/Verve/Core/VEvent.h @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// 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_VEVENT_H_ +#define _VT_VEVENT_H_ + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- +class VGroup; +class VTrack; +//----------------------------------------------------------------------------- + +class VEvent : public VObject +{ + typedef VObject Parent; + +protected: + + bool mIsPlaying; + bool mTriggered; + + S32 mTriggerTime; + S32 mDuration; + +public: + + VEvent( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + virtual bool onControllerUpdate( const S32 &pTime, const S32 &pDelta ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onUpdate( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEvent ); + +public: + + // Property Methods. + + VGroup *getGroup( void ); + template inline bool getGroup( T *&pGroup ) + { + // Reference Group. + pGroup = dynamic_cast( getGroup() ); + // Validate. + return ( pGroup != NULL ); + } + + VTrack *getTrack( void ); + template inline bool getTrack( T *&pTrack ) + { + // Reference Track. + pTrack = dynamic_cast( getTrack() ); + // Validate. + return ( pTrack != NULL ); + } + + VEvent *getNextEvent( void ); + VEvent *getPreviousEvent( void ); + + inline bool isPlaying( void ) { return mIsPlaying; }; + inline S32 getTriggerTime( void ) { return mTriggerTime; }; + inline S32 getDuration( void ) { return mDuration; }; + + virtual S32 getStartTime( void ); + virtual S32 getFinishTime( void ); + + virtual void setTriggerTime( const S32 &pTime ); + virtual void setDuration( const S32 &pDuration ); + + static bool setTriggerTime( void *obj, const char *pArray, const char *data ) { static_cast( obj )->setTriggerTime( dAtoi( data ) ); return false; }; + static bool setDuration( void *obj, const char *pArray, const char *data ) { static_cast( obj )->setDuration( dAtoi( data ) ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VGroup.cpp b/Engine/modules/Verve/Core/VGroup.cpp new file mode 100644 index 000000000..274d93775 --- /dev/null +++ b/Engine/modules/Verve/Core/VGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VGroup ); +//----------------------------------------------------------------------------- + +VGroup::VGroup( void ) +{ + setLabel( "DefaultGroup" ); +}; \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VGroup.h b/Engine/modules/Verve/Core/VGroup.h new file mode 100644 index 000000000..35d40dc4f --- /dev/null +++ b/Engine/modules/Verve/Core/VGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VGROUP_H_ +#define _VT_VGROUP_H_ + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VGroup : public VObject +{ + typedef VObject Parent; + +public: + + VGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VObject.cpp b/Engine/modules/Verve/Core/VObject.cpp new file mode 100644 index 000000000..c10c3dcdc --- /dev/null +++ b/Engine/modules/Verve/Core/VObject.cpp @@ -0,0 +1,483 @@ +//----------------------------------------------------------------------------- +// 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/VObject.h" +#include "Verve/Core/VController.h" +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VObject ); +//----------------------------------------------------------------------------- + +VObject::VObject( void ) : + mController( NULL ), + mLabel( String::EmptyString ), + mEnabled( true ) +{ + // Void. +}; + +VObject::~VObject( void ) +{ + // Remove. + remove(); +} + +void VObject::initPersistFields( void ) +{ + // Don't Use Parent Fields. + // Parent::initPersistFields(); + + addProtectedField( "Enabled", TypeBool, Offset( mEnabled, VObject ), &setEnabled, &defaultProtectedGetFn, "Enable or Disable the object from playback." ); + addProtectedField( "Label", TypeRealString, Offset( mLabel, VObject ), &setLabel, &defaultProtectedGetFn, "The label this object is referenced by." ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::getObject( pLabel ); +// +// Returns the object with the given label. If no object belongs to this object +// with that label, then a NULL value is returned. +// +//----------------------------------------------------------------------------- +VObject *VObject::getObject( const String &pLabel ) +{ + VObject *node = ( VObject* )mChildNode; + while ( node ) + { + // Compare Names. + if ( node->getLabel().equal( pLabel, String::NoCase ) ) + { + // Valid. + return node; + } + + // Next Sibling. + node = ( VObject* )node->mSiblingNextNode; + } + + // Invalid. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::isEnabled(); +// +// Returns whether this object is enabled. +// +//----------------------------------------------------------------------------- +bool VObject::isEnabled( void ) +{ + VObject *parent = dynamic_cast( getParent() ); + if ( parent && !parent->isEnabled() ) + { + return false; + } + + return mEnabled; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPlaying(); +// +// Returns whether the root controller is currently playing. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPlaying( void ) +{ + if ( getController() ) + { + return getController()->isPlaying(); + } + + return false; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPaused(); +// +// Returns whether the root controller is currently paused. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPaused( void ) +{ + if ( getController() ) + { + return getController()->isPaused(); + } + + return false; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerStopped(); +// +// Returns whether the root controller is currently stopped. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerStopped( void ) +{ + if ( getController() ) + { + return getController()->isStopped(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPlayingForward(); +// +// Returns whether the root controller is currently playing forward. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPlayingForward( void ) +{ + if ( getController() ) + { + return getController()->isPlayingForward(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerLooping(); +// +// Returns whether the root controller is looping the sequence. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerLooping( void ) +{ + if ( getController() ) + { + return getController()->isLooping(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerTime(); +// +// Returns the current time of the root controller. +// +//----------------------------------------------------------------------------- +S32 VObject::getControllerTime( void ) +{ + if ( getController() ) + { + return getController()->getTime(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerTimeScale(); +// +// Returns the current timescale of the root controller. +// +//----------------------------------------------------------------------------- +F32 VObject::getControllerTimeScale( void ) +{ + if ( getController() ) + { + return getController()->getTimeScale(); + } + + return 1.f; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerDuration(); +// +// Returns the duration of the root controller. +// +//----------------------------------------------------------------------------- +S32 VObject::getControllerDuration( void ) +{ + if ( getController() ) + { + return getController()->getDuration(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VObject::setLabel( pLabel ); +// +// Set the label property. +// +// If the project was built using the VT_EDITOR preprocessor argument, then the +// label will not be changed if the target name is already used in the parent +// object. +// +//----------------------------------------------------------------------------- +void VObject::setLabel( const String &pLabel ) +{ +#ifdef VT_EDITOR + if ( mParentNode ) + { + // Empty Label? + if ( mLabel.isEmpty() ) + { + // Set Uniqu Label. + setLabelUnique( pLabel ); + return; + } + + for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) + { + if ( walk != this ) + { + if ( pLabel == walk->getLabel() ) + { + // Exit. + return; + } + } + } + } +#endif + + // Set Label. + mLabel = pLabel; +} + +//----------------------------------------------------------------------------- +// +// VObject::setLabelUnique( pLabel ); +// +// If the label that has been passed is already in use, then a new label will +// be generated by appending an index to the label. For example: MyLabel +// becomes MyLabel0 ... MyLabelN +// +//----------------------------------------------------------------------------- +void VObject::setLabelUnique( const String &pLabel ) +{ + if ( mParentNode && pLabel.isNotEmpty() ) + { + for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) + { + if ( walk != this ) + { + if ( pLabel == walk->getLabel() ) + { + // Strip Trailing Number. + S32 i = -1; + String labelBase( String::GetTrailingNumber( pLabel, i ) ); + i++; + + // Construct New Name. + String labelBuffer = String::ToString( "%s%d", labelBase.c_str(), i ); + + // Set Name. + setLabelUnique( labelBuffer ); + + // Exit. + return; + } + } + } + } + + // Set Name. + mLabel = pLabel; +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::onAttach(); +// +// Callback made when this object is attached to another node. +// +//----------------------------------------------------------------------------- +void VObject::onAttach( void ) +{ + VTreeNode::onAttach(); + + // Store Controller. + mController = dynamic_cast( getRoot() ); + +#ifdef VT_EDITOR + if ( isProperlyAdded() ) + { + Con::executef( this, "onAttach" ); + } +#endif +} + +//----------------------------------------------------------------------------- +// +// VObject::onDetach(); +// +// Callback made when this object is detached from a parent node. +// +//----------------------------------------------------------------------------- +void VObject::onDetach( void ) +{ + VTreeNode::onDetach(); + + // Clear Controller. + mController = NULL; + +#ifdef VT_EDITOR + if ( isProperlyAdded() ) + { + Con::executef( this, "onDetach" ); + } +#endif +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VObject, writeFile, bool, 3, 3, "( string pFileName ) - Save to a given filename.\n" + "@param pFileName The target file to write to.\n" + "@return Returns true if the write was successful." ) +{ + // Write Target File. + return VPersistence::writeFile( argv[2], object ); +} + +ConsoleMethod( VObject, readFile, bool, 3, 3, "( string pFileName ) - Clears the object and loads the new data from the given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Read Target File. + return VPersistence::readFile( argv[2], object ); +} + +ConsoleMethod( VObject, getRoot, S32, 2, 2, "( void ) - Get the root object.\n" + "@return Returns the SimObjectId for the root object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->getRoot(); + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +ConsoleMethod( VObject, getParent, S32, 2, 2, "( void ) - Get the parent object.\n" + "@return Returns the SimObjectId for the parent object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->mParentNode; + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +ConsoleMethod( VObject, getIndex, S32, 2, 2, "( void ) - Get the index of this object relative to its siblings.\n" + "@return Returns the index of this object." ) +{ + return object->getIndex(); +} + +ConsoleMethod( VObject, getCount, S32, 2, 2, "( void ) - Get the number of child objects.\n" + "@return Returns the number of child objects." ) +{ + return object->size(); +} + +ConsoleMethod( VObject, getObject, S32, 3, 3, "( int pIndex ) - Get the object corresponding to the given index.\n" + "@param pIndex The index of the object you wish to retrieve.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->at( dAtoi( argv[2] ) ); + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +ConsoleMethod( VObject, clear, void, 2, 2, "( void ) - Detaches and deletes all of the child objects.\n" + "@return No return value." ) +{ + // Clear Sequence Lists. + object->clear(); +} + +ConsoleMethod( VObject, addObject, void, 3, 3, "( SimObject pObject ) - Add a child object to this node.\n" + "@param pObject The SimObjectID of the object to be added to this node.\n" + "@return No return value." ) +{ + VObject *child = dynamic_cast( Sim::findObject( argv[2] ) ); + if ( child ) + { + child->addTo( object ); + } +} + +ConsoleMethod( VObject, removeObject, void, 3, 3, "( SimObject pObject ) - Remove the target object from this node.\n" + "@param pObject The SimObjectID of the object to be removed from this node.\n" + "@return No return value." ) +{ + VObject *child = dynamic_cast( Sim::findObject( argv[2] ) ); + if ( child && child->getParent() == object ) + { + child->remove(); + } +} + +ConsoleMethod( VObject, setLabelUnique, void, 3, 3, "( string pLabel ) - Force this label to be unique.\n" + "@param pLabel The name you wish to reference this object by.\n" + "@return No return value." ) +{ + // Set Label. + object->setLabelUnique( argv[2] ); +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VObject.h b/Engine/modules/Verve/Core/VObject.h new file mode 100644 index 000000000..a4fe22f18 --- /dev/null +++ b/Engine/modules/Verve/Core/VObject.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// 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_VOBJECT_H_ +#define _VT_VOBJECT_H_ + +#ifndef _VT_VERVECONFIG_H_ +#include "Verve/VerveConfig.h" +#endif + +#ifdef VT_EDITOR + #ifndef _SIMOBJECT_H_ + #include "console/simObject.h" + #endif + + #define VObjectRep SimObject +#else + #ifndef _CONSOLEOBJECT_H_ + #include "console/consoleObject.h" + #endif + + #define VObjectRep ConsoleObject +#endif + +#ifndef _VT_VTREENODE_H_ +#include "Verve/Core/VTreeNode.h" +#endif + +#ifndef TINYXML_INCLUDED +#include "tinyxml/tinyxml.h" +#endif + +//----------------------------------------------------------------------------- +class VController; +//----------------------------------------------------------------------------- + +class VObject : public VObjectRep, + public VTreeNode +{ + typedef VObjectRep Parent; + +protected: + + VController *mController; + + String mLabel; + bool mEnabled; + +public: + + VObject( void ); + virtual ~VObject( void ); + + static void initPersistFields( void ); + + // Reference Methods. + + VObject *getObject( const String &pLabel ); + template inline bool getObject( const String &pLabel, T *&pObject ) + { + // Reference Object. + pObject = dynamic_cast( getObject( pLabel ) ); + + // Valid? + return ( pObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VObject ); + +public: + + // Property Methods. + + inline VController *getController( void ) { return mController; }; + + inline const String &getLabel( void ) const { return mLabel; }; + bool isEnabled( void ); + + bool isControllerPlaying( void ); + bool isControllerPaused( void ); + bool isControllerStopped( void ); + bool isControllerPlayingForward( void ); + bool isControllerLooping( void ); + S32 getControllerTime( void ); + F32 getControllerTimeScale( void ); + S32 getControllerDuration( void ); + + virtual void setLabel( const String &pLabel ); + void setLabelUnique( const String &pLabel ); + inline void setEnabled( const bool &pEnabled ) { mEnabled = pEnabled; }; + + // Callback Methods. + + virtual void onAttach( void ); + virtual void onDetach( void ); + + // Static Methods. + + static bool setEnabled( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setEnabled( dAtob( pData ) ); return false; }; + static bool setLabel( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setLabel( pData ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VOBJECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VTrack.cpp b/Engine/modules/Verve/Core/VTrack.cpp new file mode 100644 index 000000000..6783faece --- /dev/null +++ b/Engine/modules/Verve/Core/VTrack.cpp @@ -0,0 +1,448 @@ +//----------------------------------------------------------------------------- +// 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/VTrack.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VController.h" +#include "math/mMath.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VTrack ); +//----------------------------------------------------------------------------- + +VTrack::VTrack( void ) : + mNextEvent( NULL ) +{ + setLabel( "DefaultTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::onAttach(); +// +// This callback subscribes this object to the controller's event signal. +// +//----------------------------------------------------------------------------- +void VTrack::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller? + if ( getController() ) + { + // Subscribe to Updates. + getController()->getControllerUpdateSignal().notify( this, &VTrack::onControllerUpdate ); + + // Subscribe to Events. + getController()->getControllerEventSignal().notify( this, &VTrack::onControllerEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::onAttach(); +// +// This callback removes this object from the controller's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VTrack::onDetach( void ) +{ + // Valid Controller? + if ( getController() ) + { + // Remove Update Notification. + getController()->getControllerUpdateSignal().remove( this, &VTrack::onControllerUpdate ); + + // Remove Event Notification. + getController()->getControllerEventSignal().remove( this, &VTrack::onControllerEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerUpdate( pTime, pDelta ); +// +// The Next Event is integrated until has finished its execution. Once it has +// finished, the next event to be triggered becomes the Current Event. Doing +// this means that only one event is ever checked to see if it should be +// triggered. +// +//----------------------------------------------------------------------------- +void VTrack::onControllerUpdate( const S32 &pTime, const S32 &pDelta ) +{ + if ( !isEnabled() || !mNextEvent ) + { + // Don't Update. + return; + } + + // Update Next Event. + while ( !mNextEvent->onControllerUpdate( pTime, pDelta ) ) + { + // Next Event? + if ( !updateNextEvent() ) + { + // No Valid Events. + mNextEvent = NULL; + break; + } + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is reset the virtual method, onControllerReset is called. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VTrack::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { + case VController::k_EventReset : + { + + // Reset. + onControllerReset( getControllerTime(), isControllerPlayingForward() ); + + } break; + } + + // Continue Processing Events. + return true; +} + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerReset( pTime, pForward ); +// +// Reset the status of the track. The Next Event is allocated here. +// +//----------------------------------------------------------------------------- +void VTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Clear Next Event. + mNextEvent = NULL; + + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *event = ( VEvent* )node; + + // Reset Event. + event->onControllerReset( pTime, pForward ); + + if ( ( event->isPlaying() ) + || ( pForward && event->getTriggerTime() >= pTime ) ) + { + if ( !mNextEvent ) + { + // Use as Next Event. + mNextEvent = event; + } + } + else if ( !pForward && pTime >= event->getTriggerTime() ) + { + VEvent *nextEvent = ( VEvent* )node->mSiblingNextNode; + if ( !nextEvent || pTime < nextEvent->getTriggerTime() ) + { + // Use as Next Event. + mNextEvent = event; + } + } + } +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::sort(); +// +// Sort the track's events by the event's trigger time. +// +//----------------------------------------------------------------------------- +void VTrack::sort( void ) +{ + const S32 count = size(); + for ( S32 j = 0; j < count; j++ ) + { + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *eventA = ( VEvent* )node; + VEvent *eventB = ( VEvent* )node->mSiblingNextNode; + if ( !eventB ) + { + // No Node. + break; + } + + // Swap? + if ( eventA->getTriggerTime() > eventB->getTriggerTime() ) + { + // Get Outer Siblings. + ITreeNode *prevNode = eventA->mSiblingPrevNode; + ITreeNode *nextNode = eventB->mSiblingNextNode; + + if ( eventA->mParentNode && eventA->mParentNode->mChildNode == eventA ) + { + // New Child Node. + eventA->mParentNode->mChildNode = eventB; + } + + // + // Move A. + eventA->mSiblingPrevNode = eventB; + eventA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = eventA; + } + + // + // Move B. + + eventB->mSiblingPrevNode = prevNode; + eventB->mSiblingNextNode = eventA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = eventB; + } + } + } + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::updateNextEvent( pForward ); +// +// Point mNextEvent to the next valid event in the track's sequence. +// +//----------------------------------------------------------------------------- +bool VTrack::updateNextEvent( void ) +{ + if ( !mNextEvent ) + { + // Invalid Event. + return false; + } + + while ( ( mNextEvent = mNextEvent->getNextEvent() ) != NULL ) + { + if ( mNextEvent->isEnabled() ) + { + // Valid Event. + return true; + } + } + + // Invalid Event. + return false; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::getGroup(); +// +// Returns the Track's parent group. +// +//----------------------------------------------------------------------------- +VGroup *VTrack::getGroup( void ) +{ + return dynamic_cast( mParentNode ); +} + +//----------------------------------------------------------------------------- +// +// VTrack::getNextEvent(); +// +// Returns the Event that the Track is currently observing. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getNextEvent( void ) +{ + return mNextEvent; +} + +//----------------------------------------------------------------------------- +// +// VTrack::getCurrentEvent(); +// +// Returns the Event that the Track is currently observing and playing. This +// will only ever be non-null when the track is observing an Event that has a +// non-zero duration and has been triggered. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getCurrentEvent( void ) +{ + if ( mNextEvent && mNextEvent->isPlaying() ) + { + return mNextEvent; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VTrack::getPreviousEvent(); +// +// Returns the Event that the Track was last intergrating. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getPreviousEvent( void ) +{ + if ( mNextEvent ) + { + return mNextEvent->getPreviousEvent(); + } + + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( getChild() ); + } + + return dynamic_cast( getLastChild() ); +} + +//----------------------------------------------------------------------------- +// +// VTrack::calclateInterp( pTime ); +// +// This method returns the interp time between or within events. If the given +// time is between two events, the return time is: +// +// ( pTime - last_event_finish_time ) +// / ( next_event_start_time - last_event_finish_time ) +// +// If the given time is within an event, the return time is: +// +// ( pTime - event_start_time ) / ( event_duration ) +// +// The value returned here is between 0.0 and 1.0. +// +//----------------------------------------------------------------------------- +F32 VTrack::calculateInterp( S32 pTime ) +{ + if ( !isControllerPlayingForward() ) + { + return ( 1.f - _calculateInterp( pTime ) ); + } + + return _calculateInterp( pTime ); +} + +F32 VTrack::_calculateInterp( S32 pTime ) +{ + // Fetch Duration. + const S32 sequenceDuration = getControllerDuration(); + if ( sequenceDuration == 0 || pTime == sequenceDuration ) + { + // Sanity! + return 1.f; + } + + if ( !mChildNode ) + { + // Quick Interp. + return F32( pTime / sequenceDuration ); + } + + // Last Time. + S32 lastTime = 0; + + VEvent *walk = ( VEvent* )mChildNode; + while ( walk ) + { + const S32 startTime = walk->getStartTime(); + const S32 finishTime = walk->getFinishTime(); + + if ( pTime < startTime ) + { + return ( F32( pTime - lastTime ) / F32( startTime - lastTime ) ); + } + + // Update Last Time. + lastTime = startTime; + + if ( pTime < finishTime ) + { + return ( F32( pTime - lastTime ) / F32( finishTime - lastTime ) ); + } + + // Update Last Time. + lastTime = finishTime; + + // Fetch Next Node. + walk = ( VEvent* )walk->mSiblingNextNode; + } + + // Return. + return ( F32( pTime - lastTime ) / F32( sequenceDuration - lastTime ) ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VTrack.h b/Engine/modules/Verve/Core/VTrack.h new file mode 100644 index 000000000..eb2e576ce --- /dev/null +++ b/Engine/modules/Verve/Core/VTrack.h @@ -0,0 +1,123 @@ +//----------------------------------------------------------------------------- +// 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_VTRACK_H_ +#define _VT_VTRACK_H_ + +#ifndef _VT_VCONTROLLER_H_ +#include "Verve/Core/VController.h" +#endif + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +//----------------------------------------------------------------------------- +class VGroup; +//----------------------------------------------------------------------------- + +class VTrack : public VObject +{ + typedef VObject Parent; + +public: + + // Controller Members. + + VEvent *mNextEvent; + +public: + + VTrack(); + + // Tree Methods. + + virtual void onAttach( void ); + virtual void onDetach( void ); + + // Controller Methods. + + virtual void onControllerUpdate( const S32 &pTime, const S32 &pDelta ); + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Reference Methods. + + void sort( void ); + bool updateNextEvent( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VTrack ); + +public: + + // Property Methods. + + VGroup *getGroup( void ); + template inline bool getGroup( T *&pGroup ) + { + // Reference Group. + pGroup = dynamic_cast( getGroup() ); + // Validate. + return ( pGroup != NULL ); + } + + VEvent *getNextEvent( void ); + template inline bool getNextEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getNextEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + VEvent *getCurrentEvent( void ); + template inline bool getCurrentEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getCurrentEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + VEvent *getPreviousEvent( void ); + template inline bool getPreviousEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getPreviousEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + F32 calculateInterp( S32 pTime ); + F32 _calculateInterp( S32 pTime ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VTreeNode.cpp b/Engine/modules/Verve/Core/VTreeNode.cpp new file mode 100644 index 000000000..29f4fa076 --- /dev/null +++ b/Engine/modules/Verve/Core/VTreeNode.cpp @@ -0,0 +1,471 @@ +//----------------------------------------------------------------------------- +// 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/VTreeNode.h" +#include "console/simObject.h" +#include "platform/platform.h" + +//----------------------------------------------------------------------------- + +VTreeNode::VTreeNode( void ) +{ + mParentNode = NULL; + mChildNode = NULL; + mSiblingPrevNode = NULL; + mSiblingNextNode = NULL; +} + +VTreeNode::~VTreeNode( void ) +{ + // Delete Children. + clear(); + + // Detach. + remove(); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTreeNode::clear(); +// +// Delete all child nodes. +// +//----------------------------------------------------------------------------- +void VTreeNode::clear( void ) +{ + if ( !mChildNode ) + { + return; + } + + while ( mChildNode ) + { + // Fetch Child Node. + ITreeNode *node = mChildNode; + + // Clear It. + node->clear(); + + // Detach It. + node->remove(); + + // Delete It. + SimObject *object = dynamic_cast( node ); + if ( object ) + { + object->deleteObject(); + } + else + { + delete node; + } + } +} + +//----------------------------------------------------------------------------- +// +// ITreeNode Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTreeNode::getRoot(); +// +// Returns the root object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getRoot( void ) +{ + ITreeNode *parent = this; + while ( parent->mParentNode ) + { + parent = parent->mParentNode; + } + + return parent; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getParent(); +// +// Returns the parent object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getParent( void ) +{ + return mParentNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getChild(); +// +// Returns the first child object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getChild( void ) +{ + return mChildNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getChild(); +// +// Returns the first child object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getLastChild( void ) +{ + // Any Nodes? + if ( !mChildNode ) + { + // Null. + return NULL; + } + + // Front Node. + ITreeNode *lastNode = mChildNode; + + // Fetch Last Node. + while ( lastNode->mSiblingNextNode ) + { + lastNode = lastNode->mSiblingNextNode; + } + + // Return. + return lastNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getPrevSibling(); +// +// Returns the previous object in the linked list. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getPrevSibling( void ) +{ + return mSiblingPrevNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getNextSibling(); +// +// Returns the next object in the linked list. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getNextSibling( void ) +{ + return mSiblingNextNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::size(); +// +// Returns the number of child objects. Only includes top level. +// +//----------------------------------------------------------------------------- +int VTreeNode::size( void ) +{ + int size = 0; + + ITreeNode *node = mChildNode; + while ( node ) + { + size++; + + node = node->mSiblingNextNode; + } + + return size; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::at( pIndex ); +// +// Returns the object at the given index. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::at( const int pIndex ) +{ + int index = 0; + + ITreeNode *node = mChildNode; + while ( node ) + { + if ( index++ == pIndex ) + { + return node; + } + + node = node->mSiblingNextNode; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getIndex(); +// +// Returns the index of the object in relation to the sibling nodes. +// +//----------------------------------------------------------------------------- +int VTreeNode::getIndex( void ) +{ + if ( !inTree() ) + { + // No Index. + return 0; + } + + ITreeNode *walk = NULL; + if ( mParentNode ) + { + walk = mParentNode->mChildNode; + } + else + { + walk = this; + while ( walk->mSiblingPrevNode ) + { + // Walk Up. + walk = walk->mSiblingPrevNode; + } + } + + for ( int i = 0; walk; walk = walk->mSiblingNextNode, i++ ) + { + if ( walk == this ) + { + return i; + } + } + + AssertFatal( false, "VTreeNode::getIndex() - Node List Broken?" ); + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::addTo( pNode ); +// +// Attach this node to the back of the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::addTo( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Already In Tree. + return; + } + + // Set Parent. + mParentNode = pNode; + + if ( !pNode->mChildNode ) + { + // Store Child Node. + pNode->mChildNode = this; + } + else + { + // Front Node. + ITreeNode *headNode = pNode->mChildNode; + + // Fetch Head Node. + while ( headNode->mSiblingNextNode ) + { + headNode = headNode->mSiblingNextNode; + } + + // Reference Next Node. + headNode->mSiblingNextNode = this; + + // Reference Previous Node. + mSiblingPrevNode = headNode; + } + + // Callback. + onAttach(); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::addToFront( pNode ); +// +// Attach this node to the front of the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::addToFront( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Already In Tree. + return; + } + + // Set Parent. + mParentNode = pNode; + + if ( !pNode->mChildNode ) + { + // Store Child Node. + pNode->mChildNode = this; + } + else + { + // First Node. + ITreeNode *childNode = pNode->mChildNode; + + // Reference Previous Node. + childNode->mSiblingPrevNode = this; + + // Reference Next Node. + mSiblingNextNode = childNode; + + // Store Child Node. + pNode->mChildNode = this; + } + + // Callback. + onAttach(); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::remove(); +// +// Detach this node from the current parent node. +// +//----------------------------------------------------------------------------- +void VTreeNode::remove( void ) +{ + if ( !inTree() ) + { + return; + } + + // Callback. + onDetach(); + + if ( mParentNode && mParentNode->mChildNode == this ) + { + // Update Parent Reference. + mParentNode->mChildNode = mSiblingNextNode; + } + + if ( mSiblingNextNode ) + { + // Update Previous Node. + mSiblingNextNode->mSiblingPrevNode = mSiblingPrevNode; + } + + if ( mSiblingPrevNode ) + { + // Update Next Node. + mSiblingPrevNode->mSiblingNextNode = mSiblingNextNode; + } + + // Remove References. + mParentNode = mSiblingPrevNode = mSiblingNextNode = NULL; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::moveTo( pNode ); +// +// Detach this node and attach it to the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::moveTo( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Remove from Tree. + remove(); + } + + // Add to tree. + addTo( pNode ); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::onAttach(); +// +// This method will be called when this node, or a parent node, is attached to +// a node. +// +//----------------------------------------------------------------------------- +void VTreeNode::onAttach( void ) +{ + // Notify Children. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + node->onAttach(); + } +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::onDetach(); +// +// This method will be called when this node, or a parent node, is detached. +// +//----------------------------------------------------------------------------- +void VTreeNode::onDetach( void ) +{ + // Notify Children. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + node->onDetach(); + } +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::inTree(); +// +// Returns true if the node is the a member of a node tree. +// +//----------------------------------------------------------------------------- +bool VTreeNode::inTree( void ) +{ + return !( mParentNode == NULL && + mSiblingPrevNode == NULL && + mSiblingNextNode == NULL ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Core/VTreeNode.h b/Engine/modules/Verve/Core/VTreeNode.h new file mode 100644 index 000000000..459e972ca --- /dev/null +++ b/Engine/modules/Verve/Core/VTreeNode.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// 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_VTREENODE_H_ +#define _VT_VTREENODE_H_ + +#ifndef _VT_ITREENODE_H_ +#include "Verve/Core/ITreeNode.h" +#endif + +//----------------------------------------------------------------------------- + +class VTreeNode : public ITreeNode +{ + typedef ITreeNode Parent; + +public: + + VTreeNode( void ); + ~VTreeNode( void ); + + // Reference Methods. + + virtual void clear( void ); + + // ITreeNode Methods. + + virtual ITreeNode *getRoot( void ); + virtual ITreeNode *getParent( void ); + virtual ITreeNode *getChild( void ); + virtual ITreeNode *getLastChild( void ); + + virtual ITreeNode *getPrevSibling( void ); + virtual ITreeNode *getNextSibling( void ); + + virtual ITreeNode *at( const int pIndex ); + virtual int size( void ); + + virtual int getIndex( void ); + + virtual void addTo( ITreeNode *pNode ); + virtual void addToFront( ITreeNode *pNode ); + virtual void remove( void ); + virtual void moveTo( ITreeNode *pNode ); + + virtual void onAttach( void ); + virtual void onDetach( void ); + + virtual bool inTree( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTREENODE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.cpp b/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.cpp new file mode 100644 index 000000000..b40460871 --- /dev/null +++ b/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.cpp @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Animation/VShapeAnimationEvent.h" +#include "Verve/Extension/Animation/VShapeAnimationTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VShapeAnimationEvent ); +//----------------------------------------------------------------------------- + +VShapeAnimationEvent::VShapeAnimationEvent( void ) : + mAnimationData( String::EmptyString ), + mAutoDuration( true ) +{ + setLabel( "AnimationEvent" ); +} + +//----------------------------------------------------------------------------- + +void VShapeAnimationEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "AnimationData", TypeRealString, Offset( mAnimationData, VShapeAnimationEvent ), "The name of the Animation Sequence to play upon triggering." ); + addField( "AutoDuration", TypeBool, Offset( mAutoDuration, VShapeAnimationEvent ), "Force the Event's Duration to match the length of the Animation." ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::onTrigger( pTime, pDelta ); +// +// Play the desired animation. Also account for any offet in playtime, and +// timescale. +// +//----------------------------------------------------------------------------- +void VShapeAnimationEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::SceneObjectType *object = getSceneObject(); + VShapeAnimationTrack *track; + if ( !object || !getTrack( track ) ) + { + // Sanity! + return; + } + + // Play Animation. + VTorque::playAnimation( object, track->getThreadIndex(), mAnimationData ); + + // Set Position. + VTorque::setAnimationPosition( object, track->getThreadIndex(), getAnimationPosition( pTime + pDelta ) ); + + // Set Time Scale. + VTorque::setAnimationTimeScale( object, track->getThreadIndex(), ( ( pDelta > 0 ) ? 1.f : -1.f ) ); +} + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::onComplete( pTime, pDelta ); +// +// If the animation is cyclic, then it needs to be paused once the event has +// finished playing. +// +//----------------------------------------------------------------------------- +void VShapeAnimationEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + // Fetch Object. + VTorque::SceneObjectType *object = getSceneObject(); + VShapeAnimationTrack *track; + if ( object && VTorque::isAnimationLooping( object, mAnimationData ) && getTrack( track ) ) + { + // Pause Animation. + VTorque::pauseAnimation( object, track->getThreadIndex() ); + } +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::getAnimationPosition( pTime ); +// +// Returns the time that the animation should be positioned at, at the given +// time. This method considers whether the animation is cyclic or not and will +// return the appropriate time regardless. Time is expressed in seconds and not +// milliseconds. +// +//----------------------------------------------------------------------------- +F32 VShapeAnimationEvent::getAnimationPosition( const S32 &pTime ) +{ + // Fetch Object. + VSceneObjectTrack *track; + VTorque::SceneObjectType *object = getSceneObject(); + if ( !getTrack( track ) || !object ) + { + // Null. + return 0.f; + } + + // Fetch Interp. + F32 interp = track->calculateInterp( pTime ); + if ( !isControllerPlayingForward() ) + { + // Flip. + interp = ( 1.f - interp ); + } + + // Not Looping? + if ( !VTorque::isAnimationLooping( object, mAnimationData ) ) + { + // Return Interp. + return interp; + } + + // Fetch Sequence Duration. + const S32 duration = ( S32 )( 1000 * VTorque::getAnimationDuration( object, mAnimationData ) ); + + // Fetch Loop Interp. + const S32 loopInterp = S32( mDuration * interp ) % duration; + + return ( F32 )loopInterp / ( F32 )duration; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.h b/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.h new file mode 100644 index 000000000..9146836e9 --- /dev/null +++ b/Engine/modules/Verve/Extension/Animation/VShapeAnimationEvent.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// 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_VSHAPEANIMATIONEVENT_H_ +#define _VT_VSHAPEANIMATIONEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_ANIMATION_H_ +#include "Verve/Torque/TAnimation.h" +#endif + +//----------------------------------------------------------------------------- + +class VShapeAnimationEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + +public: + + bool mAutoDuration; + String mAnimationData; + +public: + + VShapeAnimationEvent( void ); + + static void initPersistFields( void ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VShapeAnimationEvent ); + +public: + + // Property Methods. + + F32 getAnimationPosition( const S32 &pTime ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAPEANIMATIONEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.cpp b/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.cpp new file mode 100644 index 000000000..d6f25764b --- /dev/null +++ b/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.cpp @@ -0,0 +1,185 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Animation/VShapeAnimationTrack.h" +#include "Verve/Extension/Animation/VShapeAnimationEvent.h" +#include "Verve/Core/VGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VShapeAnimationTrack ); +//----------------------------------------------------------------------------- + +VShapeAnimationTrack::VShapeAnimationTrack( void ) : + mThreadIndex( 0 ) +{ + setLabel( "AnimationTrack" ); +} + +//----------------------------------------------------------------------------- + +void VShapeAnimationTrack::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "ThreadIndex", TypeS32, Offset( mThreadIndex, VShapeAnimationTrack ), "The index of the Animation Thread to play." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is paused, or stops playing, then the animation will cease to +// play. If the controller resumes play, the animation will continue. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VShapeAnimationTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay : + { + + // Play Animation. + VTorque::setAnimationTimeScale( getSceneObject(), mThreadIndex, ( ( isControllerPlayingForward() ) ? 1.f : -1.f ) ); + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Stop Animation. + VTorque::setAnimationTimeScale( getSceneObject(), mThreadIndex, 0.f ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VShapeAnimationTrack::onControllerReset( pTime, pForward ); +// +// Reset the animation state of the target object. If there is a Next Event, +// then the animation is positioned accordingly. +// +//----------------------------------------------------------------------------- +void VShapeAnimationTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + VTorque::SceneObjectType *object = getSceneObject(); + if ( !object ) + { + // Parent Call. + Parent::onControllerReset( pTime, pForward ); + return; + } + + VShapeAnimationEvent *event; + if ( getCurrentEvent( event ) ) + { + // Stop Animation. + VTorque::stopAnimation( object, mThreadIndex ); + } + + // Parent Call. + Parent::onControllerReset( pTime, pForward ); + + if ( getCurrentEvent( event ) ) + { + // Play Animation. + VTorque::playAnimation( object, mThreadIndex, event->mAnimationData ); + + // Set Position. + VTorque::setAnimationPosition( object, mThreadIndex, event->getAnimationPosition( pTime ) ); + + // Stop Animation. + VTorque::setAnimationTimeScale( object, mThreadIndex, 0.f ); + } +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VShapeAnimationTrack, updateTrack, void, 2, 2, "( void ) - Update the Track.\n" + "@return No return value." ) +{ + for ( ITreeNode *node = object->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VShapeAnimationEvent *currEvent = ( VShapeAnimationEvent* )node; + VShapeAnimationEvent *nextEvent = ( VShapeAnimationEvent* )node->mSiblingNextNode; + if ( !currEvent->mAutoDuration ) + { + // Skip. + continue; + } + + if ( VTorque::isAnimationLooping( object->getSceneObject(), currEvent->mAnimationData ) ) + { + if ( !nextEvent ) + { + // Update Duration. + currEvent->setDuration( object->getControllerDuration() - currEvent->getTriggerTime() ); + } + else + { + // Update Duration. + currEvent->setDuration( mAbs( nextEvent->getTriggerTime() - currEvent->getTriggerTime() ) ); + } + } + else + { + // Update Duration. + currEvent->setDuration( ( S32 )( 1000 * VTorque::getAnimationDuration( object->getSceneObject(), currEvent->mAnimationData ) ) ); + } + } +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.h b/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.h new file mode 100644 index 000000000..3b9cf7bce --- /dev/null +++ b/Engine/modules/Verve/Extension/Animation/VShapeAnimationTrack.h @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// 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_VSHAPEANIMATIONTRACK_H_ +#define _VT_VSHAPEANIMATIONTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_ANIMATION_H_ +#include "Verve/Torque/TAnimation.h" +#endif + +//----------------------------------------------------------------------------- + +class VShapeAnimationTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + + U32 mThreadIndex; + +public: + + VShapeAnimationTrack( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VShapeAnimationTrack ); + +public: + + inline U32 &getThreadIndex( void ) { return mThreadIndex; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAPEANIMATIONTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraGroup.cpp b/Engine/modules/Verve/Extension/Camera/VCameraGroup.cpp new file mode 100644 index 000000000..14b2cb97c --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraGroup.cpp @@ -0,0 +1,224 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraGroup.h" +#include "Verve/Extension/Camera/VCameraTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraGroup ); +//----------------------------------------------------------------------------- + +VCameraGroup *VCameraGroup::mActiveGroup = NULL; +VCameraGroup::CameraChangeSignal VCameraGroup::mCameraChangeSignal; + +//----------------------------------------------------------------------------- + +VCameraGroup::VCameraGroup( void ) +{ + setLabel( "CameraGroup" ); +}; + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onAttach(); +// +// This callback subscribes this object to the controller's event signal. +// +//----------------------------------------------------------------------------- +void VCameraGroup::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller? + if ( getController() ) + { + // Subscribe to Events. + getController()->getControllerEventSignal().notify( this, &VCameraGroup::onControllerEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onAttach(); +// +// This callback removes this object from the controller's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VCameraGroup::onDetach( void ) +{ + // Valid Controller? + if ( getController() ) + { + // Remove Event Notification. + getController()->getControllerEventSignal().remove( this, &VCameraGroup::onControllerEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VCameraGroup::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VCameraGroup::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { +#ifdef VT_EDITOR + case VController::k_EventPause : +#endif + case VController::k_EventStop : + { + + // Clear the Camera. + clearActiveGroup(); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::setActive(); +// +// Set this Group to Active. +// +//----------------------------------------------------------------------------- +void VCameraGroup::setActive( void ) +{ + // Set Active. + setActiveGroup( this ); +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::clearActiveGroup(); +// +// Clear the Active Camera. +// +//----------------------------------------------------------------------------- +void VCameraGroup::clearActiveGroup( void ) +{ + if ( mActiveGroup ) + { + // Deactivate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventDeactivate ); + } + + // Store. + mActiveGroup = NULL; + + // Clear Camera Object. + VTorque::setCamera( NULL ); + + // Change Signal. + getCameraChangeSignal().trigger( NULL ); +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::setActiveGroup( pCameraGroup ); +// +// Change the current camera group. The actual camera object is the object that +// the group references. +// +// A NULL value of pCameraGroup will clear the active camera, which generally +// reverts to the connection's control object. The camera is also cleared when +// the Controller stops playing. +// +//----------------------------------------------------------------------------- +void VCameraGroup::setActiveGroup( VCameraGroup *pCameraGroup ) +{ + // Change Camera? + if ( pCameraGroup == mActiveGroup || + pCameraGroup && !pCameraGroup->isEnabled() ) + { + // Invalid Target. + return; + } + + if ( mActiveGroup ) + { + // Deactivate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventDeactivate ); + } + + // Store. + mActiveGroup = pCameraGroup; + + if ( mActiveGroup ) + { + // Set Camera Object. + VTorque::setCamera( mActiveGroup->getSceneObject() ); + + // Activate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventActivate ); + } + else + { + // Clear Camera Object. + VTorque::setCamera( NULL ); + } + + // Change Signal. + getCameraChangeSignal().trigger( mActiveGroup ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraGroup.h b/Engine/modules/Verve/Extension/Camera/VCameraGroup.h new file mode 100644 index 000000000..eea9a2f7b --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraGroup.h @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERAGROUP_H_ +#define _VT_VCAMERAGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +#ifndef _VT_VCONTROLLER_H +#include "Verve/Core/VController.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraGroup; + +//----------------------------------------------------------------------------- + +class VCameraGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + enum eCameraEventType + { + k_EventActivate, + k_EventDeactivate, + }; + + typedef Signal CameraEventSignal; + typedef Signal CameraChangeSignal; + +protected: + + static VCameraGroup *mActiveGroup; + static CameraChangeSignal mCameraChangeSignal; + + CameraEventSignal mCameraEventSignal; + +public: + + VCameraGroup( void ); + + // Tree Methods. + + void onAttach( void ); + void onDetach( void ); + + // Controller Methods. + + bool onControllerEvent( VController::eControllerEventType pEvent ); + + // Camera Methods. + + inline bool isActive( void ) { return ( bool )( this == getActiveGroup() ); }; + inline VCameraGroup *getActiveGroup( void ) { return mActiveGroup; }; + + void setActive( void ); + + static void clearActiveGroup( void ); + static void setActiveGroup( VCameraGroup *pCameraGroup ); + + // Signal Methods. + + static inline CameraChangeSignal &getCameraChangeSignal( void ) { return mCameraChangeSignal; }; + inline CameraEventSignal &getCameraEventSignal( void ) { return mCameraEventSignal; }; + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERAGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.cpp b/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.cpp new file mode 100644 index 000000000..88c528d27 --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.cpp @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------- +// 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/Camera/VCameraGroup.h" +#include "Verve/Extension/Camera/VCameraShakeEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraShakeEvent ); +//----------------------------------------------------------------------------- + +VCameraShakeEvent::VCameraShakeEvent( void ) : + mAmplitude( Point3F::Zero ), + mFalloff( 10.f ), + mFrequency( Point3F::Zero ) +{ + // Clear Label. + setLabel( "CameraShakeEvent" ); +} + +void VCameraShakeEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Amplitude", TypePoint3F, Offset( mAmplitude, VCameraShakeEvent ), "Amplitude of the Camera Shake event." ); + addField( "Falloff", TypeF32, Offset( mFalloff, VCameraShakeEvent ), "Falloff of the Camera Shake event." ); + addField( "Frequency", TypePoint3F, Offset( mFrequency, VCameraShakeEvent ), "Frequency of the Camera Shake event." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeEvent::onTrigger( pTime, pDelta ); +// +// Start shaking the camera. Also account for any offet in playtime, and +// timescale. +// +//----------------------------------------------------------------------------- +void VCameraShakeEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Group. + VCameraGroup *group; + if ( !getGroup( group ) || !group->isActive() ) + { + // Inactive. + return; + } + + // Duration. + //const F32 duration = ( mDuration - mAbs( pTime - getStartTime() ) ) / ( 1000.f * mFabs( getControllerTimeScale() ) ); + const F32 duration = ( mDuration - mAbs( pTime - getStartTime() ) ) / 1000.f; + + // Shake Camera. + VTorque::startCameraShake( duration, mFalloff, mAmplitude, mFrequency ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.h b/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.h new file mode 100644 index 000000000..9a8af7899 --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraShakeEvent.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERASHAKEEVENT_H_ +#define _VT_VCAMERASHAKEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraShakeEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VectorF mAmplitude; + F32 mFalloff; + VectorF mFrequency; + +public: + + VCameraShakeEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraShakeEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERASHAKEEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.cpp b/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.cpp new file mode 100644 index 000000000..4f6fb5e81 --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.cpp @@ -0,0 +1,114 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraShakeTrack.h" +#include "Verve/Extension/Camera/VCameraShakeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraShakeTrack ); +//----------------------------------------------------------------------------- + +VCameraShakeTrack::VCameraShakeTrack( void ) +{ + setLabel( "CameraShakeTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incoming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VCameraShakeTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + // Parent Call. + if ( !Parent::onCameraEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { + case VCameraGroup::k_EventActivate : + { + + VCameraShakeEvent *event; + if ( getCurrentEvent( event ) ) + { + // Re-Trigger Event. + event->onTrigger( getControllerTime(), 0 ); + } + + } break; + + case VCameraGroup::k_EventDeactivate : + { + + // Stop Camera Shake. + VTorque::stopCameraShake(); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeTrack::onControllerReset( pTime, pForward ); +// +// Stop all camera shake events. +// +//----------------------------------------------------------------------------- +void VCameraShakeTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + // Stop Camera Shake. + VTorque::stopCameraShake(); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.h b/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.h new file mode 100644 index 000000000..2c09900bc --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraShakeTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERASHAKETRACK_H_ +#define _VT_VCAMERASHAKETRACK_H_ + +#ifndef _VT_VCAMERATRACK_H_ +#include "Verve/Extension/Camera/VCameraTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraShakeTrack : public VCameraTrack +{ + typedef VCameraTrack Parent; + +public: + + VCameraShakeTrack( void ); + + // Camera Methods. + + bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Controller Methods. + + void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraShakeTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERASHAKETRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraTrack.cpp b/Engine/modules/Verve/Extension/Camera/VCameraTrack.cpp new file mode 100644 index 000000000..47e734af9 --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraTrack.cpp @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraTrack ); +//----------------------------------------------------------------------------- + +VCameraTrack::VCameraTrack( void ) +{ + setLabel( "CameraTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onAttach(); +// +// This callback subscribes this object to the Camera Group's event signal. +// +//----------------------------------------------------------------------------- +void VCameraTrack::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller & Group? + VCameraGroup *group; + if ( getController() && getGroup( group ) ) + { + // Add Event Notification. + group->getCameraEventSignal().notify( this, &VCameraTrack::onCameraEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onAttach(); +// +// This callback removes this object from the Camera Group's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VCameraTrack::onDetach( void ) +{ + // Valid Controller & Group? + VCameraGroup *group; + if ( getController() && getGroup( group ) ) + { + // Clear Event Notification. + group->getCameraEventSignal().remove( this, &VCameraTrack::onCameraEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incomming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VCameraTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VCameraTrack::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Ok. + return true; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Camera/VCameraTrack.h b/Engine/modules/Verve/Extension/Camera/VCameraTrack.h new file mode 100644 index 000000000..6866638a2 --- /dev/null +++ b/Engine/modules/Verve/Extension/Camera/VCameraTrack.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERATRACK_H_ +#define _VT_VCAMERATRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_VCAMERAGROUP_H_ +#include "Verve/Extension/Camera/VCameraGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VCameraTrack( void ); + + // Tree Methods. + + void onAttach( void ); + void onDetach( void ); + + // Camera Methods. + + virtual bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERATRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorEvent.cpp b/Engine/modules/Verve/Extension/Director/VDirectorEvent.cpp new file mode 100644 index 000000000..9030b4018 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorEvent.cpp @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------- +// 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/Director/VDirectorEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorEvent ); +//----------------------------------------------------------------------------- + +VDirectorEvent::VDirectorEvent( void ) : + mTarget( String::EmptyString ) +{ + // Void. +} + +void VDirectorEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Target", TypeRealString, Offset( mTarget, VDirectorEvent ), "The name of the CameraGroup that will be activated upon triggering." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDirectorEvent::onTrigger( pTime, pDelta ); +// +// Cut the camera to the target group. +// +//----------------------------------------------------------------------------- +void VDirectorEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Controller. + VController *controller = getController(); + + // Valid Target? + VCameraGroup *targetGroup = NULL; + if ( !controller->getObject( mTarget, targetGroup ) ) + { + Con::warnf( "VDirectorEvent::onTrigger() - Invalid Target Group specified." ); + return; + } + + // Change Camera. + targetGroup->setActive(); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorEvent.h b/Engine/modules/Verve/Extension/Director/VDirectorEvent.h new file mode 100644 index 000000000..e890e5a06 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorEvent.h @@ -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_VDIRECTOREVENT_H_ +#define _VT_VDIRECTOREVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_VCAMERAGROUP_H_ +#include "Verve/Extension/Camera/VCameraGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + String mTarget; + +public: + + VDirectorEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTOREVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorGroup.cpp b/Engine/modules/Verve/Extension/Director/VDirectorGroup.cpp new file mode 100644 index 000000000..4f8934124 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorGroup.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VDirectorGroup.h" +#include "Verve/Extension/Director/VDirectorTrack.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorGroup ); +//----------------------------------------------------------------------------- + +VDirectorGroup::VDirectorGroup( void ) : + mActiveCamera( NULL ) +{ + setLabel( "DirectorGroup" ); +}; + +//----------------------------------------------------------------------------- +// +// VDirectorGroup::getDirectorTrack(); +// +// Returns the DirectorTrack reference. +// +//----------------------------------------------------------------------------- +VDirectorTrack *VDirectorGroup::getDirectorTrack( void ) +{ + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + if ( VDirectorTrack *track = dynamic_cast( node ) ) + { + // Return Track. + return track; + } + } + + // Invalid Track. + return NULL; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorGroup.h b/Engine/modules/Verve/Extension/Director/VDirectorGroup.h new file mode 100644 index 000000000..bcf9b7a44 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorGroup.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// 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_VDIRECTORGROUP_H_ +#define _VT_VDIRECTORGROUP_H_ + +#ifndef _VT_VGROUP_H_ +#include "Verve/Core/VGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorTrack; +class VCameraGroup; + +//----------------------------------------------------------------------------- + +class VDirectorGroup : public VGroup +{ + typedef VGroup Parent; + +protected: + + // Camera. + VCameraGroup *mActiveCamera; + +public: + + VDirectorGroup( void ); + + VDirectorTrack *getDirectorTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTORGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorTrack.cpp b/Engine/modules/Verve/Extension/Director/VDirectorTrack.cpp new file mode 100644 index 000000000..7592b8882 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VDirectorTrack.h" + +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorTrack ); +//----------------------------------------------------------------------------- + +VDirectorTrack::VDirectorTrack( void ) +{ + setLabel( "DirectorTrack" ); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VDirectorTrack, updateTrack, void, 2, 2, "( void ) - Update the Track.\n" + "@return No return value." ) +{ + for ( ITreeNode *node = object->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *currEvent = ( VEvent* )node; + VEvent *nextEvent = ( VEvent* )node->mSiblingNextNode; + + if ( !nextEvent ) + { + // Update Duration. + currEvent->setDuration( object->getControllerDuration() - currEvent->getTriggerTime() ); + } + else + { + // Update Duration. + currEvent->setDuration( mAbs( nextEvent->getTriggerTime() - currEvent->getTriggerTime() ) ); + } + } +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VDirectorTrack.h b/Engine/modules/Verve/Extension/Director/VDirectorTrack.h new file mode 100644 index 000000000..98b36a410 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VDirectorTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VDIRECTORTRACK_H_ +#define _VT_VDIRECTORTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VDirectorTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTORTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.cpp b/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.cpp new file mode 100644 index 000000000..09df231b1 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.cpp @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSceneJumpEvent.h" +#include "Verve/Extension/Director/VDirectorGroup.h" +#include "Verve/Extension/Director/VDirectorTrack.h" +#include "Verve/Extension/Director/VDirectorEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneJumpEvent ); +//----------------------------------------------------------------------------- + +VSceneJumpEvent::VSceneJumpEvent( void ) : + mTarget( String::EmptyString ) +{ + setLabel( "SceneJumpEvent" ); +} + +void VSceneJumpEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Target", TypeRealString, Offset( mTarget, VSceneJumpEvent ), "The name of the Scene that the controller will jump to upon triggering." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneJumpEvent::onTrigger( pTime, pDelta ); +// +// Tell the controller to jump to a new scene. +// +//----------------------------------------------------------------------------- +void VSceneJumpEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VDirectorTrack *track = getController()->getDirectorTrack(); + if ( !track ) + { + // Invalid Track. + return; + } + + // Get Event. + VDirectorEvent *event; + if ( !track->getObject( mTarget, event ) ) + { + // Can't Jump. + return; + } + + // Go To Scene. + getController()->jump( VController::k_JumpTime, event->getTriggerTime() ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.h b/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.h new file mode 100644 index 000000000..bf7b597bf --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSceneJumpEvent.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEJUMPEVENT_H_ +#define _VT_VSCENEJUMPEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneJumpEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + String mTarget; + +public: + + VSceneJumpEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneJumpEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEJUMPEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.cpp b/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.cpp new file mode 100644 index 000000000..2a6e290d8 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSceneJumpTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneJumpTrack ); +//----------------------------------------------------------------------------- + +VSceneJumpTrack::VSceneJumpTrack( void ) +{ + setLabel( "SceneJumpTrack" ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.h b/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.h new file mode 100644 index 000000000..fefb4e4f6 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSceneJumpTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEJUMPTRACK_H_ +#define _VT_VSCENEJUMPTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneJumpTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSceneJumpTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneJumpTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEJUMPTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSlowMoEvent.cpp b/Engine/modules/Verve/Extension/Director/VSlowMoEvent.cpp new file mode 100644 index 000000000..3427bda43 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSlowMoEvent.cpp @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSlowMoEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSlowMoEvent ); +//----------------------------------------------------------------------------- + +VSlowMoEvent::VSlowMoEvent( void ) : + mTimeScale( 1.f ), + mTimeScaleTickDelta( 0.f ) +{ + setLabel( "SlowMoEvent" ); +} + +void VSlowMoEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "TimeScale", TypeF32, Offset( mTimeScale, VSlowMoEvent ), "The Time Scale to be applied to the Root Controller." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onTrigger( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Instant Update? + if ( getDuration() == 0 ) + { + // Apply & Return. + controller->setTimeScale( mTimeScale ); + return; + } + + // Determine the Number of Ticks. + const F32 tickCount = ( ( F32 )getDuration() ) / TickMs; + + // Determine the Tick Delta. + mTimeScaleTickDelta = ( mTimeScale - controller->getTimeScale() ) / tickCount; +} + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onUpdate( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onUpdate( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onUpdate( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Fetch Current Time Scale. + const F32 timeScale = controller->getTimeScale(); + + // Apply Update. + controller->setTimeScale( timeScale + mTimeScaleTickDelta ); +} + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onComplete( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onComplete( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Tidy Up. + controller->setTimeScale( mTimeScale ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSlowMoEvent.h b/Engine/modules/Verve/Extension/Director/VSlowMoEvent.h new file mode 100644 index 000000000..1cdf75889 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSlowMoEvent.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VSLOWMOEVENT_H_ +#define _VT_VSLOWMOEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VSlowMoEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + F32 mTimeScale; + F32 mTimeScaleTickDelta; + +public: + + VSlowMoEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onUpdate( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSlowMoEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSLOWMOEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSlowMoTrack.cpp b/Engine/modules/Verve/Extension/Director/VSlowMoTrack.cpp new file mode 100644 index 000000000..094acfa5e --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSlowMoTrack.cpp @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSlowMoTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSlowMoTrack ); +//----------------------------------------------------------------------------- + +VSlowMoTrack::VSlowMoTrack( void ) +{ + setLabel( "SlowMoTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSlowMoTrack::onControllerEvent( pEvent ); +// +// ... +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VSlowMoTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventStop : + { + + // Reset Time Scale. + getController()->setTimeScale( ( isControllerPlayingForward() ) ? 1.f : -1.f ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VSlowMoTrack::onControllerReset( pTime, pForward ); +// +// ... +// +//----------------------------------------------------------------------------- +void VSlowMoTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Parent Reset. + Parent::onControllerReset( pTime, pForward ); + + // Reset Time Scale. + getController()->setTimeScale( ( pForward ) ? 1.f : -1.f ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Director/VSlowMoTrack.h b/Engine/modules/Verve/Extension/Director/VSlowMoTrack.h new file mode 100644 index 000000000..143203c99 --- /dev/null +++ b/Engine/modules/Verve/Extension/Director/VSlowMoTrack.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_VSLOWMOTRACK_H_ +#define _VT_VSLOWMOTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VSlowMoTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSlowMoTrack( void ); + + // Controller Methods. + + bool onControllerEvent( VController::eControllerEventType pEvent ); + void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSlowMoTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSLOWMOTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/GUI/VFadeEvent.cpp b/Engine/modules/Verve/Extension/GUI/VFadeEvent.cpp new file mode 100644 index 000000000..c8d0db6c0 --- /dev/null +++ b/Engine/modules/Verve/Extension/GUI/VFadeEvent.cpp @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// 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/Extension/GUI/VFadeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeEvent ); +//----------------------------------------------------------------------------- + +VFadeEvent::VFadeEvent( void ) +{ + setLabel( "FadeEvent" ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeEvent::onTrigger( pTime, pDelta ); +// +// Start the fade sequence if a valid fade control can be found. +// +//----------------------------------------------------------------------------- +void VFadeEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + // Start Fade. + fadeControl->start( getFadeType(), mDuration ); + + // Set Elapsed Time. + fadeControl->mElapsedTime = mAbs( pTime - getStartTime() ); +} + +//----------------------------------------------------------------------------- +// +// VFadeEvent::onComplete( pTime, pDelta ); +// +// Tidy up the fade control once the event has finished. +// +//----------------------------------------------------------------------------- +void VFadeEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + // Set Elapsed Time. + fadeControl->mElapsedTime = mDuration; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeEvent::getFadeType(); +// +// Returns the type of fade (in or out) that this event will use. Zero and Even +// indices will Fade Out, while Odd numbers will Fade In. +// +//----------------------------------------------------------------------------- +VFadeControl::eFadeType VFadeEvent::getFadeType( void ) +{ + if ( !isControllerPlayingForward() ) + { + return ( getIndex() % 2 == 0 ) ? VFadeControl::k_TypeOut : VFadeControl::k_TypeIn; + } + + return ( getIndex() % 2 == 0 ) ? VFadeControl::k_TypeIn : VFadeControl::k_TypeOut; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/GUI/VFadeEvent.h b/Engine/modules/Verve/Extension/GUI/VFadeEvent.h new file mode 100644 index 000000000..78c8d7c5f --- /dev/null +++ b/Engine/modules/Verve/Extension/GUI/VFadeEvent.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VFADEEVENT_H_ +#define _VT_VFADEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_VFADECONTROL_H_ +#include "Verve/GUI/VFadeControl.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VFadeEvent( void ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeEvent ); + +public: + + VFadeControl::eFadeType getFadeType( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADEEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/GUI/VFadeTrack.cpp b/Engine/modules/Verve/Extension/GUI/VFadeTrack.cpp new file mode 100644 index 000000000..e293672db --- /dev/null +++ b/Engine/modules/Verve/Extension/GUI/VFadeTrack.cpp @@ -0,0 +1,139 @@ +//----------------------------------------------------------------------------- +// 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/Extension/GUI/VFadeTrack.h" +#include "Verve/Extension/GUI/VFadeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeTrack ); +//----------------------------------------------------------------------------- + +VFadeTrack::VFadeTrack( void ) +{ + setLabel( "FadeTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is paused, or stops playing, then the fade control will cease +// playing. If the controller resumes play, the fade control will continue. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VFadeTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + // Fetch the next Event. + VFadeEvent *event; + if ( !getNextEvent( event ) ) + { + // No Event. + return true; + } + + // Fetch GUI Control. + VFadeControl *fadeControl = dynamic_cast( Sim::findObject( "VFadeControlGui" ) ); + if ( !fadeControl ) + { + // No Control. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay: + { + // Play? + const S32 &time = getControllerTime(); + fadeControl->mActive = ( time > event->getTriggerTime() + && time < event->getFinishTime() ) ; + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Pause. + fadeControl->mActive = false; + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VFadeTrack::onControllerReset( pTime, pForward ); +// +// Reset the fade state of the fade control. +// +//----------------------------------------------------------------------------- +void VFadeTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + Parent::onControllerReset( pTime, pForward ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + VFadeEvent *event; + if ( !getNextEvent( event ) ) + { + // No Events. + return; + } + + // Apply Settings. + fadeControl->mActive = false; + fadeControl->mFadeType = event->getFadeType(); + fadeControl->mDuration = event->getDuration(); + fadeControl->mElapsedTime = getMax( pTime - event->getTriggerTime(), 0 ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/GUI/VFadeTrack.h b/Engine/modules/Verve/Extension/GUI/VFadeTrack.h new file mode 100644 index 000000000..87ca4b9d8 --- /dev/null +++ b/Engine/modules/Verve/Extension/GUI/VFadeTrack.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_VFADETRACK_H_ +#define _VT_VFADETRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VFadeTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADETRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.cpp b/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.cpp new file mode 100644 index 000000000..c08156e49 --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereGroup ); +//----------------------------------------------------------------------------- + +VSpawnSphereGroup::VSpawnSphereGroup( void ) +{ + setLabel( "SpawnSphereGroup" ); +}; \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.h b/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.h new file mode 100644 index 000000000..5a92713ca --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHEREGROUP_H_ +#define _VT_VSPAWNSPHEREGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VSpawnSphereGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHEREGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp new file mode 100644 index 000000000..92218060a --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereSpawnTargetEvent.h" +#include "Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereSpawnTargetEvent ); +//----------------------------------------------------------------------------- + +VSpawnSphereSpawnTargetEvent::VSpawnSphereSpawnTargetEvent( void ) +{ + setLabel( "SpawnTargetEvent" ); +} + +void VSpawnSphereSpawnTargetEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetEvent::onTrigger( pTime, pDelta ); +// +// Spawn the Target. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Track. + VSpawnSphereSpawnTargetTrack *track; + if ( !getTrack( track ) ) + { + return; + } + + // Spawn the Target. + track->spawnTarget(); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h new file mode 100644 index 000000000..60b39952d --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHERESPAWNTARGETEVENT_H_ +#define _VT_VSPAWNSPHERESPAWNTARGETEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_SPAWNSPHERE_H_ +#include "Verve/Torque/TSpawnSphere.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereSpawnTargetEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; +public: + + VSpawnSphereSpawnTargetEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereSpawnTargetEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHERESPAWNTARGETEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp new file mode 100644 index 000000000..d0cc2930a --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereSpawnTargetTrack.h" +#include "Verve/Torque/TSpawnSphere.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereSpawnTargetTrack ); +//----------------------------------------------------------------------------- + +VSpawnSphereSpawnTargetTrack::VSpawnSphereSpawnTargetTrack( void ) +{ + setLabel( "SpawnTargetTrack" ); +} + +void VSpawnSphereSpawnTargetTrack::initPersistFields( void ) +{ + // Parent Call. + Parent::initPersistFields(); + + addField( "DespawnOnLoop", TypeBool, Offset( mDespawnOnLoop, VSpawnSphereSpawnTargetTrack ), "Despawn all targets when the Controller loops?" ); + addField( "DespawnOnStop", TypeBool, Offset( mDespawnOnStop, VSpawnSphereSpawnTargetTrack ), "Despawn all targets when the Controller stops playing?" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::onControllerEvent( pEvent ); +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VSpawnSphereSpawnTargetTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventLoop : + { + if ( mDespawnOnLoop ) + { + despawnTargets(); + } + + } break; + + case VController::k_EventStop : + { + if ( mDespawnOnStop ) + { + despawnTargets(); + } + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Spawn Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::spawnTarget( pTime, pForward ); +// +// Spawn an Object. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetTrack::spawnTarget( void ) +{ + VTorque::SpawnSphereType *object; + if ( !getSceneObject( object ) ) + { + return; + } + + // Spawn the Object. + SimObject *spawnedObject = object->spawnObject(); + + // Scene Object? + VTorque::SceneObjectType *sceneObject = dynamic_cast( spawnedObject ); + if ( sceneObject ) + { + sceneObject->setPosition( object->getPosition() ); + } + + // Valid? + if ( spawnedObject ) + { + // Add Reference. + mSpawnList.addObject( spawnedObject ); + } +} + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::despawnTargets(); +// +// Despawn all of the objects spawned by this track. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetTrack::despawnTargets( void ) +{ + while( mSpawnList.size() > 0 ) + { + // Fetch the Last Object + SimObject *object = mSpawnList.last(); + // Remove it. + mSpawnList.popObject(); + + // Delete the Object. + object->deleteObject(); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h new file mode 100644 index 000000000..0df6f2ae5 --- /dev/null +++ b/Engine/modules/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHERESPAWNTARGETTRACK_H_ +#define _VT_VSPAWNSPHERESPAWNTARGETTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereSpawnTargetTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +protected: + + SimSet mSpawnList; + + bool mDespawnOnStop; + bool mDespawnOnLoop; + +public: + + VSpawnSphereSpawnTargetTrack( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + + // Spawn Methods. + + virtual void spawnTarget( void ); + virtual void despawnTargets( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereSpawnTargetTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHERESPAWNTARGETTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp new file mode 100644 index 000000000..94f34c350 --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectAnimationEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectAnimationEvent ); +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +VLightObjectAnimationEvent::VLightObjectAnimationEvent( void ) : + mAnimationData( NULL ) +{ + setLabel( "AnimationEvent" ); +} + +void VLightObjectAnimationEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "AnimationData", TYPEID(), Offset( mAnimationData, VLightObjectAnimationEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationEvent::onTrigger( pTime, pDelta ); +// +// When this Event is triggered the light object will begin to play the target +// animation. +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Play the Animation. + VTorque::playAnimation( lightObject, mAnimationData ); + } +} + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationEvent::onComplete( pTime, pDelta ); +// +// The current animation played by the light object will be paused when this +// Event completes its updates. +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Pause the Animation. + VTorque::pauseAnimation( lightObject ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.h b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.h new file mode 100644 index 000000000..18162ff2c --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationEvent.h @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTANIMATIONEVENT_H_ +#define _VT_VLIGHTOBJECTANIMATIONEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectAnimationEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + SimObjectPtr mAnimationData; + +public: + + VLightObjectAnimationEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectAnimationEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTANIMATIONEVENT_H_ diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp new file mode 100644 index 000000000..fe2455f4f --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp @@ -0,0 +1,118 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectAnimationTrack.h" +#include "Verve/Extension/LightObject/VLightObjectAnimationEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectAnimationTrack ); +//----------------------------------------------------------------------------- + +VLightObjectAnimationTrack::VLightObjectAnimationTrack( void ) +{ + setLabel( "AnimationTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationTrack::onControllerEvent( pEvent ); +// +// +// +//----------------------------------------------------------------------------- +bool VLightObjectAnimationTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( !getSceneObject( lightObject ) ) + { + // Skip. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay : + { + + // Play Animation? + VLightObjectAnimationEvent *event; + if ( getCurrentEvent( event ) ) + { + // Play. + VTorque::playAnimation( lightObject ); + } + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Stop the Animation. + VTorque::pauseAnimation( lightObject ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationTrack::onControllerReset( pTime, pForward ); +// +// +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Stop the Animation. + VTorque::pauseAnimation( lightObject ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.h b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.h new file mode 100644 index 000000000..6485e8428 --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectAnimationTrack.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTANIMATIONTRACK_H_ +#define _VT_VLIGHTOBJECTANIMATIONTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectAnimationTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VLightObjectAnimationTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectAnimationTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTANIMATIONTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.cpp b/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.cpp new file mode 100644 index 000000000..9db010fc2 --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectGroup ); +//----------------------------------------------------------------------------- + +VLightObjectGroup::VLightObjectGroup( void ) +{ + setLabel( "LightObjectGroup" ); +}; \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.h b/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.h new file mode 100644 index 000000000..16af01bcd --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTGROUP_H_ +#define _VT_VLIGHTOBJECTGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VLightObjectGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp new file mode 100644 index 000000000..4e1475a5f --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectToggleEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectToggleEvent ); +//----------------------------------------------------------------------------- + +VLightObjectToggleEvent::VLightObjectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VLightObjectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VLightObjectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectToggleEvent::onTrigger( pTime, pDelta ); +// +// Toggle the Light Object. +// +//----------------------------------------------------------------------------- +void VLightObjectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle Light. + VTorque::setLightObjectOn( lightObject, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.h b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.h new file mode 100644 index 000000000..382aee1c7 --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTTOGGLEEVENT_H_ +#define _VT_VLIGHTOBJECTTOGGLEEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectToggleEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VLightObjectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp new file mode 100644 index 000000000..a4a5387eb --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectToggleTrack.h" +#include "Verve/Extension/LightObject/VLightObjectToggleEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectToggleTrack ); +//----------------------------------------------------------------------------- + +VLightObjectToggleTrack::VLightObjectToggleTrack( void ) +{ + setLabel( "ToggleTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectToggleTrack::onControllerReset( pTime, pForward ); +// +// Enable or Disable the light object after a reset. +// +//----------------------------------------------------------------------------- +void VLightObjectToggleTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + VLightObjectToggleEvent *event; + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) && getPreviousEvent( event ) ) + { + // Turn On? + const bool turnOn = ( event->mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle the Light. + VTorque::setLightObjectOn( lightObject, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.h b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.h new file mode 100644 index 000000000..510c290bb --- /dev/null +++ b/Engine/modules/Verve/Extension/LightObject/VLightObjectToggleTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTTOGGLETRACK_H_ +#define _VT_VLIGHTOBJECTTOGGLETRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectToggleTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VLightObjectToggleTrack( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectToggleTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Motion/VMotionEvent.cpp b/Engine/modules/Verve/Extension/Motion/VMotionEvent.cpp new file mode 100644 index 000000000..d972168ec --- /dev/null +++ b/Engine/modules/Verve/Extension/Motion/VMotionEvent.cpp @@ -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( 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( 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; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Motion/VMotionEvent.h b/Engine/modules/Verve/Extension/Motion/VMotionEvent.h new file mode 100644 index 000000000..2ef710e06 --- /dev/null +++ b/Engine/modules/Verve/Extension/Motion/VMotionEvent.h @@ -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_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Motion/VMotionTrack.cpp b/Engine/modules/Verve/Extension/Motion/VMotionTrack.cpp new file mode 100644 index 000000000..bce52f93f --- /dev/null +++ b/Engine/modules/Verve/Extension/Motion/VMotionTrack.cpp @@ -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( 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( 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( 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 \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Motion/VMotionTrack.h b/Engine/modules/Verve/Extension/Motion/VMotionTrack.h new file mode 100644 index 000000000..b0fc25c34 --- /dev/null +++ b/Engine/modules/Verve/Extension/Motion/VMotionTrack.h @@ -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_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp new file mode 100644 index 000000000..00c30388c --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectGroup ); +//----------------------------------------------------------------------------- + +VParticleEffectGroup::VParticleEffectGroup( void ) +{ + setLabel( "ParticleEffectGroup" ); +}; \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.h b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.h new file mode 100644 index 000000000..aa7806366 --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEEFFECTGROUP_H_ +#define _VT_VPARTICLEEFFECTGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VParticleEffectGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEEFFECTGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp new file mode 100644 index 000000000..658f3b5d0 --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectToggleEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectToggleEvent ); +//----------------------------------------------------------------------------- + +VParticleEffectToggleEvent::VParticleEffectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VParticleEffectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VParticleEffectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VParticleEffectToggleEvent::onTrigger( pTime, pDelta ); +// +// Toggle the Particle Effect. +// +//----------------------------------------------------------------------------- +void VParticleEffectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::ParticleEffectType *particleEffect; + if ( getSceneObject( particleEffect ) ) + { + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle Particle Effect. + VTorque::setParticleEffectOn( particleEffect, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h new file mode 100644 index 000000000..e4028413a --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEFFECTTOGGLEEVENT_H_ +#define _VT_VPARTICLEFFECTTOGGLEEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_PARTICLEEFFECT_H_ +#include "Verve/Torque/TParticleEffect.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectToggleEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VParticleEffectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEFFECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp new file mode 100644 index 000000000..30ce242f5 --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectToggleTrack.h" +#include "Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectToggleTrack ); +//----------------------------------------------------------------------------- + +VParticleEffectToggleTrack::VParticleEffectToggleTrack( void ) +{ + setLabel( "ToggleTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VParticleEffectToggleTrack::onControllerReset( pTime, pForward ); +// +// Enable or Disable the particle effect after a reset. +// +//----------------------------------------------------------------------------- +void VParticleEffectToggleTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + VParticleEffectToggleEvent *event; + VTorque::ParticleEffectType *particleEffect; + if ( getSceneObject( particleEffect ) && getPreviousEvent( event ) ) + { + // Turn On? + const bool turnOn = ( event->mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle the Particle Effect. + VTorque::setParticleEffectOn( particleEffect, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h new file mode 100644 index 000000000..5974dbeb8 --- /dev/null +++ b/Engine/modules/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEEFFECTTOGGLETRACK_H_ +#define _VT_VPARTICLEEFFECTTOGGLETRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_PARTICLEEFFECT_H_ +#include "Verve/Torque/TParticleEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectToggleTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VParticleEffectToggleTrack( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectToggleTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEEFFECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp new file mode 100644 index 000000000..5e5d65d40 --- /dev/null +++ b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/PostEffect/VPostEffectToggleEvent.h" +#include "Verve/Extension/PostEffect/VPostEffectToggleTrack.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPostEffectToggleEvent ); +//----------------------------------------------------------------------------- + +VPostEffectToggleEvent::VPostEffectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VPostEffectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VPostEffectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VPostEffectToggleEvent::onTrigger( pTime, pDelta ); +// +// Only enable this effect if the parent group is currently active. +// +//----------------------------------------------------------------------------- +void VPostEffectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Parent Objects. + VCameraGroup *group; + VPostEffectToggleTrack *track; + if ( ( !getGroup( group ) || !group->isActive() ) || !getTrack( track ) ) + { + // Quit. + return; + } + + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Enable Effect. + VTorque::setPostEffectOn( track->getPostEffect(), turnOn ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.h b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.h new file mode 100644 index 000000000..66668307b --- /dev/null +++ b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPOSTEFFECTTOGGLEEVENT_H_ +#define _VT_VPOSTEFFECTTOGGLEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VPostEffectToggleEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VPostEffectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VPostEffectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPOSTEFFECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp new file mode 100644 index 000000000..ff2dd52a5 --- /dev/null +++ b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// 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/Extension/PostEffect/VPostEffectToggleTrack.h" +#include "Verve/Extension/PostEffect/VPostEffectToggleEvent.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPostEffectToggleTrack ); +//----------------------------------------------------------------------------- + +VPostEffectToggleTrack::VPostEffectToggleTrack( void ) : + mPostEffect( NULL ) +{ + setLabel( "PostEffectTrack" ); +} + +void VPostEffectToggleTrack::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "PostEffect", TYPEID(), Offset( mPostEffect, VPostEffectToggleTrack ), "The name of the PostEffect object to be triggered." ); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VPostEffectToggleTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incoming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VPostEffectToggleTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + // Parent Call. + if ( !Parent::onCameraEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() || !mPostEffect.isValid() ) + { + // Quit Now. + return true; + } + + switch( pEvent ) + { + case VCameraGroup::k_EventActivate : + { + + VPostEffectToggleEvent *event; + if ( getPreviousEvent( event ) && event->mEventType == VSharedEnum::k_ActionTurnOn ) + { + // Toggle Post Effect On. + VTorque::setPostEffectOn( mPostEffect, true ); + } + + } break; + + case VCameraGroup::k_EventDeactivate : + { + + // Turn Post Effect Off. + VTorque::setPostEffectOn( mPostEffect, false ); + + } break; + } + + return true; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.h b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.h new file mode 100644 index 000000000..24a531684 --- /dev/null +++ b/Engine/modules/Verve/Extension/PostEffect/VPostEffectToggleTrack.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPOSTEFFECTTOGGLETRACK_H_ +#define _VT_VPOSTEFFECTTOGGLETRACK_H_ + +#ifndef _VT_VCAMERATRACK_H_ +#include "Verve/Extension/Camera/VCameraTrack.h" +#endif + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VPostEffectToggleTrack : public VCameraTrack +{ + typedef VCameraTrack Parent; + +protected: + + SimObjectPtr mPostEffect; + +public: + + VPostEffectToggleTrack( void ); + + static void initPersistFields( void ); + + // Camera Methods. + + bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Console Declaration. + + DECLARE_CONOBJECT( VPostEffectToggleTrack ); + +public: + + VTorque::PostEffectType *getPostEffect( void ) { return mPostEffect; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPOSTEFFECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.cpp b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.cpp new file mode 100644 index 000000000..7be35e944 --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectEvent ); +//----------------------------------------------------------------------------- + +VSceneObjectEvent::VSceneObjectEvent( void ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectEvent::getSceneObject(); +// +// Returns the parent group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectEvent::getSceneObject( void ) +{ + VSceneObjectGroup *group; + if ( !getGroup( group ) ) + { + // No Group! + return NULL; + } + + // Return Object. + return group->getSceneObject(); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VSceneObjectEvent, getSceneObject, S32, 2, 2, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.h b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.h new file mode 100644 index 000000000..5dd4bc7df --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectEvent.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTEVENT_H_ +#define _VT_VSCENEOBJECTEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VSceneObjectEvent( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.cpp b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.cpp new file mode 100644 index 000000000..1b07a32b9 --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.cpp @@ -0,0 +1,104 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Core/VController.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectGroup ); +//----------------------------------------------------------------------------- + +VSceneObjectGroup::VSceneObjectGroup( void ) : + mDataReference( String::EmptyString ), + mSceneObject( NULL ) +{ + setLabel( "SceneObjectGroup" ); +}; + +void VSceneObjectGroup::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Reference", TypeRealString, Offset( mDataReference, VSceneObjectGroup ), "The name of the data field referencing the targeted object." ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectGroup::getObject(); +// +// Returns the group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectGroup::getSceneObject( void ) +{ +#ifndef VT_EDITOR + // Already Referenced? + if ( mSceneObject ) + { + // Return Object. + return mSceneObject; + } +#endif + + VController *controller = getController(); + if ( !controller ) + { + // No Controller! + return NULL; + } + + String fieldValue; + if ( controller->getDataValue( mDataReference, fieldValue ) ) + { + // Store Object. + mSceneObject = dynamic_cast( Sim::findObject( fieldValue ) ); + } + + // Return. + return mSceneObject; +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VSceneObjectGroup, getSceneObject, S32, 2, 2, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.h b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.h new file mode 100644 index 000000000..9af52eef6 --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectGroup.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTGROUP_H_ +#define _VT_VSCENEOBJECTGROUP_H_ + +#ifndef _VT_VGROUP_H_ +#include "Verve/Core/VGroup.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectGroup : public VGroup +{ + typedef VGroup Parent; + +public: + + // Reference Members. + + String mDataReference; + VTorque::SceneObjectType *mSceneObject; + +public: + + VSceneObjectGroup( void ); + + static void initPersistFields( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTGROUP_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.cpp b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.cpp new file mode 100644 index 000000000..adb58d029 --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectTrack ); +//----------------------------------------------------------------------------- + +VSceneObjectTrack::VSceneObjectTrack( void ) +{ + setLabel( "SceneObjectTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectTrack::getSceneObject(); +// +// Returns the parent group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectTrack::getSceneObject( void ) +{ + VSceneObjectGroup *group; + if ( !getGroup( group ) ) + { + // No Group! + return NULL; + } + + // Return Object. + return group->getSceneObject(); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VSceneObjectTrack, getSceneObject, S32, 2, 2, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.h b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.h new file mode 100644 index 000000000..d07517862 --- /dev/null +++ b/Engine/modules/Verve/Extension/SceneObject/VSceneObjectTrack.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTTRACK_H_ +#define _VT_VSCENEOBJECTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSceneObjectTrack( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Script/VScriptEvent.cpp b/Engine/modules/Verve/Extension/Script/VScriptEvent.cpp new file mode 100644 index 000000000..48b78a7e4 --- /dev/null +++ b/Engine/modules/Verve/Extension/Script/VScriptEvent.cpp @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// 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/Core/VTrack.h" + +#include "Verve/Extension/Script/VScriptEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VScriptEvent ); +//----------------------------------------------------------------------------- + +// Implement the Command Type enum list. +ImplementEnumType( VScriptEventCommandType, "" ) + { VScriptEvent::k_TypeExpression, "EXPRESSION" }, + { VScriptEvent::k_TypeMethod, "METHOD" }, +EndImplementEnumType; + +//----------------------------------------------------------------------------- + +VScriptEvent::VScriptEvent( void ) : + mCommandType( k_TypeMethod ), + mCommand( String::EmptyString ) +{ + setLabel( "ScriptEvent" ); +} + +void VScriptEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "CommandType", TYPEID(), Offset( mCommandType, VScriptEvent ), "The type of command to be evaluated." ); + addField( "Command", TypeRealString, Offset( mCommand, VScriptEvent ), "The command to be evaluated." ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VScriptEvet::onTrigger( pTime, pDelta ); +// +// Execute a method or evaluate a command. +// +//----------------------------------------------------------------------------- +void VScriptEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + switch ( mCommandType ) + { + case k_TypeExpression : + { + + // Evaluate Expression. + Con::evaluate( mCommand, false, NULL ); + + } break; + + case k_TypeMethod : + { + + SimObject *object = getSceneObject(); + if ( object ) + { + // Execute Method. + Con::executef( object, mCommand ); + } + else + { + // Execute Function. + Con::executef( mCommand ); + } + + } break; + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Script/VScriptEvent.h b/Engine/modules/Verve/Extension/Script/VScriptEvent.h new file mode 100644 index 000000000..ee0b139ca --- /dev/null +++ b/Engine/modules/Verve/Extension/Script/VScriptEvent.h @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// 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_VSCRIPTEVENT_H_ +#define _VT_VSCRIPTEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VScriptEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + +public: + + enum eCommandType + { + k_TypeExpression, + k_TypeMethod, + + k_TypeInvalid, + }; + + eCommandType mCommandType; + String mCommand; + +public: + + VScriptEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VScriptEvent ); +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VScriptEvent::eCommandType VScriptEventCommandType; + +// Declare Enum Types. +DefineEnumType( VScriptEventCommandType ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCRIPTEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Script/VScriptEventTrack.cpp b/Engine/modules/Verve/Extension/Script/VScriptEventTrack.cpp new file mode 100644 index 000000000..142d7bc1b --- /dev/null +++ b/Engine/modules/Verve/Extension/Script/VScriptEventTrack.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Script/VScriptEventTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VScriptEventTrack ); +//----------------------------------------------------------------------------- + +VScriptEventTrack::VScriptEventTrack( void ) +{ + setLabel( "ScriptEventTrack" ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/Script/VScriptEventTrack.h b/Engine/modules/Verve/Extension/Script/VScriptEventTrack.h new file mode 100644 index 000000000..e0360ab4f --- /dev/null +++ b/Engine/modules/Verve/Extension/Script/VScriptEventTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSCRIPTEVENTTRACK_H_ +#define _VT_VSCRIPTEVENTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VScriptEventTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VScriptEventTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VScriptEventTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCRIPTEVENTTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp new file mode 100644 index 000000000..92c352427 --- /dev/null +++ b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// 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/SoundEffect/VSoundEffectEvent.h" +#include "Verve/Extension/SoundEffect/VSoundEffectTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSoundEffectEvent ); +//----------------------------------------------------------------------------- + +VSoundEffectEvent::VSoundEffectEvent( void ) : + mSoundEffect( NULL ) +{ + setLabel( "SoundEvent" ); +} + +void VSoundEffectEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "SoundEffect", TYPEID(), Offset( mSoundEffect, VSoundEffectEvent ), &setSoundData, &defaultProtectedGetFn, "" ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectEvent::onTrigger( pTime, pDelta ); +// +// Play the target sound effect. If this track belongs to a SceneObjectGroup, +// then the sound will play with the reference object's transform. If this is +// not the case, then a 2D sound will be played. +// +//----------------------------------------------------------------------------- +void VSoundEffectEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Track. + VSoundEffectTrack *track; + if ( !getTrack( track ) ) + { + return; + } + + // Position & Pitch. + U32 position = mAbs( ( pTime + pDelta ) - getStartTime() ); + F32 pitch = mFabs( getControllerTimeScale() ); + if ( position < SFXStartBuffer ) + { + // Zero. + position = 0; + } + + VSceneObjectGroup *group; + if ( getGroup( group ) ) + { + // Play Sound With Reference. + track->mSource = VTorque::playSound( mSoundEffect, group->getSceneObject(), position, pitch ); + } + else + { + // Play Sound. + track->mSource = VTorque::playSound( mSoundEffect, position, pitch ); + } +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectEvent::setDuration( pDuration ); +// +// This event's duration is always set to the sound object's duration. +// +//----------------------------------------------------------------------------- +void VSoundEffectEvent::setDuration( const S32 &pDuration ) +{ + // Clear Duration. + mDuration = VTorque::getSoundDuration( mSoundEffect ); +} + +//----------------------------------------------------------------------------- +// +// Static Field Methods. +// +//----------------------------------------------------------------------------- + +bool VSoundEffectEvent::setSoundData( void *pObject, const char *pArray, const char *pData ) +{ + // Fetch Event. + VSoundEffectEvent *event = static_cast( pObject ); + + // Use Object. + event->mSoundEffect = dynamic_cast( Sim::findObject( pData ) ); + + // Set Duration. + event->setDuration( 0 ); + + return false; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.h b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.h new file mode 100644 index 000000000..79ea79d65 --- /dev/null +++ b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectEvent.h @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// 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_VSOUNDEFFECTEVENT_H_ +#define _VT_VSOUNDEFFECTEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VSoundEffectEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + + enum + { + SFXStartBuffer = 100, + }; + +public: + + SimObjectPtr mSoundEffect; + +public: + + VSoundEffectEvent( void ); + + static void initPersistFields( void ); + + static bool setSoundData( void *pObject, const char *pArray, const char *pData ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSoundEffectEvent ); + +public: + + // Property Methods. + + virtual void setDuration( const S32 &pDuration ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSOUNDEFFECTEVENT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp new file mode 100644 index 000000000..040040d31 --- /dev/null +++ b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SoundEffect/VSoundEffectTrack.h" +#include "Verve/Extension/SoundEffect/VSoundEffectEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSoundEffectTrack ); +//----------------------------------------------------------------------------- + +VSoundEffectTrack::VSoundEffectTrack( void ) : + mSource( NULL ) +{ + setLabel( "SoundTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectTrack::onControllerEvent( pEvent ); +// +// If the controller ceases playback and the track has a valid reference to a +// source provider, then the sound is stopped. +// +//----------------------------------------------------------------------------- +bool VSoundEffectTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPause : + case VController::k_EventStop : + { +#ifdef VT_EDITOR + + if ( mSource ) + { + // Stop Sound. + VTorque::stopSound( mSource ); + + // Clear Source. + mSource = NULL; + } + +#endif + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VSoundEffectTrack::onControllerReset( pTime, pForward ); +// +// If the track is reset and it has a valid reference to a source provider, +// then the sound is stopped. +// +//----------------------------------------------------------------------------- +void VSoundEffectTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + if ( mSource ) + { + // Stop Sound. + VTorque::stopSound( mSource ); + } + + // Clear Source. + mSource = NULL; +} \ No newline at end of file diff --git a/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.h b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.h new file mode 100644 index 000000000..1b4eccb24 --- /dev/null +++ b/Engine/modules/Verve/Extension/SoundEffect/VSoundEffectTrack.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VSOUNDEFFECTTRACK_H_ +#define _VT_VSOUNDEFFECTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VSoundEffectTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VTorque::SoundSourceType *mSource; + +public: + + VSoundEffectTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSoundEffectTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSOUNDEFFECTTRACK_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorButton.cpp b/Engine/modules/Verve/GUI/VEditorButton.cpp new file mode 100644 index 000000000..1e548280c --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorButton.cpp @@ -0,0 +1,216 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorButton.h" +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gui/core/guiCanvas.h" +#include "gui/core/guiDefaultControlRender.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorButton ); +//----------------------------------------------------------------------------- + +VEditorButton::VEditorButton( void ) : + mIsDraggable( false ) +{ + // Void. +} + +void VEditorButton::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "IsDraggable", TypeBool, Offset( mIsDraggable, VEditorButton ) ); +} + +//----------------------------------------------------------------------------- + +void VEditorButton::onMouseDown( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseDown( pEvent ); + + onMouseEvent( "onMouseDown", pEvent ); +} + +void VEditorButton::onMouseUp( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseUp( pEvent ); + + if ( mIsDraggable && isMouseLocked() ) + { + // Unlock. + mouseUnlock(); + } + + onMouseEvent( "onMouseUp", pEvent ); +} + +void VEditorButton::onMouseDragged( const GuiEvent &pEvent ) +{ + if ( !mActive || !mIsDraggable ) + { + return; + } + + Parent::onMouseDragged( pEvent ); + + if ( !isMouseLocked() ) + { + GuiCanvas *canvas = getRoot(); + if ( canvas->getMouseLockedControl() ) + { + GuiEvent event; + canvas->getMouseLockedControl()->onMouseLeave( event ); + canvas->mouseUnlock( canvas->getMouseLockedControl() ); + } + + // Lock. + mouseLock(); + } + + onMouseEvent( "onMouseDragged", pEvent ); +} + +void VEditorButton::onRightMouseDown( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onRightMouseDown( pEvent ); + + onMouseEvent( "onRightMouseDown", pEvent ); +} + +void VEditorButton::onRightMouseUp( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onRightMouseUp( pEvent ); + + onMouseEvent( "onRightMouseUp", pEvent ); +} + +void VEditorButton::onMouseEnter( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseEnter( pEvent ); + + onMouseEvent( "onMouseEnter", pEvent ); +} + +void VEditorButton::onMouseLeave( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseLeave( pEvent ); + + onMouseEvent( "onMouseLeave", pEvent ); +} + +void VEditorButton::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- + +void VEditorButton::onRender( Point2I offset, const RectI& updateRect ) +{ + // Fetch Texture. + GFXTexHandle texture = getTextureForCurrentState(); + + // Valid? + if ( texture ) + { + GFX->getDrawUtil()->clearBitmapModulation(); + GFX->getDrawUtil()->drawBitmapStretch( texture, RectI( offset, getExtent() ) ); + } + else + { + if ( mProfile->mBorder != 0 ) + { + RectI boundsRect( offset, getExtent() ); + + if ( mDepressed || mStateOn || mMouseOver ) + { + renderFilledBorder( boundsRect, mProfile->mBorderColorHL, mProfile->mFillColorHL ); + } + else + { + renderFilledBorder( boundsRect, mProfile->mBorderColor, mProfile->mFillColor ); + } + } + } + + // Render Text. + GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor ); + renderJustifiedText( offset + mProfile->mTextOffset, getExtent(), mButtonText ); + + renderChildControls( offset, updateRect); +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VEditorButton, getState, bool, 2, 2, "()" ) +{ + return object->getStateOn(); +} \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorButton.h b/Engine/modules/Verve/GUI/VEditorButton.h new file mode 100644 index 000000000..15b3e0dfa --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorButton.h @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORBUTTON_H_ +#define _VT_VEDITORBUTTON_H_ + +#ifndef _GUIBITMAPBUTTON_H_ +#include "gui/buttons/guiBitmapButtonCtrl.h" +#endif + +class VEditorButton : public GuiBitmapButtonTextCtrl +{ + typedef GuiBitmapButtonTextCtrl Parent; + +public: + + bool mIsDraggable; + +public: + + VEditorButton(); + + static void initPersistFields( void ); + + void onMouseDown( const GuiEvent &pEvent ); + void onMouseUp( const GuiEvent &pEvent ); + void onMouseDragged( const GuiEvent &pEvent ); + + void onRightMouseDown( const GuiEvent &pEvent ); + void onRightMouseUp( const GuiEvent &pEvent ); + + void onMouseEnter( const GuiEvent &pEvent ); + void onMouseLeave( const GuiEvent &pEvent ); + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + void onRender( Point2I offset, const RectI &updateRect ); + +public: + + DECLARE_CONOBJECT( VEditorButton ); +}; + +#endif //_VT_VEDITORBUTTON_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorScrollControl.cpp b/Engine/modules/Verve/GUI/VEditorScrollControl.cpp new file mode 100644 index 000000000..b503ed0d6 --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorScrollControl.cpp @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorScrollControl.h" +#include "gfx/gfxDrawUtil.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorScrollControl ); +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Mouse Methods. +// +//----------------------------------------------------------------------------- + +void VEditorScrollControl::onMouseUp( const GuiEvent &pEvent ) +{ + Parent::onMouseUp( pEvent ); + + // Event. + onMouseEvent( "onMouseUp", pEvent ); +} + +void VEditorScrollControl::onRightMouseUp( const GuiEvent &pEvent ) +{ + Parent::onMouseUp( pEvent ); + + // Event. + onMouseEvent( "onRightMouseUp", pEvent ); +} + +void VEditorScrollControl::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + const S32 offsetX = ( mHasVScrollBar ) ? mScrollBarThickness : 0; + const S32 offsetY = ( mHasHScrollBar ) ? mScrollBarThickness : 0; + + const RectI contentRect( 2, 2, getWidth() - offsetX - 4 - 1, getHeight() - offsetY - 4 - ( mHasHScrollBar ) ); + if ( !contentRect.pointInRect( pEvent.mousePoint ) ) + { + // Return! + return; + } + + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VEditorScrollControl::onRender( Point2I pOffset, const RectI &pUpdateRect ) +{ + Parent::onRender( pOffset, pUpdateRect ); + + const S32 offsetX = ( mHasVScrollBar ) ? mScrollBarThickness : 1; + const S32 offsetY = ( mHasHScrollBar ) ? mScrollBarThickness : 1; + + RectI contentRect( pOffset.x + 1, pOffset.y + 1, getWidth() - offsetX - 1, getHeight() - offsetY - 1 ); + contentRect.intersect( pUpdateRect ); + + GFX->getDrawUtil()->drawRect( contentRect, mProfile->mBorderColor ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorScrollControl.h b/Engine/modules/Verve/GUI/VEditorScrollControl.h new file mode 100644 index 000000000..5d3e1d72e --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorScrollControl.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORSCROLLCONTROL_H_ +#define _VT_VEDITORSCROLLCONTROL_H_ + +#ifndef _GUISCROLLCTRL_H_ +#include "gui/containers/guiScrollCtrl.h" +#endif + +//----------------------------------------------------------------------------- + +class VEditorScrollControl : public GuiScrollCtrl +{ + typedef GuiScrollCtrl Parent; + +public: + + // Mouse. + + virtual void onMouseUp( const GuiEvent &pEvent ); + virtual void onRightMouseUp( const GuiEvent &pEvent ); + + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + // Rendering. + + void onRender( Point2I pOffset, const RectI &pUpdateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEditorScrollControl ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEDITORSCROLLCONTROL_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorWindow.cpp b/Engine/modules/Verve/GUI/VEditorWindow.cpp new file mode 100644 index 000000000..fe7a2e859 --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorWindow.cpp @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorWindow.h" +#include "gfx/gfxInit.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorWindow ); +//----------------------------------------------------------------------------- + +bool VEditorWindow::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + GFXAdapter *adapter = GFXInit::getBestAdapterChoice(); + if ( adapter && adapter->mType != NullDevice ) + { + mPlatformWindow->setMinimumWindowSize( Point2I( 904, 287 ) ); + } + + return true; +} + +//----------------------------------------------------------------------------- + +ConsoleMethod( VEditorWindow, resetCursor, void, 2, 2, "( )" ) +{ + S32 currCursor = PlatformCursorController::curArrow; + if ( object->mCursorChanged == currCursor ) + { + return; + } + + PlatformWindow *window = object->getPlatformWindow(); + PlatformCursorController *controller = window->getCursorController(); + + if( object->mCursorChanged != -1) + { + controller->popCursor(); + } + + controller->pushCursor(currCursor); + object->mCursorChanged = currCursor; + + Platform::setWindowLocked( false ); +} + +ConsoleMethod( VEditorWindow, setVideoMode, void, 5, 8, + "(int width, int height, bool fullscreen, [int bitDepth], [int refreshRate])\n" + "Change the video mode of this canvas. This method has the side effect of setting the $pref::Video::mode to the new values.\n\n" + "\\param width The screen width to set.\n" + "\\param height The screen height to set.\n" + "\\param fullscreen Specify true to run fullscreen or false to run in a window\n" + "\\param bitDepth [optional] The desired bit-depth. Defaults to the current setting. This parameter is ignored if you are running in a window.\n" + "\\param refreshRate [optional] The desired refresh rate. Defaults to the current setting. This parameter is ignored if you are running in a window" + "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) +{ + if (!object->getPlatformWindow()) + return; + + // Update the video mode and tell the window to reset. + GFXVideoMode vm = object->getPlatformWindow()->getVideoMode(); + + U32 width = dAtoi(argv[2]); + U32 height = dAtoi(argv[3]); + + bool changed = false; + if (width == 0 && height > 0) + { + // Our width is 0 but our height isn't... + // Try to find a matching width + for(S32 i=0; igetPlatformWindow()->getGFXDevice()->getVideoModeList()->size(); i++) + { + const GFXVideoMode &newVm = (*(object->getPlatformWindow()->getGFXDevice()->getVideoModeList()))[i]; + + if(newVm.resolution.y == height) + { + width = newVm.resolution.x; + changed = true; + break; + } + } + } + else if (height == 0 && width > 0) + { + // Our height is 0 but our width isn't... + // Try to find a matching height + for(S32 i=0; igetPlatformWindow()->getGFXDevice()->getVideoModeList()->size(); i++) + { + const GFXVideoMode &newVm = (*(object->getPlatformWindow()->getGFXDevice()->getVideoModeList()))[i]; + + if(newVm.resolution.x == width) + { + height = newVm.resolution.y; + changed = true; + break; + } + } + } + + if (width == 0 || height == 0) + { + // Got a bad size for both of our dimensions or one of our dimensions and + // didn't get a match for the other default back to our current resolution + width = vm.resolution.x; + height = vm.resolution.y; + + changed = true; + } + + if (changed) + Con::errorf("GuiCanvas::setVideoMode(): Error - Invalid resolution of (%d, %d) - attempting (%d, %d)", dAtoi(argv[2]), dAtoi(argv[3]), width, height); + + vm.resolution = Point2I(width, height); + vm.fullScreen = dAtob(argv[4]); + + // These optional params are set to default at construction of vm. If they + // aren't specified, just leave them at whatever they were set to. + if ((argc > 5) && (dStrlen(argv[5]) > 0)) + { + vm.bitDepth = dAtoi(argv[5]); + } + if ((argc > 6) && (dStrlen(argv[6]) > 0)) + { + vm.refreshRate = dAtoi(argv[6]); + } + + if ((argc > 7) && (dStrlen(argv[7]) > 0)) + { + vm.antialiasLevel = dAtoi(argv[7]); + } + +#ifndef TORQUE_OS_XENON + object->getPlatformWindow()->setVideoMode(vm); +#endif +} \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VEditorWindow.h b/Engine/modules/Verve/GUI/VEditorWindow.h new file mode 100644 index 000000000..938c909e9 --- /dev/null +++ b/Engine/modules/Verve/GUI/VEditorWindow.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORWINDOW_H_ +#define _VT_VEDITORWINDOW_H_ + +#ifndef _GUICANVAS_H_ +#include "gui/core/guiCanvas.h" +#endif + +//----------------------------------------------------------------------------- + +class VEditorWindow : public GuiCanvas +{ + typedef GuiCanvas Parent; + +public: + + // Properties. + + virtual bool onAdd( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEditorWindow ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEDITORWINDOW_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VFadeControl.cpp b/Engine/modules/Verve/GUI/VFadeControl.cpp new file mode 100644 index 000000000..5854ac4f2 --- /dev/null +++ b/Engine/modules/Verve/GUI/VFadeControl.cpp @@ -0,0 +1,114 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VFadeControl.h" + +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeControl ); +//----------------------------------------------------------------------------- + +VFadeControl::VFadeControl( void ) : + mActive( false ), + mFadeType( k_TypeInvalid ), + mElapsedTime( 0 ), + mDuration( 1000 ), + mLastTime( 0 ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VFadeControl::onRender( Point2I pOffset, const RectI &pUpdateRect ) +{ + Parent::onRender( pOffset, pUpdateRect ); + + if ( mFadeType == k_TypeInvalid ) + { + // Invalid Fade State. + return; + } + + // Fetch Time. + const U32 time = Platform::getRealMilliseconds(); + // Fetch Delta. + const U32 delta = ( time - mLastTime ); + // Store Time. + mLastTime = time; + + if ( mActive ) + { + // Update Elapsed Time. + mElapsedTime += delta; + } + + F32 alpha = 1.f - mClampF( F32( mElapsedTime ) / F32( mDuration ), 0.f, 1.f ); + + if ( mFadeType == k_TypeOut ) + { + // Flip. + alpha = 1.f - alpha; + } + + if ( alpha > 0.f ) + { + // Render. + GFX->getDrawUtil()->drawRectFill( pOffset, pOffset + getExtent(), ColorF( 0, 0, 0, alpha ) ); + } + + if ( mElapsedTime >= mDuration ) + { + // Stop. + mActive = false; + } +} + +//----------------------------------------------------------------------------- +// +// Control Methods. +// +//----------------------------------------------------------------------------- + +void VFadeControl::start( eFadeType pType, S32 pDuration ) +{ + mActive = true; + + mFadeType = pType; + + mElapsedTime = 0; + mDuration = pDuration; + + mLastTime = Platform::getRealMilliseconds(); +} + +void VFadeControl::pause( void ) +{ + mActive = false; +} \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VFadeControl.h b/Engine/modules/Verve/GUI/VFadeControl.h new file mode 100644 index 000000000..d26cdb97f --- /dev/null +++ b/Engine/modules/Verve/GUI/VFadeControl.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// 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_VFADECONTROL_H_ +#define _VT_VFADECONTROL_H_ + +#ifndef _GUICONTROL_H_ +#include "gui/core/guiControl.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeControl : public GuiControl +{ + typedef GuiControl Parent; + +public: + + enum eFadeType + { + k_TypeIn, + k_TypeOut, + + k_TypeInvalid, + }; + + bool mActive; + eFadeType mFadeType; + + S32 mElapsedTime; + S32 mDuration; + S32 mLastTime; + +public: + + VFadeControl( void ); + + // Render Methods. + + virtual void onRender( Point2I pOffset, const RectI &pUpdateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeControl ); + +public: + + void start( eFadeType pType, S32 pDuration ); + void pause( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADECONTROL_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VTimeLineControl.cpp b/Engine/modules/Verve/GUI/VTimeLineControl.cpp new file mode 100644 index 000000000..100f8d2de --- /dev/null +++ b/Engine/modules/Verve/GUI/VTimeLineControl.cpp @@ -0,0 +1,476 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VTimeLineControl.h" +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gui/core/guiCanvas.h" + +//----------------------------------------------------------------------------- + +const S32 gUnitsPerSec = 200; + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VTimeLineControl ); +//----------------------------------------------------------------------------- + +VTimeLineControl::VTimeLineControl( void ) : + mIsController( true ), + mController( NULL ), + mDurationOffset( 50 ) +{ + mSelection.Active = false; + mSelection.StartTime = 0; + mSelection.EndTime = 0; +} + +void VTimeLineControl::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "IsController", TypeBool, Offset( mIsController, VTimeLineControl ) ); + addField( "Controller", TYPEID(), Offset( mController, VTimeLineControl ) ); + addField( "DurationOffset", TypeS32, Offset( mDurationOffset, VTimeLineControl ) ); +} + +//----------------------------------------------------------------------------- +// +// Mouse Methods. +// +//----------------------------------------------------------------------------- + +void VTimeLineControl::onMouseDown( const GuiEvent &pEvent ) +{ + Parent::onMouseDown( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + if ( !isMouseLocked() ) + { + GuiCanvas *canvas = getRoot(); + if ( canvas->getMouseLockedControl() ) + { + GuiEvent event; + canvas->getMouseLockedControl()->onMouseLeave( event ); + canvas->mouseUnlock( canvas->getMouseLockedControl() ); + } + + // Lock. + mouseLock(); + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + // Selection? + if ( pEvent.modifier & SI_SHIFT ) + { + if ( !mSelection.Active ) + { + // Selection Active. + mSelection.Active = true; + mSelection.StartTime = mController->getTime(); + mSelection.EndTime = time; + } + else + { + // Update Selection. + mSelection.EndTime = time; + } + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + + // Set First Responder. + setFirstResponder(); + + if ( pEvent.modifier & SI_CTRL ) + { + // Set Time, No Reset. + mController->setTime( time ); + } + else + { + // Reset. + mController->reset( time ); + } +} + +void VTimeLineControl::onMouseUp( const GuiEvent &pEvent ) +{ + if ( isMouseLocked() ) + { + // Unlock. + mouseUnlock(); + } + + if ( mIsController && mController && !mController->isPlaying() ) + { + // Stop without Reset. + mController->stop( false ); + } +} + +void VTimeLineControl::onMouseDragged( const GuiEvent &pEvent ) +{ + Parent::onMouseDragged( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + if ( pEvent.modifier & SI_SHIFT ) + { + if ( mSelection.Active ) + { + // Update Selection. + mSelection.EndTime = time; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + + if ( pEvent.modifier & SI_CTRL ) + { + // Set Time, No Reset. + mController->setTime( time ); + } + else if ( !mSelection.Active ) + { + // Reset. + mController->reset( time ); + } +} + +void VTimeLineControl::onRightMouseDown( const GuiEvent &pEvent ) +{ + Parent::onRightMouseDown( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + // Set First Responder. + setFirstResponder(); + + if ( mSelection.Active ) + { + const S32 minTime = getMin( mSelection.StartTime, mSelection.EndTime ); + const S32 maxTime = getMax( mSelection.StartTime, mSelection.EndTime ); + if ( time >= minTime && time <= maxTime ) + { + // Callback. + onMouseEvent( "onSelectionRightClick", pEvent ); + + // Don't Update Time. + return; + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + } + + // Reset. + mController->reset( time ); +} + +void VTimeLineControl::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VTimeLineControl::onPreRender( void ) +{ + setUpdate(); +} + +void VTimeLineControl::onRender( Point2I offset, const RectI &updateRect ) +{ + if ( !mController ) + { + // Default Render. + Parent::onRender( offset, updateRect ); + + // Quit. + return; + } + + // Render Properties. + const S32 tickOffset = toPoint( 0 ); + const S32 timeLineWidth = toPoint( mController->getDuration() ) - tickOffset; + const F32 tickStep = 0.5f; + const S32 tickInterval = ( mIsController ) ? getWidth() : timeLineWidth; + const S32 tickIntervalCount = ( S32 )mFloor( tickInterval / ( gUnitsPerSec * tickStep ) ) + 1; + + // Tick Render Proeprties. + const Point2I tickExtent( 0, getHeight() - 1 ); + + // Text Render Properties. + const Point2I textExtent( gUnitsPerSec, mProfile->mFontSize ); + const Point2I textOffset( 4, -mProfile->mFontSize ); + + // Render Border. + GFX->getDrawUtil()->drawRectFill( RectI( offset + Point2I( tickOffset + 1, 1 ), Point2I( timeLineWidth - 1, getHeight() - 1 ) ), mProfile->mFillColorHL ); + + // Font Color. + GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor ); + + for ( S32 i = 0; i < tickIntervalCount; i++ ) + { + // Tick Position. + const Point2I tickPosition = offset + Point2I( tickOffset + i * ( gUnitsPerSec * tickStep ), 0 ); + + // Line Color. + const ColorI lineColor = ( ( i % 2 ) ) ? mProfile->mBorderColorHL : mProfile->mBorderColor; + + // Draw Line. + GFX->getDrawUtil()->drawLine( tickPosition, tickPosition + tickExtent, lineColor ); + + if ( mIsController ) + { + // Render Times. + renderJustifiedText( tickPosition + tickExtent + textOffset, textExtent, avar( "%.2f", ( F32 )( i * tickStep ) ) ); + } + } + + // Render Children + renderChildControls( offset, updateRect ); + + if ( mSelection.Active ) + { + // Selection Width. + const S32 selectionWidth = mCeil( mAbs( toPoint( mSelection.EndTime ) - toPoint( mSelection.StartTime ) ) ); + + // Selection Position. + const S32 selectionPositionX = toPoint( getMin( mSelection.StartTime, mSelection.EndTime ) ); + + // Selection Properties. + const Point2I selectionExtent( selectionWidth, getHeight() ); + const Point2I selectionPosition = offset + Point2I( selectionPositionX, 0 ); + + // Render Time Cue. + GFX->getDrawUtil()->drawRectFill( RectI( selectionPosition, selectionExtent ), ColorF( 0.f, 0.f, 0.f, 0.5f ) ); + + if ( mIsController ) + { + // Buffer. + char buffer[2][128]; + dSprintf( buffer[0], 128, "%.2f", ( F32 )( mSelection.StartTime / 1000.f ) ); + dSprintf( buffer[1], 128, "%.2f", ( F32 )( mSelection.EndTime / 1000.f ) ); + + if ( mSelection.StartTime < mSelection.EndTime ) + { + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer[0] ); + + // Text Position. + const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 ); + const Point2I endText = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( startText, textExtent, buffer[0] ); + renderJustifiedText( endText, textExtent, buffer[1] ); + } + else + { + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer[1] ); + + // Text Position. + const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 ); + const Point2I endText = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( startText, textExtent, buffer[1] ); + renderJustifiedText( endText, textExtent, buffer[0] ); + } + } + } + + if ( mController && !mSelection.Active ) + { + // Time Cue Properties. + const Point2I timeCueExtent( ( mIsController ) ? 4 : 2, getHeight() ); + const Point2I timeCuePosition = offset + Point2I( toPoint( mController->getTime() ) - ( timeCueExtent.x / 2 ), 0 ); + + // Render Time Cue. + GFX->getDrawUtil()->drawRectFill( RectI( timeCuePosition, timeCueExtent ), ColorF( 0.f, 0.f, 0.f, 0.5f ) ); + + if ( mIsController ) + { + // Buffer. + char buffer[128]; + dSprintf( buffer, 128, "%.2f", ( F32 )( mController->getTime() / 1000.f ) ); + + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer ); + + // Text Position. + const Point2I textPosition( getMin( getMax( timeCuePosition.x + 6, updateRect.point.x + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), timeCuePosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( textPosition, textExtent, buffer ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VTimeLineControl, toPoint, S32, 3, 3, "( pTime )" ) +{ + return object->toPoint( dAtoi( argv[2] ) ); +} + +S32 VTimeLineControl::toTime( const S32 &pPoint ) +{ + return ( ( S32 )( 1000.f * ( F32 )pPoint / gUnitsPerSec ) - mDurationOffset ); +} + +ConsoleMethod( VTimeLineControl, toTime, S32, 3, 3, "( pPoint )" ) +{ + return object->toTime( dAtoi( argv[2] ) ); +} + +S32 VTimeLineControl::toPoint( const S32 &pTime ) +{ + return ( S32 )( gUnitsPerSec * ( ( F32 )( pTime + mDurationOffset ) / 1000.f ) ); +} + +ConsoleMethod( VTimeLineControl, getSelection, const char *, 2, 2, "( )" ) +{ + const S32 minTime = getMin( object->mSelection.StartTime, object->mSelection.EndTime ); + const S32 maxTime = getMax( object->mSelection.StartTime, object->mSelection.EndTime ); + + // Fetch Return Buffer. + char *retBuffer = Con::getReturnBuffer( 256 ); + + // Write. + dSprintf( retBuffer, 256, "%d %d %d", object->mSelection.Active, minTime, maxTime - minTime ); + + // Return. + return retBuffer; +} + +ConsoleMethod( VTimeLineControl, setSelection, void, 3, 5, "( pActive, [pTime, pDuration] )" ) +{ + object->mSelection.Active = dAtob( argv[2] ); + if ( argc > 3 ) + { + object->mSelection.StartTime = dAtoi( argv[3] ); + object->mSelection.EndTime = object->mSelection.StartTime + dAtoi( argv[4] ); + } +} + +ConsoleMethod( VTimeLineControl, updateDuration, void, 2, 2, "( )" ) +{ + object->updateDuration(); +} + +void VTimeLineControl::updateDuration( void ) +{ + if ( !mController ) + { + // No Controller. + return; + } + + // Add 500ms. + const S32 length = toPoint( mController->getDuration() + 500 ); + + // Set Min Extent. + setMinExtent( Point2I( length, getHeight() ) ); + + if ( getWidth() < length ) + { + // Conform to Min Extent. + setExtent( length, getHeight() ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/GUI/VTimeLineControl.h b/Engine/modules/Verve/GUI/VTimeLineControl.h new file mode 100644 index 000000000..1dd1b9851 --- /dev/null +++ b/Engine/modules/Verve/GUI/VTimeLineControl.h @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// 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_VTIMELINECONTROL_H_ +#define _VT_VTIMELINECONTROL_H_ + +#ifndef _GUICONTROL_H_ +#include "gui/core/guiControl.h" +#endif + +#ifndef _VT_VCONTROLLER_H_ +#include "Verve/Core/VController.h" +#endif + +//----------------------------------------------------------------------------- + +class VTimeLineControl : public GuiControl +{ + typedef GuiControl Parent; + +public: + + struct sSelection + { + bool Active; + S32 StartTime; + S32 EndTime; + }; + + bool mIsController; + VController *mController; + + S32 mDurationOffset; + + sSelection mSelection; + +public: + + VTimeLineControl( void ); + + static void initPersistFields( void ); + + // Mouse. + + virtual void onMouseDown( const GuiEvent &pEvent ); + virtual void onMouseUp( const GuiEvent &pEvent ); + virtual void onMouseDragged( const GuiEvent &pEvent ); + + virtual void onRightMouseDown( const GuiEvent &pEvent ); + + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + // Rendering. + + void onPreRender( void ); + void onRender( Point2I offset, const RectI &updateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VTimeLineControl ); + +public: + + S32 toTime( const S32 &pPoint ); + S32 toPoint( const S32 &pTime ); + + void updateDuration( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTIMELINECONTROL_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TAnimation.h b/Engine/modules/Verve/Torque/TAnimation.h new file mode 100644 index 000000000..4c5307bec --- /dev/null +++ b/Engine/modules/Verve/Torque/TAnimation.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_ANIMATION_H_ +#define _VT_TORQUE_ANIMATION_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + bool isAnimationLooping( SceneObjectType *pObject, const char *pData ); + + String getAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + F32 getAnimationDuration( SceneObjectType *pObject, const char *pData ); + void setAnimationPosition( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pPosition ); + void setAnimationTimeScale( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pTimeScale ); + + void playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex, const char *pData ); + void playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + void stopAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + void pauseAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); +}; + +#endif // _VT_TORQUE_ANIMATION_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TCamera.h b/Engine/modules/Verve/Torque/TCamera.h new file mode 100644 index 000000000..329bf093b --- /dev/null +++ b/Engine/modules/Verve/Torque/TCamera.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_CAMERA_H_ +#define _VT_TORQUE_CAMERA_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +#ifndef _CAMERAFXMGR_H_ +#include "T3D/fx/cameraFXMgr.h" +#endif + +namespace VTorque +{ + bool isCamera( SceneObjectType *pObject ); + void setCamera( SceneObjectType *pObject ); + + void startCameraShake( const F32 &pDuration, const F32 &pFalloff, const VectorF &pAmplitude, const VectorF &pFrequency ); + void stopCameraShake( void ); +}; + +#endif // _VT_TORQUE_CAMERA_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TLightObject.h b/Engine/modules/Verve/Torque/TLightObject.h new file mode 100644 index 000000000..0b44cd607 --- /dev/null +++ b/Engine/modules/Verve/Torque/TLightObject.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_LIGHTOBJECT_H_ +#define _VT_TORQUE_LIGHTOBJECT_H_ + +#ifndef _LIGHTBASE_H_ +#include "T3D/lightBase.h" +#endif + +#ifndef _LIGHTANIMDATA_H_ +#include "T3D/lightAnimData.h" +#endif + +namespace VTorque +{ + + typedef LightBase LightObjectType; + typedef LightAnimData LightAnimationDataType; + + bool isLightObjectEnabled( LightObjectType *pLightObject ); + void setLightObjectOn( LightObjectType *pLightObject, const bool &pStatus ); + + void playAnimation( LightObjectType *pLightObject, LightAnimationDataType *pLightAnimationData ); + void playAnimation( LightObjectType *pLightObject ); + void pauseAnimation( LightObjectType *pLightObject ); +}; + +#endif // _VT_TORQUE_LIGHTOBJECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TMotion.h b/Engine/modules/Verve/Torque/TMotion.h new file mode 100644 index 000000000..d77118945 --- /dev/null +++ b/Engine/modules/Verve/Torque/TMotion.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_MOTION_H_ +#define _VT_TORQUE_MOTION_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +#ifndef _VT_VPATH_H_ +#include "Verve/VPath/VPath.h" +#endif + +namespace VTorque +{ + typedef VPath PathObjectType; + + bool isMovable( SimObject *pObject ); + bool isPath( SimObject *pObject ); + bool isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject ); + + F32 getPathNodeLength( PathObjectType *pPath, const S32 &pNode ); + + void attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ); + void detachPathObject( PathObjectType *pPath, SceneObjectType *pObject ); + + void setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive ); + void setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp ); + void setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset ); + void setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed ); + void setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData = String::EmptyString ); + void setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward ); + void setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ); + void setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ); +}; + +#endif // _VT_TORQUE_MOTION_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TParticleEffect.h b/Engine/modules/Verve/Torque/TParticleEffect.h new file mode 100644 index 000000000..c1350af0e --- /dev/null +++ b/Engine/modules/Verve/Torque/TParticleEffect.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_PARTICLEEFFECT_H_ +#define _VT_TORQUE_PARTICLEEFFECT_H_ + +#ifndef _H_PARTICLE_EMITTER +#include "T3D/fx/particleEmitter.h" +#endif + +#ifndef _PARTICLEEMITTERDUMMY_H_ +#include "T3D/fx/particleEmitterNode.h" +#endif + +namespace VTorque +{ + + typedef ParticleEmitterNode ParticleEffectType; + + bool isParticleEffectEnabled( ParticleEffectType *pParticleEffect ); + void setParticleEffectOn( ParticleEffectType *pParticleEffect, const bool &pStatus ); +}; + +#endif // _VT_TORQUE_PARTICLEEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TPostEffect.h b/Engine/modules/Verve/Torque/TPostEffect.h new file mode 100644 index 000000000..58edcf43e --- /dev/null +++ b/Engine/modules/Verve/Torque/TPostEffect.h @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_POSTEFFECT_H_ +#define _VT_TORQUE_POSTEFFECT_H_ + +#ifndef _POST_EFFECT_H_ +#include "postFx/postEffect.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef PostEffect PostEffectType; + + bool isPostEffectEnabled( PostEffectType *pPostEffect ); + void setPostEffectOn( PostEffectType *pPostEffect, const bool &pStatus ); +}; + +#endif // _VT_TORQUE_POSTEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TSceneObject.h b/Engine/modules/Verve/Torque/TSceneObject.h new file mode 100644 index 000000000..8f487b3b0 --- /dev/null +++ b/Engine/modules/Verve/Torque/TSceneObject.h @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SCENEOBJECT_H_ +#define _VT_TORQUE_SCENEOBJECT_H_ + +#ifndef _SCENEOBJECT_H_ +#include "scene/sceneObject.h" +#endif + +namespace VTorque +{ + typedef SceneObject SceneObjectType; +}; + +#endif // _VT_TORQUE_SCENEOBJECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TSoundEffect.h b/Engine/modules/Verve/Torque/TSoundEffect.h new file mode 100644 index 000000000..3c3aa9fbc --- /dev/null +++ b/Engine/modules/Verve/Torque/TSoundEffect.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SOUNDEFFECT_H_ +#define _VT_TORQUE_SOUNDEFFECT_H_ + +#ifndef _SFXPROFILE_H_ +#include "sfx/sfxProfile.h" +#endif + +#ifndef _SFXSOUND_H_ +#include "sfx/sfxSound.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef SFXProfile SoundEffectType; + typedef SFXSound SoundSourceType; + + bool isSoundLooping( SoundEffectType *pSoundProfile ); + S32 getSoundDuration( SoundEffectType *pSoundProfile ); + + SoundSourceType *playSound( SoundEffectType *pSoundProfile, const U32 &pPosition, const F32 &pPitch ); + SoundSourceType *playSound( SoundEffectType *pSoundProfile, SceneObjectType *pObject, const U32 &pPosition, const F32 &pPitch ); + + void playSound( SoundSourceType *pSource ); + void pauseSound( SoundSourceType *pSource ); + void stopSound( SoundSourceType *pSource ); + + void setSoundPosition( SoundSourceType *pSource, const U32 &pPosition ); + void setSoundPitch( SoundSourceType *pSource, const F32 &pPitch ); +}; + +#endif // _VT_TORQUE_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque/TSpawnSphere.h b/Engine/modules/Verve/Torque/TSpawnSphere.h new file mode 100644 index 000000000..e9899d87d --- /dev/null +++ b/Engine/modules/Verve/Torque/TSpawnSphere.h @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SPAWNSPHERE_H_ +#define _VT_TORQUE_SPAWNSPHERE_H_ + +#ifndef _MISSIONMARKER_H_ +#include "T3D/missionMarker.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef SpawnSphere SpawnSphereType; +}; + +#endif // _VT_TORQUE_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VAnimation.cpp b/Engine/modules/Verve/Torque3D/VAnimation.cpp new file mode 100644 index 000000000..38eaf983e --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VAnimation.cpp @@ -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. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TAnimation.h" + +#include "T3D/shapeBase.h" + +//----------------------------------------------------------------------------- +// +// Animation Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isAnimationLooping( SceneObjectType *pObject, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return false; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return false; + } + + // Return Cyclic. + return shape->getShape()->sequences[sequenceIndex].isCyclic(); +} + +String VTorque::getAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return ""; + } + + // Return Name. + return shape->getThreadSequenceName( pThreadIndex ); +} + +F32 VTorque::getAnimationDuration( SceneObjectType *pObject, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return 0.f; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return 0.f; + } + + // Return Duration. + return shape->getShape()->sequences[sequenceIndex].duration; +} + +void VTorque::setAnimationPosition( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pPosition ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Set Position. + shape->setThreadPosition( 0, pPosition ); +} + +void VTorque::setAnimationTimeScale( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pTimeScale ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Set TimeScale. + shape->setThreadTimeScale( pThreadIndex, pTimeScale ); +} + +void VTorque::playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return; + } + + // Play Sequence. + shape->setThreadSequence( pThreadIndex, sequenceIndex ); +} + +void VTorque::playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Play Sequence. + shape->playThread( pThreadIndex ); +} + +void VTorque::stopAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Pause Thread. + shape->stopThread( pThreadIndex ); +} + +void VTorque::pauseAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Pause Thread. + shape->pauseThread( pThreadIndex ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VCamera.cpp b/Engine/modules/Verve/Torque3D/VCamera.cpp new file mode 100644 index 000000000..4e01e5516 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VCamera.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque/TCamera.h" +#include "Verve/Torque3D/VCameraShake.h" + +#include "T3D/gameBase/gameConnection.h" + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isCamera( SceneObjectType *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +void VTorque::setCamera( SceneObjectType *pObject ) +{ + // Fetch Game Base. + GameBase *object = dynamic_cast( pObject ); + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + GameConnection *connection = dynamic_cast( *itr ); + if ( connection ) + { + // Set Camera Object. + connection->setCameraObject( object ); + } + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VCameraShake.cpp b/Engine/modules/Verve/Torque3D/VCameraShake.cpp new file mode 100644 index 000000000..774715340 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VCameraShake.cpp @@ -0,0 +1,245 @@ +//----------------------------------------------------------------------------- +// 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/Torque3D/VCameraShake.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VCameraShakeNetEvent ); +//----------------------------------------------------------------------------- + +// ShakeCamera( 1, 10, "1 0 0", "1 0 0" ); +ConsoleFunction( ShakeCamera, void, 5, 5, "( pDuration, pFalloff, pAmplitude, pFrequency )" ) +{ + // Duration. + const F32 duration = dAtof( argv[1] ); + + // Falloff. + const F32 falloff = dAtof( argv[2] ); + + // Amplitude. + VectorF amplitude; + dSscanf( argv[3], "%g %g %g", &litude.x, &litude.y, &litude.z ); + + // Frequency. + VectorF frequency; + dSscanf( argv[4], "%g %g %g", &frequency.x, &frequency.y, &frequency.z ); + + // Shake Camera. + VTorque::startCameraShake( duration, falloff, amplitude, frequency ); +} + +void VTorque::startCameraShake( const F32 &pDuration, const F32 &pFalloff, const VectorF &pAmplitude, const VectorF &pFrequency ) +{ +#ifdef VT_EDITOR + + // Create FX Event + CameraShake *camShake = new CameraShake(); + + // Set Duration. + camShake->setDuration( pDuration ); + + // Set Falloff. + camShake->setFalloff( pFalloff ); + + // Set Amplitude. + VectorF amp = pAmplitude; + camShake->setAmplitude( amp ); + + // Set Frequency. + VectorF freq = pFrequency; + camShake->setFrequency( freq ); + + // Initialise. + camShake->init(); + + // Add to Manager. + gCamFXMgr.addFX( camShake ); + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VCameraShakeNetEvent *event = new VCameraShakeNetEvent(); + + // Setup Event. + event->mEventType |= ( VCameraShakeNetEvent::k_TypeClear | VCameraShakeNetEvent::k_TypeMake ); + event->mDuration = pDuration; + event->mFalloff = pFalloff; + event->mAmplitude = pAmplitude; + event->mFrequency = pFrequency; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +void VTorque::stopCameraShake( void ) +{ +#ifdef VT_EDITOR + + // Clear Manager. + gCamFXMgr.clear(); + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VCameraShakeNetEvent *event = new VCameraShakeNetEvent(); + + // Setup Event. + event->mEventType |= VCameraShakeNetEvent::k_TypeClear; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +//----------------------------------------------------------------------------- + +VCameraShakeNetEvent::VCameraShakeNetEvent( void ) : mEventType( 0 ), + mDuration( 0.f ), + mFalloff( 10.f ), + mAmplitude( Point3F::Zero ), + mFrequency( Point3F::Zero ) +{ + // Void. +} + +void VCameraShakeNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VCameraShakeNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Clear Manager? + pStream->write( mEventType & k_TypeClear ); + + // Make Event? + if ( pStream->write( mEventType & k_TypeMake ) ) + { + // Duration. + pStream->write( mDuration ); + + // Falloff. + pStream->write( mFalloff ); + + // Amplitude. + pStream->write( mAmplitude.x ); + pStream->write( mAmplitude.y ); + pStream->write( mAmplitude.z ); + + // Frequency. + pStream->write( mFrequency.x ); + pStream->write( mFrequency.y ); + pStream->write( mFrequency.z ); + } +} + +void VCameraShakeNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Clear Manager? + if ( pStream->readFlag() ) + { + // Update State. + mEventType |= k_TypeClear; + } + + // Make Event? + if ( pStream->readFlag() ) + { + // Update State. + mEventType |= k_TypeMake; + + // Duration. + pStream->read( &mDuration ); + + // Falloff. + pStream->read( &mFalloff ); + + // Amplitude. + pStream->read( &mAmplitude.x ); + pStream->read( &mAmplitude.y ); + pStream->read( &mAmplitude.z ); + + // Frequency. + pStream->read( &mFrequency.x ); + pStream->read( &mFrequency.y ); + pStream->read( &mFrequency.z ); + } +} + +void VCameraShakeNetEvent::process( NetConnection *pConnection ) +{ + if ( mEventType & k_TypeClear ) + { + // Clear Manager. + gCamFXMgr.clear(); + } + + if ( mEventType & k_TypeMake ) + { + // Create FX Event + CameraShake *camShake = new CameraShake(); + + // Set Duration. + camShake->setDuration( mDuration ); + + // Set Falloff. + camShake->setFalloff( mFalloff ); + + // Set Amplitude. + camShake->setAmplitude( mAmplitude ); + + // Set Frequency. + camShake->setFrequency( mFrequency ); + + // Initialise. + camShake->init(); + + // Add to Manager. + gCamFXMgr.addFX( camShake ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VCameraShake.h b/Engine/modules/Verve/Torque3D/VCameraShake.h new file mode 100644 index 000000000..2e40359d1 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VCameraShake.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_CAMERASHAKE_H_ +#define _VT_VTORQUE3D_CAMERASHAKE_H_ + +#ifndef _VT_TORQUE_CAMERA_H_ +#include "Verve/Torque/TCamera.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VCameraShakeNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + enum eEventType + { + k_TypeClear = BIT( 0 ), + k_TypeMake = BIT( 1 ), + }; + + U32 mEventType; + + F32 mDuration; + F32 mFalloff; + VectorF mAmplitude; + VectorF mFrequency; + +public: + + VCameraShakeNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VCameraShakeNetEvent ); +}; + +#endif // _VT_VTORQUE3D_CAMERASHAKE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VLightObject.cpp b/Engine/modules/Verve/Torque3D/VLightObject.cpp new file mode 100644 index 000000000..dcf1d016e --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VLightObject.cpp @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TLightObject.h" + +//----------------------------------------------------------------------------- +// +// Light Object Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isLightObjectEnabled( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return false; + } + + // Get Enabled. + return pLightObject->getLightEnabled(); +} + +void VTorque::setLightObjectOn( LightObjectType *pLightObject, const bool &pStatus ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Set Enabled. + pLightObject->setLightEnabled( pStatus ); +} + +void VTorque::playAnimation( LightObjectType *pLightObject, LightAnimationDataType *pLightAnimationData ) +{ + if ( !pLightObject || !pLightAnimationData ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->playAnimation( pLightAnimationData ); +} + +void VTorque::playAnimation( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->playAnimation(); +} + +void VTorque::pauseAnimation( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->pauseAnimation(); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VMotion.cpp b/Engine/modules/Verve/Torque3D/VMotion.cpp new file mode 100644 index 000000000..54bff56e5 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VMotion.cpp @@ -0,0 +1,458 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TMotion.h" +#include "Verve/VPath/VPath.h" + +//----------------------------------------------------------------------------- + +// Sync the local connection when editing path objects? +// Note: This was originally done so that editing was very smooth, but it turns +// out that any lag was due to errors in the pathing operations +// themselves. If issues persist, then uncomment this definition and you +// might see a marked improvement in performance while editing in Verve. +//#define VT_SYNC_LOCALCLIENT + +//----------------------------------------------------------------------------- +// +// Utility Methods. +// +//----------------------------------------------------------------------------- + +NetObject *getClientObject( NetObject *pObject ) +{ + if ( !pObject ) + { + return NULL; + } + + NetConnection *toServer = NetConnection::getConnectionToServer(); + NetConnection *toClient = NetConnection::getLocalClientConnection(); + if ( !toServer || !toClient ) + { + return NULL; + } + + const S32 ghostIndex = toClient->getGhostIndex( pObject ); + if ( ghostIndex == -1 ) + { + return NULL; + } + + return toServer->resolveGhost( ghostIndex ); +} + +void _attachPathObject( VPath *pPath, SceneObject *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) +{ + if ( pOrientation == String::EmptyString ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex ); + // Quit. + return; + } + + // Fetch Orientation. + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, NULL ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Object. + SceneObject *lookAtObject = dynamic_cast( Sim::findObject( pOrientationData ) ); + // Valid Object? + if ( lookAtObject != NULL ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtObject ); + } + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + if ( dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ) == 3 ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtPoint ); + } + + } break; + } +} + +//----------------------------------------------------------------------------- +// +// Path Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isMovable( SimObject *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +bool VTorque::isPath( SimObject *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +bool VTorque::isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return false; + } + + // Return. + return pPath->isObjectAttached( pObject ); +} + +F32 VTorque::getPathNodeLength( PathObjectType *pPath, const S32 &pNode ) +{ + if ( !pPath ) + { + // Sanity! + return false; + } + + // Normalize Node Index. + S32 nodeIndex = pNode; + pPath->normalizeNodeIndex( nodeIndex ); + + // Fetch Node. + VPathNode *node = pPath->getNode( nodeIndex ); + + // Return Length. + return node->getLength(); +} + +void VTorque::attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Attach Object. + _attachPathObject( pPath, pObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Attach Object. + _attachPathObject( clientPath, clientObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); + } + +#endif +} + +void VTorque::detachPathObject( PathObjectType *pPath, SceneObjectType *pObject ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Detach Object. + pPath->detachObject( pObject ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Detach Object. + clientPath->detachObject( clientObject ); + } + +#endif +} + +void VTorque::setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object State. + pPath->setPathObjectActive( pObject, pActive ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object State. + clientPath->setPathObjectActive( clientObject, pActive ); + } + +#endif +} + +void VTorque::setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Interp. + pPath->setPathObjectInterp( pObject, pInterp ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectInterp( clientObject, pInterp ); + } + +#endif +} + +void VTorque::setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Offset. + pPath->setPathObjectOffset( pObject, pOffset ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectOffset( clientObject, pOffset ); + } + +#endif +} + +void VTorque::setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Speed. + pPath->setPathObjectSpeed( pObject, pSpeed ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectSpeed( clientObject, pSpeed ); + } + +#endif +} + +void VTorque::setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Set the orientation mode. + // Note: Call the console method so we don't have to handle all the different modes here. + Con::executef( pPath, "setPathObjectOrientationMode", pObject->getIdString(), pOrientation, pOrientationData ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // TODO: Handle synching the client path immediately. + +#endif + + /* + // Set the Default Mode. + if ( pOrientation == String::EmptyString ) + { + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, VPathObject::k_OrientationToPath ); + return; + } + + // Fetch Orientation. + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + + // Fetch Object. + SceneObjectType *lookAtObject; + if ( !Sim::findObject( pOrientationData, lookAtObject ) ) + { + // Invalid Object. + return; + } + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type, lookAtObject ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type, lookAtPoint ); + + } break; + } + */ +} + +void VTorque::setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Forward. + pPath->setPathObjectForward( pObject, pForward ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectForward( clientObject, pForward ); + } + +#endif +} + +void VTorque::setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object Current Node. + pPath->setPathObjectNode( pObject, pNode ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object Current Node. + clientPath->setPathObjectNode( clientObject, pNode ); + } + +#endif +} + +void VTorque::setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object End Node. + pPath->setPathObjectEndNode( pObject, pNode ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object End Node. + clientPath->setPathObjectEndNode( clientObject, pNode ); + } + +#endif +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VParticleEffect.cpp b/Engine/modules/Verve/Torque3D/VParticleEffect.cpp new file mode 100644 index 000000000..b1e35b5a1 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VParticleEffect.cpp @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TParticleEffect.h" + +//----------------------------------------------------------------------------- +// +// Particle Effect Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isParticleEffectEnabled( ParticleEffectType *pParticleEffect ) +{ + if ( !pParticleEffect ) + { + // Sanity! + return false; + } + + // Get Active. + return pParticleEffect->getActive(); +} + +void VTorque::setParticleEffectOn( ParticleEffectType *pParticleEffect, const bool &pStatus ) +{ + if ( !pParticleEffect ) + { + // Sanity! + return; + } + + // Set Active. + pParticleEffect->setActive( pStatus ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VPostEffect.cpp b/Engine/modules/Verve/Torque3D/VPostEffect.cpp new file mode 100644 index 000000000..e9f245790 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VPostEffect.cpp @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque3D/VPostEffect.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +// +// Post Effect Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isPostEffectEnabled( PostEffectType *pPostEffect ) +{ + if ( !pPostEffect ) + { + // Sanity! + return false; + } + + return pPostEffect->isEnabled(); +} + +void VTorque::setPostEffectOn( PostEffectType *pPostEffect, const bool &pStatus ) +{ + if ( !pPostEffect ) + { + // Sanity! + return; + } + +#ifdef VT_EDITOR + + if ( pStatus ) + { + // Enable Effect. + pPostEffect->enable(); + } + else + { + // Disable Effect. + pPostEffect->disable(); + } + +#else + + // Fetch Name. + StringTableEntry name = pPostEffect->getName(); + if ( !name || name == StringTable->insert( "" ) ) + { + Con::warnf( "VTorque::setPostEffectOn() - Invalid Object Name." ); + return; + } + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VPostEffectNetEvent *event = new VPostEffectNetEvent(); + + // Setup Event. + event->mPostEffect = name; + event->mEnabled = pStatus; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VPostEffectNetEvent ); +//----------------------------------------------------------------------------- + +VPostEffectNetEvent::VPostEffectNetEvent( void ) : mPostEffect( StringTable->insert( "" ) ), + mEnabled( false ) +{ + // Void. +} + +void VPostEffectNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VPostEffectNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Object Name. + pStream->writeString( mPostEffect ); + + // Status. + pStream->writeFlag( mEnabled ); +} + +void VPostEffectNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Object Name. + mPostEffect = pStream->readSTString(); + + // Status. + mEnabled = pStream->readFlag(); +} + +void VPostEffectNetEvent::process( NetConnection *pConnection ) +{ + PostEffect *postEffect; + if ( !Sim::findObject( mPostEffect, postEffect ) ) + { + Con::warnf( "VPostEffectNetEvent::process() - Unable to find PostEffect Object '%s'", mPostEffect ); + return; + } + + if ( mEnabled ) + { + // Enable Effect. + postEffect->enable(); + } + else + { + // Disable Effect. + postEffect->disable(); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VPostEffect.h b/Engine/modules/Verve/Torque3D/VPostEffect.h new file mode 100644 index 000000000..bbb64aecc --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VPostEffect.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_POSTEFFECT_H_ +#define _VT_VTORQUE3D_POSTEFFECT_H_ + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VPostEffectNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + StringTableEntry mPostEffect; + bool mEnabled; + +public: + + VPostEffectNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VPostEffectNetEvent ); +}; + +#endif // _VT_VTORQUE3D_POSTEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VSoundEffect.cpp b/Engine/modules/Verve/Torque3D/VSoundEffect.cpp new file mode 100644 index 000000000..8dda926c3 --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VSoundEffect.cpp @@ -0,0 +1,354 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque3D/VSoundEffect.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" +#include "math/mathIO.h" +#include "sfx/sfxSystem.h" +#include "sfx/sfxDescription.h" + +//----------------------------------------------------------------------------- +// +// Sound Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isSoundLooping( SoundEffectType *pSoundProfile ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return false; + } + + // Return Looping. + return pSoundProfile->getDescription()->mIsLooping; +} + +S32 VTorque::getSoundDuration( SoundEffectType *pSoundProfile ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return 0; + } + + // Return Duration. + return pSoundProfile->getSoundDuration(); +} + +VTorque::SoundSourceType *VTorque::playSound( SoundEffectType *pSoundProfile, const U32 &pPosition, const F32 &pPitch ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return NULL; + } + +#ifdef VT_EDITOR + + // Play Sound. + SFXSound *source = ( SFXSound* )SFX->playOnce( pSoundProfile ); + + if ( source ) + { + // Set Position. + source->setPosition( pPosition ); + + // Set Pitch. + source->setPitch( pPitch ); + } + + // Return Source. + return source; + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VSoundEffectNetEvent *event = new VSoundEffectNetEvent(); + + // Setup Event. + event->mProfile = pSoundProfile; + event->mPosition = pPosition; + event->mPitch = pPitch; + event->mIs3D = false; + + // Post Event. + connection->postNetEvent( event ); + } + } + + return NULL; + +#endif +} + +VTorque::SoundSourceType *VTorque::playSound( SoundEffectType *pSoundProfile, SceneObjectType *pObject, const U32 &pPosition, const F32 &pPitch ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return NULL; + } + +#ifdef VT_EDITOR + + // Fetch Reference Transform. + const MatrixF &transform = pObject->getTransform(); + + // Play Sound. + SFXSound *source = ( SFXSound* )SFX->playOnce( pSoundProfile, &transform ); + + if ( source ) + { + // Set Position. + source->setPosition( pPosition ); + + // Set Pitch. + source->setPitch( pPitch ); + } + + // Return Source. + return source; + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VSoundEffectNetEvent *event = new VSoundEffectNetEvent(); + + // Setup Event. + event->mProfile = pSoundProfile; + event->mPosition = pPosition; + event->mPitch = pPitch; + event->mIs3D = true; + event->mTransform = pObject->getTransform(); + + // Post Event. + connection->postNetEvent( event ); + } + } + + return NULL; + +#endif +} + +void VTorque::playSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Play. + pSource->play(); +} + +void VTorque::pauseSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Pause. + pSource->pause(); +} + +void VTorque::stopSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Stop. + pSource->stop(); +} + +void VTorque::setSoundPosition( SoundSourceType *pSource, const U32 &pPosition ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Set Position. + pSource->setPosition( pPosition ); +} + +void VTorque::setSoundPitch( SoundSourceType *pSource, const F32 &pPitch ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Set Pitch. + pSource->setPitch( pPitch ); +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VSoundEffectNetEvent ); +//----------------------------------------------------------------------------- + +VSoundEffectNetEvent::VSoundEffectNetEvent( void ) : mProfile( NULL ), + mPosition( 0.f ), + mPitch( 1.f ), + mIs3D( false ), + mTransform( MatrixF::Identity ) +{ + // Void. +} + +void VSoundEffectNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VSoundEffectNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid? + if ( !pStream->writeFlag( mProfile != NULL ) ) + { + return; + } + + // Profile. + pStream->writeInt( mProfile->getId() - DataBlockObjectIdFirst, DataBlockObjectIdBitSize ); + + // Position. + pStream->write( mPosition ); + + // Pitch. + pStream->write( mPitch ); + + // 3D? + if ( pStream->writeFlag( mIs3D ) ) + { + // Rotation. + SFXDescription* description = mProfile->getDescription(); + if ( pStream->writeFlag( description->mConeInsideAngle || description->mConeOutsideAngle ) ) + { + // Entire Transform. + pStream->writeAffineTransform( mTransform ); + } + else + { + // Position. + mathWrite( *pStream, mTransform.getColumn3F( 3 ) ); + } + } +} + +void VSoundEffectNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid? + if ( !pStream->readFlag() ) + { + return; + } + + // Profile. + Sim::findObject( pStream->readInt( DataBlockObjectIdBitSize ) + DataBlockObjectIdFirst, mProfile ); + + // Position. + pStream->read( &mPosition ); + + // Pitch. + pStream->read( &mPitch ); + + // 3D? + if ( pStream->readFlag() ) + { + // Yup! + mIs3D = true; + + // Rotation? + if ( pStream->readFlag() ) + { + // Transform. + pStream->readAffineTransform( &mTransform ); + } + else + { + // Position. + Point3F pos; + mathRead( *pStream, &pos ); + mTransform.setColumn( 3, pos ); + } + } +} + +void VSoundEffectNetEvent::process( NetConnection *pConnection ) +{ + // Valid? + if ( !mProfile ) + { + return; + } + + SFXSound *source = NULL; + if ( mIs3D ) + { + // Play 3D Sound. + source = ( SFXSound* )SFX->playOnce( mProfile, &mTransform ); + } + else + { + // Play 2D Sound. + source = ( SFXSound* )SFX->playOnce( mProfile ); + } + + if ( source ) + { + // Set Position. + source->setPosition( mPosition ); + + // Set Pitch. + source->setPitch( mPitch ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VSoundEffect.h b/Engine/modules/Verve/Torque3D/VSoundEffect.h new file mode 100644 index 000000000..812f8f89c --- /dev/null +++ b/Engine/modules/Verve/Torque3D/VSoundEffect.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_SOUNDEFFECT_H_ +#define _VT_VTORQUE3D_SOUNDEFFECT_H_ + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VSoundEffectNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + SFXProfile *mProfile; + + F32 mPosition; + F32 mPitch; + + bool mIs3D; + MatrixF mTransform; + +public: + + VSoundEffectNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VSoundEffectNetEvent ); +}; + +#endif // _VT_VTORQUE3D_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/Torque3D/VSpawnSphere.cpp b/Engine/modules/Verve/Torque3D/VSpawnSphere.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.cpp new file mode 100644 index 000000000..240c4d0b0 --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.cpp @@ -0,0 +1,259 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActor.h" + +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VHumanoidActor ); +//----------------------------------------------------------------------------- + +VHumanoidActor::VHumanoidActor( void ) +{ + // Void. +} + +VHumanoidActor::~VHumanoidActor( void ) +{ + // Void. +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::onNewDataBlock( pDataBlock ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::onNewDataBlock( GameBaseData *pDataBlock, bool pReload ) +{ + // Store DataBlock Reference. + mDataBlock = dynamic_cast( pDataBlock ); + + // Valid Data? + if ( !mDataBlock || !Parent::onNewDataBlock( pDataBlock, pReload ) ) + { + // Invalid Data. + return false; + } + + // Initialise the Controllers. + if ( !initAnimationController() || !initPhysicsController() ) + { + // Invalid. + return false; + } + + // Initialise the Base Animation Thread. + mAnimationController.initBaseAnimation( VHumanoidActorData::k_IdleAnimation, 0.f, 1.f ); + // Initialise the Arm Animation Thread. + mAnimationController.initArmAnimation( VHumanoidActorData::k_ArmsUpDownAnimation, 0.5f, 1.f ); + + /* + // Initialise Head Threads. + initAnimationSequence( VHumanoidActorData::k_HeadHorizontalAnimation, mHeadAnimation.HThread, 0.5f ); + initAnimationSequence( VHumanoidActorData::k_HeadVerticalAnimation, mHeadAnimation.VThread, 0.5f ); + */ + + // Valid Data. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::processTick( pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::processTick( const Move *pMove ) +{ + // Parent Call. + Parent::processTick( pMove ); + + // Update Physics. + mPhysicsController.update( TickSec, pMove ); + + // Update Container. + updateContainer(); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::interpolateTick( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::interpolateTick( F32 pDelta ) +{ + // Parent Call. + Parent::interpolateTick( pDelta ); + + // Update Physics. + mPhysicsController.interpolateTick( pDelta ); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::advanceTime( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::advanceTime( F32 pDelta ) +{ + // Parent Call. + Parent::advanceTime( pDelta ); + + // Valid Animation Controller? + if ( getAnimationController() ) + { + // Update Animations. + getAnimationController()->update( pDelta ); + } +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VHumanoidActor::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Parent Call. + U32 retMask = Parent::packUpdate( pConnection, pMask, pStream ); + + // Physics Controller? + if ( pStream->writeFlag( pMask & PhysicsMask ) ) + { + // Pack Physics. + retMask &= mPhysicsController.packUpdate( pConnection, pMask, pStream ); + } + + return retMask; +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Parent Call. + Parent::unpackUpdate( pConnection, pStream ); + + // Physics Controller? + if ( pStream->readFlag() ) + { + // Unpack Physics. + mPhysicsController.unpackUpdate( pConnection, pStream ); + } +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::initAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::initAnimationController( void ) +{ + // Reference Object. + mAnimationController.setObject( this ); + // Initialise. + return mAnimationController.initAnimationTable(); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::getAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +VActorAnimationController *VHumanoidActor::getAnimationController( void ) +{ + return &mAnimationController; +} + + + + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::initPhysicsController(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::initPhysicsController( void ) +{ + // Initialise. + return mPhysicsController.initPhysicsController( this ); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::getAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +VActorPhysicsController *VHumanoidActor::getPhysicsController( void ) +{ + return &mPhysicsController; +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.h new file mode 100644 index 000000000..65ecb22bf --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActor.h @@ -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_VHUMANOIDACTOR_H_ +#define _VT_VHUMANOIDACTOR_H_ + +#ifndef _VT_VACTOR_H_ +#include "../VActor.h" +#endif + +#ifndef _VT_VHUMANOIDACTORDATA_H_ +#include "VHumanoidActorData.h" +#endif + +#ifndef _VT_VHUMANOIDACTORANIMATIONCONTROLLER_H_ +#include "VHumanoidActorAnimationController.h" +#endif + +#ifndef _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ +#include "VHumanoidActorPhysicsController.h" +#endif + +//----------------------------------------------------------------------------- + +class VHumanoidActor : public VActor +{ + typedef VActor Parent; + +protected: + + VHumanoidActorAnimationController mAnimationController; + VHumanoidActorPhysicsController mPhysicsController; + +public: + + VHumanoidActor( void ); + ~VHumanoidActor( void ); + + // Initialisation Methods. + + bool onNewDataBlock( GameBaseData *pDataBlock, bool pReload ); + + // Update Methods. + + void processTick( const Move *pMove ); + void interpolateTick( F32 pDelta ); + void advanceTime( F32 pDelta ); + + U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); + + // Animation Methods. + + bool initAnimationController( void ); + VActorAnimationController *getAnimationController( void ); + + // Physics Methods. + + bool initPhysicsController( void ); + VActorPhysicsController *getPhysicsController( void ); + + DECLARE_CONOBJECT( VHumanoidActor ); +}; + +#endif // _VT_VHUMANOIDACTOR_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp new file mode 100644 index 000000000..e6a1e4521 --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorAnimationController.h" + +//----------------------------------------------------------------------------- + +VHumanoidActorAnimationController::VHumanoidActorAnimationController( void ) +{ + // Void. +} + +VHumanoidActorAnimationController::~VHumanoidActorAnimationController( void ) +{ + // Void. +} + +//----------------------------------------------------------------------------- + +bool VHumanoidActorAnimationController::initArmAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Initialise Animation Ref. + return initAnimation( mArmAnimation, pIndex, pPosition, pTimeScale ); +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods +// +//----------------------------------------------------------------------------- + +void VHumanoidActorAnimationController::update( const F32 &pDelta ) +{ + // Parent Call. + VActorAnimationController::update( pDelta ); + + // Update the Look Thread. + if ( mArmAnimation.Thread ) + { + // Set Position. + getShapeInstance()->setPos( mArmAnimation.Thread, 0.5f ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h new file mode 100644 index 000000000..adf77fc0d --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORANIMATIONCONTROLLER_H_ +#define _VT_VHUMANOIDACTORANIMATIONCONTROLLER_H_ + +#ifndef _VT_VACTORANIMATIONCONTROLLER_H_ +#include "../VActorAnimationController.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VHumanoidActorAnimationController : public VActorAnimationController +{ +public: + + /* + struct sHeadAnimation + { + S32 HSequence; + TSThread *HThread; + Range HRange; + + S32 VSequence; + TSThread *VThread; + Range VRange; + + S32 FaceSequence; + TSThread *FaceThread; + + sHeadAnimation( void ) : + HSequence( -1 ), + HThread( NULL ), + HRange( 0.f, 1.f ), + VSequence( -1 ), + VThread( NULL ), + VRange( 0.f, 1.f ) + { + // Void. + } + }; + */ + +protected: + + //sHeadAnimation mHeadAnimation; + + sAnimationRef mHeadHAnimation; + sAnimationRef mHeadVAnimation; + sAnimationRef mArmAnimation; + +public: + + VHumanoidActorAnimationController( void ); + virtual ~VHumanoidActorAnimationController( void ); + + // Initialisation Methods. + + bool initArmAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + // Animation Methods. + + void update( const F32 &pDelta ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.cpp new file mode 100644 index 000000000..46a9eb448 --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.cpp @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorData.h" +#include "VHumanoidAnimationStates.h" +#include "VHumanoidPhysicsStates.h" + +//----------------------------------------------------------------------------- +// Animation Table. +//----------------------------------------------------------------------------- + +static VActorData::sAnimationSequence animSequenceLookup[] = + { + // State Based Animations. + { VHumanoidActorData::k_IdleAnimation, "root", 0.0f, ActorAnimationStateInstance( HumanoidIdle ) }, + + { VHumanoidActorData::k_WalkForwardAnimation, "walk", 0.1f, ActorAnimationStateInstance( HumanoidWalkForward ) }, + { VHumanoidActorData::k_WalkBackwardAnimation, "walkback", 0.1f, ActorAnimationStateInstance( HumanoidWalkBackward ) }, + + { VHumanoidActorData::k_RunForwardAnimation, "run", 0.1f, ActorAnimationStateInstance( HumanoidRunForward ) }, + { VHumanoidActorData::k_RunBackwardAnimation, "runback", 0.1f, ActorAnimationStateInstance( HumanoidRunBackward ) }, + + { VHumanoidActorData::k_SwimIdleAnimation, "swimroot", 1.0f, ActorAnimationStateInstance( HumanoidSwimIdle ) }, + { VHumanoidActorData::k_SwimForwardAnimation, "swim", 1.0f, ActorAnimationStateInstance( HumanoidSwimForward ) }, + { VHumanoidActorData::k_SwimBackwardAnimation, "swimback", 1.0f, ActorAnimationStateInstance( HumanoidSwimBackward ) }, + + // Support Animations. + { VHumanoidActorData::k_HeadHorizontalAnimation, "headside" }, + { VHumanoidActorData::k_HeadVerticalAnimation, "head" }, + + { VHumanoidActorData::k_ArmsUpDownAnimation, "look" }, + }; + +//----------------------------------------------------------------------------- +// Physics Table. +//----------------------------------------------------------------------------- + +static VActorData::sPhysicsState physStateLookup[] = + { + { VHumanoidActorData::k_OnGroundPhysics, 0.f, ActorPhysicsStateInstance( HumanoidOnGround ) }, + { VHumanoidActorData::k_InAirPhysics, 0.f, ActorPhysicsStateInstance( HumanoidInAir ) }, + { VHumanoidActorData::k_InWaterPhysics, 0.f, ActorPhysicsStateInstance( HumanoidInWater ) }, + }; + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_DATABLOCK_V1( VHumanoidActorData ); +//----------------------------------------------------------------------------- + +VHumanoidActorData::VHumanoidActorData( void ) +{ + // Void. +}; + +bool VHumanoidActorData::preload( bool pServer, String &pErrorStr ) +{ + if ( !Parent::preload( pServer, pErrorStr ) ) + { + return false; + } + + // Initialise Animation List. + if ( !initAnimationSequenceList( sizeof( animSequenceLookup ) / sizeof( VActorData::sAnimationSequence ), &animSequenceLookup[0] ) ) + { + Con::errorf( "VHumanoidActorData::preload() - Failed to Initialise Actor Animations." ); + return false; + } + + // Initialise Physics State List. + if ( !initPhysicsStateList( sizeof( physStateLookup ) / sizeof( VActorData::sPhysicsState ), &physStateLookup[0] ) ) + { + Con::errorf( "VHumanoidActorData::preload() - Failed to Initialise Actor Physics States." ); + return false; + } + + // Valid Load. + return true; +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.h new file mode 100644 index 000000000..0a5aa4b8c --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorData.h @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORDATA_H_ +#define _VT_VHUMANOIDACTORDATA_H_ + +#ifndef _VT_VACTORDATA_H_ +#include "../VActorData.h" +#endif + +//----------------------------------------------------------------------------- + +struct VHumanoidActorData : public VActorData +{ +private: + + typedef VActorData Parent; + friend class VHumanoidActor; + +public: + + enum eAnimationList + { + k_IdleAnimation = Parent::k_NextAnimation + 0, + + k_WalkForwardAnimation = Parent::k_NextAnimation + 1, + k_WalkBackwardAnimation = Parent::k_NextAnimation + 2, + + k_RunForwardAnimation = Parent::k_NextAnimation + 3, + k_RunBackwardAnimation = Parent::k_NextAnimation + 4, + + k_SwimIdleAnimation = Parent::k_NextAnimation + 5, + k_SwimForwardAnimation = Parent::k_NextAnimation + 6, + k_SwimBackwardAnimation = Parent::k_NextAnimation + 7, + + k_HeadHorizontalAnimation = Parent::k_NextAnimation + 8, + k_HeadVerticalAnimation = Parent::k_NextAnimation + 9, + + k_ArmsUpDownAnimation = Parent::k_NextAnimation + 10, + + k_NextAnimation = Parent::k_NextAnimation + 11, + }; + + enum ePhysicsStateList + { + k_OnGroundPhysics = Parent::k_NextPhysicsState + 0, + k_InAirPhysics = Parent::k_NextPhysicsState + 1, + k_InWaterPhysics = Parent::k_NextPhysicsState + 2, + + k_NextPhysicsState = Parent::k_NextPhysicsState + 3, + }; + +public: + + VHumanoidActorData( void ); + + virtual bool preload( bool pServer, String &pErrorStr ); + + DECLARE_CONOBJECT( VHumanoidActorData ); +}; + +#endif // _VT_VHUMANOIDACTORDATA_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp new file mode 100644 index 000000000..ae205c5cf --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorPhysicsController.h" + +//----------------------------------------------------------------------------- + +VHumanoidActorPhysicsController::VHumanoidActorPhysicsController( void ) +{ + // Void. +} + +VHumanoidActorPhysicsController::~VHumanoidActorPhysicsController( void ) +{ + // Void. +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h new file mode 100644 index 000000000..ef984210a --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORPHYSICSCONTROLLER_H_ +#define _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ + +#ifndef _VT_VACTORPHYSICSCONTROLLER_H_ +#include "../VActorPhysicsController.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VHumanoidActorPhysicsController : public VActorPhysicsController +{ +public: + + VHumanoidActorPhysicsController( void ); + ~VHumanoidActorPhysicsController( void ); +}; + +#endif // _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp new file mode 100644 index 000000000..3ca29f7ce --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp @@ -0,0 +1,213 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidAnimationStates.h" +#include "VHumanoidActor.h" + +#include "../VActorAnimationController.h" +#include "../VActorPhysicsController.h" + +//----------------------------------------------------------------------------- +// +// Implement Animation States. +// +//----------------------------------------------------------------------------- + +ImplementActorAnimationState( HumanoidIdle, VHumanoidActorData::k_IdleAnimation ); + +ImplementActorAnimationState( HumanoidWalkForward, VHumanoidActorData::k_WalkForwardAnimation ); +ImplementActorAnimationState( HumanoidWalkBackward, VHumanoidActorData::k_WalkBackwardAnimation ); + +ImplementActorAnimationState( HumanoidRunForward, VHumanoidActorData::k_RunForwardAnimation ); +ImplementActorAnimationState( HumanoidRunBackward, VHumanoidActorData::k_RunBackwardAnimation ); + +ImplementActorAnimationState( HumanoidSwimIdle, VHumanoidActorData::k_SwimIdleAnimation ); +ImplementActorAnimationState( HumanoidSwimForward, VHumanoidActorData::k_SwimForwardAnimation ); +ImplementActorAnimationState( HumanoidSwimBackward, VHumanoidActorData::k_SwimBackwardAnimation ); + + + + +//----------------------------------------------------------------------------- +// +// Execute Animation States. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// OnGround Animation States +// +//----------------------------------------------------------------------------- + +ExecuteActorAnimationState( HumanoidIdle ) +{ + // Always Enter. + return true; +} + +ExecuteActorAnimationState( HumanoidWalkForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Forward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Forward & Slow Enough? + return ( ( physicsController->getMoveState() & k_ForwardMove ) && + ( moveSpeed < pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidWalkBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Backward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Backward? + return ( ( physicsController->getMoveState() & k_BackwardMove ) && + ( moveSpeed < pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidRunForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Forward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Forward? + return ( ( physicsController->getMoveState() & k_ForwardMove ) && + ( moveSpeed >= pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidRunBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Backward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Backward? + return ( ( physicsController->getMoveState() & k_BackwardMove ) && + ( moveSpeed >= pObject->getDataBlock()->getRunSpeed() ) ); +} + + + + +//----------------------------------------------------------------------------- +// +// InWater Animation States +// +//----------------------------------------------------------------------------- + +ExecuteActorAnimationState( HumanoidSwimIdle ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Idle? + return ( physicsController->getMoveState() & k_NullMove ); +} + +ExecuteActorAnimationState( HumanoidSwimForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Moving Around? + return ( physicsController->getMoveState() & ( k_ForwardMove | + k_UpMove | + k_DownMove ) ); +} + +ExecuteActorAnimationState( HumanoidSwimBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Moving Backward? + return ( physicsController->getMoveState() & k_BackwardMove ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.h new file mode 100644 index 000000000..d71967d54 --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidAnimationStates.h @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDANIMATIONSTATES_H_ +#define _VT_VHUMANOIDANIMATIONSTATES_H_ + +#ifndef _VT_VACTORANIMATIONSTATES_H_ +#include "../VActorAnimationStates.h" +#endif + +//----------------------------------------------------------------------------- + +DeclareActorAnimationState( HumanoidIdle ); + +DeclareActorAnimationState( HumanoidWalkForward ); +DeclareActorAnimationState( HumanoidWalkBackward ); + +DeclareActorAnimationState( HumanoidRunForward ); +DeclareActorAnimationState( HumanoidRunBackward ); + +DeclareActorAnimationState( HumanoidSwimIdle ); +DeclareActorAnimationState( HumanoidSwimForward ); +DeclareActorAnimationState( HumanoidSwimBackward ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VHUMANOIDANIMATIONSTATES_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp b/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp new file mode 100644 index 000000000..c2b8492ba --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidPhysicsStates.h" +#include "VHumanoidActor.h" + +#include "../VActorPhysicsController.h" + +//----------------------------------------------------------------------------- +// +// Implement Physics States. +// +//----------------------------------------------------------------------------- + +ImplementActorPhysicsState( HumanoidOnGround, VHumanoidActorData::k_OnGroundPhysics ); +ImplementActorPhysicsState( HumanoidInAir, VHumanoidActorData::k_InAirPhysics ); +ImplementActorPhysicsState( HumanoidInWater, VHumanoidActorData::k_InWaterPhysics ); + + + + +//----------------------------------------------------------------------------- +// +// Execute Animation States. +// +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidOnGround ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( !physicsController->isOnGround() ) + { + // No. + return false; + } + + // On Ground. + return true; +} + +ProcessActorPhysicsState( HumanoidOnGround ) +{ + // Void. +} + +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidInAir ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Air? + if ( !physicsController->isInAir() ) + { + // No. + return false; + } + + // In Air. + return true; +} + +ProcessActorPhysicsState( HumanoidInAir ) +{ + // Apply Gravity for the Tick. + pObject->getPhysicsController()->applyGravity( pElapsedTime ); +} + +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidInWater ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // Sumberged? + if ( !physicsController->isInWater() ) + { + // No. + return false; + } + + // Swimming + return true; +} + +ProcessActorPhysicsState( HumanoidInWater ) +{ + // Void. +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h b/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h new file mode 100644 index 000000000..8020d53f5 --- /dev/null +++ b/Engine/modules/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDPHYSICSSTATES_H_ +#define _VT_VHUMANOIDPHYSICSSTATES_H_ + +#ifndef _VT_VACTORPHYSICSSTATES_H_ +#include "../VActorPhysicsStates.h" +#endif + +//----------------------------------------------------------------------------- + +DeclareActorPhysicsState( HumanoidOnGround ); +DeclareActorPhysicsState( HumanoidInAir ); +DeclareActorPhysicsState( HumanoidInWater ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VHUMANOIDPHYSICSSTATES_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Types/VEnumerators.h b/Engine/modules/Verve/VActor/Types/VEnumerators.h new file mode 100644 index 000000000..2300330db --- /dev/null +++ b/Engine/modules/Verve/VActor/Types/VEnumerators.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_ENUMERATORS_H_ +#define _VT_ENUMERATORS_H_ + +//----------------------------------------------------------------------------- + +enum eMove +{ + k_NullMove = 0, + + k_ForwardMove = ( 1 << 0 ), + k_BackwardMove = ( 1 << 1 ), + k_LeftMove = ( 1 << 2 ), + k_RightMove = ( 1 << 3 ), + k_UpMove = ( 1 << 4 ), + k_DownMove = ( 1 << 5 ), + + k_XMove = ( k_LeftMove | k_RightMove ), + k_YMove = ( k_ForwardMove | k_BackwardMove ), + k_ZMove = ( k_UpMove | k_DownMove ), +}; + +enum eControlState +{ + k_NullControlState = 0, + + k_PathControlState, + k_GoToControlState, +}; + +#endif // _VT_ENUMERATORS_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Types/VRange.h b/Engine/modules/Verve/VActor/Types/VRange.h new file mode 100644 index 000000000..bb28a27e5 --- /dev/null +++ b/Engine/modules/Verve/VActor/Types/VRange.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_TYPERANGE_H_ +#define _VT_TYPERANGE_H_ + +#ifndef _TORQUE_TYPES_H_ +#include "platform/types.h" +#endif + +class Range +{ +public: + + Range( void ) : + Min( 0.f ), + Max( 1.f ), + Delta( 1.f ) + { + // Void. + }; + + Range( F32 pMin, F32 pMax ) : + Min( pMin ), + Max( pMax ), + Delta( pMax - pMin ) + { + // Void. + }; + + F32 Min; + F32 Max; + F32 Delta; +}; + +#endif // _VT_TYPERANGE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/Types/VTypes.h b/Engine/modules/Verve/VActor/Types/VTypes.h new file mode 100644 index 000000000..cc6c4918d --- /dev/null +++ b/Engine/modules/Verve/VActor/Types/VTypes.h @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// 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_TYPES_H_ +#define _VT_TYPES_H_ + +#ifndef _VT_ENUMERATORS_H_ +#include "VEnumerators.h" +#endif + +#ifndef _VT_TYPERANGE_H_ +#include "VRange.h" +#endif + +#endif // _VT_TYPES_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActor.cpp b/Engine/modules/Verve/VActor/VActor.cpp new file mode 100644 index 000000000..97dcb0257 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActor.cpp @@ -0,0 +1,232 @@ +//----------------------------------------------------------------------------- +// 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 "VActor.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VActor ); +//----------------------------------------------------------------------------- + +VActor::VActor( void ) : + mDataBlock( NULL ) +{ + // Void. +} + +VActor::~VActor( void ) +{ + // Void. +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::onAdd(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActor::onAdd( void ) +{ + if ( !Parent::onAdd() || !mDataBlock ) + { + return false; + } + + // Add to Scene. + addToScene(); + + if ( isServerObject() ) + { + // Script Callback. + scriptOnAdd(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VActor::onRemove(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onRemove( void ) +{ + // Script Callback. + scriptOnRemove(); + + // Remove From Scene. + removeFromScene(); + + Parent::onRemove(); +} + +//----------------------------------------------------------------------------- +// +// VActor::onNewDataBlock( pDataBlock ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActor::onNewDataBlock( GameBaseData *pDataBlock, bool pReload ) +{ + // Store DataBlock Reference. + mDataBlock = dynamic_cast( pDataBlock ); + + if ( !mDataBlock ) + { + // Invalid Data. + return false; + } + + // Parent Call. + return Parent::onNewDataBlock( pDataBlock, pReload ); +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::processTick( pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::processTick( const Move *pMove ) +{ + // Parent Call. + Parent::processTick( pMove ); + + // Triggers? + if ( pMove && mDamageState == Enabled ) + { + // Handle each Image Trigger. + const U32 imageCount = getMin( ShapeBase::MaxMountedImages, MaxTriggerKeys ); + for ( U32 i = 0; i < imageCount; i++ ) + { + setImageTriggerState( i, pMove->trigger[i] ); + } + } +} + +//----------------------------------------------------------------------------- +// +// VActor::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActor::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Parent Call. + return Parent::packUpdate( pConnection, pMask, pStream ); +} + +//----------------------------------------------------------------------------- +// +// VActor::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Parent Call. + Parent::unpackUpdate( pConnection, pStream ); +} + + + + +//----------------------------------------------------------------------------- +// +// Physics Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::setTransform( pMatrix ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::setTransform( const MatrixF &pMatrix ) +{ + Parent::setTransform( pMatrix ); + + // Server Object? + if ( isServerObject() ) + { + // Move Object. + setMaskBits( MoveMask ); + } +} + +//----------------------------------------------------------------------------- +// +// VActor::onMount( pObject, pNode ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onMount( SceneObject *pObject, S32 pNode ) +{ + // Parent Call. + Parent::onMount( pObject, pNode ); + + // Post Event. + mEventSignal.trigger( k_MountEvent ); +} + +//----------------------------------------------------------------------------- +// +// VActor::onUnmount( pObject, pNode ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onUnmount( SceneObject *pObject, S32 pNode ) +{ + // Parent Call. + Parent::onUnmount( pObject, pNode ); + + // Post Event. + mEventSignal.trigger( k_UnmountEvent ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActor.h b/Engine/modules/Verve/VActor/VActor.h new file mode 100644 index 000000000..3b0446f18 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActor.h @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// 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_VACTOR_H_ +#define _VT_VACTOR_H_ + +#ifndef _VT_VACTORDATA_H_ +#include "VActorData.h" +#endif + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +//----------------------------------------------------------------------------- +class VActorAnimationController; +class VActorPhysicsController; +//----------------------------------------------------------------------------- + +class VActor : public ShapeBase +{ + typedef ShapeBase Parent; + +public: + + enum eMaskBits + { + // Physics Bits. + MoveMask = Parent::NextFreeMask << 0, + PhysicsMask = ( MoveMask ), + + NextFreeMask = Parent::NextFreeMask << 1, + }; + + enum eEventType + { + k_MountEvent, + k_UnmountEvent, + }; + + typedef Signal tEventSignal; + +protected: + + VActorData *mDataBlock; + + // Event Signal. + tEventSignal mEventSignal; + +public: + + VActor( void ); + ~VActor( void ); + + // Initialisation Methods. + + bool onAdd( void ); + void onRemove( void ); + + bool onNewDataBlock( GameBaseData *pDataBlock, bool pReload ); + + // Update Methods. + + virtual void processTick( const Move *pMove ); + + virtual U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + virtual void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); + + DECLARE_CONOBJECT( VActor ); + +public: + + // Accessor Methods. + + inline VActorData *getDataBlock( void ) { return mDataBlock; }; + inline tEventSignal &getEventSignal( void ) { return mEventSignal; }; + + // Animation Methods. + + /// Get Animation Controller. + virtual VActorAnimationController *getAnimationController( void ) { return NULL; }; + + // Physics Methods. + + /// Set Transform. + virtual void setTransform( const MatrixF &pMatrix ); + + /// Get Physics Controller. + virtual VActorPhysicsController *getPhysicsController( void ) { return NULL; }; + + /// On Mount. + virtual void onMount( SceneObject *pObject, S32 pNode ); + /// On Unmount. + virtual void onUnmount( SceneObject *pObject, S32 pNode ); +}; + +#endif // _VT_VACTOR_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorAnimationController.cpp b/Engine/modules/Verve/VActor/VActorAnimationController.cpp new file mode 100644 index 000000000..b740c566a --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorAnimationController.cpp @@ -0,0 +1,354 @@ +//----------------------------------------------------------------------------- +// 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 "VActorAnimationController.h" + +#include "VActor.h" +#include "VActorData.h" +#include "VActorAnimationStates.h" + +//----------------------------------------------------------------------------- + +VActorAnimationController::VActorAnimationController( void ) : + mObject( NULL ) +{ + // Void. +} + +VActorAnimationController::~VActorAnimationController( void ) +{ + // Clear Table. + mAnimationTable.clear(); +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimationTable(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimationTable( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No, Quit Now. + return false; + } + + // Clear the Table. + mAnimationTable.clear(); + + // Fetch Sequence List. + VActorData::tAnimationSequenceVector *sequenceList = getObject()->getDataBlock()->getAnimationList(); + + // Initialise the Animation States. + for ( VActorData::tAnimationSequenceVector::iterator itr = sequenceList->begin(); + itr != sequenceList->end(); + itr++ ) + { + // Fetch Sequence Definition. + const VActorData::sAnimationSequence &animSequence = ( *itr ); + + // Valid State? + if ( animSequence.State ) + { + // Register Animation. + mAnimationTable.registerState( animSequence.State, animSequence.Priority ); + } + } + + // Sort the Table. + mAnimationTable.sort(); + + // Valid. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimation( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimation( sAnimationRef &pAnimation, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Valid Object & Sequence? + if ( !isValidObject() || !isAnimationSequence( pIndex ) ) + { + // No, Quit Now. + return false; + } + + // Store as Current Animation. + pAnimation.Index = pIndex; + + // Initialise Thread. + return initAnimationThread( pAnimation.Thread, pAnimation.Index, pPosition, pTimeScale ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimationThread( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimationThread( TSThread *&pThread, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Valid Object & Sequence? + if ( !isValidObject() || !isAnimationSequence( pIndex ) ) + { + // No, Quit Now. + return false; + } + + // Valid Thread? + if ( !pThread ) + { + // Create a Thread. + pThread = getShapeInstance()->addThread(); + } + + // Init the Sequence. + getShapeInstance()->setSequence( pThread, getAnimationSequence( pIndex ), pPosition ); + + // Set Initial Time Scale. + getShapeInstance()->setTimeScale( pThread, pTimeScale ); + + // Valid. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initBaseAnimation( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initBaseAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + return initAnimation( mBaseAnimation, pIndex, pPosition, pTimeScale ); +} + + + + +//----------------------------------------------------------------------------- +// +// Accessor Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::isValidObject(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::isValidObject( void ) +{ + return ( mObject != NULL && mObject->getDataBlock() != NULL ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getObject(); +// +// ... +// +//----------------------------------------------------------------------------- +VActor *VActorAnimationController::getObject( void ) +{ + return mObject; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::setObject( pObject ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorAnimationController::setObject( VActor *pObject ) +{ + // Set Object. + mObject = pObject; + + // Set Table's Reference. + mAnimationTable.setObject( pObject ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getShape(); +// +// ... +// +//----------------------------------------------------------------------------- +const TSShape *VActorAnimationController::getShape( void ) +{ + if ( !isValidObject() ) + { + return NULL; + } + + return mObject->getShape(); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getShapeInstance(); +// +// ... +// +//----------------------------------------------------------------------------- +TSShapeInstance *VActorAnimationController::getShapeInstance( void ) +{ + if ( !isValidObject() ) + { + return NULL; + } + + return mObject->getShapeInstance(); +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods +// +//----------------------------------------------------------------------------- + +void VActorAnimationController::update( const F32 &pDelta ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No, Quit Now. + return; + } + + // Update Animation State. + mAnimationTable.execute(); + + // Advance Threads. + getShapeInstance()->advanceTime( pDelta, mBaseAnimation.Thread ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::isAnimationSequence( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::isAnimationSequence( const U32 &pIndex ) +{ + return ( getAnimationSequence( pIndex ) != -1 ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getAnimationSequence( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +S32 VActorAnimationController::getAnimationSequence( const U32 &pIndex ) +{ + // Valid Object? + if ( !mObject || !mObject->getDataBlock() ) + { + // No, Invalid Sequence. + return -1; + } + + // Return Sequence. + return mObject->getDataBlock()->getAnimationSequence( pIndex ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getAnimation( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActorAnimationController::getAnimation( void ) +{ + // Base Animation Initialised? + if ( !mBaseAnimation.Thread ) + { + // Null. + return U32_MAX; + } + + // Return Current Animation. + return mBaseAnimation.Index; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::setAnimation( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorAnimationController::setAnimation( const U32 &pIndex ) +{ + // Base Animation Initialised? + if ( !mBaseAnimation.Thread || mBaseAnimation.Index == pIndex ) + { + // Don't Update. + return; + } + + // Store as Current Animation. + mBaseAnimation.Index = pIndex; + + // Fetch the Sequence. + const S32 &sequence = getAnimationSequence( pIndex ); + + // Valid? + if ( sequence != -1 ) + { + // Play the Sequence. + getShapeInstance()->transitionToSequence( mBaseAnimation.Thread, sequence, 0.f, 0.15f, true ); + //getShapeInstance()->setSequence( mBaseAnimation.Thread, sequence, 0.f ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorAnimationController.h b/Engine/modules/Verve/VActor/VActorAnimationController.h new file mode 100644 index 000000000..660248b8b --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorAnimationController.h @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// 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_VACTORANIMATIONCONTROLLER_H_ +#define _VT_VACTORANIMATIONCONTROLLER_H_ + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSSHAPEINSTANCE_H_ +#include "ts/tsShapeInstance.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VActorAnimationController +{ +public: + + struct sAnimationRef + { + U32 Index; + TSThread *Thread; + + sAnimationRef( void ) : + Index( U32_MAX ), + Thread( NULL ) + { + // Void. + } + }; + +protected: + + VActor *mObject; + + VActorStateTable mAnimationTable; + sAnimationRef mBaseAnimation; + +public: + + VActorAnimationController( void ); + virtual ~VActorAnimationController( void ); + + // Initialisation Methods. + + bool initAnimationTable( void ); + bool initAnimation( sAnimationRef &pAnimation, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + bool initAnimationThread( TSThread *&pThread, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + bool initBaseAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + // Accessor Methods. + + bool isValidObject( void ); + VActor *getObject( void ); + void setObject( VActor *pObject ); + + const TSShape *getShape( void ); + TSShapeInstance *getShapeInstance( void ); + + // Animation Methods. + + virtual void update( const F32 &pDelta ); + + bool isAnimationSequence( const U32 &pIndex ); + S32 getAnimationSequence( const U32 &pIndex ); + + U32 getAnimation( void ); + void setAnimation( const U32 &pIndex ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorAnimationStates.h b/Engine/modules/Verve/VActor/VActorAnimationStates.h new file mode 100644 index 000000000..f1e0c44a6 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorAnimationStates.h @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// 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_VACTORANIMATIONSTATES_H_ +#define _VT_VACTORANIMATIONSTATES_H_ + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSINGLETON_H_ +#include "core/util/tSingleton.h" +#endif + +//----------------------------------------------------------------------------- + +class VActorAnimationState : public VActorState +{ +public: + + virtual void exit( VActor *pObject ) {}; +}; + +//----------------------------------------------------------------------------- + +#define DeclareActorAnimationState( name ) \ + class VActor##name##AnimationState : public VActorAnimationState \ + { \ + public: \ + void enter( VActor *pObject ); \ + bool execute( VActor *pObject ); \ + } + +#define ActorAnimationStateInstance( name ) \ + Singleton::instance() + +#define ImplementActorAnimationState( name, sequence ) \ + void VActor##name##AnimationState::enter( VActor *pObject ) { pObject->getAnimationController()->setAnimation( sequence ); } + +#define ExecuteActorAnimationState( name ) \ + bool VActor##name##AnimationState::execute( VActor *pObject ) + +//----------------------------------------------------------------------------- + +#endif // _VT_VACTORANIMATIONSTATES_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorData.cpp b/Engine/modules/Verve/VActor/VActorData.cpp new file mode 100644 index 000000000..24d3b54d1 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorData.cpp @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------------- +// 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 "VActorData.h" + +#include "console/consoleTypes.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_DATABLOCK_V1( VActorData ); +//----------------------------------------------------------------------------- + +VActorData::VActorData( void ) : + mMaxStepHeight( 1.f ), + mRunSpeed( 6.f ), + mSubmergeCoverage( 0.25f ) +{ + // Setup Shadowing. + shadowEnable = true; + shadowSize = 256; + shadowProjectionDistance = 14.0f; + + VECTOR_SET_ASSOCIATION( mAnimationSequenceList ); + VECTOR_SET_ASSOCIATION( mPhysicsList ); +} + +VActorData::~VActorData( void ) +{ + // Void. +} + +void VActorData::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "MaxStepHeight", TypeF32, Offset( mMaxStepHeight, VActorData ) ); + addField( "RunSpeed", TypeF32, Offset( mRunSpeed, VActorData ) ); + + addField( "SubmergeCoverage", TypeF32, Offset( mSubmergeCoverage, VActorData ) ); +} + +//----------------------------------------------------------------------------- + +bool VActorData::initAnimationSequenceList( const S32 &pSize, const sAnimationSequence *pTable ) +{ + if ( !mShape ) + { + // Sanity! + return false; + } + + // Clear the List. + mAnimationSequenceList.clear(); + + // Initialise each Animation Sequence. + for ( U32 i = 0; i < pSize; i++ ) + { + // Fetch Sequence Definition. + const sAnimationSequence &animSequenceDef = pTable[i]; + + // Update Animation Details. + sAnimationSequence animSequence = animSequenceDef; + // Find Sequence. + animSequence.Sequence = mShape->findSequence( animSequenceDef.Name ); + + // Store. + mAnimationSequenceList.push_back( animSequence ); + } + + return true; +} + +bool VActorData::initAnimationTransitionList( const S32 &pSize, const sAnimationTransition *pTable ) +{ + if ( !mShape ) + { + // Sanity! + return false; + } + + // Clear the List. + mAnimationTransitionList.clear(); + + // Store each Animation Transition. + for ( U32 i = 0; i < pSize; i++ ) + { + // Store. + mAnimationTransitionList.push_back( pTable[i] ); + } + + return true; +} + +bool VActorData::initPhysicsStateList( const S32 &pSize, const sPhysicsState *pTable ) +{ + // Clear the List. + mPhysicsList.clear(); + + // Initialise each Animation Sequence. + for ( U32 i = 0; i < pSize; i++ ) + { + // Store. + mPhysicsList.push_back( pTable[i] ); + } + + return true; +} + +//----------------------------------------------------------------------------- + +void VActorData::packData( BitStream *pStream ) +{ + Parent::packData( pStream ); + + pStream->write( mMaxStepHeight ); + pStream->write( mRunSpeed ); + + pStream->write( mSubmergeCoverage ); +} + +void VActorData::unpackData( BitStream *pStream ) +{ + Parent::unpackData( pStream ); + + pStream->read( &mMaxStepHeight ); + pStream->read( &mRunSpeed ); + + pStream->read( &mSubmergeCoverage ); +} + +//----------------------------------------------------------------------------- + +S32 VActorData::getAnimationSequence( const U32 &pIndex ) +{ + // Iterate over the Registered Animations. + for ( tAnimationSequenceVector::iterator itr = mAnimationSequenceList.begin(); itr != mAnimationSequenceList.end(); itr++ ) + { + // Fetch Sequence Defintion. + const sAnimationSequence &animSequence = ( *itr ); + + // Target Index? + if ( animSequence.Index == pIndex ) + { + // Return Sequence ID. + return animSequence.Sequence; + } + } + + // Invalid Sequence. + return -1; +}; \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorData.h b/Engine/modules/Verve/VActor/VActorData.h new file mode 100644 index 000000000..2aaf0fc58 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorData.h @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------- +// 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_VACTORDATA_H_ +#define _VT_VACTORDATA_H_ + +#ifndef _SHAPEBASE_H_ +#include "T3D/shapeBase.h" +#endif + +//----------------------------------------------------------------------------- +class VActor; +class VActorStateTable; +class VActorAnimationState; +class VActorPhysicsState; +//----------------------------------------------------------------------------- + +struct VActorData : public ShapeBaseData +{ +private: + + typedef ShapeBaseData Parent; + friend class VActor; + +public: + + // Animation Data. + + enum eAnimationList + { + k_NextAnimation = 0, + }; + + struct sAnimationSequence + { + U32 Index; + const char *Name; + F32 Priority; + + VActorAnimationState *State; + S32 Sequence; + }; + + struct sAnimationTransition + { + U32 FromIndex; + U32 ToIndex; + + F32 Duration; + + bool Ordered; + U32 Sequence; + }; + + typedef Vector tAnimationSequenceVector; + typedef Vector tAnimationTransitionVector; + + // Physics Data. + + enum ePhysicsStateList + { + k_NextPhysicsState = 0, + }; + + struct sPhysicsState + { + U32 Index; + F32 Priority; + + VActorPhysicsState *State; + }; + typedef Vector tPhysicsStateVector; + +protected: + + tAnimationSequenceVector mAnimationSequenceList; + tAnimationTransitionVector mAnimationTransitionList; + tPhysicsStateVector mPhysicsList; + + F32 mMaxStepHeight; + F32 mRunSpeed; + + F32 mSubmergeCoverage; + +public: + + VActorData( void ); + ~VActorData( void ); + + static void initPersistFields( void ); + + virtual bool initAnimationSequenceList( const S32 &pSize, const sAnimationSequence *pTable ); + virtual bool initAnimationTransitionList( const S32 &pSize, const sAnimationTransition *pTable ); + virtual bool initPhysicsStateList( const S32 &pSize, const sPhysicsState *pTable ); + + virtual void packData( BitStream *pStream ); + virtual void unpackData( BitStream *pStream ); + + DECLARE_CONOBJECT( VActorData ); + +public: + + tAnimationSequenceVector *getAnimationList( void ) { return &mAnimationSequenceList; }; + S32 getAnimationSequence( const U32 &pIndex ); + + tPhysicsStateVector *getPhysicsStateList( void ) { return &mPhysicsList; }; + + inline const F32 &getMaxStepHeight( void ) const { return mMaxStepHeight; }; + inline const F32 &getRunSpeed( void ) const { return mRunSpeed; }; + inline const F32 &getSumbergeCoverage( void ) const { return mSubmergeCoverage; }; +}; + +#endif // _VT_VACTORDATA_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorPhysicsController.cpp b/Engine/modules/Verve/VActor/VActorPhysicsController.cpp new file mode 100644 index 000000000..5e3332d59 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorPhysicsController.cpp @@ -0,0 +1,1277 @@ +//----------------------------------------------------------------------------- +// 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 "VActorPhysicsController.h" + +#include "VActor.h" +#include "VActorData.h" +#include "VActorPhysicsStates.h" + +#include "Verve/VPath/VPath.h" + +#include "collision/clippedPolyList.h" +#include "collision/earlyOutPolyList.h" +#include "collision/extrudedPolyList.h" +#include "core/stream/bitStream.h" +#include "environment/waterObject.h" + +//----------------------------------------------------------------------------- + +static const U32 sGroundCollisionMask = ( StaticObjectType | StaticShapeObjectType | TerrainObjectType ); +static const U32 sMoveCollisionMask = ( PlayerObjectType | VehicleObjectType ); +static const U32 sCollisionMask = ( sGroundCollisionMask | sMoveCollisionMask ); + +//----------------------------------------------------------------------------- + +VActorPhysicsController::VActorPhysicsController( void ) : + mObject( NULL ), + mMountedPath( NULL ), + mPhysicsState( 0 ), + mControlState( k_NullControlState ), + mMoveState( k_NullMove ), + mVelocity( VectorF::Zero ), + mGravity( 0.f, 0.f, -9.8f ) +{ + // Void. +} + +VActorPhysicsController::~VActorPhysicsController( void ) +{ + // Clear Object. + clearObject(); +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::initPhysicsController(); +// +// Initialise the physics table and setup the interface between the Controller +// and the reference object. +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::initPhysicsController( VActor *pObject ) +{ + // Valid Object? + if ( !pObject ) + { + // Assert & Quit. + AssertFatal( false, "VActorPhysicsController::initPhysicsController() - Invalid Object Specified." ); + return false; + } + + // Set Object. + mObject = pObject; + // Register for Actor Events. + mObject->getEventSignal().notify( this, &VActorPhysicsController::onActorEvent ); + + // Set Table's Reference. + mPhysicsStateTable.setObject( pObject ); + + // Init the Convex Box. + mConvex.init( pObject ); + + // Reset Interp. + mInterpController.resetDelta( pObject->getTransform() ); + + // Validate. + return initPhysicsTable(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::initPhysicsTable(); +// +// Register the available physics states which this controller may utilize. +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::initPhysicsTable( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No, Quit Now. + return false; + } + + // Clear the Table. + mPhysicsStateTable.clear(); + + // Fetch Sequence List. + VActorData::tPhysicsStateVector *stateList = getObjectDataBlock()->getPhysicsStateList(); + + // Initialise the Physics States. + for ( VActorData::tPhysicsStateVector::iterator itr = stateList->begin(); + itr != stateList->end(); + itr++ ) + { + // Fetch Sequence Definition. + const VActorData::sPhysicsState &physState = ( *itr ); + + // Valid State? + if ( physState.State ) + { + // Register State. + mPhysicsStateTable.registerState( physState.State, physState.Priority ); + } + } + + // Sort the Table. + mPhysicsStateTable.sort(); + + // Valid. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// Accessor Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isValidObject(); +// +// Do we have a valid reference object? +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::isValidObject( void ) +{ + return ( mObject && mObject->getDataBlock() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getObject(); +// +// Return the reference object. +// +//----------------------------------------------------------------------------- +VActor *VActorPhysicsController::getObject( void ) +{ + return mObject; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getObjectDataBlock(); +// +// Get the Actor Data for the reference object. +// +//----------------------------------------------------------------------------- +VActorData *VActorPhysicsController::getObjectDataBlock( void ) +{ + // Valid Object? + if ( !mObject ) + { + // No. + return NULL; + } + + // Return DataBlock. + return mObject->getDataBlock(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearObject(); +// +// Clear the reference object. Note that this should *never* be called outside +// of the controller's destructor! +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearObject( void ) +{ + // Valid Object? + if ( !mObject ) + { + // No. + return; + } + + // Clear Notify. + mObject->getEventSignal().remove( this, &VActorPhysicsController::onActorEvent ); + + // Clear Object. + mObject = NULL; + + // Clear Table. + mPhysicsStateTable.setObject( NULL ); + mPhysicsStateTable.clear(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getControlState(); +// +// Get the current Control State. +// +//----------------------------------------------------------------------------- +const U32 VActorPhysicsController::getControlState( void ) +{ + return mControlState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearControlState( pControlState ); +// +// Clear the Control State of a particular mask. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearControlState( const U32 &pControlState ) +{ + mControlState &= ( ~pControlState ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setControlState( pControlState ); +// +// Set the Control State. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setControlState( const U32 &pControlState ) +{ + mControlState = pControlState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isMoving(); +// +// Is the Actor currently Moving? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isMoving( void ) +{ + return ( !mIsZero( getVelocity().lenSquared() ) ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isMoving( pMoveState ); +// +// Is the Actor currently moving with the desired state? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isMoving( const U32 &pMoveState ) +{ + // Moving? + return ( ( getMoveState() & pMoveState ) && isMoving() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getMoveState(); +// +// Get the current Move State. +// +//----------------------------------------------------------------------------- +const U32 VActorPhysicsController::getMoveState( void ) +{ + // Return Move State. + return mMoveState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearMoveState( pMoveState ); +// +// Clear the Move State of a particular mask. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearMoveState( const U32 &pMoveState ) +{ + // Set Move State. + mMoveState &= ( ~pMoveState ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setMoveState( pMoveState ); +// +// Set the Move State. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setMoveState( const U32 &pMoveState ) +{ + // Set Move State. + mMoveState = pMoveState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isPathing(); +// +// Is the Actor Pathing? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isPathing( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return false; + } + + return ( mMountedPath != NULL ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getPathObject(); +// +// Get the Path Object the Actor is mounted to. +// +//----------------------------------------------------------------------------- +VPath *VActorPhysicsController::getPathObject( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return NULL; + } + + return mMountedPath; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isOnGround(); +// +// Is the Actor On the Ground? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isOnGround( void ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No. + return false; + } + + // On Ground? + return ( mOnGround && mGroundObject && !isInWater() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isInAir(); +// +// Is the Actor in the Air? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isInAir( void ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No. + return false; + } + + // In Air? + return ( !isOnGround() && !isInWater() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isInWater(); +// +// Is the Actor in the Water? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isInWater( void ) +{ + // Valid Objects? + if ( !isValidObject() || !getWaterObject() ) + { + // No. + return false; + } + + // Submerged? + return ( ( mObject->getWaterCoverage() + POINT_EPSILON ) >= mObject->getDataBlock()->getSumbergeCoverage() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getWaterObject(); +// +// Get the current Water Object the Actor is in. +// +//----------------------------------------------------------------------------- +WaterObject *VActorPhysicsController::getWaterObject( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return NULL; + } + + return mObject->getCurrentWaterObject(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getTransform(); +// +// Get the Actor's Transform. +// +//----------------------------------------------------------------------------- +MatrixF VActorPhysicsController::getTransform( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return MatrixF::Identity; + } + + // Return Transform. + return mObject->getTransform(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setTransform( pTransform ); +// +// Set the Actor's Transform. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setTransform( const MatrixF &pTransform ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return; + } + + // Apply Transform. + mObject->setTransform( pTransform ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getPosition(); +// +// Get the Actor's Position. +// +//----------------------------------------------------------------------------- +Point3F VActorPhysicsController::getPosition( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return Point3F::Zero; + } + + // Return Position. + return mObject->getPosition(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setPosition( pPosition ); +// +// Set the Actor's Position. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setPosition( const Point3F &pPosition ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return; + } + + // Apply Position. + mObject->setPosition( pPosition ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::applyGravity( pElapsedTime ); +// +// Apply gravity for the elapsed period. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::applyGravity( const F32 &pElapsedTime ) +{ + // Get Velocity. + VectorF velocity = getVelocity(); + // Add Tick Gravity. + velocity += getGravity() * pElapsedTime; + // Apply. + setVelocity( velocity ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getVelocity(); +// +// Get the Actor's Velocity. +// +//----------------------------------------------------------------------------- +VectorF VActorPhysicsController::getVelocity( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return VectorF::Zero; + } + + // Return Velocity. + return mVelocity; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setVelocity( pVelocity ); +// +// Set the Actor's Velocity. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setVelocity( const VectorF &pVelocity ) +{ + // Set Velocity. + mVelocity = pVelocity; +} + + + + +//----------------------------------------------------------------------------- +// +// Physics Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::update( pDelta, pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::update( const F32 &pDelta, const Move *pMove ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No, Quit Now. + return; + } + + // Pre-tick Update. + preTickUpdate( pDelta ); + + // Integrate Tick Update. + integrateTickUpdate( pDelta, pMove ); + + // Post-tick Update. + postTickUpdate( pDelta ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::preTickUpdate( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::preTickUpdate( const F32 &pDelta ) +{ + // Pop Delta. + mInterpController.popDelta(); + + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::preTickUpdate() - Invalid Path State." ); + + // Fetch Mount Velocity. + const VectorF &mountVelocity = mMountedPath->getMountVelocity( mObject->getMountNode() ); + + // Use X & Y Velocity. + VectorF velocity = getVelocity(); + velocity.x = mountVelocity.x; + velocity.y = mountVelocity.y; + + // Apply Updates. + setVelocity( velocity ); + + } break; + } + + // Update Move State. + updateMoveState(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::integrateTickUpdate( pDelta, pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::integrateTickUpdate( const F32 &pDelta, const Move *pMove ) +{ + // Update Collision Set. + updateWorkingCollisionSet(); + // Ground Ground Status. + updateGroundStatus(); + + // Execute Physics Table. + VActorPhysicsState *physState = dynamic_cast( mPhysicsStateTable.execute() ); + // Assert. + AssertFatal( physState, "VActorPhysicsController::update() - Invalid Physics State in the Table." ); + + // Process the State. + physState->processTick( mObject, pDelta, pMove ); + + // Process Collisions. + processCollisions(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::postTickUpdate( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::postTickUpdate( const F32 &pDelta ) +{ + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." ); + + // Fetch Mount Transform. + MatrixF transform; + mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform ); + // Fetch Mount Position. + const Point3F &mountPosition = transform.getPosition(); + + // Update X & Y Position. + Point3F position = getPosition(); + position.x = mountPosition.x; + position.y = mountPosition.y; + + // In Water? + bool underWater = false; + if ( isInWater() ) + { + // Fetch Body of Water. + WaterObject *waterBody = getWaterObject(); + + // Fetch Surface Position. + const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) ); + // Fetch Submersion Position. + const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() ); + + // Choose a Z Value. + // Note: This is done so that the Actor will either path under the + // water, or it will swim along the water's surface. + position.z = getMin( mountPosition.z, sumbersionPosition ); + + // Under Water? + underWater = ( position.z < sumbersionPosition ); + } + + // Under Water? + if ( !underWater ) + { + // Fetch Y Column. + VectorF forwardVector; + transform.getColumn( 1, &forwardVector ); + + // Determine Angle. + const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y ); + + // Reset Transform. + transform.set( EulerF( 0.f, 0.f, angle ) ); + + // In the air? + if ( !isOnGround() ) + { + // Apply z-axis force. + position.z += ( getVelocity().z * pDelta ); + } + } + + // Update Transform. + transform.setPosition( position ); + + // Apply Update. + setTransform( transform ); + + } break; + + default : + { + // Fetch Transform. + MatrixF transform = getTransform(); + + // Determine the Post-Tick Position. + Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta ); + // Set the Post Tick Position. + transform.setPosition( postTickPosition ); + + // Apply the Transform. + setTransform( transform ); + + } break; + } + + // Push Delta. + mInterpController.pushDelta( getTransform() ); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::interpolateTick( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::interpolateTick( const F32 &pDelta ) +{ + // Fetch Interpolated Transform. + const MatrixF transform = mInterpController.getTransform( pDelta ); + // Apply Render Transform. + mObject->setRenderTransform( transform ); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateWorkingCollisionSet(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateWorkingCollisionSet() +{ + // Contstruct Bounding Box. + const Box3F boundingBox = mConvex.getBoundingBox( getTransform(), mObject->getScale() ); + + // Determine Sweep Vector. + const VectorF sweepVector = ( getVelocity() * TickSec ); + + // Construct Swept Box. + Box3F sweptBox = boundingBox; + sweptBox.minExtents.setMin( boundingBox.minExtents + sweepVector ); + sweptBox.maxExtents.setMax( boundingBox.maxExtents + sweepVector ); + + // Update Collision List. + mObject->disableCollision(); + mConvex.updateWorkingList( sweptBox, sCollisionMask ); + mObject->enableCollision(); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateMoveState(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateMoveState( void ) +{ + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::updateMoveState() - Invalid Path State." ); + + // Update Move State. + VPathObject *pathObject = mMountedPath->getPathObject( mObject ); + if ( !pathObject->isActive() ) + { + // Idle. + setMoveState( k_NullMove ); + } + else + { + // Set Movement Direction. + setMoveState( ( pathObject->isForward() ) ? k_ForwardMove : k_BackwardMove ); + } + + } break; + + default : + { + // Set Idle. + setMoveState( k_NullMove ); + + } break; + } +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearGroundStatus(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearGroundStatus( void ) +{ + // Clear Grounding. + mOnGround = false; + mGroundObject = NULL; + mGroundNormal.zero(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateGroundStatus(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateGroundStatus( void ) +{ + // Submerged? + if ( isInWater() ) + { + // Clear Ground Status. + clearGroundStatus(); + return; + } + + // Check for Grounding. + SceneObject *groundObject; + Point3F groundPoint; + VectorF groundNormal; + if ( !findGroundContact( groundObject, groundPoint, groundNormal ) ) + { + // Clear Ground Status. + clearGroundStatus(); + return; + } + + // Tidy up the Contact Position. + // Note: This basically "clamps" the Actor to the surface of the ground + // object. + const Point3F objPosition = getPosition(); + setPosition( objPosition - Point3F( 0.f, 0.f, ( objPosition.z - groundPoint.z ) ) ); + + // Clear Z-Axis Velocity. + mVelocity.z = 0.f; + + // Store Details. + mOnGround = true; + mGroundObject = groundObject; + mGroundNormal = groundNormal; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::findGroundContact( pContactObject, pContactPoint, pContactNormal ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal ) +{ + // Setup Collision List. + static CollisionList sCollisionList; + sCollisionList.clear(); + + static Polyhedron sBoxPolyhedron; + static ExtrudedPolyList sExtrudedPolyList; + + // Fetch Max Step Height. + const F32 stepHeight = mObject->getDataBlock()->getMaxStepHeight(); + + // Determine Positions. + const Point3F preTickPosition = getPosition() + Point3F( 0.f, 0.f, stepHeight ); + const VectorF preTickVelocity = getVelocity() + mGravity - VectorF( 0.f, 0.f, stepHeight / TickSec ); + const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec ); + const VectorF postTickVector = postTickPosition - preTickPosition; + + // Construct Scaled Box. + Box3F scaledBox = mObject->getObjBox(); + scaledBox.minExtents.convolve( mObject->getScale() ); + scaledBox.maxExtents.convolve( mObject->getScale() ); + + // Setup Polyherdron. + MatrixF collisionMatrix( true ); + collisionMatrix.setPosition( preTickPosition ); + sBoxPolyhedron.buildBox( collisionMatrix, scaledBox ); + + // Setup Extruded Poly List. + sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector ); + sExtrudedPolyList.setVelocity( preTickVelocity ); + sExtrudedPolyList.setCollisionList( &sCollisionList ); + + // Construct World Convex Box & Adjust for Sweep. + Box3F convexBox = scaledBox; + getTransform().mul( convexBox ); + convexBox.minExtents += postTickVector; + convexBox.maxExtents += postTickVector; + + // Build List of Contacts. + CollisionWorkingList &rList = mConvex.getWorkingList(); + for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext ) + { + Convex *convexShape = pList->mConvex; + + // Ground Object? + if ( !( convexShape->getObject()->getTypeMask() & sGroundCollisionMask ) ) + { + // No, Continue. + continue; + } + + // Overlap? + const Box3F &collisionConvexBox = convexShape->getBoundingBox(); + if ( convexBox.isOverlapped( collisionConvexBox ) ) + { + // Build Contact Information. + convexShape->getPolyList( &sExtrudedPolyList ); + } + } + + // Valid Collision? + if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() < 0.f || sCollisionList.getTime() > 1.f ) + { + // No, Quit Now. + return false; + } + + // Use First Collision. + Collision *collision = &sCollisionList[0]; + + // More Collisions? + if ( sCollisionList.getCount() > 1 ) + { + // Check for Better Contacts. + for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ ) + { + if ( cp->faceDot > collision->faceDot ) + { + // Use this One. + collision = cp; + } + } + } + + // Set Properties. + pContactObject = collision->object; + //pContactPoint = collision->point; + pContactPoint = ( preTickPosition + ( preTickVelocity * TickSec * sCollisionList.getTime() ) ); + pContactNormal = collision->normal; + + // Valid Contact. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::processCollisions(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::processCollisions( void ) +{ + // Find & Resolve Collisions. + Collision *collision; + if ( findCollision( collision ) ) + { + // Solve the Collision. + solveCollision( collision ); + } +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::findCollision( pCollision ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::findCollision( Collision *&pCollision ) +{ + // Setup Collision List. + static CollisionList sCollisionList; + sCollisionList.clear(); + + static Polyhedron sBoxPolyhedron; + static ExtrudedPolyList sExtrudedPolyList; + + // Determine Positions. + const Point3F preTickPosition = getPosition(); + const VectorF preTickVelocity = getVelocity(); + const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec ); + const VectorF postTickVector = postTickPosition - preTickPosition; + + // Construct Scaled Box. + Box3F scaledBox = mObject->getObjBox(); + scaledBox.minExtents.convolve( mObject->getScale() ); + scaledBox.maxExtents.convolve( mObject->getScale() ); + + // Setup Polyherdron. + MatrixF collisionMatrix( true ); + collisionMatrix.setPosition( preTickPosition ); + sBoxPolyhedron.buildBox( collisionMatrix, scaledBox ); + + // Setup Extruded Poly List. + sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector ); + sExtrudedPolyList.setVelocity( preTickVelocity ); + sExtrudedPolyList.setCollisionList( &sCollisionList ); + + // Construct World Convex Box & Adjust for Sweep. + Box3F convexBox = scaledBox; + getTransform().mul( convexBox ); + convexBox.minExtents += postTickVector; + convexBox.maxExtents += postTickVector; + + // Determine the Collision Mask. + const U32 collisionMask = ( isInWater() ) ? ( sGroundCollisionMask | sMoveCollisionMask ) : sMoveCollisionMask; + + // Build List of Contacts. + CollisionWorkingList &rList = mConvex.getWorkingList(); + for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext ) + { + Convex *convexShape = pList->mConvex; + + // Valid Collision Target? + if ( !( convexShape->getObject()->getTypeMask() & collisionMask ) ) + { + // No, Continue. + continue; + } + + // Overlap? + const Box3F &collisionConvexBox = convexShape->getBoundingBox(); + if ( convexBox.isOverlapped( collisionConvexBox ) ) + { + // Build Contact Information. + convexShape->getPolyList( &sExtrudedPolyList ); + } + } + + // Valid Collision? + if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() > 1.f ) + { + // No, Quit Now. + return false; + } + + // Use First Collision. + Collision *collision = &sCollisionList[0]; + + // More Collisions? + if ( sCollisionList.getCount() > 1 ) + { + // Check for Better Contacts. + for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ ) + { + if ( cp->faceDot > collision->faceDot ) + { + // Use this One. + collision = cp; + } + } + } + + // Store Reference. + pCollision = collision; + + // Valid Collision. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::solveCollision( pCollision ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::solveCollision( Collision *pCollision ) +{ + // Fetch Velocity. + VectorF velocity = getVelocity(); + // Resolve Collision. + velocity -= ( pCollision->normal * mDot( getVelocity(), pCollision->normal ) ); + + // Pathing? + if ( isPathing() ) + { + // Clear X & Y Velocity Adjustments. + // Note: This means that any collisions made during pathing will not + // be solved, unless they only affect Z position. It is up to the + // user to construct Paths which avoid obsticles! + velocity.x = velocity.y = 0.f; + } + + // Set Velocity. + setVelocity( velocity ); +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::onActorEvent( pEvent ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::onActorEvent( const VActor::eEventType &pEvent ) +{ + switch( pEvent ) + { + case VActor::k_MountEvent : + { + // Set Control State. + setControlState( k_PathControlState ); + + // Store Path. + mMountedPath = dynamic_cast( mObject->getObjectMount() ); + + } break; + + case VActor::k_UnmountEvent : + { + // Clear Control State. + clearControlState( k_PathControlState ); + + // Clear Path. + mMountedPath = NULL; + // Clear X & Y Velocity. + setVelocity( VectorF( 0.f, 0.f, mVelocity.z ) ); + + } break; + } +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActorPhysicsController::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Return Mask. + U32 retMask = 0; + + // Valid Object? + if ( !pStream->writeFlag( isValidObject() ) ) + { + return retMask; + } + + // Write Move? + const bool writeMove = ( pMask & VActor::MoveMask ) && !isPathing(); + if ( pStream->writeFlag( writeMove ) ) + { + // Write Position. + const Point3F &position = getPosition(); + pStream->write( position.x ); + pStream->write( position.y ); + pStream->write( position.z ); + } + + return retMask; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid Object? + if ( !pStream->readFlag() ) + { + return; + } + + // Read Move? + if ( pStream->readFlag() ) + { + // Read Position. + Point3F position; + pStream->read( &position.x ); + pStream->read( &position.y ); + pStream->read( &position.z ); + + // Apply. + setPosition( position ); + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorPhysicsController.h b/Engine/modules/Verve/VActor/VActorPhysicsController.h new file mode 100644 index 000000000..3e4a2912e --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorPhysicsController.h @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------- +// 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_VACTORPHYSICSCONTROLLER_H_ +#define _VT_VACTORPHYSICSCONTROLLER_H_ + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _VT_VACTOR_H_ +#include "VActor.h" +#endif + +#ifndef _VT_VINTERPCONTROLLER_H_ +#include "VInterpController.h" +#endif + +#ifndef _BOXCONVEX_H_ +#include "collision/boxConvex.h" +#endif + +//----------------------------------------------------------------------------- + +class VPath; + +//----------------------------------------------------------------------------- + +class VActorPhysicsController +{ +protected: + + SimObjectPtr mObject; + SimObjectPtr mMountedPath; + + VActorStateTable mPhysicsStateTable; + + VInterpController mInterpController; + + U32 mPhysicsState; + U32 mControlState; + U32 mMoveState; + + OrthoBoxConvex mConvex; + + VectorF mGravity; + VectorF mVelocity; + + bool mOnGround; + SimObjectPtr mGroundObject; + VectorF mGroundNormal; + +public: + + VActorPhysicsController( void ); + virtual ~VActorPhysicsController( void ); + + // Initialisation Methods. + + bool initPhysicsController( VActor *pObject ); + bool initPhysicsTable( void ); + + // Accessor Methods. + + bool isValidObject( void ); + VActor *getObject( void ); + VActorData *getObjectDataBlock( void ); + void clearObject( void ); + + virtual const U32 getControlState( void ); + virtual void clearControlState( const U32 &pControlState ); + virtual void setControlState( const U32 &pControlState ); + + virtual const bool isMoving( void ); + virtual const bool isMoving( const U32 &pMoveState ); + virtual const U32 getMoveState( void ); + virtual void clearMoveState( const U32 &pMoveState ); + virtual void setMoveState( const U32 &pMoveState ); + + virtual const bool isPathing( void ); + virtual VPath *getPathObject( void ); + + virtual const bool isInWater( void ); + virtual WaterObject *getWaterObject( void ); + + virtual const bool isOnGround( void ); + virtual const bool isInAir( void ); + inline SceneObject *getGroundObject( void ) { return mGroundObject; }; + inline const VectorF &getGroundNormal( void ) { return mGroundNormal; }; + + inline const U32 &getPhysicsState( void ) { return mPhysicsState; }; + inline void setPhysicsState( const U32 &pState ) { mPhysicsState = pState; }; + + virtual MatrixF getTransform( void ); + virtual void setTransform( const MatrixF &pTransform ); + + virtual Point3F getPosition( void ); + virtual void setPosition( const Point3F &pPosition ); + + inline VectorF getGravity( void ) { return mGravity; }; + inline void setGravity( VectorF &pGravity ) { mGravity = pGravity; }; + virtual void applyGravity( const F32 &pElapsedTime ); + + virtual VectorF getVelocity( void ); + virtual void setVelocity( const VectorF &pVelocity ); + + // Physics Methods. + + void update( const F32 &pDelta, const Move *pMove ); + + virtual void preTickUpdate( const F32 &pDelta ); + virtual void integrateTickUpdate( const F32 &pDelta, const Move *pMove ); + virtual void postTickUpdate( const F32 &pDelta ); + + void interpolateTick( const F32 &pDelta ); + + void updateWorkingCollisionSet( void ); + + void updateMoveState( void ); + + void clearGroundStatus( void ); + void updateGroundStatus( void ); + bool findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal ); + + void processCollisions( void ); + bool findCollision( Collision *&pCollision ); + void solveCollision( Collision *pCollision ); + + // Updates Methods. + + void onActorEvent( const VActor::eEventType &pEvent ); + + U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorPhysicsStates.h b/Engine/modules/Verve/VActor/VActorPhysicsStates.h new file mode 100644 index 000000000..24585b07a --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorPhysicsStates.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// 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_VACTORPHYSICSSTATES_H_ +#define _VT_VACTORPHYSICSSTATES_H_ + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSINGLETON_H_ +#include "core/util/tSingleton.h" +#endif + +//----------------------------------------------------------------------------- +struct Move; +//----------------------------------------------------------------------------- + +class VActorPhysicsState : public VActorState +{ +public: + + virtual void exit( VActor *pObject ) {}; + + virtual void processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ) = 0; +}; + +//----------------------------------------------------------------------------- + +#define DeclareActorPhysicsState( name ) \ + class VActor##name##PhysicsState : public VActorPhysicsState \ + { \ + public: \ + void enter( VActor *pObject ); \ + bool execute( VActor *pObject ); \ + void processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ); \ + } + +#define ActorPhysicsStateInstance( name ) \ + Singleton::instance() + +#define ImplementActorPhysicsState( name, state ) \ + void VActor##name##PhysicsState::enter( VActor *pObject ) { pObject->getPhysicsController()->setPhysicsState( state ); } + +#define ExecuteActorPhysicsState( name ) \ + bool VActor##name##PhysicsState::execute( VActor *pObject ) + +#define ProcessActorPhysicsState( name ) \ + void VActor##name##PhysicsState::processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ) + +//----------------------------------------------------------------------------- + +#endif // _VT_VACTORPHYSICSSTATES_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorStateTable.cpp b/Engine/modules/Verve/VActor/VActorStateTable.cpp new file mode 100644 index 000000000..a2c065ce7 --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorStateTable.cpp @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// 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 "VActorStateTable.h" +#include "VActor.h" + +//----------------------------------------------------------------------------- + +bool VActorStateTable::isRegisteredState( VActorState *pState ) +{ + for ( tStateConstIterator itr = mStateVector.begin(); itr != mStateVector.end(); itr++ ) + { + // Target State? + if ( ( *itr ).State == pState ) + { + // Yes. + return true; + } + } + + // No. + return false; +} + +void VActorStateTable::clear( void ) +{ + // Clear the States. + mLastState = NULL; + mCurrentState = NULL; + + // Clear the State Vector. + mStateVector.clear(); +}; + +void VActorStateTable::sort( void ) +{ + mStateVector.sort( &_onSortCallback ); +} + +void VActorStateTable::registerState( VActorState *pState, const F32 &pPriority ) +{ + // Already a State? + if ( isRegisteredState( pState ) ) + { + // Exit Now. + return; + } + + // Create the Reference. + sStateRef entry; + entry.State = pState; + entry.Priority = pPriority; + + // Push to Back. + mStateVector.push_back( entry ); + + // Set Current? + if ( mStateVector.size() == 1 ) + { + // Set State. + setState( pState ); + } +}; + +void VActorStateTable::setState( VActorState *pState ) +{ + if ( !mObject || !pState || pState == mCurrentState ) + { + // Invalid. + return; + } + + if ( mCurrentState ) + { + // Exit. + exit(); + + // Exit the Old State. + mCurrentState->exit( mObject ); + } + + // Update States. + mLastState = mCurrentState; + mCurrentState = pState; + + // Enter. + enter(); + + // Enter the New State. + pState->enter( mObject ); +}; + +VActorState *VActorStateTable::execute( void ) +{ + if ( !mObject || !mCurrentState ) + { + // Invalid. + return NULL; + } + + for ( tStateConstIterator itr = mStateVector.begin(); itr != mStateVector.end(); itr++ ) + { + // Fetch State Reference. + const sStateRef &stateRef = ( *itr ); + + // Enter State? + if ( stateRef.State->execute( mObject ) ) + { + // Set the State. + setState( stateRef.State ); + + // Return. + return stateRef.State; + } + } + + // No Valid Entries, Ouch! + Con::warnf( "VActorStateTable::execute() - No Valid Entries." ); + + // Return Current State. + return mCurrentState; +} + +S32 QSORT_CALLBACK VActorStateTable::_onSortCallback( const VActorStateTable::sStateRef *pA, const VActorStateTable::sStateRef *pB ) +{ + if ( pB->Priority > pA->Priority ) + { + return 1; + } + else if ( pB->Priority < pA->Priority ) + { + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VActorStateTable.h b/Engine/modules/Verve/VActor/VActorStateTable.h new file mode 100644 index 000000000..6a514a2fc --- /dev/null +++ b/Engine/modules/Verve/VActor/VActorStateTable.h @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------------- +// 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_VACTORSTATETABLE_H_ +#define _VT_VACTORSTATETABLE_H_ + +#ifndef _TVECTOR_H +#include "core/util/tVector.h" +#endif + +//----------------------------------------------------------------------------- +class VActor; +class VActorStateTable; +//----------------------------------------------------------------------------- + +class VActorState +{ +public: + + VActorState( void ) { }; + virtual ~VActorState( void ) { }; + + virtual void enter( VActor *pObject ) = 0; + virtual bool execute( VActor *pObject ) = 0; + virtual void exit( VActor *pObject ) = 0; +}; + +//----------------------------------------------------------------------------- + +class VActorStateTable +{ +public: + + struct sStateRef + { + VActorState *State; + F32 Priority; + }; + + typedef Vector tStateVector; + typedef tStateVector::iterator tStateIterator; + typedef tStateVector::const_iterator tStateConstIterator; + +protected: + + tStateVector mStateVector; + + VActor *mObject; + + VActorState *mLastState; + VActorState *mCurrentState; + +public: + + VActorStateTable( void ) : + mObject( NULL ), + mLastState( NULL ), + mCurrentState( NULL ) + { + VECTOR_SET_ASSOCIATION( mStateVector ); + }; + + virtual ~VActorStateTable( void ) + { + // Clear Table. + clear(); + }; + + void registerState( VActorState *pState, const F32 &pPriority = 0.5f ); + + virtual void enter( void ) { }; + virtual VActorState *execute( void ); + virtual void exit( void ) { }; + + //------------------------------------------------------------------------- + // + // Gets + // + //------------------------------------------------------------------------- + + inline VActor *getObject( void ) { return mObject; }; + + bool isRegisteredState( VActorState *pState ); + + inline VActorState *getCurrentState( void ) { return mCurrentState; }; + inline VActorState *getLastState( void ) { return mLastState; }; + + //------------------------------------------------------------------------- + // + // Sets + // + //------------------------------------------------------------------------- + + void clear( void ); + void sort( void ); + + inline void setObject( VActor *pObject ) { mObject = pObject; }; + void setState( VActorState *pState ); + + //------------------------------------------------------------------------- + // + // Accessors + // + //------------------------------------------------------------------------- + + tStateConstIterator begin( void ) const { return mStateVector.begin(); }; + tStateConstIterator end( void ) const { return mStateVector.end(); }; + S32 size( void ) const { return mStateVector.size(); }; + +protected: + + static S32 QSORT_CALLBACK _onSortCallback( const VActorStateTable::sStateRef *pA, const VActorStateTable::sStateRef *pB ); +}; + +#endif // _VT_VACTORSTATETABLE_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VActor/VInterpController.h b/Engine/modules/Verve/VActor/VInterpController.h new file mode 100644 index 000000000..3b9f34a1c --- /dev/null +++ b/Engine/modules/Verve/VActor/VInterpController.h @@ -0,0 +1,207 @@ +//----------------------------------------------------------------------------- +// 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_VINTERPCONTROLLER_H_ +#define _VT_VINTERPCONTROLLER_H_ + +#ifndef _MATH_H_ +#include "math/mMath.h" +#endif + +//----------------------------------------------------------------------------- + +class VInterpController +{ +protected: + + Point3F mPosition[2]; + QuatF mRotation[2]; + +public: + + //------------------------------------------------------------------------- + // Interpolation Methods. + //------------------------------------------------------------------------- + + /// Get Position. + Point3F getPosition( const F32 &pDelta ) + { + // Interpolate Position. + Point3F interpPosition; + interpPosition.interpolate( mPosition[1], mPosition[0], pDelta ); + // Return Interpolated Point. + return interpPosition; + }; + + /// Get Rotation. + QuatF getRotation( const F32 &pDelta ) + { + // Interpolate Rotation. + QuatF interpRotation; + interpRotation.interpolate( mRotation[1], mRotation[0], pDelta ); + // Return Interpolated Quat. + return interpRotation; + }; + + /// Get Transform. + MatrixF getTransform( const F32 &pDelta ) + { + // Get Position. + const Point3F interpPosition = getPosition( pDelta ); + // Get Rotation. + const QuatF interpRotation = getRotation( pDelta ); + + // Setup Matrix. + MatrixF transform; + interpRotation.setMatrix( &transform ); + // Set Position. + transform.setPosition( interpPosition ); + + // Return Matrix. + return transform; + }; + + //------------------------------------------------------------------------- + // Delta Methods. + //------------------------------------------------------------------------- + + /// Reset Delta. + void resetDelta( const Point3F &pPosition, const QuatF &pRotation ) + { + mPosition[0] = mPosition[1] = pPosition; + mRotation[0] = mRotation[1] = pRotation; + }; + + /// Reset Delta. + void resetDelta( const MatrixF &pMatrix ) + { + // Setup Quat. + QuatF rotationQuat( pMatrix ); + // Reset Delta. + resetDelta( pMatrix.getPosition(), rotationQuat ); + }; + + /// Reset Delta (Vector) + void resetDelta( const Point3F &pPosition, const VectorF &pForwardVector ) + { + // Assert. + AssertFatal( pForwardVector.isUnitLength(), "VInterpController::resetDelta() - Forward Vector hasn't been Normalized." ); + + // Static Up Vector. + static const VectorF sUpVector( 0.f, 0.f, 1.f ); + + // X-Axis. + VectorF xVec = mCross( pForwardVector, sUpVector ); + xVec.normalize(); + // Z-Axis. + VectorF zVec = mCross( xVec, pForwardVector ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF transform; + transform.setColumn( 0, xVec ); + transform.setColumn( 1, pForwardVector ); + transform.setColumn( 2, zVec ); + transform.setColumn( 3, pPosition ); + + // Reset Delta. + resetDelta( transform ); + }; + + /// Reset Delta (AngAxis) + void resetDelta( const Point3F &pPosition, const AngAxisF &pAngAxis ) + { + // Setup Matrix. + MatrixF transform; + pAngAxis.setMatrix( &transform ); + // Set Position. + transform.setPosition( pPosition ); + + // Reset Delta. + resetDelta( transform ); + }; + + /// Push Delta. + void pushDelta( const Point3F &pPosition, const QuatF &pRotation ) + { + mPosition[1] = pPosition; + mRotation[1] = pRotation; + }; + + /// Push Delta (Matrix) + void pushDelta( const MatrixF &pMatrix ) + { + // Setup Quat. + QuatF rotationQuat( pMatrix ); + // Push Delta. + pushDelta( pMatrix.getPosition(), rotationQuat ); + }; + + /// Push Delta (Vector) + void pushDelta( const Point3F &pPosition, const VectorF &pForwardVector ) + { + // Assert. + AssertFatal( pForwardVector.isUnitLength(), "VInterpController::pushDelta() - Forward Vector hasn't been Normalized." ); + + // Static Up Vector. + static const VectorF sUpVector( 0.f, 0.f, 1.f ); + + // X-Axis. + VectorF xVec = mCross( pForwardVector, sUpVector ); + xVec.normalize(); + // Z-Axis. + VectorF zVec = mCross( xVec, pForwardVector ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF transform; + transform.setColumn( 0, xVec ); + transform.setColumn( 1, pForwardVector ); + transform.setColumn( 2, zVec ); + transform.setColumn( 3, pPosition ); + + // Push Delta. + pushDelta( transform ); + }; + + /// Push Delta (AngAxis) + void pushDelta( const Point3F &pPosition, const AngAxisF &pAngAxis ) + { + // Setup Matrix. + MatrixF transform; + pAngAxis.setMatrix( &transform ); + // Set Position. + transform.setPosition( pPosition ); + + // Push Delta. + pushDelta( transform ); + }; + + /// Pop Delta. + void popDelta( void ) + { + mPosition[0] = mPosition[1]; + mRotation[0] = mRotation[1]; + }; +}; + +#endif // _VT_VINTERPCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VNetState.cpp b/Engine/modules/Verve/VPath/VNetState.cpp new file mode 100644 index 000000000..d08c2ea0d --- /dev/null +++ b/Engine/modules/Verve/VPath/VNetState.cpp @@ -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; + } +} \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VNetState.h b/Engine/modules/Verve/VPath/VNetState.h new file mode 100644 index 000000000..9cecef0a7 --- /dev/null +++ b/Engine/modules/Verve/VPath/VNetState.h @@ -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 Connection; + U32 Mask; + + VNetStateInfo( void ) : + Connection( NULL ), + Mask( 0 ) + { + // Void. + }; + + VNetStateInfo( NetConnection *pConnection, U32 pMask ) + { + Connection = pConnection; + Mask = pMask; + }; +}; + +//----------------------------------------------------------------------------- + +class VNetState : public Vector +{ +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_ \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPath.cpp b/Engine/modules/Verve/VPath/VPath.cpp new file mode 100644 index 000000000..762055cca --- /dev/null +++ b/Engine/modules/Verve/VPath/VPath.cpp @@ -0,0 +1,3452 @@ +//----------------------------------------------------------------------------- +// 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 "VPath.h" + +#include "console/consoleTypes.h" +#include "core/iTickable.h" +#include "core/stream/bitStream.h" +#include "math/mMathFn.h" +#include "math/mathIO.h" + +//----------------------------------------------------------------------------- + +// Uncomment this definition to debug the network information. +//#define VPATH_DEBUG_NET + +// Uncomment this definition to debug the time step information +//#define VPATH_DEBUG_STEP + +//----------------------------------------------------------------------------- + +SimObjectPtr VPath::gServerSet = NULL; + +U32 VPath::gMaxNodeTransmit = 16; +U32 VPath::gMaxNodeBits = 8; +U32 VPath::gMaxNodeCount = 1 << gMaxNodeBits; // 256 + +U32 VPath::gMaxObjectTransmit = 4; +U32 VPath::gMaxObjectBits = 4; +U32 VPath::gMaxObjectCount = 1 << gMaxObjectBits; // 16 + +Point3F VPath::gBezierAxis( 0.f, 1.f, 0.f ); +Point3F VPath::gBezierUp( 0.f, 0.f, 1.f ); + +//----------------------------------------------------------------------------- + +static U32 gPathTypeBits = getBinLog2( getNextPow2( VPath::k_PathTypeSize ) ); +static F32 gBezierInterpStep = 0.0001f; + +//----------------------------------------------------------------------------- +// Path Type Table. +//----------------------------------------------------------------------------- + +// Implement the Path Type enum list. +ImplementEnumType( VPathType, "" ) + { VPath::k_PathBezier, "BEZIER" }, + { VPath::k_PathLinear, "LINEAR" }, +EndImplementEnumType; + +static VPath::ePathType getPathTypeEnum( const char *pLabel ) +{ + VPath::ePathType out; + if ( !castConsoleTypeFromString( out, pLabel ) ) + { + // Bah! + return VPath::k_PathInvalid; + } + + // Return. + return out; +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VPath ); +//----------------------------------------------------------------------------- + +VPath::VPath( void ) : + mPathType( k_PathBezier ) +{ + // Marker Type. + mTypeMask = MarkerObjectType; + + // Ghost & Scope. + mNetFlags.set( Ghostable | ScopeAlways ); + + // Process Ticks. + setProcessTick( true ); + + VECTOR_SET_ASSOCIATION( mNodeList ); + VECTOR_SET_ASSOCIATION( mObjectList ); +} + +VPath::~VPath( void ) +{ + // Void. +} + +bool VPath::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + // Add to Scene. + addToScene(); + + if ( isServerObject() ) + { + // Read Fields. + readFields(); + + // Add to Set. + getServerSet()->addObject( this ); + } + + return true; +} + +void VPath::onDeleteNotify( SimObject *pObject ) +{ + // Parent Notify. + Parent::onDeleteNotify( pObject ); + + if ( SceneObject *sceneObject = dynamic_cast( pObject ) ) + { + // Detach Object. + detachObject( sceneObject ); + + // Exit. + return; + } + + if ( NetConnection *connection = dynamic_cast( pObject ) ) + { + // Clear Connection References. + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Erase Connection. + ( *itr )->clearConnection( connection ); + } + + // Exit. + return; + } +} + +void VPath::onRemove( void ) +{ + // Remove From Scene. + removeFromScene(); + + // Clear Everything. + clear(); + + Parent::onRemove(); +} + +void VPath::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "PathType", TYPEID(), Offset( mPathType, VPath ), &setPathType, &defaultProtectedGetFn, "The type of path this is." ); +} + +SimSet *VPath::getServerSet( void ) +{ + if ( !gServerSet ) + { + gServerSet = new SimSet(); + gServerSet->registerObject( "ServerPathSet" ); + Sim::getRootGroup()->addObject( gServerSet ); + } + + return gServerSet; +} + +ConsoleFunction( getServerPathSet, int, 1, 1, "( void )" ) +{ + return VPath::getServerSet()->getId(); +} + +//----------------------------------------------------------------------------- +// +// Editor Methods. +// +//----------------------------------------------------------------------------- + +bool VPath::collideBox( const Point3F &pStart, const Point3F &pEnd, RayInfo* pInfo ) +{ + if ( mObjBox.isContained( pStart ) ) + { + pInfo->t = 0.f; + pInfo->object = this; + pInfo->normal = VectorF( 0.f, 0.f, 1.f ); + pInfo->material = NULL; + + return true; + } + + return Parent::collideBox( pStart, pEnd, pInfo ); +} + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +F32 VPath::getUpdatePriority( CameraScopeQuery *pFocusObject, U32 pUpdateMask, S32 pUpdateSkips ) +{ + if ( mObjectList.size() > 0 ) + { + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Fetch Object. + VPathObject *pathObject = ( *itr ); + if ( pathObject->isActive() ) + { + // High Priority. + return 100.f; + } + } + } + + // Normal Priority. + return 0.f; +} + +void VPath::updateContainer( void ) +{ + if ( mNodeList.size() == 0 ) + { + // Sanity!. + return; + } + + // Init Min / Max. + mObjBox.minExtents = ( mNodeList[0]->getLocalPosition() ); + mObjBox.maxExtents = mObjBox.minExtents; + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Node Position. + const Point3F &nodeLocalPosition = node->getLocalPosition(); + + // Update Object Box. + mObjBox.minExtents.setMin( nodeLocalPosition ); + mObjBox.maxExtents.setMax( nodeLocalPosition ); + } + + // Adjust. + mObjBox.minExtents -= Point3F( 1.f, 1.f, 1.f ); + mObjBox.maxExtents += Point3F( 1.f, 1.f, 1.f ); + + // Reset Box. + resetWorldBox(); + resetRenderWorldBox(); +} + +void VPath::updateNodeTransforms( void ) +{ + // Fetch Transform Details. + const MatrixF &pathTransform = getTransform(); + const QuatF &pathRotation( pathTransform ); + const VectorF &pathScale = getScale(); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Fetch Node Spatials. + const Point3F &nodePosition = node->getLocalPosition(); + const QuatF &nodeRotation = node->getLocalRotation(); + + // Calculate the new Position. + Point3F newPosition = nodePosition; + newPosition.convolve( pathScale ); + pathTransform.mulP( newPosition ); + + // Calculate the new Rotation. + QuatF newRotation; + newRotation.mul( nodeRotation, pathRotation ); + + // Apply. + node->setWorldPosition( newPosition ); + node->setWorldRotation( newRotation ); + } +} + +void VPath::setTransform( const MatrixF &pMatrix ) +{ + // Parent Call. + Parent::setTransform( pMatrix ); + + // Update Nodes. + updateNodeTransforms(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +void VPath::setScale( const VectorF &pScale ) +{ + // Parent Call. + Parent::setScale( pScale ); + + // Update Nodes. + updateNodeTransforms(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +ConsoleMethod( VPath, setPathType, void, 3, 3, "( string pPathType ) - The path type dictates how attached objects move between nodes. There are currently two supported path types, \"BEZIER\" and \"LINEAR\".\n" + "@return No return value." ) +{ + // Fetch Enum. + const VPath::ePathType &type = getPathTypeEnum( argv[2] ); + + // Update. + object->setPathType( type ); +} + +void VPath::setPathType( const ePathType &pType ) +{ + // Apply Value. + mPathType = pType; + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +bool VPath::setPathType( void *pObject, const char *pArray, const char *pData ) +{ + // Apply Type. + static_cast( pObject )->setPathType( getPathTypeEnum( pData ) ); + return false; +} + +//----------------------------------------------------------------------------- +// +// Mounting Methods. +// +//----------------------------------------------------------------------------- + +bool VPath::isMountIndex( const U32 &pIndex ) +{ + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + // Yes. + return true; + } + } + + // No. + return false; +} + +U32 VPath::getAvailableMountIndex( void ) +{ + U32 i = 0; + while( isMountIndex( i ) ) + { + // Increment. + i++; + } + + // Return Index. + return i; +} + +void VPath::mountObject( SceneObject *pObject, S32 pIndex, const MatrixF &pTransform ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::mountObject() %d | %d, IsAttached %d", isServerObject(), pObject->getId(), isObjectAttached( pObject ) ); +#endif + + // Attached? + if ( !isObjectAttached( pObject ) ) + { + if ( isServerObject() ) + { + // Shouldn't Use this Method. + Con::warnf( "VPath::mountObject() - Use 'attachObject' instead." ); + } + + // Not Attached. + return; + } + + // Parent Call. + Parent::mountObject( pObject, pIndex, pTransform ); + + // Clear the mounted mask. + // Note: This is so that we send the mounting information via the VPath + // packets instead of letting T3D handle it. + pObject->clearMaskBits( SceneObject::MountedMask ); +} + +void VPath::unmountObject( SceneObject *pObject ) +{ + // Fetch Path Object. + VPathObject *pathObject = getPathObject( pObject ); + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::unmountObject() %d | %d, IsAttached %d", isServerObject(), pObject->getId(), pathObject != NULL ); +#endif + + // Valid? + if ( !pathObject || pObject->getObjectMount() != this ) + { + // Warn. + Con::warnf( "VPath::unmountObject() - Object is not attached to this Path. %d", pObject->getId() ); + // Not Mounted Here! + return; + } + + // Parent Call. + Parent::unmountObject( pObject ); + + // Clear the mounted mask. + // Note: This is so that we send the mounting information via the VPath + // packets instead of letting T3D handle it. + pObject->clearMaskBits( SceneObject::MountedMask ); +} + +void VPath::getMountTransform( S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Reset Transform. + *pTransform = pInTransform; + // Sanity! + return; + } + + // Advance the Object. + advanceObject( pathObject, TickSec ); + + // Apply Transform. + *pTransform = pathObject->getTransform(); +} + +void VPath::getRenderMountTransform( F32 pDelta, S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Reset Transform. + *pTransform = pInTransform; + // Sanity! + return; + } + + // Apply Transform. + *pTransform = pathObject->getRenderTransform( pDelta ); +} + +VectorF VPath::getMountVelocity( const U32 &pIndex ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Sanity! + return VectorF::Zero; + } + + // Determine Velocity. + return ( pathObject->getOrientation() * pathObject->getSpeed() ); +} + +//----------------------------------------------------------------------------- +// +// Persistence Methods. +// +//----------------------------------------------------------------------------- + +void VPath::readFields( void ) +{ + const char *nodeData = ""; + for ( S32 nodeIndex = 0; dStrcmp( nodeData = getDataField( StringTable->insert( avar( "Node%d", nodeIndex ) ), NULL ), "" ) != 0; nodeIndex++ ) + { + // Create Node. + VPathNode *node = createNode(); + // Deserialize the Node. + node->fromString( nodeData ); + // Add the Node. + addNode( node ); + + // Clear Field. + setDataField( StringTable->insert( avar( "Node%d", nodeIndex ) ), NULL, "" ); + } + + // Update Transforms. + updateNodeTransforms(); + + // Update Size. + updateContainer(); + + // Calculate Path. + calculatePath(); +} + +void VPath::writeFields( Stream &pStream, U32 pTabStop ) +{ + // Field Name. + StringTableEntry fieldName = StringTable->insert( "node" ); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Set Field. + setDataField( fieldName, avar( "%d" , ( itr - mNodeList.begin() ) ), ( *itr )->toString().c_str() ); + } + + // Write Fields. + Parent::writeFields( pStream, pTabStop ); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Clear Field. + setDataField( fieldName, avar( "%d" , ( itr - mNodeList.begin() ) ), "" ); + } +} + +U32 VPath::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + U32 retMask = Parent::packUpdate( pConnection, pMask, pStream ); + + if ( pMask & InitialUpdateMask ) + { + // Delete Notify. + deleteNotify( pConnection ); + } + + if ( pStream->writeFlag( pMask & PathUpdateMask ) ) + { + // Write Path Type. + pStream->writeInt( mPathType, gPathTypeBits ); + + // Write Transform. + mathWrite( *pStream, mObjToWorld ); + // Write Scale. + mathWrite( *pStream, mObjScale ); + } + + if ( pStream->writeFlag( pMask & NodeUpdateMask ) ) + { + // Path needs recalculating? + bool needsCalculating = false; + + // Delete Vector. + Vector deleteVector; + // Update Vector. + Vector updateVector; + + for ( U32 i = 0; i < mNodeList.size(); i++ ) + { + // Fetch Node. + VPathNode *node = mNodeList[i]; + + // Already In Map? + if ( !node->isConnection( pConnection ) ) + { + // Insert. + node->addConnection( pConnection ); + } + + // Fetch State. + VNetStateInfo *state = node->getState( pConnection ); + + // Delete new node? + if ( state->Mask & VPathNode::k_StateDelete + && state->Mask & VPathNode::k_StateCreate ) + { + // Remove Node. + removeNode( i-- ); + // Flag true. + needsCalculating = true; + } + + // Delete? + else if ( state->Mask & VPathNode::k_StateDelete ) + { + // Add To List. + deleteVector.push_front( i ); + } + + // Update? + else if ( state->Mask & VPathNode::k_StateUpdate ) + { + if ( updateVector.size() < gMaxNodeTransmit ) + { + // Add To List. + updateVector.push_back( i ); + } + } + } + + // More Updates? + if ( updateVector.size() == gMaxNodeTransmit ) + { + // More Updates. + retMask |= NodeUpdateMask; + } + + // Write Count. + pStream->writeInt( updateVector.size(), gMaxNodeBits + 1 ); + + for ( Vector::iterator itr = updateVector.begin(); itr != updateVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxNodeBits ); + // Pack Update. + retMask |= mNodeList[index]->packNode( pConnection, pStream ); + } + + // Write Count. + pStream->writeInt( deleteVector.size(), gMaxNodeBits + 1 ); + + if ( deleteVector.size() > 0 ) + { + for ( Vector::iterator itr = deleteVector.begin(); itr != deleteVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxNodeBits ); + // Remove Node. + removeNode( index ); + } + + // Flag true. + needsCalculating = true; + // Clear Vector. + deleteVector.clear(); + } + + // Recalculate path? + if ( needsCalculating ) + { + // Update Size. + updateContainer(); + // Calculate Path. + calculatePath(); + } + } + + if ( pStream->writeFlag( pMask & ObjectUpdateMask ) ) + { + // Detach Vector. + Vector detachVector; + // Update Vector. + Vector updateVector; + + for ( U32 i = 0; i < mObjectList.size(); i++ ) + { + // Fetch Node. + VPathObject *pathObject = mObjectList[i]; + + // Already In Map? + if ( !pathObject->isConnection( pConnection ) ) + { + // Insert. + pathObject->addConnection( pConnection ); + } + + // Fetch State. + VNetStateInfo *state = pathObject->getState( pConnection ); + + // Detach newly attached object? + if ( state->Mask & VPathObject::k_StateAttach + && state->Mask & VPathObject::k_StateDetach ) + { + // Process Detach. + onDetachObject( pathObject ); + // Decrease index. + i -= 1; + + // Skip. + continue; + } + + // Update? + if ( state->Mask & VPathObject::k_StateUpdate ) + { + if ( updateVector.size() < gMaxObjectTransmit ) + { + // Add To List. + updateVector.push_back( i ); + } + } + + // Detach? + if ( state->Mask & VPathObject::k_StateDetach ) + { + // Add To List. + detachVector.push_front( i ); + } + } + + // More Updates? + if ( updateVector.size() == gMaxObjectTransmit ) + { + // More Updates. + retMask |= ObjectUpdateMask; + } + + // Write Count. + pStream->writeInt( updateVector.size(), gMaxObjectBits + 1 ); + + for ( Vector::iterator itr = updateVector.begin(); itr != updateVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxObjectBits ); + + // Fetch the object. + VPathObject *pathObject = mObjectList[index]; + // Fetch State. + VNetStateInfo *state = pathObject->getState( pConnection ); + + // Was the Object Attached? + if ( pStream->writeFlag( state->Mask & VPathObject::k_StateAttach ) ) + { +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::packUpdate() - Attached - %d | %d", isServerObject(), index ); +#endif + + // Clear Update. + state->Mask &= ~VPathObject::k_StateAttach; + } + + // Pack Object. + retMask |= mObjectList[index]->packUpdate( pConnection, pStream ); + } + + // Write Count. + pStream->writeInt( detachVector.size(), gMaxObjectBits + 1 ); + + if ( detachVector.size() > 0 ) + { + for ( Vector::iterator itr = detachVector.begin(); itr != detachVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + // Write Index. + pStream->writeInt( index, gMaxObjectBits ); + // Process Detach. + onDetachObject( mObjectList[index] ); + } + + // Clear Vector. + detachVector.clear(); + } + } + + // Return. + return retMask; +} + +void VPath::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + Parent::unpackUpdate( pConnection, pStream ); + + // Update Path? + if ( pStream->readFlag() ) + { + // Read Path Type. + mPathType = pStream->readInt( gPathTypeBits ); + + // Read Transform. + mathRead( *pStream, &mObjToWorld ); + // Read Scale. + mathRead( *pStream, &mObjScale ); + + // Update Nodes. + updateNodeTransforms(); + // Calculate Path. + calculatePath(); + } + + // Update Nodes? + if ( pStream->readFlag() ) + { + // Number To Update. + const U32 updateCount = pStream->readInt( gMaxNodeBits + 1 ); + + for ( U32 i = 0; i < updateCount; i++ ) + { + // Read Index. + const U32 nodeIndex = pStream->readInt( gMaxNodeBits ); + + // Was the Node Created? + if ( pStream->readFlag() ) + { + // Create Node. + VPathNode *node = createNode(); + // Add the Node. + addNode( node, nodeIndex ); + } + + // Reference Node. + VPathNode *node = mNodeList[nodeIndex]; + // Apply Update. + node->unpackNode( pConnection, pStream ); + } + + // Number To Delete. + const U32 deleteCount = pStream->readInt( gMaxNodeBits + 1 ); + + for ( U32 i = 0; i < deleteCount; i++ ) + { + // Remove Node. + removeNode( pStream->readInt( gMaxNodeBits ) ); + } + + // Update Size. + updateContainer(); + // Calculate Path. + calculatePath(); + } + + // Update Objects? + if ( pStream->readFlag() ) + { + // Number To Update. + const U32 updateCount = pStream->readInt( gMaxObjectBits + 1 ); + + for ( U32 i = 0; i < updateCount; i++ ) + { + // Read Index. + const U32 objectIndex = pStream->readInt( gMaxObjectBits ); + + // Read Attached. + // Note: The editor handles the both the server and client side attachment calls. + // This is dangerous because there could be a mix up in indices, but it is + // needed to ensure the editor runs smoothly :( + const bool wasAttached = pStream->readFlag(); + if ( wasAttached && objectIndex >= mObjectList.size() ) + { +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::unpackUpdate() - WasAttached - %d | %d", isServerObject(), objectIndex ); +#endif + + // Create & Add to the List. + attachObject( new VPathObject() ); + } + + // Reference Node. + VPathObject *pathObject = mObjectList[objectIndex]; + + // Unpack Update. + pathObject->unpackUpdate( pConnection, pStream ); + + // Object Attached this Unpack? + if ( wasAttached ) + { + // Reset. + setPathObjectInterp( pathObject, pathObject->getTimeInterp() ); + } + } + + // Number To Detach. + const U32 detachCount = pStream->readInt( gMaxObjectBits + 1 ); + + for ( U32 i = 0; i < detachCount; i++ ) + { + // Fetch the path object. + VPathObject *pathObject = mObjectList[pStream->readInt( gMaxObjectBits )]; + // Detach callback. + onDetachObject( pathObject ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Node Methods. +// +//----------------------------------------------------------------------------- + +VPathNode *VPath::createNode( void ) +{ + return new VPathNode(); +} + +void VPath::deleteNode( VPathNode *pNode ) +{ + delete pNode; +} + +void VPath::clear( void ) +{ + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + VPathObject *pathObject = ( *itr ); + + // Fetch the attached object. + SceneObject *refObject = pathObject->getObject(); + // Unmount Object. + unmountObject( refObject ); + + // Delete the Path Object. + delete pathObject; + } + + // Clear Object List. + mObjectList.clear(); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + deleteNode( ( *itr ) ); + } + + // Clear Node List. + mNodeList.clear(); + + if ( isServerObject() ) + { + // Update. + setMaskBits( NodeUpdateMask ); + } +} + +VPathNode *VPath::getNode( const S32 &pNodeIndex ) +{ + // Sanity! + AssertFatal( pNodeIndex >= 0 && pNodeIndex < mNodeList.size(), "VPath::getNode() - Invalid Index" ); + + // Return Node. + return mNodeList[pNodeIndex]; +} + +ConsoleMethod( VPath, addNode, void, 4, 5, "( transform pTransform, float pWeight, [int pLocation] ) - Add a node with the given properties. Nodes represent physical points that attached objects move towards or between, but the PathType determines \"how\" they move between them.\n" + "@param pTransform The position and rotation of the new node.\n" + "@param pWeight The weight of the new node.\n" + "@param pLocation The index of the new node.\n" + "@return No return value.") +{ + // Fetch Invers Path Transform. + MatrixF pathTransformInv = object->getTransform(); + pathTransformInv.setPosition( Point3F::Zero ); + pathTransformInv.inverse(); + + Point3F pos; + QuatF rot; + AngAxisF aa; + + // Scan. + dSscanf( argv[2], "%g %g %g %g %g %g %g", &pos.x, &pos.y, &pos.z, &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle ); + + // Set Rotation. + rot.set( aa ); + + // Weight. + F32 weight = dAtof( argv[3] ); + + // World to Local Position. + Point3F nodePosition = ( pos - object->getPosition() ); + pathTransformInv.mulP( nodePosition ); + + // World to Local Rotation. + MatrixF nodeRotationMat; + rot.setMatrix( &nodeRotationMat ); + pathTransformInv.mul( nodeRotationMat ); + + // Set Quat. + QuatF nodeRotation; + nodeRotation.set( nodeRotationMat ); + + S32 location = -1; + if ( argc >= 5 ) + { + // Target Location. + location = dAtoi( argv[4] ); + } + + // Add Node. + VPathNode *node = object->addNode( nodePosition, nodeRotation, weight, location ); + + // Valid Node? + if ( node ) + { + // Update Size. + object->updateContainer(); + + // Calculate Path. + object->calculatePath(); + } +} + +VPathNode *VPath::addNode( const Point3F &pPosition, const QuatF &pRotation, const F32 &pWeight, const S32 &pLocation ) +{ + // Reference Object. + VPathNode *pathNode = createNode(); + + // Store Properties. + pathNode->setLocalPosition( pPosition ); + pathNode->setLocalRotation( pRotation ); + pathNode->setWeight( pWeight ); + + // Add Node. + return addNode( pathNode, pLocation ); +} + +VPathNode *VPath::addNode( VPathNode *pNode, const S32 &pLocation ) +{ + if ( pNode->getPath() ) + { + // Error. + Con::errorf( "VPath::addNode() - Node already belongs to a Path, '%d'", pNode->getPath()->getId() ); + + return NULL; + } + else if ( mNodeList.size() == gMaxNodeCount ) + { + // Error. + Con::errorf( "VPath::addNode() - Reached Max Nodes (%d)", gMaxNodeCount ); + + // Delete Node. + deleteNode( pNode ); + + return NULL; + } + + // Set Path. + pNode->setPath( this ); + + // Update World Data. + pNode->updateWorldData(); + + if ( pLocation < 0 ) + { + // Push Back. + mNodeList.push_back( pNode ); + } + else + { + // Fetch Size. + const S32 nodeCount = mNodeList.size(); + + if ( pLocation >= nodeCount ) + { + // Push Back. + mNodeList.push_back( pNode ); + } + else + { + // Insert. + mNodeList.insert( ( mNodeList.address() + pLocation ), pNode ); + } + } + + if ( isServerObject() ) + { + // Update. + setMaskBits( NodeUpdateMask ); + } + + // Return Node. + return pNode; +} + +ConsoleMethod( VPath, deleteNode, void, 3, 3, "( int pNodeIndex ) - Delete the node with the given index. If you delete a node that an attached object is moving to, or from then the object's movement will adjust so that it has a valid path.\n" + "@param pNodeIndex The index of the node to be deleted.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Apply Update. + object->deleteNode( nodeIndex ); +} + +void VPath::deleteNode( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::deleteNode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Remove Node References. + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Fetch Object. + VPathObject *pathObject = ( *itr ); + + if ( ( pathObject->getSourceNode() >= pNodeIndex ) || ( pathObject->getDestinationNode() >= pNodeIndex ) ) + { + S32 srcNode = pathObject->getSourceNode(); + S32 dstNode = pathObject->getDestinationNode(); + + if ( pathObject->isForward() ) + { + if ( srcNode >= pNodeIndex ) + { + srcNode -= 1; + } + + if ( dstNode > pNodeIndex ) + { + dstNode -= 1; + } + } + else + { + if ( srcNode > pNodeIndex ) + { + srcNode -= 1; + } + + if ( dstNode >= pNodeIndex ) + { + dstNode -= 1; + } + } + + // Normalize indices. + normalizeNodeIndex( srcNode, ( mNodeList.size() - 1 ) ); + normalizeNodeIndex( dstNode, ( mNodeList.size() - 1 ) ); + + // Apply Update. + pathObject->setNode( srcNode, dstNode ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + } + } + } + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + + // Flag for Deletion. + node->setMaskBits( VPathNode::k_StateDelete ); + } +} + +void VPath::removeNode( const S32 &pNodeIndex ) +{ + // Fetch the node. + VPathNode *node = getNode( pNodeIndex ); + if ( !node ) + { + // Quit. + return; + } + + // Delete Node. + deleteNode( node ); + // Erase Node. + mNodeList.erase( pNodeIndex ); +} + +S32 VPath::normalizeNodeIndex( S32 &pNodeIndex ) +{ + const S32 nodeCount = mNodeList.size(); + if ( nodeCount == 0 ) + { + // No Nodex. + pNodeIndex = 0; + } + else + { + while ( pNodeIndex < 0 ) + { + // Wrap Backwards. + pNodeIndex += nodeCount; + } + + // Wrap Forwards. + pNodeIndex %= nodeCount; + } + + // Return Index. + return pNodeIndex; +} + +S32 VPath::normalizeNodeIndex( const S32 &pNodeIndex ) +{ + // Temp. + S32 nodeIndex = pNodeIndex; + + // Return Index. + return normalizeNodeIndex( nodeIndex ); +} + +S32 VPath::normalizeNodeIndex( S32 &pNodeIndex, const S32 &pNodeCount ) +{ + if ( pNodeCount == 0 ) + { + // No Nodex. + pNodeIndex = 0; + } + else + { + while ( pNodeIndex < 0 ) + { + // Wrap Backwards. + pNodeIndex += pNodeCount; + } + + // Wrap Forwards. + pNodeIndex %= pNodeCount; + } + + // Return Index. + return pNodeIndex; +} + +//----------------------------------------------------------------------------- +// +// Object Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VPath, isObjectAttached, bool, 3, 3, "( SimObject pObject ) - Is the object attached to this path?\n" + "@param pObject The SimObjectID of the object you wish to check.\n" + "@return Returns true if the object is attached to this path." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::isObjectAttached() - Invalid Target Object." ); + return false; + } + + // Attached? + return object->isObjectAttached( sceneObject ); +} + +bool VPath::isObjectAttached( SceneObject *pObject ) +{ + // Valid Object? + return ( getPathObject( pObject ) != NULL ); +} + +VPathObject *VPath::getPathObject( SceneObject *pObject ) +{ + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Correct Object? + if ( ( *itr )->getObject() == pObject ) + { + // Yes. + return ( *itr ); + } + } + + return NULL; +} + +ConsoleMethod( VPath, attachObject, void, 7, 8, "( SimObject pObject, bool pForward, float pSpeed, bool pRelative, int pStartNode, [int pEndNode] ) - Attach an object to this path with the given properties. If the object is already attached to a path, then a warning will be displayed and the object will *not* be attached to this path.\n" + "@param pObject The SimObjectID of the object to be attached.\n" + "@param pForward Should the object be moving forward?\n" + "@param pSpeed The speed that the object will travel around the path.\n" + "@param pRelative Offset the object based on the difference between the start node and its current position.\n" + "@param pStartNode The index of the node this object starts pathing from.\n" + "@param pEndNode The index of the node this object will stop pathing at." + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::attachObject() - Invalid Target Object." ); + return; + } + + // Fetch Direction. + const bool forward = dAtob( argv[3] ); + // Fetch Speed. + const F32 speed = dAtof( argv[4] ); + // Fetch Relativity. + const bool relative = dAtob( argv[5] ); + // Fetch Start Node. + const S32 startNode = dAtoi( argv[6] ); + // Fetch End Node. + const S32 endNode = ( argc >= 8 ) ? dAtoi( argv[7] ) : -1; + + // Attach Object. + object->attachObject( sceneObject, forward, speed, relative, startNode, endNode ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode ) +{ + attachObject( pObject, pForward, pSpeed, pRelative, pStartNode, pEndNode, VPathObject::k_OrientationToPath, NULL ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode ) +{ + attachObject( pObject, pForward, pSpeed, pRelative, pStartNode, pEndNode, pOrientationMode, NULL ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode, void *pOrientationData ) +{ + // Already Pathing? + if ( isObjectAttached( pObject ) ) + { + Con::warnf( "VPath::attachObject() - Object Already Attached to a Path." ); + return; + } + + // Determine Target Nodes. + const S32 srcNode = normalizeNodeIndex( pStartNode ); + const S32 dstNode = normalizeNodeIndex( ( pForward ) ? pStartNode + 1 : pStartNode - 1 ); + const S32 endNode = ( pEndNode == -1 ) ? pEndNode : normalizeNodeIndex( pEndNode ); + + // Valid Source Node? + if ( getNodeCount() == 0 || !getNode( srcNode ) ) + { + Con::warnf( "VPath::attachObject() - Invalid Start Node." ); + return; + } + + VPathObject *pathObject = new VPathObject(); + + // Init Properties. + pathObject->setActive( true ); + pathObject->setObject( pObject ); + + pathObject->setForward( pForward ); + + pathObject->setTimeInterp( 0.f ); + pathObject->setPathInterp( 0.f ); + pathObject->setOffset( Point3F::Zero ); + pathObject->setSpeed( pSpeed ); + + switch( pOrientationMode ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + pathObject->setOrientationMode( pOrientationMode ); + + } break; + + case VPathObject::k_OrientationToObject : + { + pathObject->setOrientationMode( pOrientationMode, (SceneObject*)pOrientationData ); + + } break; + + case VPathObject::k_OrientationToPoint : + { + pathObject->setOrientationMode( pOrientationMode, ( *(Point3F*)pOrientationData ) ); + + } break; + } + + pathObject->setNode( srcNode, dstNode ); + pathObject->setStartNode( srcNode ); + pathObject->setEndNode( endNode ); + + // Fetch Init Node. + VPathNode *node = mNodeList[srcNode]; + + // Relative Position? + if ( pRelative ) + { + // Set Position Offset. + pathObject->setOffset( pObject->getPosition() - node->getWorldPosition() ); + } + + // Set info. + setPathObjectInterp( pathObject, 0.f ); + + // Attach. + attachObject( pathObject ); +} + +void VPath::attachObject( VPathObject *pPathObject ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::attachObject() - %d", isServerObject() ); +#endif + + if ( mObjectList.size() == gMaxObjectCount ) + { + Con::errorf( "VPath::attachObject() - Reached Max Objects (%d)", gMaxObjectCount ); + return; + } + + // Add to List. + mObjectList.push_back( pPathObject ); + + // Callback. + onAttachObject( pPathObject ); + + if ( isServerObject() ) + { + // Update. + setMaskBits( ObjectUpdateMask ); + } +} + +void VPath::onAttachObject( VPathObject *pPathObject ) +{ + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject ) + { + return; + } + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::onAttachObject() - %d | %d", isServerObject(), refObject->getId() ); +#endif + + // Delete Notify. + deleteNotify( refObject ); + + if ( isServerObject() ) + { + // Fetch the Available Mount Index. + U32 mountIndex = getAvailableMountIndex(); + // Mount the Object to this Path. + mountObject( refObject, mountIndex ); + + // Return Buffer. + char buffer[1][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + + // Callback. + // VPath::onAttachObject( %object ); + Con::executef( this, "onAttachObject", buffer[0] ); + } +} + +ConsoleMethod( VPath, detachObject, void, 3, 3, "( SimObject pObject ) - Detach the object from this path in place.\n" + "@param pObject The SimObjectID of the object to be detached.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::detachObject() - Invalid Target Object." ); + return; + } + + // Detach Object. + object->detachObject( sceneObject ); +} + +void VPath::detachObject( SceneObject *pObject ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::detachObject() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Detach. + detachObject( pathObject ); +} + +void VPath::detachObject( VPathObject *pPathObject ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::detachObject() - %d", isServerObject() ); +#endif + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Detach. + pPathObject->setMaskBits( VPathObject::k_StateDetach ); + } + + /* + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( refObject ) + { + // Unmount Object. + unmountObject( refObject ); + } + */ +} + +void VPath::onDetachObject( VPathObject *pPathObject ) +{ + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject ) + { + return; + } + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::onDetachObject() - %d | %d", isServerObject(), refObject->getId() ); +#endif + + // Reset. + setPathObjectInterp( pPathObject, pPathObject->getTimeInterp() ); + // Unmount Object. + unmountObject( refObject ); + + // Delete the Path Object. + delete pPathObject; + // Remove from the Set. + mObjectList.erase( mObjectList.find_next( pPathObject ) ); + + // Clear Delete Notify. + clearNotify( refObject ); + + if ( isServerObject() ) + { + // Return Buffer. + char buffer[1][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + + // Callback. + // VPath::onDetachObject( %object ); + Con::executef( this, "onDetachObject", buffer[0] ); + } +} + +void VPath::processTick( const Move *pMove ) +{ +} + +void VPath::advanceObject( VPathObject *pPathObject, const F32 &pDelta ) +{ + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject || mIsZero( pDelta ) ) + { + // Ignore. + return; + } + + // Spatial Delta. + pPathObject->popDelta(); + + // Active and Moving? + if ( !pPathObject->isActive() || mIsZero( pPathObject->getSpeed() ) ) + { + // Update Delta. + pPathObject->pushDelta( refObject->getPosition(), refObject->getTransform().getForwardVector() ); + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + VPathNode *lenNode = ( pPathObject->isForward() ) ? srcNode : dstNode; + + // Calculate Interp Delta. + const F32 stepDistance = ( pPathObject->getSpeed() * pDelta ); + const F32 speedMod = ( pPathObject->getSpeed() / lenNode->getLength() ); + F32 timeInterp = pPathObject->getTimeInterp(); + F32 timeInterpDelta = ( speedMod * pDelta ); + F32 pathInterp = pPathObject->getPathInterp(); + F32 pathInterpDelta = 0.f; + + // Fetch the old position. + const Point3F oldPosition = pPathObject->getPosition(); + // Calculate the new position and path delta. + Point3F newPosition = getAdvancedPathPosition( pPathObject, stepDistance, pathInterpDelta ); + + // Finished? + if ( ( timeInterp + timeInterpDelta ) >= 1.f ) + { + // Finished? + if ( pPathObject->getDestinationNode() == pPathObject->getEndNode() ) + { + // Stop Updates. + pPathObject->setActive( false ); + } + else + { + // Update Nodes. + const S32 srcNodeIndex = pPathObject->getDestinationNode(); + const S32 dstNodeIndex = normalizeNodeIndex( ( pPathObject->isForward() ) ? srcNodeIndex + 1 : srcNodeIndex - 1 ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::errorf( "Change Node:\n Source, %d\n Destination, %d", srcNodeIndex, dstNodeIndex ); +#endif + + // Apply Changes. + pPathObject->setNode( srcNodeIndex, dstNodeIndex ); + pPathObject->setTimeInterp( 0.f ); + pPathObject->setPathInterp( 0.f ); + pPathObject->setPosition( newPosition ); + + // Reset local interp information. + timeInterp = 0.f; + timeInterpDelta = 0.f; + pathInterp = 0.f; + pathInterpDelta = 0.f; + + // Fetch the distance we've travelled. + const F32 &advanceDistance = ( newPosition - oldPosition ).len(); + // Any remaining distance? + if ( ( stepDistance - advanceDistance ) > 0.0001f ) + { + // Determine how much more we need to move. + Point3F newPosition0 = newPosition; + newPosition = getAdvancedPathPosition( pPathObject, ( stepDistance - advanceDistance ), pathInterpDelta ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::errorf( "Transition Step: %f\nTransition Distance: %f + %f = %f", pathInterpDelta, advanceDistance, ( newPosition - newPosition0 ).len(), advanceDistance + ( newPosition - newPosition0 ).len() ); +#endif + } + } + + if ( isServerObject() ) + { + // Return Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pPathObject->isActive() ? pPathObject->getSourceNode() : pPathObject->getDestinationNode() ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", !pPathObject->isActive() ); + + // Callback. + // VPath::onReachNode( %object, %node, %finished ); + Con::executef( this, "onReachNode", buffer[0], buffer[1], buffer[2] ); + } + } + + // Update Object Interp. + timeInterp = mClampF( timeInterp + timeInterpDelta, 0.f, 1.f ); + pathInterp = mClampF( pathInterp + pathInterpDelta, 0.f, 1.f ); + + // Apply Changes. + pPathObject->setTimeInterp( timeInterp ); + pPathObject->setPathInterp( pathInterp ); + pPathObject->setPosition( newPosition ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::printf( "Time / Distance: %f %f / %f %f", timeInterp, pathInterp, stepDistance, ( newPosition - oldPosition ).len() ); +#endif + + switch ( pPathObject->getOrientationMode().Type ) + { + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToObject : + case VPathObject::k_OrientationToPoint : + { + // Update Orientation. + updateOrientation( pPathObject ); + + } break; + + case VPathObject::k_OrientationToPath : + { + // Determine the path orientation. + VectorF pathOrientation = ( newPosition - oldPosition ); + pathOrientation.normalize(); + + // Update Orientation. + updateOrientation( pPathObject, pathOrientation ); + + } break; + } + + // Update Delta. + pPathObject->pushDelta( pPathObject->getPosition(), pPathObject->getOrientation() ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Update This Object. + pPathObject->setMaskBits( VPathObject::k_StateUpdatePosition ); + } +} + +void VPath::updatePosition( VPathObject *pPathObject ) +{ + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Fetch Position. + F32 pathInterp = 0.f; + const Point3F newPosition = getPathPosition( srcNode, dstNode, pPathObject->getTimeInterp(), pPathObject->isForward(), pathInterp ); + + // Apply Position. + pPathObject->setPosition( newPosition ); + pPathObject->setPathInterp( pathInterp ); +} + +void VPath::updateOrientation( VPathObject *pPathObject ) +{ + // Update Orientation? + if ( pPathObject->getOrientationMode().Type == VPathObject::k_OrientationFree ) + { + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Determine Path Orientation. + VectorF pathOrientation; + switch ( pPathObject->getOrientationMode().Type ) + { + case VPathObject::k_OrientationInterpolate : + { + // Interpolate Between Transforms. + QuatF rot; + rot.interpolate( srcNode->getWorldRotation(), dstNode->getWorldRotation(), pPathObject->getPathInterp() ); + + // Set Matrix. + MatrixF mat; + rot.setMatrix( &mat ); + + // Fetch Orientation. + pathOrientation = mat.getColumn3F( 1 ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Orientation. + pathOrientation = ( pPathObject->getOrientationMode().Object->getPosition() - pPathObject->getWorldPosition() ); + pathOrientation.normalizeSafe(); + + } break; + + case VPathObject::k_OrientationToPoint : + { + // Fetch Orientation. + pathOrientation = ( pPathObject->getOrientationMode().Point - pPathObject->getWorldPosition() ); + pathOrientation.normalizeSafe(); + + } break; + + case VPathObject::k_OrientationToPath : + { + // Fetch Orientation. + pathOrientation = getPathOrientation( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->isForward() ); + + } break; + } + + // Update. + updateOrientation( pPathObject, pathOrientation ); +} + +void VPath::updateOrientation( VPathObject *pPathObject, const Point3F &pPathOrientation ) +{ + // Update Orientation? + if ( pPathObject->getOrientationMode().Type == VPathObject::k_OrientationFree ) + { + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Determine Source Orientation. + VectorF srcOrientation; + switch ( srcNode->getOrientationMode().Type ) + { + case VPathNode::k_OrientationToPoint : + { + // Fetch Orientation. + srcOrientation = ( srcNode->getOrientationMode().Point - pPathObject->getWorldPosition() ); + srcOrientation.normalize(); + + } break; + + default : + { + // Use Path Orientation. + srcOrientation = pPathOrientation; + + } break; + } + + // Determine Destination Orientation. + VectorF dstOrientation; + switch ( dstNode->getOrientationMode().Type ) + { + case VPathNode::k_OrientationToPoint : + { + // Fetch Orientation. + dstOrientation = ( dstNode->getOrientationMode().Point - pPathObject->getWorldPosition() ); + dstOrientation.normalize(); + + } break; + + default : + { + // Use Path Orientation. + dstOrientation = pPathOrientation; + + } break; + } + + // Determine Actual Orientation. + VectorF orientation; + orientation.interpolate( srcOrientation, dstOrientation, pPathObject->getTimeInterp() ); + + // Apply. + pPathObject->setOrientation( orientation ); +} + +//----------------------------------------------------------------------------- +// +// Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculatePath( void ) +{ + if ( mNodeList.size() < 2 ) + { + // No Path. + return; + } + + switch ( mPathType ) + { + case k_PathLinear : + { + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + if ( itr == ( mNodeList.end() - 1 ) ) + { + // Head, Front. + calculateLinearPath( ( *itr ), ( *( mNodeList.begin() ) ) ); + } + else + { + // Head, Next. + calculateLinearPath( ( *itr ), ( *( itr + 1 ) ) ); + } + } + + } break; + + case k_PathBezier : + { + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + if ( itr == ( mNodeList.end() - 1 ) ) + { + // Head, Prev, Front. + calculateBezierPath( ( *itr ), ( *( mNodeList.begin() ) ) ); + } + else + { + // Head, Prev, Next. + calculateBezierPath( ( *itr ), ( *( itr + 1 ) ) ); + } + } + + } break; + } +} + +Point3F VPath::getAdvancedPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + switch( mPathType ) + { + case k_PathLinear : + { + return getAdvancedLinearPathPosition( pPathObject, pTargetDistance, pPathInterpDelta ); + + } break; + + case k_PathBezier : + { + return getAdvancedBezierPathPosition( pPathObject, pTargetDistance, pPathInterpDelta ); + + } break; + } + + // Sanity! + AssertFatal( false, "Invalid path type!" ); + return Point3F::Zero; +} + +ConsoleMethod( VPath, getPathTransform, const char *, 5, 5, "( int pSrcNodeIndex, int pDstNodeIndex, int pTimeInterp ) - Get the transform of the path at the interp point between two nodes.\n" + "@param pSrcNodeIndex The first node.\n" + "@param pDstNodeIndex The second node.\n" + "@param pTimeInterp The time to interp between the two nodes. Value is between 0.0 and 1.0.\n" + "@return Returns the transform of the interp time between the two given nodes." ) +{ + // Fetch Nodes. + VPathNode *srcNode = object->getNode( dAtoi( argv[2] ) ); + VPathNode *dstNode = object->getNode( dAtoi( argv[3] ) ); + + // Interp Time. + const F32 &interp = dAtof( argv[4] ); + + // Fetch Position & Orientation. + const Point3F position = object->getPathPosition( srcNode, dstNode, interp, true ); + const VectorF orientation = object->getPathOrientation( srcNode, dstNode, interp, true ); + + // Y-Axis. + VectorF yVec = orientation; + yVec.normalize(); + + // X-Axis. + VectorF xVec = mCross( yVec, VPath::gBezierUp ); + xVec.normalize(); + + // Z-Axis. + VectorF zVec = mCross( xVec, yVec ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF mat( true ); + mat.setColumn( 0, xVec ); + mat.setColumn( 1, yVec ); + mat.setColumn( 2, zVec ); + + // AngAxis. + AngAxisF aa( mat ); + + // Return Buffer; + char *buffer = Con::getReturnBuffer( 256 ); + dSprintf( buffer, 256, "%g %g %g %g %g %g %g", position.x, position.y, position.z, + aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + // Return. + return buffer; +} + +ConsoleMethod( VPath, getPathPosition, const char *, 5, 5, "( int pSrcNodeIndex, int pDstNodeIndex, int pTimeInterp ) - Get the world position of the path at the interp point between two nodes.\n" + "@param pSrcNodeIndex The first node.\n" + "@param pDstNodeIndex The second node.\n" + "@param pTimeInterp The time to interp between the two nodes. Value is between 0.0 and 1.0.\n" + "@return Returns the world position of the interp time between the two given nodes." ) +{ + // Fetch Nodes. + VPathNode *srcNode = object->getNode( dAtoi( argv[2] ) ); + VPathNode *dstNode = object->getNode( dAtoi( argv[3] ) ); + + // Interp Time. + const F32 &interp = dAtof( argv[4] ); + + // Find Position. + const Point3F position = object->getPathPosition( srcNode, dstNode, interp, true ); + + // Return Buffer; + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%g %g %g", position.x, position.y, position.z ); + + // Return. + return buffer; +} + +Point3F VPath::getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + F32 pathInterp = 0.f; + return getPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pathInterp ); +} + +Point3F VPath::getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + switch( mPathType ) + { + case k_PathBezier : + { + return getBezierPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pPathInterp ); + + } break; + + case k_PathLinear : + { + return getLinearPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pPathInterp ); + + } break; + } + + // NULL. + return Point3F::Zero; +} + +VectorF VPath::getPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + switch( mPathType ) + { + case k_PathBezier : + { + return getBezierPathOrientation( pSourceNode, pDestinationNode, pTimeInterp, pForward ); + + } break; + + case k_PathLinear : + { + return getLinearPathOrientation( pSourceNode, pDestinationNode, pTimeInterp, pForward ); + + } break; + } + + // NULL. + return VectorF::Zero; +} + +//----------------------------------------------------------------------------- +// +// Linear Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculateLinearPath( VPathNode *pNode, VPathNode *pNextNode ) +{ + // Calculate Segment Length. + pNode->setLength( ( pNextNode->getWorldPosition() - pNode->getWorldPosition() ).len() ); +} + +Point3F VPath::getAdvancedLinearPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + + // Fetch the length of the segment. + const F32 length = ( pPathObject->isForward() ) ? srcNode->getLength() : dstNode->getLength(); + + // Set the interp delta. + pPathInterpDelta = ( pTargetDistance / length ); + + // Return the position. + F32 pathInterp = 0.f; + return getLinearPathPosition( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->isForward(), pathInterp ); +} + +Point3F VPath::getLinearPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + // Set path interp to the time interp. + pPathInterp = pTimeInterp; + + if ( pTimeInterp <= 0.f ) + { + // Source Node. + return pSourceNode->getWorldPosition(); + } + else if ( pTimeInterp >= 1.f ) + { + // Destination Node. + return pDestinationNode->getWorldPosition(); + } + + // Calculate Position. + Point3F position; + position.interpolate( pSourceNode->getWorldPosition(), pDestinationNode->getWorldPosition(), pTimeInterp ); + + // Return. + return position; +} + +VectorF VPath::getLinearPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + // Calculate Orientation. + VectorF newOrientation = ( pDestinationNode->getWorldPosition() - pSourceNode->getWorldPosition() ); + newOrientation.normalizeSafe(); + + // Return. + return newOrientation; +} + +//----------------------------------------------------------------------------- +// +// Bezier Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculateBezierPath( VPathNode *pNode, VPathNode *pNextNode ) +{ + // Reset Length. + F32 segmentLength = 0.f; + + // Positions. + const Point3F &pt0 = pNode->getWorldPosition(); + const Point3F &pt3 = pNextNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pNode->getWorldRotation().setMatrix( &mat0 ); + pNextNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pNode->getWeight() ); + Point3F pt2( -gBezierAxis * pNextNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Initial Position. + Point3F ptA = pt0; + const F32 i = gBezierInterpStep; + for ( F32 t = 0.f, it = ( 1.f - t ); t <= 1.f; t += i, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F ptB = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + + // Add Segment. + segmentLength += ( ptB - ptA ).len(); + + // Store Position. + ptA = ptB; + } + + // Apply Update. + pNode->setLength( segmentLength ); +} + +Point3F VPath::getAdvancedBezierPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + + // Fetch the delta position. + return getBezierPathPosition( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->getPosition(), pTargetDistance, pPathObject->isForward(), true, pPathInterpDelta ); +} + +Point3F VPath::getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + // Fetch the length of the segment. + const F32 length = ( pForward ) ? pSourceNode->getLength() : pDestinationNode->getLength(); + + // Determine the real interp time for the distance fraction. + return getBezierPathPosition( pSourceNode, pDestinationNode, 0.f, pSourceNode->getWorldPosition(), ( length * pTimeInterp ), pForward, false, pPathInterp ); +} + +Point3F VPath::getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const Point3F &pReferencePosition, const F32 &pTargetDistance, const bool &pForward, const bool &pRelativeToReference, F32 &pPathInterpDelta ) +{ + // Positions. + const Point3F &pt0 = pSourceNode->getWorldPosition(); + const Point3F &pt3 = pDestinationNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pSourceNode->getWorldRotation().setMatrix( &mat0 ); + pDestinationNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pSourceNode->getWeight() ); + Point3F pt2( -gBezierAxis * pDestinationNode->getWeight() ); + + if ( !pForward ) + { + pt1 *= -1.f; + pt2 *= -1.f; + } + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Move Position. + Point3F movePosition = pReferencePosition; + // Movement Distance. + F32 moveDistance = 0.f; + + // Determine the Real Delta. + const F32 i = gBezierInterpStep; + for ( F32 t = ( pTimeInterp + i ), it = ( 1.f - t ); t <= 1.f; t += i, it = ( 1.f - t ) ) + { + // Calculate Step. + const Point3F stepPosition = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + // Step Length. + const F32 &stepDistance = ( stepPosition - movePosition ).len(); + + if ( pRelativeToReference ) + { + // Calculate Distance. + moveDistance = ( pReferencePosition - stepPosition ).len(); + + // Moved Target Distance? + if ( moveDistance >= pTargetDistance ) + { + // Interpolate Step. + const F32 stepInterp = ( moveDistance - pTargetDistance ) / moveDistance; + // Store Interp Delta. + pPathInterpDelta = ( t - pTimeInterp ) * ( 1.f - stepInterp ); + + // Interpolate the step. + Point3F outPosition; + outPosition.interpolate( pReferencePosition, stepPosition, ( 1.f - stepInterp ) ); + // Return the position. + return outPosition; + } + } + else + { + // Calculate Distance. + moveDistance += stepDistance; + + // Moved Target Distance? + if ( moveDistance >= pTargetDistance ) + { + // Interpolate Step. + const F32 stepInterp = ( moveDistance - pTargetDistance ) / stepDistance; + // Store Interp Delta. + pPathInterpDelta = ( t - pTimeInterp ) - ( stepInterp * i ); + + // Interpolate the step. + Point3F outPosition; + outPosition.interpolate( movePosition, stepPosition, ( 1.f - stepInterp ) ); + // Return the position. + return outPosition; + } + } + + // Apply New Position. + movePosition = stepPosition; + } + + // Update. + pPathInterpDelta = ( 1.f - pTimeInterp ); + // At the destination node? + return pt3; +} + +VectorF VPath::getBezierPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + // Positions. + const Point3F &pt0 = pSourceNode->getWorldPosition(); + const Point3F &pt3 = pDestinationNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pSourceNode->getWorldRotation().setMatrix( &mat0 ); + pDestinationNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pSourceNode->getWeight() ); + Point3F pt2( -gBezierAxis * pDestinationNode->getWeight() ); + + if ( !pForward ) + { + pt1 *= -1.f; + pt2 *= -1.f; + } + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + const F32 halfStep = ( gBezierInterpStep / 2.f ); + if ( ( pTimeInterp - halfStep ) <= 0.f ) + { + // Orientation From Node Tangent. + pt1.normalize(); + + // Return. + return pt1; + } + else if ( ( pTimeInterp + halfStep ) >= 1.f ) + { + // Orientation From Node Tangent. + pt2.normalize(); + + // Return. + return -pt2; + } + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Interp Times. + const F32 t0 = ( pTimeInterp - halfStep ); + const F32 it0 = ( 1.f - t0 ); + + const F32 t1 = ( pTimeInterp + halfStep ); + const F32 it1 = ( 1.f - t1 ); + + // Calculate Position. + Point3F d0 = ( pt0 * it0 * it0 * it0 ) + ( 3 * pt1 * it0 * it0 * t0 ) + ( 3 * pt2 * it0 * t0 * t0 ) + ( pt3 * t0 * t0 * t0 ); + Point3F d1 = ( pt0 * it1 * it1 * it1 ) + ( 3 * pt1 * it1 * it1 * t1 ) + ( 3 * pt2 * it1 * t1 * t1 ) + ( pt3 * t1 * t1 * t1 ); + + // Set Orientation. + Point3F orientation = ( d1 - d0 ); + orientation.normalizeSafe(); + + // Return. + return orientation; +} + +//----------------------------------------------------------------------------- +// +// Path Node Property Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VPath, getNodeCount, S32, 2, 2, "() - Get the number of nodes in this path.\n" + "@return Returns the number of nodes." ) +{ + // Return Count. + return object->getNodeCount(); +} + +S32 VPath::getNodeCount( void ) +{ + // Return the Size of the Node List. + return mNodeList.size(); +} + +ConsoleMethod( VPath, getNodeLocalTransform, const char *, 3, 3, "( int pNodeIndex ) - Get the local transform (local position and rotation) of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the transform of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeLocalPosition( dAtoi( argv[2] ) ); + + // Fetch Rotation. + const QuatF &rotation = object->getNodeLocalRotation( dAtoi( argv[2] ) ); + + // Angle & Axis. + AngAxisF aa( rotation ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 256 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g %.3g %.3g %.3g %.3g", position.x, position.y, position.z, aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + return buffer; +} + +ConsoleMethod( VPath, getNodeLocalPosition, const char *, 3, 3, "( int pNodeIndex ) - Get the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + " @return Returns the Local Position of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeLocalPosition( dAtoi( argv[2] ) ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g", position.x, position.y, position.z ); + + return buffer; +} + +Point3F VPath::getNodeLocalPosition( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLocalPosition() - Invalid Index Specified (%d).", pNodeIndex ); + return Point3F::Zero; + } + + return mNodeList[pNodeIndex]->getLocalPosition(); +} + +ConsoleMethod( VPath, getNodeLocalRotation, const char *, 3, 3, "( int pNodeIndex ) - Get the Local Rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the Local Rotation of the given node." ) +{ + // Fetch Rotation. + const QuatF &rotation = object->getNodeLocalRotation( dAtoi( argv[2] ) ); + + // Angle & Axis. + AngAxisF aa( rotation ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g %.3g", aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + return buffer; +} + +QuatF VPath::getNodeLocalRotation( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLocalRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return QuatF( Point3F::Zero, 0.f ); + } + + return mNodeList[pNodeIndex]->getLocalRotation(); +} + +ConsoleMethod( VPath, getNodeWorldTransform, const char *, 3, 3, "( int pNodeIndex ) - Get the World Transform (position and rotation) of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the transform of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeWorldPosition( dAtoi( argv[2] ) ); + + // Fetch Rotation. + const QuatF &rotation = object->getNodeWorldRotation( dAtoi( argv[2] ) ); + + // Angle & Axis. + AngAxisF aa( rotation ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 256 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g %.3g %.3g %.3g %.3g", position.x, position.y, position.z, aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + return buffer; +} + +ConsoleMethod( VPath, getNodeWorldPosition, const char *, 3, 3, "( int pNodeIndex ) - Get the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the World Position of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeWorldPosition( dAtoi( argv[2] ) ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g", position.x, position.y, position.z ); + + return buffer; +} + +Point3F VPath::getNodeWorldPosition( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWorldPosition() - Invalid Index Specified (%d).", pNodeIndex ); + return Point3F::Zero; + } + + return mNodeList[pNodeIndex]->getWorldPosition(); +} + +ConsoleMethod( VPath, getNodeWorldRotation, const char *, 3, 3, "( int pNodeIndex ) - Get the World Rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the World Rotation of the given node." ) +{ + // Fetch Rotation. + const QuatF &rotation = object->getNodeWorldRotation( dAtoi( argv[2] ) ); + + // Angle & Axis. + AngAxisF aa( rotation ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g %.3g", aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + return buffer; +} + +QuatF VPath::getNodeWorldRotation( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWorldRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return QuatF( Point3F::Zero, 0.f ); + } + + return mNodeList[pNodeIndex]->getWorldRotation(); +} + +ConsoleMethod( VPath, getNodeWeight, F32, 3, 3, "( int pNodeIndex ) - Get the weight of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the weight of the given node." ) +{ + // Fetch Weight. + return object->getNodeWeight( dAtoi( argv[2] ) ); +} + +F32 VPath::getNodeWeight( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWeight() - Invalid Index Specified (%d).", pNodeIndex ); + return 0.f; + } + + return mNodeList[pNodeIndex]->getWeight(); +} + +ConsoleMethod( VPath, getNodeLength, F32, 3, 3, "( int pNodeIndex ) - Get the length of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the length of the given node." ) +{ + // Fetch Length. + return object->getNodeLength( dAtoi( argv[2] ) ); +} + +F32 VPath::getNodeLength( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLength() - Invalid Index Specified (%d).", pNodeIndex ); + return 0.f; + } + + return mNodeList[pNodeIndex]->getLength(); +} + +ConsoleMethod( VPath, setNodeTransform, void, 4, 4, "( int pNodeIndex, matrix pTransform ) - Set the transform of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pTransform The new transform to be applied to the node.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Fetch Position & Rotation. + Point3F position; + AngAxisF aa; + QuatF rotation; + dSscanf( argv[3], "%g %g %g %g %g %g %g", &position.x, &position.y, &position.z, + &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle ); + + // Set Rotation. + rotation.set( aa ); + + // Apply Update. + object->setNodePosition( nodeIndex, position ); + object->setNodeRotation( nodeIndex, rotation ); +} + +ConsoleMethod( VPath, setNodePosition, void, 4, 4, "( int pNodeIndex, vector pPosition ) - Set the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pPosition The new position to be applied to the node.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Fetch Position. + Point3F position; + dSscanf( argv[3], "%g %g %g", &position.x, &position.y, &position.z ); + + // Apply Update. + object->setNodePosition( nodeIndex, position ); +} + +void VPath::setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodePosition() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setLocalPosition( pPosition ); + + // Update Size. + updateContainer(); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +ConsoleMethod( VPath, setNodeRotation, void, 4, 4, "( int pNodeIndex, angAxis pRotation ) - Set the rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pRotation The new rotation to be applied to the node.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Fetch Rotation. + AngAxisF aa; + QuatF rotation; + dSscanf( argv[3], "%g %g %g %g", &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle ); + + // Set Rotation. + rotation.set( aa ); + + // Apply Update. + object->setNodeRotation( nodeIndex, rotation ); +} + +void VPath::setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setLocalRotation( pRotation ); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +ConsoleMethod( VPath, setNodeWeight, void, 4, 4, "( int pNodeIndex, float pWeight ) - Set the weight of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pWeight The new weight to be applied to the node.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Fetch Weight. + const F32 nodeWeight = dAtof( argv[3] ); + + // Apply Update. + object->setNodeWeight( nodeIndex, nodeWeight ); +} + +void VPath::setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeWeight() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setWeight( pWeight ); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +ConsoleMethod( VPath, getNodeOrientationMode, const char *, 3, 3, "( int pNodeIndex ) - Gets the current orientation mode of the node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns a string indicating the orientation mode and its properties." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + if ( nodeIndex < 0 || nodeIndex >= object->getNodeCount() ) + { + // Woops! + Con::warnf( "VPath::getNodeOrientationMode() - Invalid Index Specified (%d).", nodeIndex ); + return ""; + } + + // Fetch Object + VPathNode *node = object->getNode( nodeIndex ); + + // Fetch Orientation Mode. + const VPathNode::sOrientation &orientation = node->getOrientationMode(); + + // Determine the Type. + StringTableEntry type = VPathNode::getOrientationTypeLabel( orientation.Type ); + + // Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + + switch( orientation.Type ) + { + case VPathNode::k_OrientationFree : + { + // Buffer String. + dSprintf( buffer, 128, "%s", type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + // Fetch Point. + const Point3F &lookAtPoint = orientation.Point; + // Buffer String. + dSprintf( buffer, 128, "%s\t%.2f %.2f %.2f", type, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z ); + + } break; + } + + // Return Buffer. + return buffer; +} + +ConsoleMethod( VPath, setNodeOrientationMode, void, 4, 5, "( int pNodeIndex, string pOrientationType, [vector pPoint] ) - Set the orientation mode of the node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pOrientationType The new orientation type of the object.\n" + "@param pPoint If the orientation type is set to POINT, this parameter must be a vector.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Orient? + const VPathNode::eOrientationType type = VPathNode::getOrientationTypeEnum( argv[3] ); + + switch ( type ) + { + case VPathNode::k_OrientationFree : + { + // Apply Mode. + object->setNodeOrientationMode( nodeIndex, type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( argv[4], "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + object->setNodeOrientationMode( nodeIndex, type, lookAtPoint ); + + } break; + + default : + { + AssertFatal( false, "VPath::setNodeOrientationMode() - Invalid Orientation Mode Specified." ); + + } break; + } +} + +void VPath::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeOrientationMode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply. + node->setOrientationMode( pType ); + + // Network Flags. + setMaskBits( NodeUpdateMask ); +} + +void VPath::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F pPoint ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeOrientationMode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply. + node->setOrientationMode( pType, pPoint ); + + // Network Flags. + setMaskBits( NodeUpdateMask ); +} + +//----------------------------------------------------------------------------- +// +// Path Object Property Methods. +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VPath, isPathObjectActive, bool, 3, 3, "( SimObject pObject ) - Is the object actively traveling around this path?\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns true of the object is active." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::isPathObjectActive() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->isActive(); +} + +ConsoleMethod( VPath, setPathObjectActive, void, 4, 4, "( SimObject pObject, bool pActive ) - Enable or disable the object from traveling around this path. Inactive objects are still attached to the path, but are not updated.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pActive The new status of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectActive() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectActive( sceneObject, dAtob( argv[3] ) ); +} + +void VPath::setPathObjectActive( SceneObject *pObject, const bool &pActive ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectActive() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setActive( pActive ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, getPathObjectInterp, F32, 3, 3, "( SimObject pObject ) - Get the current interp position of the path object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the current interp position." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectInterp() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getTimeInterp(); +} + +ConsoleMethod( VPath, setPathObjectInterp, void, 4, 4, "( SimObject pObject, float pTimeInterp ) - Set the interp position of the object between its current nodes.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pTimeInterp The new interp position of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectInterp() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectInterp( sceneObject, dAtof( argv[3] ) ); +} + +void VPath::setPathObjectInterp( SceneObject *pObject, const F32 &pTimeInterp ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectInterp() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Update. + setPathObjectInterp( pathObject, pTimeInterp ); +} + +void VPath::setPathObjectInterp( VPathObject *pPathObject, const F32 &pTimeInterp ) +{ + // Set Interp Time. + pPathObject->setTimeInterp( pTimeInterp ); + + // Update Position. + updatePosition( pPathObject ); + // Update Orientation. + updateOrientation( pPathObject ); + // Reset the delta. + pPathObject->resetDelta(); + + // Set the object transform. + pPathObject->getObject()->setTransform( pPathObject->getTransform() ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Update This Object. + pPathObject->setMaskBits( VPathObject::k_StateUpdatePosition ); + } +} + +ConsoleMethod( VPath, getPathObjectOffset, const char *, 3, 3, "( SimObject pObject ) - Get the position offset assigned to this object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the position offset." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectOffset() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Fetch Offset. + const Point3F &offset = pathObject->getOffset(); + + // Buffer. + char *buffer = Con::getReturnBuffer( 64 ); + dSprintf( buffer, 64, "%f %f %f", offset.x, offset.y, offset.z ); + return buffer; +} + +ConsoleMethod( VPath, setPathObjectOffset, void, 4, 4, "( SimObject pObject, vector pOffset ) - Set the position offset of the object. As the object is moving along the path, its position is offset by this value. Setting the \"Relative\" parameter while attaching an object will automatically apply an offset value.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pOffset The new position offset of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectOffset() - Invalid Target Object." ); + return; + } + + // Relative Offset. + Point3F offset( 0.f, 0.f, 0.f ); + // Scan. + dSscanf( argv[3], "%g %g %g", &offset.x, &offset.y, &offset.z ); + + // Apply. + object->setPathObjectOffset( sceneObject, offset ); +} + +void VPath::setPathObjectOffset( SceneObject *pObject, const Point3F &pOffset ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOffset() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOffset( pOffset ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, getPathObjectSpeed, F32, 3, 3, "( SimObject pObject ) - Get the speed this object is traveling along the path at.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the speed of the object." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectSpeed() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getSpeed(); +} + +ConsoleMethod( VPath, setPathObjectSpeed, void, 4, 4, "( SimObject pObject, float pSpeed ) - Set the speed of the object.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pSpeed The new speed of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectSpeed() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectSpeed( sceneObject, dAtof( argv[3] ) ); +} + +void VPath::setPathObjectSpeed( SceneObject *pObject, const F32 &pSpeed ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectSpeed() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setSpeed( mFabs( pSpeed ) ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, getPathObjectOrientationMode, const char *, 3, 3, "( SimObject pObject ) - Gets the current orientation mode of the object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns a string indicating the orientation mode and its properties." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectOrientationMode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Fetch Orientation Mode. + const VPathObject::sOrientation &orientation = pathObject->getOrientationMode(); + + // Determine the Type. + StringTableEntry type = VPathObject::getOrientationTypeLabel( orientation.Type ); + + // Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + + switch( orientation.Type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Buffer String. + dSprintf( buffer, 128, "%s", type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch the Object ID. + const S32 objId = ( ( orientation.Object ) ? orientation.Object->getId() : 0 ); + // Buffer String. + dSprintf( buffer, 128, "%s %d", type, objId ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + const Point3F &lookAtPoint = orientation.Point; + // Buffer String. + dSprintf( buffer, 128, "%s %f %f %f", type, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z ); + + } break; + } + + // Return Buffer. + return buffer; +} + +ConsoleMethod( VPath, setPathObjectOrientationMode, void, 4, 5, "( SimObject pObject, string pOrientationType, [SimObject pObject / vector pPoint] ) - Set the orientation mode of the object. This property affects the rotation of the object. If you wish to ignore the object's rotation altogether, set the mode to \"FREE\".\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pOrientationType The new orientation type of the object.\n" + "@param pObject If the orientation type is set to OBJECT, this parameter must be the SimObjectID of a scene object.\n" + "@param pPoint If the orientation type is set to POINT, this parameter must be a vector.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectOrientationMode() - Invalid Target Object." ); + return; + } + + // Orient? + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( argv[3] ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Object. + SceneObject *lookAtObject = dynamic_cast( Sim::findObject( argv[4] ) ); + if ( !lookAtObject ) + { + Con::errorf( "VPath::setPathObjectOrientationMode() - Invalid LookAt Object." ); + return; + } + + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type, lookAtObject ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( argv[4], "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type, lookAtPoint ); + + } break; + + default : + { + AssertFatal( false, "VPath::setPathObjectOrientationMode() - Invalid Orientation Mode Specified." ); + + } break; + } +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, SceneObject *pLookAtObject ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType, pLookAtObject ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, const Point3F pPoint ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType, pPoint ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, isPathObjectForward, bool, 3, 3, "( SimObject pObject ) - Get if this object is traveling forwards along the path.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns true if the object is traveling forwards." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::isPathObjectForward() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->isForward(); +} + +ConsoleMethod( VPath, setPathObjectForward, void, 4, 4, "( SimObject pObject, bool pForward ) - Set the travel direction of the object.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pForward The direction of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectForward() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectForward( sceneObject, dAtob( argv[3] ) ); +} + +void VPath::setPathObjectForward( SceneObject *pObject, const bool &pForward ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectForward() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setForward( pForward ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, getPathObjectNode, S32, 3, 3, "( SimObject pObject ) - Gets the last node of the object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the node index." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectNode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getSourceNode(); +} + +ConsoleMethod( VPath, setPathObjectNode, void, 4, 4, "( SimObject pObject, bool pNodeIndex ) - Move the object to the node's position. You may also want to observe the \"setPathObjectInterp\" method.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pNodeIndex The index of the node that the object will reposition to.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectNode() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectNode( sceneObject, dAtoi( argv[3] ) ); +} + +void VPath::setPathObjectNode( SceneObject *pObject, const S32 &pNodeIndex ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectNode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Source & Destination Nodes. + const S32 srcNode = pNodeIndex; + const S32 dstNode = ( pathObject->isForward() ) ? ( pNodeIndex + 1 ) : ( pNodeIndex - 1 ); + + // Set Current Node. + pathObject->setNode( normalizeNodeIndex( srcNode ), normalizeNodeIndex( dstNode ) ); + + // Reset Interp. + pathObject->setTimeInterp( 0.f ); + pathObject->setPathInterp( 0.f ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +ConsoleMethod( VPath, getPathObjectEndNode, S32, 3, 3, "( SimObject pObject ) - Get the index of the node this object is meant to stop upon reaching.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the node index." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::getPathObjectEndNode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getEndNode(); +} + +ConsoleMethod( VPath, setPathObjectEndNode, void, 4, 4, "( SimObject pObject, bool pNodeIndex ) - Set end node of the path object. If a value of \"-1\" is applied, the object will path indefinitely.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pNodeIndex The index of the node that the object will cease pathing upon reaching.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectEndNode() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectEndNode( sceneObject, dAtoi( argv[3] ) ); +} + +void VPath::setPathObjectEndNode( SceneObject *pObject, const S32 &pNodeIndex ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectEndNode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Set index. + S32 index = pNodeIndex; + + if ( index != -1 ) + { + // Normalize index. + normalizeNodeIndex( index ); + } + + // Apply. + pathObject->setEndNode( index ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPath.h b/Engine/modules/Verve/VPath/VPath.h new file mode 100644 index 000000000..925d88d78 --- /dev/null +++ b/Engine/modules/Verve/VPath/VPath.h @@ -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 VPathNodeVector; +typedef VPathNodeVector::iterator VPathNodeIterator; + +typedef Vector VPathObjectVector; +typedef VPathObjectVector::iterator VPathObjectIterator; + +//----------------------------------------------------------------------------- + +class VPath : public SceneObject +{ + typedef SceneObject Parent; + + friend class VPathEditor; + +public: + + // Static Members. + + static SimObjectPtr 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_ \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathEditor.cpp b/Engine/modules/Verve/VPath/VPathEditor.cpp new file mode 100644 index 000000000..3ab2f8282 --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathEditor.cpp @@ -0,0 +1,2205 @@ +//----------------------------------------------------------------------------- +// 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 "VPathEditor.h" + +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gfx/primBuilder.h" +#include "gui/worldEditor/worldEditor.h" +#include "math/mathUtils.h" +#include "sim/netConnection.h" + +//----------------------------------------------------------------------------- + +static F32 gProjectDistance = 2000.f; +static F32 gSelectionDistance = 2.f; + +static ColorI gPathColor( 255, 255, 255 ); +static ColorI gPathColorSel( 0, 255, 255 ); +static ColorI gNodeLookAtPointColor( 255, 127, 39 ); + +//----------------------------------------------------------------------------- + +// Implement the Edit Mode enum list. +ImplementEnumType( VPathEditorMode, "" ) + { VPathEditor::k_Gizmo, "GIZMO" }, + { VPathEditor::k_AddNode, "ADDNODE" }, + { VPathEditor::k_DeleteNode, "DELETENODE" }, +EndImplementEnumType; + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPathEditor ); +//----------------------------------------------------------------------------- + +VPathEditor::VPathEditor( void ) : + mIsDirty( false ), + mEditMode( k_Gizmo ), + mEditWeight( false ), + mEditWeightHandle( -1 ) +{ + // Void. +} + +bool VPathEditor::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + // Assign Gizmo Name. + mGizmo->assignName( "VPathEditorGizmo" ); + + return true; +} + +bool VPathEditor::onWake( void ) +{ + // Clear Selection. + updateSelection( NULL, -1 ); + + // Return Parent Value. + return Parent::onWake(); +} + +void VPathEditor::initPersistFields( void ) +{ + addField( "IsDirty", TypeBool, Offset( mIsDirty, VPathEditor ) ); + addField( "EditMode", TYPEID(), Offset( mEditMode, VPathEditor ) ); + + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// Gui Events +// +//----------------------------------------------------------------------------- + +void VPathEditor::on3DMouseDown( const Gui3DMouseEvent &pEvent ) +{ + // Using the Gizmo? + if ( mEditMode != k_Gizmo ) + { + // No, Quit Now. + return; + } + + // Gizmo Event. + mGizmo->on3DMouseDown( pEvent ); + + if ( isValidSelection() ) + { + // Store Node Information. + pushNodeEdit(); + + switch( mGizmoProfile->mode ) + { + case MoveMode: + case RotateMode: + { + if ( mGizmo->getSelection() != Gizmo::None ) + { + // Using Gizmo. + return; + } + + } break; + + case ScaleMode: + { + if ( isEditingWeight( pEvent ) ) + { + // Editing Weights. + return; + } + + } break; + } + } + else if ( mSelection.Path ) + { + // Store Path Information. + pushPathEdit(); + + if ( mGizmo->getSelection() != Gizmo::None ) + { + // Using Gizmo. + return; + } + } + + // Update Selection. + if ( !updateSelection( pEvent ) ) + { + // Clear Selection. + updateSelection( NULL, -1 ); + } +} + +void VPathEditor::on3DMouseUp( const Gui3DMouseEvent &pEvent ) +{ + switch ( mEditMode ) + { + case k_Gizmo : + { + // Gizmo Event. + mGizmo->on3DMouseUp( pEvent ); + + // Handle History Actions. + popPathEdit(); + popNodeEdit(); + + // Clear Editing. + mEditWeight = false; + + } break; + + case k_AddNode : + { + if ( mSelection.Path != NULL ) + { + // Add New! + addNode( pEvent ); + + // Dirty. + mIsDirty = true; + } + + } break; + + case k_DeleteNode : + { + // Update Selection. + if ( updateSelection( pEvent ) ) + { + if ( isValidSelection() ) + { + // Delete Node. + deleteNode( mSelection.Node ); + + // Dirty. + mIsDirty = true; + } + + // Clear Node Selection. + updateSelection( mSelection.Path, -1 ); + } + + } break; + } +} + +void VPathEditor::on3DMouseMove( const Gui3DMouseEvent &pEvent ) +{ + // Update? + if ( mEditMode != k_Gizmo || !mSelection.Path ) + { + return; + } + + // Update Gizmo? + if ( mSelection.Node == -1 || mGizmoProfile->mode != ScaleMode ) + { + // Gizmo Event. + mGizmo->on3DMouseMove( pEvent ); + } +} + +void VPathEditor::on3DMouseDragged( const Gui3DMouseEvent &pEvent ) +{ + // Update? + if ( mEditMode != k_Gizmo || !mSelection.Path ) + { + return; + } + + // Update Gizmo? + if ( mSelection.Node == -1 || mGizmoProfile->mode != ScaleMode ) + { + // Gizmo Event. + mGizmo->on3DMouseDragged( pEvent ); + + // Handle Gizmo? + if ( mGizmo->getSelection() == Gizmo::None ) + { + // Return. + return; + } + } + + // Editing the Path? + if ( mSelection.Node == -1 ) + { + switch ( mGizmoProfile->mode ) + { + case MoveMode : + { + // Fetch Node Position. + const Point3F oldPosition = mSelection.Path->getPosition(); + // Determine New Position. + const Point3F newPosition = ( oldPosition + mGizmo->getOffset() ); + + // Apply New Position. + setPathPosition( newPosition ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + /* + case RotateMode : + { + + // Rotation Delta. + MatrixF deltaRotation( EulerF( mGizmo->getDeltaRot() ) ); + + // Fetch Current Transform. + MatrixF mat = mSelection.Path->getTransform(); + mat.mul( deltaRotation ); + + // Apply New Transform. + setPathTransform( mat ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + + case ScaleMode : + { + + // Apply New Scale. + setPathScale( mGizmo->getScale() ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + */ + } + } + + // No, Editing a Node + else + { + switch ( mGizmoProfile->mode ) + { + case MoveMode : + { + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Fetch Node Position. + const Point3F oldPosition = node->getLocalPosition(); + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + Point3F deltaPosition = mGizmo->getOffset(); + pathTransform.mulP( deltaPosition ); + + // Apply New Position. + setNodePosition( mSelection.Node, ( oldPosition + deltaPosition ) ); + + } break; + + case RotateMode : + { + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + // Rotation Delta. + MatrixF deltaRotation( EulerF( mGizmo->getDeltaRot() ) ); + pathTransform.mul( deltaRotation ); + + // Fetch Current Transform. + MatrixF mat = node->getWorldTransform(); + mat.mul( deltaRotation ); + + // Construct Quat. + QuatF newRotation; + newRotation.set( mat ); + + // Apply New Rotation. + setNodeRotation( mSelection.Node, newRotation ); + + } break; + + case ScaleMode : + { + + if ( isEditingWeight() ) + { + // Edit Weight. + updateWeight( pEvent ); + } + + } break; + } + } +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +VPath *VPathEditor::getClientPath( VPath *pPath ) +{ + if ( !pPath ) + { + return NULL; + } + + NetConnection *toServer = NetConnection::getConnectionToServer(); + NetConnection *toClient = NetConnection::getLocalClientConnection(); + if ( !toServer || !toClient ) + { + return NULL; + } + + const S32 ghostIndex = toClient->getGhostIndex( pPath ); + if ( ghostIndex == -1 ) + { + return NULL; + } + + return dynamic_cast( toServer->resolveGhost( ghostIndex ) ); +} + +//----------------------------------------------------------------------------- +// +// Selection Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::updateSelection( const Gui3DMouseEvent &pEvent ) +{ + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + RayInfo ri; + if ( !gServerContainer.collideBox( pt0, pt1, MarkerObjectType, &ri ) ) + { + // No Object. + return false; + } + + VPath *path = dynamic_cast( ri.object ); + if ( !path ) + { + // No Path Object. + return false; + } + + // No Node. + S32 nodeIndex = -1; + + for ( VPathNodeIterator itr = path->mNodeList.begin(); itr != path->mNodeList.end(); itr++ ) + { + VPathNode *node = ( *itr ); + + Point3F projPosition; + project( node->getWorldPosition(), &projPosition ); + + if ( projPosition.z <= 0.0f ) + { + continue; + } + + const Point2I rectHalfSize( 8, 8 ); + const Point2I screenPosition( ( S32 )projPosition.x, ( S32 )projPosition.y ); + const RectI screenRect( screenPosition - rectHalfSize, 2 * rectHalfSize ); + + // Mouse Close Enough? + if ( screenRect.pointInRect( pEvent.mousePoint ) ) + { + // Select Node. + nodeIndex = ( itr - path->mNodeList.begin() ); + } + } + + // Set Selection. + updateSelection( path, nodeIndex ); + + // Valid Selection. + return true; +} + +void VPathEditor::updateSelection( VPath *pPathObject, const S32 &pNodeIndex ) +{ + // Store Selection. + mSelection.Path = pPathObject; + mSelection.Node = pNodeIndex; + + // Quick Update. + updateSelection(); + + // Return Buffer. + char buffer[2][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", ( pPathObject ) ? pPathObject->getId() : 0 ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + + // Callback. + Con::executef( this, "onUpdateSelection", buffer[0], buffer[1] ); +} + +void VPathEditor::updateSelection( void ) +{ + if ( !isValidSelection() ) + { + // No Further Updates. + return; + } + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Fetch Node Rotation Matrix. + MatrixF mat; + node->getWorldRotation().setMatrix( &mat ); + + // Determine Tangent Axis. + Point3F pt0( VPath::gBezierAxis * node->getWeight() ); + Point3F pt1( -VPath::gBezierAxis * node->getWeight() ); + + // Rotate Axis. + mat.mulP( pt0 ); + mat.mulP( pt1 ); + + // Offset Points. + pt0 += node->getWorldPosition(); + pt1 += node->getWorldPosition(); + + // Store Points. + mSelection.TangentHandle[0] = pt0; + mSelection.TangentHandle[1] = pt1; +} + +ConsoleMethod( VPathEditor, clearSelection, void, 2, 2, "( void )" ) +{ + // Clear Selection. + object->updateSelection( NULL, -1 ); +} + +ConsoleMethod( VPathEditor, setSelection, void, 3, 4, "( pObject, [pNodeIndex] )" ) +{ + // Fetch Path. + VPath *path = dynamic_cast( Sim::findObject( argv[2] ) ); + if ( !path ) + { + Con::errorf( "VPathEditor::setSelection() - Unable to select target Object." ); + return; + } + + if ( argc == 3 ) + { + // Select Path. + object->updateSelection( path, -1 ); + return; + } + + // Select Path & Node. + object->updateSelection( path, dAtoi( argv[3] ) ); +} + +ConsoleMethod( VPathEditor, isValidSelection, bool, 2, 2, "( void )" ) +{ + return object->isValidSelection(); +} + +ConsoleMethod( VPathEditor, getSelectedPath, S32, 2, 2, "( void )" ) +{ + // Fetch Path. + VPath *path = object->mSelection.Path; + + // Return ID. + return ( path ) ? path->getId() : 0; +} + +ConsoleMethod( VPathEditor, getSelectedNode, S32, 2, 2, "( void )" ) +{ + // Return Node Index. + return ( object->mSelection.Path ) ? object->mSelection.Node : -1; +} + +ConsoleMethod( VPathEditor, deleteSelection, void, 2, 2, "( void )" ) +{ + // Valid Selection? + if ( object->isValidSelection() ) + { + object->deleteNode( object->mSelection.Node ); + } +} + +//----------------------------------------------------------------------------- +// +// Weight Editing Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::isEditingWeight( const Gui3DMouseEvent &pEvent ) +{ + if ( !isValidSelection() || mSelection.Path->mPathType != VPath::k_PathBezier ) + { + // False. + mEditWeight = false; + + // Invalid Selection. + return false; + } + + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + // Min Index. + S32 minNode = -1; + F32 minDistance = F32_MAX; + + for ( S32 i = 0; i < 2; i++ ) + { + Point3F pt; + if ( !Utility::FindNearestPointOnLine( mSelection.TangentHandle[i], pt0, pt1, &pt ) ) + { + // Skip. + continue; + } + + // Distance. + const F32 ptDistance = ( pt - mSelection.TangentHandle[i] ).len(); + if ( ptDistance < minDistance ) + { + // Store Index. + minNode = i; + + // Store Distance. + minDistance = ptDistance; + } + } + + if ( minDistance > gSelectionDistance ) + { + // False. + mEditWeight = false; + + // Too Far Away. + return false; + } + + // True. + mEditWeight = true; + mEditWeightHandle = minNode; + + return true; +} + +void VPathEditor::updateWeight( const Gui3DMouseEvent &pEvent ) +{ + if ( !isEditingWeight() ) + { + // Woops! + return; + } + + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + Point3F nodePos = node->getWorldPosition(); + + // Fetch Node Transform. + MatrixF mat = node->getWorldTransform(); + + // Fetch the Normal. + const VectorF planeNormal = mat.getColumn3F( 0 ); + + // Construct Plane. + const PlaneF plane( nodePos, planeNormal ); + + Point3F iPt; + if ( plane.intersect( pEvent.pos, pEvent.vec, &iPt ) ) + { +/* + // Fetch Edit Vector. + VectorF tangentVect( mSelection.TangentHandle[mEditWeightHandle] - nodePos ); + tangentVect.normalize(); + + // Fetch Mouse Vector. + VectorF mouseVec( iPt - nodePos ); + F32 mouseDist = mouseVec.len(); + mouseVec.normalize(); + + // Find the Angles. + F32 tangentAngle = mAtan2( -tangentVect.z, tangentVect.x ); + F32 mouseAngle = mAtan2( -mouseVec.z, mouseVec.x ); + + // Determine Sign. + const S32 sign = ( planeNormal.y > 0.f ) ? -1.f : 1.f; + + // Delta Rotation.. + const QuatF deltaRotation( AngAxisF( planeNormal, sign * ( mouseAngle - tangentAngle ) ) ); + + // Calculate New Rotation. + QuatF newRotation; + newRotation.mul( nodePos, deltaRotation ); + + // Apply Rotation. + setNodeRotation( mSelection.Node, newRotation ); +*/ +/* + // Fetch Edit Vector. + VectorF handleVec( mSelection.TangentHandle[mEditWeightHandle] - nodePos ); + handleVec.normalize(); + + // Fetch Mouse Vector. + VectorF mouseVec( iPt - nodePos ); + mouseVec.normalize(); + + // Find the Angles. + F32 handleAngle = Utility::GetPitch( handleVec ); //mAtan2( -handleVec.z, handleVec.x ); + F32 mouseAngle = Utility::GetPitch( mouseVec ); //mAtan2( -mouseVec.z, mouseVec.x ); + + // Determine Sign. + const S32 sign = ( planeNormal.y > 0.f ) ? -1.f : 1.f; + + // Delta Rotation. + MatrixF rotMat; + AngAxisF::RotateY( sign * ( mouseAngle - handleAngle ), &rotMat ); + + // Rotate. + mat.mul( rotMat ); + + QuatF newRotation; + newRotation.set( mat ); + + // Apply Rotation. + setNodeRotation( mSelection.Node, newRotation ); +*/ + // Apply Weight. + setNodeWeight( mSelection.Node, ( iPt - nodePos ).len() ); + } +} + +//----------------------------------------------------------------------------- +// +// Path Editing Methods. +// +//----------------------------------------------------------------------------- + +void VPathEditor::setPathPosition( const Point3F &pPosition ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Update Position. + serverPath->setPosition( pPosition ); + clientPath->setPosition( pPosition ); + + // Update Selection. + updateSelection(); +} + +void VPathEditor::setPathRotation( const QuatF &pRotation ) +{ + // Determine the Matrix. + MatrixF mat; + pRotation.setMatrix( &mat ); + mat.setPosition( mSelection.Path->getPosition() ); + + // Update Transform. + setPathTransform( mat ); +} + +void VPathEditor::setPathTransform( const MatrixF &pTransform ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Update Transform. + serverPath->setTransform( pTransform ); + clientPath->setTransform( pTransform ); + + // Update Selection. + updateSelection(); +} + +void VPathEditor::setPathScale( const VectorF &pScale ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Fetch Current Scale. + VectorF scale = serverPath->getScale(); + scale.convolve( pScale ); + + // Update Scale. + serverPath->setScale( scale ); + clientPath->setScale( scale ); + + // Update Selection. + updateSelection(); +} + +//----------------------------------------------------------------------------- +// +// Node Editing Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::getPointOnPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + if ( pPath->getNodeCount() < 2 ) + { + // Start / End Points. + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + // Create Intersection Plane. + const PlaneF plane( pPath->getPosition(), VPath::gBezierUp ); + + // Intersection Point. + Point3F intersectionPoint; + if ( !plane.intersect( pEvent.pos, pEvent.vec, &intersectionPoint ) ) + { + // No Intersection. + return false; + } + + // I'th Node. + pNode = pPath->getNodeCount(); + // Set Identity. + pTransform.identity(); + // Set Position. + pTransform.setPosition( intersectionPoint ); + + // Return. + return true; + } + + switch ( pPath->mPathType ) + { + case VPath::k_PathLinear : + { + + return getPointOnLinearPath( pPath, pEvent, pNode, pTransform ); + + } break; + + case VPath::k_PathBezier : + { + + return getPointOnBezierPath( pPath, pEvent, pNode, pTransform ); + + } break; + } + + return false; +} + +bool VPathEditor::getPointOnLinearPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + // Start / End Points. + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + S32 minNode = -1; + F32 minDistance = F32_MAX; + Point3F minPoint( 0.f, 0.f, 0.f ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Project to Screen. + Point3F srcNodeScreenPosition, dstNodeScreenPosition; + project( srcNode->getWorldPosition(), &srcNodeScreenPosition ); + project( dstNode->getWorldPosition(), &dstNodeScreenPosition ); + + // Skip? + if ( srcNodeScreenPosition.z > 1.f && dstNodeScreenPosition.z > 1.f ) + { + continue; + } + + Point3F ptOut0, ptOut1; + F32 ptOutDistance; + if ( !Utility::FindNearestDistanceBetweenLines( pt0, pt1, + srcNode->getWorldPosition(), dstNode->getWorldPosition(), + &ptOut0, &ptOut1, &ptOutDistance ) ) + { + continue; + } + + if ( ptOutDistance < minDistance ) + { + minDistance = ptOutDistance; + minPoint = ptOut1; + minNode = ( itr - pPath->mNodeList.begin() ); + } + } + + // Distance too Large? + if ( minDistance > 0.25f ) + { + // Invalid. + return false; + } + + // Setup. + pTransform.identity(); + pTransform.setPosition( minPoint ); + + // Store Node. + pNode = minNode; + + return true; +} + +bool VPathEditor::getPointOnBezierPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + S32 minNode = -1; + F32 minInterp = 0.f; + F32 minDistance = F32_MAX; + Point3F minPoint( 0.f, 0.f, 0.f ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Project to Screen. + Point3F srcNodeScreenPosition, dstNodeScreenPosition; + project( srcNode->getWorldPosition(), &srcNodeScreenPosition ); + project( dstNode->getWorldPosition(), &dstNodeScreenPosition ); + + // Skip? + if ( srcNodeScreenPosition.z > 1.f && dstNodeScreenPosition.z > 1.f ) + { + continue; + } + + // Positions. + const Point3F &pt0 = srcNode->getWorldPosition(); + const Point3F &pt3 = dstNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + srcNode->getWorldRotation().setMatrix( &mat0 ); + dstNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( VPath::gBezierAxis * srcNode->getWeight() ); + Point3F pt2( -VPath::gBezierAxis * dstNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + for ( F32 t = 0.f, it = 1.f; t <= 1.f; t += 0.1f, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F pos = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + + // Determine the Screen Position. + Point3F screenPos; + project( pos, &screenPos ); + // Behind? + if ( screenPos.z > 1.f ) + { + // Skip Point. + continue; + } + + // Determine the Distance. + F32 screenDistance = Point2F( screenPos.x - pEvent.mousePoint.x, screenPos.y - pEvent.mousePoint.y ).lenSquared(); + // Min Distance? + if ( screenDistance < minDistance ) + { + // Store. + minDistance = screenDistance; + minInterp = t; + minPoint = pos; + minNode = ( itr - pPath->mNodeList.begin() ); + } + } + } + + // Distance too Large? + if ( minDistance > 1000.f ) + { + // Invalid. + return false; + } + + // Fetch Orientation. + const VectorF &orientation = pPath->getPathOrientation( pPath->getNode( minNode ), + pPath->getNode( ( minNode + 1 ) % pPath->getNodeCount() ), + minInterp, true ); + + // Z-Axis. + VectorF zVec = -orientation; + zVec.normalize(); + + // X-Axis. + VectorF xVec = mCross( VPath::gBezierUp, zVec ); + xVec.normalize(); + + // Y-Axis. + VectorF yVec = mCross( zVec, xVec ); + yVec.normalize(); + + // Setup Object Transform. + pTransform.identity(); + pTransform.setColumn( 0, xVec ); + pTransform.setColumn( 1, -zVec ); + pTransform.setColumn( 2, yVec ); + // Set the Position. + pTransform.setPosition( minPoint ); + + // Store Node. + pNode = minNode; + + return true; +} + +void VPathEditor::addNode( const Gui3DMouseEvent &pEvent ) +{ + VPath *path = mSelection.Path; + if ( !path ) + { + // Woops! + return; + } + + // Min Index. + S32 nodeIndex = -1; + MatrixF nodeTransform( true ); + if ( !getPointOnPath( path, pEvent, nodeIndex, nodeTransform ) ) + { + // Can't Add. + return; + } + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + Point3F nodePosition = ( nodeTransform.getPosition() - mSelection.Path->getPosition() ); + pathTransform.mulP( nodePosition ); + + // Node Rotation. + nodeTransform.mul( pathTransform ); + QuatF nodeRotation( nodeTransform ); + + // Node Weights. + F32 nodeWeight = 10.f; + + // Add New Node. + VPathNode *node = path->addNode( nodePosition, nodeRotation, nodeWeight, ++nodeIndex ); + + // Valid Node? + if ( !node ) + { + return; + } + + // Update Size. + path->updateContainer(); + + // Calculate Path. + path->calculatePath(); + + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor::addNode() - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorAddNodeAction *editAction = new VPathEditorAddNodeAction(); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = path; + editAction->mNodeIndex = nodeIndex; + + editAction->mNodePosition = nodePosition; + editAction->mNodeRotation = nodeRotation; + editAction->mNodeWeight = nodeWeight; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Set World Editor Dirty. + setWorldEditorDirty(); +} + +void VPathEditor::deleteNode( const S32 &pNodeIndex ) +{ + VPath *path = mSelection.Path; + if ( !path ) + { + // Woops! + return; + } + + // Fetch Node Properites. + VPathNode *node = path->getNode( pNodeIndex ); + const Point3F position = node->getLocalPosition(); + const QuatF rotation = node->getLocalRotation(); + const F32 weight = node->getWeight(); + + // Delete Node. + path->deleteNode( pNodeIndex ); + + // Update Path. + path->updateContainer(); + + // Calculate Path. + path->calculatePath(); + + // Selected Node? + const S32 _nodeIndex = pNodeIndex; + if ( pNodeIndex == mSelection.Node ) + { + // Update Selection. + updateSelection( mSelection.Path, -1 ); + } + + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor::deleteNode() - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorDeleteNodeAction *editAction = new VPathEditorDeleteNodeAction(); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = path; + editAction->mNodeIndex = _nodeIndex; + + editAction->mNodePosition = position; + editAction->mNodeRotation = rotation; + editAction->mNodeWeight = weight; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Set World Editor Dirty. + setWorldEditorDirty(); +} + +void VPathEditor::setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeLocalPosition( pNodeIndex ) == pPosition ) + { + return; + } + + // Set Position. + serverPath->setNodePosition( pNodeIndex, pPosition ); + clientPath->setNodePosition( pNodeIndex, pPosition ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodePosition", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeLocalRotation( pNodeIndex ) == pRotation ) + { + return; + } + + // Set Position. + serverPath->setNodeRotation( pNodeIndex, pRotation ); + clientPath->setNodeRotation( pNodeIndex, pRotation ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeRotation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeWeight( pNodeIndex ) == pWeight ) + { + return; + } + + // Set Weight. + serverPath->setNodeWeight( pNodeIndex, pWeight ); + clientPath->setNodeWeight( pNodeIndex, pWeight ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeWeight", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Set Orientation Mode. + serverPath->setNodeOrientationMode( pNodeIndex, pType ); + clientPath->setNodeOrientationMode( pNodeIndex, pType ); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeOrientation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F &pPoint ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Set Orientation Mode. + serverPath->setNodeOrientationMode( pNodeIndex, pType, pPoint ); + clientPath->setNodeOrientationMode( pNodeIndex, pType, pPoint ); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeOrientation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::pushPathEdit( void ) +{ + // Clear Current Edit Dirty. + mPathEdit.Dirty = false; + + if ( mSelection.Path != NULL ) + { + // Store Node Details. + mPathEdit.Transform = mSelection.Path->getTransform(); + } +} + +void VPathEditor::popPathEdit( void ) +{ + // Did Edit? + if ( mPathEdit.Dirty && mSelection.Path != NULL ) + { + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorEditPathAction *editAction = new VPathEditorEditPathAction( "Edit Path" ); + + // Store Editor. + editAction->mEditor = this; + + // Store Path Details. + editAction->mPath = mSelection.Path; + editAction->mTransform = mPathEdit.Transform; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Clear Dirty. + mPathEdit.Dirty = false; + + // Set World Editor Dirty. + setWorldEditorDirty(); + } +} + +void VPathEditor::pushNodeEdit( void ) +{ + // Clear Current Edit Dirty. + mNodeEdit.Dirty = false; + + if ( isValidSelection() ) + { + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Store Node Details. + mNodeEdit.Position = node->getLocalPosition(); + mNodeEdit.Rotation = node->getLocalRotation(); + mNodeEdit.Weight = node->getWeight(); + } +} + +void VPathEditor::popNodeEdit( void ) +{ + // Did Edit? + if ( mNodeEdit.Dirty && isValidSelection() ) + { + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorEditNodeAction *editAction = new VPathEditorEditNodeAction( "Edit Node" ); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = mSelection.Path; + editAction->mNodeIndex = mSelection.Node; + + editAction->mNodePosition = mNodeEdit.Position; + editAction->mNodeRotation = mNodeEdit.Rotation; + editAction->mNodeWeight = mNodeEdit.Weight; + + editAction->mNodeOrientation = mSelection.Path->getNode( mSelection.Node )->getOrientationMode(); + + // Add To Manager. + historyManager->addAction( editAction ); + + // Clear Dirty. + mNodeEdit.Dirty = false; + + // Set World Editor Dirty. + setWorldEditorDirty(); + } +} + +void VPathEditor::setWorldEditorDirty( void ) +{ + WorldEditor *worldEditor; + if ( Sim::findObject( "EWorldEditor", worldEditor ) ) + { + worldEditor->setDirty(); + } +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VPathEditor::setStateBlock( void ) +{ + // Valid State Block? + if ( !mStateBlock ) + { + // Setup Definition. + GFXStateBlockDesc def; + def.blendDefined = true; + def.blendEnable = true; + def.blendSrc = GFXBlendSrcAlpha; + def.blendDest = GFXBlendInvSrcAlpha; + def.zDefined = true; + def.cullDefined = false; + + // Create State Block. + mStateBlock = GFX->createStateBlock( def ); + } + + // Set State Block. + GFX->setStateBlock( mStateBlock ); +} + +void VPathEditor::renderScene( const RectI &pUpdateRect ) +{ + // Setup State Block. + setStateBlock(); + + if ( isValidSelection() ) + { + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Render Gizmo? + if ( mEditMode == k_Gizmo && mGizmoProfile->mode != ScaleMode ) + { + // Fetch Node Transform. + MatrixF mat= node->getWorldTransform(); + + // Move Gizmo. + mGizmo->set( mat, node->getWorldPosition(), Point3F( 1.0f, 1.0f, 1.0f ) ); + + // Render Gizmo. + mGizmo->renderGizmo( mLastCameraQuery.cameraMatrix ); + } + + // Render Handles? + if ( mSelection.Path->mPathType == VPath::k_PathBezier ) + { + // Fetch Tangent Handles. + const Point3F &pt0 = mSelection.TangentHandle[0]; + const Point3F &pt1 = mSelection.TangentHandle[1]; + + // State Block. + GFXStateBlockDesc desc; + desc.setZReadWrite( true, true ); + desc.fillMode = GFXFillSolid; + + // Set Color. + PrimBuild::color( gPathColorSel ); + + // Render Line. + PrimBuild::begin( GFXLineList, 2 ); + PrimBuild::vertex3fv( pt0 ); + PrimBuild::vertex3fv( pt1 ); + PrimBuild::end(); + + // Render Handles. + GFX->getDrawUtil()->drawSphere( desc, 0.1f, pt0, gPathColorSel ); + GFX->getDrawUtil()->drawSphere( desc, 0.1f, pt1, gPathColorSel ); + } + + // ToPoint Node? + if ( node->getOrientationMode().Type == VPathNode::k_OrientationToPoint ) + { + PrimBuild::color( gNodeLookAtPointColor ); + PrimBuild::begin( GFXLineStrip, 2 ); + + PrimBuild::vertex3fv( node->getWorldPosition() ); + PrimBuild::vertex3fv( node->getOrientationMode().Point ); + + PrimBuild::end(); + } + } + else if ( mSelection.Path && mEditMode == k_Gizmo ) + { + switch ( mGizmoProfile->mode ) + { + case MoveMode: + { + // Fetch Path Transform. + const MatrixF &mat = mSelection.Path->getTransform(); + + // Fetch the Path's Box Center. + const Point3F &pos = mSelection.Path->getWorldBox().getCenter(); + + // Move Gizmo. + mGizmo->set( mat, pos, Point3F( 1.0f, 1.0f, 1.0f ) ); + + // Render Gizmo. + mGizmo->renderGizmo( mLastCameraQuery.cameraMatrix ); + + } break; + } + } + + // Render Path Segments. + renderPaths( k_RenderSegments ); + + // Set Clip Rect. + GFX->setClipRect( pUpdateRect ); + + // Render Path Nodes. + renderPaths( k_RenderNodes ); + + if ( isValidSelection() ) + { + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // ToPoint Node? + if ( node->getOrientationMode().Type == VPathNode::k_OrientationToPoint ) + { + // Project to Screen. + Point3F screenPosition; + project( node->getOrientationMode().Point, &screenPosition ); + if ( screenPosition.z <= 1.0f ) + { + // Determine the center & size of the node rectangle. + Point2I nodeCenter = Point2I( screenPosition.x, screenPosition.y ); + Point2I nodeHalfSize = Point2I( 8, 8 ); + // Determine Render Rectangle. + RectI nodeRect; + nodeRect.point = nodeCenter - nodeHalfSize; + nodeRect.extent = ( 2 * nodeHalfSize ); + + // Draw? + if ( getBounds().overlaps( nodeRect ) ) + { + // Render the Point. + GFX->getDrawUtil()->drawRectFill( nodeRect, gNodeLookAtPointColor ); + } + } + } + } +} + +void VPathEditor::renderPaths( const RenderType &pRenderType ) +{ + SimSet *objectSet = VPath::getServerSet(); + for ( SimSetIterator itr( objectSet ); *itr; ++itr ) + { + VPath *path = dynamic_cast( *itr ); + if ( path ) + { + // Render Path. + renderPath( pRenderType, path, ( path == mSelection.Path ) ? gPathColorSel : gPathColor ); + } + } +} + +void VPathEditor::renderPath( const RenderType &pRenderType, VPath *pPath, const ColorI &pColor ) +{ + if ( !pPath ) + { + // Sanity! + return; + } + + switch ( pRenderType ) + { + case k_RenderSegments : + { + switch ( pPath->mPathType ) + { + case VPath::k_PathLinear : + { + renderLinearPath( pPath, pColor ); + + } break; + + case VPath::k_PathBezier : + { + renderBezierPath( pPath, pColor ); + + } break; + } + + } break; + + case k_RenderNodes : + { + // Fetch Draw Util. + GFXDrawUtil *drawUtil = GFX->getDrawUtil(); + + // Fetch Bounds. + RectI bounds = getBounds(); + + const Point2I nodeMinHalfSize( 8, 8 ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Project to Screen. + Point3F screenPosition; + project( node->getWorldPosition(), &screenPosition ); + if ( screenPosition.z > 1.0f ) + { + continue; + } + + // Determine the node text information. + const char *nodeText = avar( "%d", ( itr - pPath->mNodeList.begin() ) ); + const Point2I nodeTextHalfSize = Point2I( 0.5f * (F32)getControlProfile()->mFont->getStrWidth( nodeText ), + 0.5f * (F32)getControlProfile()->mFont->getHeight() ); + + // Determine the center & size of the node rectangle. + Point2I nodeCenter = Point2I( screenPosition.x, screenPosition.y ); + Point2I nodeHalfSize = Point2I( nodeTextHalfSize.x + 3, nodeTextHalfSize.y + 3 ); + nodeHalfSize.setMax( nodeMinHalfSize ); + // Determine Render Rectangle. + RectI nodeRect; + nodeRect.point = nodeCenter - nodeHalfSize; + nodeRect.extent = ( 2 * nodeHalfSize ); + + // Draw? + if ( !bounds.overlaps( nodeRect ) ) + { + continue; + } + + // Render the Point. + drawUtil->drawRectFill( nodeRect, pColor ); + + // Draw the node index text. + drawUtil->setBitmapModulation( getControlProfile()->mFontColor ); + drawUtil->drawText( getControlProfile()->mFont, nodeCenter - nodeTextHalfSize, nodeText ); + } + + } break; + } +} + +void VPathEditor::renderLinearPath( VPath *pPath, const ColorI &pColor ) +{ + if ( pPath->mNodeList.size() < 2 ) + { + // No Lines. + return; + } + + PrimBuild::color( pColor ); + PrimBuild::begin( GFXLineStrip, ( pPath->mNodeList.size() + 1 ) ); + + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Apply Vertex. + PrimBuild::vertex3fv( ( *itr )->getWorldPosition() ); + } + + // Loop Back. + PrimBuild::vertex3fv( pPath->mNodeList.front()->getWorldPosition() ); + + PrimBuild::end(); +} + +void VPathEditor::renderBezierPath( VPath *pPath, const ColorI &pColor ) +{ + if ( pPath->mNodeList.size() < 2 ) + { + // No Lines. + return; + } + + PrimBuild::color( pColor ); + PrimBuild::begin( GFXLineStrip, U32( ( ( 1.01f / 0.01f ) + 1 ) * pPath->mNodeList.size() ) ); + + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Positions. + const Point3F &pt0 = srcNode->getWorldPosition(); + const Point3F &pt3 = dstNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + srcNode->getWorldRotation().setMatrix( &mat0 ); + dstNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( VPath::gBezierAxis * srcNode->getWeight() ); + Point3F pt2( -VPath::gBezierAxis * dstNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + for ( F32 t = 0.f, it = 1.f; t <= 1.f; t += 0.01f, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F pos = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + // Apply Vertex. + PrimBuild::vertex3fv( pos ); + } + } + + PrimBuild::end(); +} + +//----------------------------------------------------------------------------- +// +// History Events +// +//----------------------------------------------------------------------------- + +void VPathEditor::VPathEditorEditPathAction::undo( void ) +{ + const MatrixF oldTransform = mTransform; + const MatrixF newTransform = mPath->getTransform(); + + // Apply Old Values. + mEditor->setPathTransform( oldTransform ); + + // The ol' Switcheroo. + mTransform = newTransform; + + // Update Selection. + mEditor->updateSelection(); + + if ( mPath == mEditor->mSelection.Path ) + { + // Arg Buffer. + char buffer[32]; + dSprintf( buffer, sizeof( buffer ), "%d", mPath->getId() ); + + // Callback. + Con::executef( mEditor, "onUpdatePath", buffer ); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorEditPathAction::redo( void ) +{ + // Undo. + undo(); +} + +void VPathEditor::VPathEditorEditNodeAction::undo( void ) +{ + // Fetch Properties. + const Point3F oldPosition = mNodePosition; + const QuatF oldRotation = mNodeRotation; + const F32 oldWeight = mNodeWeight; + const VPathNode::sOrientation oldOrientation = mNodeOrientation; + + VPathNode *node = mPath->getNode( mNodeIndex ); + const Point3F newPosition = node->getLocalPosition(); + const QuatF newRotation = node->getLocalRotation(); + const F32 newWeight = node->getWeight(); + const VPathNode::sOrientation newOrientation = node->getOrientationMode(); + + // Apply Old Values. + mPath->setNodePosition( mNodeIndex, oldPosition ); + mPath->setNodeRotation( mNodeIndex, oldRotation ); + mPath->setNodeWeight( mNodeIndex, oldWeight ); + + switch( oldOrientation.Type ) + { + case VPathNode::k_OrientationFree : + { + + // Orient Free. + mPath->setNodeOrientationMode( mNodeIndex, oldOrientation.Type ); + + } break; + + case VPathNode::k_OrientationToPoint : + { + + // Orient To Point. + mPath->setNodeOrientationMode( mNodeIndex, oldOrientation.Type, oldOrientation.Point ); + + } break; + } + + // The ol' Switcheroo. + mNodePosition = newPosition; + mNodeRotation = newRotation; + mNodeWeight = newWeight; + mNodeOrientation = newOrientation; + + // Update Selection. + mEditor->updateSelection(); + + if ( mPath == mEditor->mSelection.Path ) + { + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mPath->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", mNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mEditor->mSelection.Node == mNodeIndex ) ); + + // Callback. + Con::executef( mEditor, "onUpdateNode", buffer[0], buffer[1], buffer[2] ); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorEditNodeAction::redo( void ) +{ + // Undo. + undo(); +} + +void VPathEditor::VPathEditorAddNodeAction::undo( void ) +{ + // Selected Node? + if ( mNodeIndex == mEditor->mSelection.Node ) + { + // Update Selection. + mEditor->updateSelection( mEditor->mSelection.Path, -1 ); + } + + // Delete Node. + mPath->deleteNode( mNodeIndex ); + + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorAddNodeAction::redo( void ) +{ + // Add Node. + VPathNode *node = mPath->addNode( mNodePosition, mNodeRotation, mNodeWeight, mNodeIndex ); + + // Valid Node? + if ( node ) + { + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorDeleteNodeAction::undo( void ) +{ + // Add Node. + VPathNode *node = mPath->addNode( mNodePosition, mNodeRotation, mNodeWeight, mNodeIndex ); + + // Valid Node? + if ( node ) + { + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorDeleteNodeAction::redo( void ) +{ + // Delete Node. + mPath->deleteNode( mNodeIndex ); + + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +//----------------------------------------------------------------------------- +// +// Script Edit Methods +// +//----------------------------------------------------------------------------- + +ConsoleMethod( VPathEditor, setNodePosition, void, 3, 3, "( pPosition )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodePosition() - Invalid Node Selection." ); + return; + } + + // Fetch Position. + Point3F position; + dSscanf( argv[2], "%g %g %g", &position.x, &position.y, &position.z ); + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodePosition( object->mSelection.Node, position ); + + // Create Undo Action. + object->popNodeEdit(); +} + +ConsoleMethod( VPathEditor, setNodeRotation, void, 3, 3, "( pRotation )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeRotation() - Invalid Node Selection." ); + return; + } + + // Fetch Rotation. + AngAxisF aa; + QuatF rotation; + dSscanf( argv[2], "%g %g %g %g", &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle ); + + // Set Rotation. + rotation.set( aa ); + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodeRotation( object->mSelection.Node, rotation ); + + // Create Undo Action. + object->popNodeEdit(); +} + +ConsoleMethod( VPathEditor, setNodeWeight, void, 3, 3, "( pWeight )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeWeight() - Invalid Node Selection." ); + return; + } + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodeWeight( object->mSelection.Node, dAtof( argv[2] ) ); + + // Create Undo Action. + object->popNodeEdit(); +} + +ConsoleMethod( VPathEditor, setNodeOrientationMode, void, 3, 4, "( string pOrientationType, [vector pPoint] )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeOrientationMode() - Invalid Node Selection." ); + return; + } + + // Store. + object->pushNodeEdit(); + + // Orient? + const VPathNode::eOrientationType type = VPathNode::getOrientationTypeEnum( argv[2] ); + + switch ( type ) + { + case VPathNode::k_OrientationFree : + { + + // Apply Mode. + object->setNodeOrientationMode( object->mSelection.Node, type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( argv[3], "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + object->setNodeOrientationMode( object->mSelection.Node, type, lookAtPoint ); + + } break; + } + + // Create Undo Action. + object->popNodeEdit(); +} + +//----------------------------------------------------------------------------- +// +// Utility +// +//----------------------------------------------------------------------------- + +bool Utility::FindNearestDistanceBetweenLines( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, Point3F *pOutA, Point3F *pOutB, F32 *pDist ) +{ + const Point3F pA1A0 = ( pA1 - pA0 ); + if ( pA1A0.isZero() ) + { + return false; + } + + const Point3F pB1B0 = ( pB1 - pB0 ); + if ( pB1B0.isZero() ) + { + return false; + } + + const Point3F pA0B0 = ( pA0 - pB0 ); + + const F32 &d1343 = pA0B0.x * pB1B0.x + pA0B0.y * pB1B0.y + pA0B0.z * pB1B0.z; + const F32 &d4321 = pB1B0.x * pA1A0.x + pB1B0.y * pA1A0.y + pB1B0.z * pA1A0.z; + const F32 &d1321 = pA0B0.x * pA1A0.x + pA0B0.y * pA1A0.y + pA0B0.z * pA1A0.z; + const F32 &d4343 = pB1B0.x * pB1B0.x + pB1B0.y * pB1B0.y + pB1B0.z * pB1B0.z; + const F32 &d2121 = pA1A0.x * pA1A0.x + pA1A0.y * pA1A0.y + pA1A0.z * pA1A0.z; + + const F32 &denom = d2121 * d4343 - d4321 * d4321; + if ( mIsZero( denom ) ) + { + return false; + } + + const F32 &mua = ( d1343 * d4321 - d1321 * d4343 ) / denom; + const F32 &mub = ( d1343 + d4321 * mua ) / d4343; + + *pOutA = pA0 + mua *pA1A0; + *pOutB = pB0 + mub *pB1B0; + + // Store Distance. + *pDist = ( ( *pOutA ) - ( *pOutB ) ).len(); + + return true; +} + +bool Utility::IntersectLineSegment( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, const bool pSnap, Point3F *pX ) +{ + // + // Finding the intersection with the following method: + // We have line a going from P1 to P2: + // Pa = P1 + ua( P2 - P1 ) + // and line b going from P3 to P4: + // Pb = P3 + ub( P4 - P3 ) + // + // Solving for Pa = Pb: + // x1 + ua( x2 - x1 ) = x3 + ub( x4 - x3 ) + // y1 + ua( y2 - y1 ) = y3 + ub( y4 - y3 ) + // + // Solving for ua and ub: + // ua = ( ( x4 - x3 )( y1 - y3 ) - ( y4 - y3 )( x1 - x3 ) ) / d + // ub = ( ( x2 - x1 )( y1 - y3 ) - ( y2 - y1 )( x1 - x3 ) ) / d + // denom = ( y4 - y3 )( x2 - x1 ) - ( x4 - x3 )( y2 - y1 ) + // + // x = x1 + ua( x2 - x1 ) + // y = y1 + ua( y2 - y1 ) + // + + const F32 d = ( ( pB1.y - pB0.y ) * ( pA1.x - pA0.x ) ) - ( ( pB1.x - pB0.x ) * ( pA1.y - pA0.y ) ); + + if ( d == 0.0f ) + { + // Lines are parallel + return false; + } + + // Find the point of intersection + const F32 uA = ( ( ( pB1.x - pB0.x ) * ( pA0.y - pB0.y ) ) - ( ( pB1.y - pB0.y ) * ( pA0.x - pB0.x ) ) ) / d; + const F32 uB = ( ( ( pA1.x - pA0.x ) * ( pA0.y - pB0.y ) ) - ( ( pA1.y - pA0.y ) * ( pA0.x - pB0.x ) ) ) / d; + + if ( !pSnap + && ( ( uA < 0.0f ) || ( uA > 1.0f ) + || ( uB < 0.0f ) || ( uB > 1.0f ) ) ) + { + return false; + } + + if ( pX ) + { + if ( uA < 0.0f ) + { + *pX = pA0; + } + else if ( uA > 1.f ) + { + *pX = pA1; + } + else + { + // The path intersects the segment + *pX = pA0 + uA * ( pA1 - pA0 ); + } + } + + return true; +} + +bool Utility::FindNearestPointOnLine( const Point3F &pSrcPosition, const Point3F &pA0, const Point3F &pA1, Point3F *pDstPosition ) +{ + const Point3F up( 0.0f, 0.0f, 1.0f ); + + Point3F dir = ( pA1 - pA0 ); + dir.normalize(); + + Point3F normal = mCross( dir, up ); + normal.normalize(); + + // Find the nearest intersection point between the point and the line + + const Point3F b0 = pSrcPosition + ( normal * 100000.0f ); + const Point3F b1 = pSrcPosition - ( normal * 100000.0f ); + + return IntersectLineSegment( pA0, pA1, b0, b1, true, pDstPosition ); +} + +F32 Utility::GetPitch( const VectorF &pVec ) +{ + F32 pitch; + if ( mFabs( pVec.x ) > mFabs( pVec.y ) ) + { + pitch = mAtan2( mFabs( pVec.z ), mFabs( pVec.x ) ); + } + else + { + pitch = mAtan2( mFabs( pVec.z ), mFabs( pVec.y ) ); + } + + if ( pVec.z < 0.f ) + { + pitch = -pitch; + } + + return pitch; +} + +F32 Utility::GetYaw( const VectorF &pVec ) +{ + F32 yaw = mAtan2( pVec.x, pVec.y ); + if ( yaw < 0.f ) + { + yaw += M_2PI_F; + } + + return yaw; +} \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathEditor.h b/Engine/modules/Verve/VPath/VPathEditor.h new file mode 100644 index 000000000..c337edd0c --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathEditor.h @@ -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_ \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathNode.cpp b/Engine/modules/Verve/VPath/VPathNode.cpp new file mode 100644 index 000000000..d18794c4e --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathNode.cpp @@ -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 ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathNode.h b/Engine/modules/Verve/VPath/VPathNode.h new file mode 100644 index 000000000..dd829c5b5 --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathNode.h @@ -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_ \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathObject.cpp b/Engine/modules/Verve/VPath/VPathObject.cpp new file mode 100644 index 000000000..5d1116b78 --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathObject.cpp @@ -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( 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( 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( 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 ); +} \ No newline at end of file diff --git a/Engine/modules/Verve/VPath/VPathObject.h b/Engine/modules/Verve/VPath/VPathObject.h new file mode 100644 index 000000000..72153021d --- /dev/null +++ b/Engine/modules/Verve/VPath/VPathObject.h @@ -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_ \ No newline at end of file diff --git a/Engine/modules/Verve/VerveConfig.h b/Engine/modules/Verve/VerveConfig.h new file mode 100644 index 000000000..deaf8f831 --- /dev/null +++ b/Engine/modules/Verve/VerveConfig.h @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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_VERVECONFIG_H_ +#define _VT_VERVECONFIG_H_ + +//----------------------------------------------------------------------------- + +//#define VT_EDITOR + +//----------------------------------------------------------------------------- + +#endif // _VT_VERVECONFIG_H_ \ No newline at end of file diff --git a/Engine/source/T3D/assets/GameObjectAsset.cpp b/Engine/source/T3D/assets/GameObjectAsset.cpp index c49588b8e..43b17f3de 100644 --- a/Engine/source/T3D/assets/GameObjectAsset.cpp +++ b/Engine/source/T3D/assets/GameObjectAsset.cpp @@ -137,6 +137,8 @@ void GameObjectAsset::initializeAsset() if (Platform::isFile(mScriptFile)) Con::executeFile(mScriptFile, false, false); + + mTAMLFile = expandAssetFilePath(mTAMLFile); } void GameObjectAsset::onAssetRefresh() @@ -146,6 +148,8 @@ void GameObjectAsset::onAssetRefresh() if (Platform::isFile(mScriptFile)) Con::executeFile(mScriptFile, false, false); + + mTAMLFile = expandAssetFilePath(mTAMLFile); } void GameObjectAsset::setScriptFile(const char* pScriptFile) @@ -161,7 +165,7 @@ void GameObjectAsset::setScriptFile(const char* pScriptFile) return; // Update. - mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : StringTable->insert(pScriptFile); + mScriptFile = expandAssetFilePath(pScriptFile); // Refresh the asset. refreshAsset(); @@ -177,11 +181,11 @@ void GameObjectAsset::setTAMLFile(const char* pTAMLFile) pTAMLFile = StringTable->insert(pTAMLFile); // Ignore no change, - if (pTAMLFile == mScriptFile) + if (pTAMLFile == mTAMLFile) return; // Update. - mTAMLFile = getOwned() ? expandAssetFilePath(pTAMLFile) : StringTable->insert(pTAMLFile); + mTAMLFile = expandAssetFilePath(pTAMLFile); // Refresh the asset. refreshAsset(); diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 5637d1eff..cace59c49 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -90,8 +90,8 @@ ConsoleSetType(TypeMaterialAssetPtr) MaterialAsset::MaterialAsset() { mShaderGraphFile = ""; - mScriptFile = ""; - mMatDefinitionName = ""; + mScriptFile = StringTable->EmptyString(); + mMatDefinitionName = StringTable->EmptyString(); } //----------------------------------------------------------------------------- @@ -111,7 +111,7 @@ void MaterialAsset::initPersistFields() addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); - addField("materialDefinitionName", TypeRealString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for."); + addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for."); } void MaterialAsset::initializeAsset() diff --git a/Engine/source/T3D/assets/MaterialAsset.h b/Engine/source/T3D/assets/MaterialAsset.h index df6a135fb..4ace9586f 100644 --- a/Engine/source/T3D/assets/MaterialAsset.h +++ b/Engine/source/T3D/assets/MaterialAsset.h @@ -56,7 +56,7 @@ class MaterialAsset : public AssetBase typedef AssetBase Parent; String mShaderGraphFile; - String mScriptFile; + StringTableEntry mScriptFile; StringTableEntry mMatDefinitionName; public: diff --git a/Engine/source/Verve/Core/ITreeNode.h b/Engine/source/Verve/Core/ITreeNode.h new file mode 100644 index 000000000..943dd554d --- /dev/null +++ b/Engine/source/Verve/Core/ITreeNode.h @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// 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_ITREENODE_H_ +#define _VT_ITREENODE_H_ + +//----------------------------------------------------------------------------- + +class ITreeNode +{ +public: + + ITreeNode *mParentNode; + ITreeNode *mChildNode; + + ITreeNode *mSiblingPrevNode; + ITreeNode *mSiblingNextNode; + +public: + + ITreeNode( void ) : + mParentNode( 0 ), + mChildNode( 0 ), + mSiblingPrevNode( 0 ), + mSiblingNextNode( 0 ) + { + // Void. + }; + + virtual ~ITreeNode( void ) + { + // Void. + }; + + virtual void clear( void ) = 0; // Clear the Node. + + virtual ITreeNode *getRoot( void ) = 0; // Get Root Node. + virtual ITreeNode *getParent( void ) = 0; // Get Parent Node. + virtual ITreeNode *getChild( void ) = 0; // Get Child Node. + virtual ITreeNode *getLastChild( void ) = 0; // Get Last Child Node. + + virtual ITreeNode *getPrevSibling( void ) = 0; // Get Previous Sibling Node. + virtual ITreeNode *getNextSibling( void ) = 0; // Get Next Sibling Node. + + virtual void addTo( ITreeNode *pNode ) = 0; // Add Node to target node. + virtual void remove( void ) = 0; // Remove this Node from the tree. + virtual void moveTo( ITreeNode* node ) = 0; // Move to specified Node. + + virtual void onAttach( void ) = 0; // Attach Callback. + virtual void onDetach( void ) = 0; // Detach Callback. + + virtual bool inTree( void ) = 0; // Is Node in a tree? +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_ITREENODE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/Persistence/VPersistence.cpp b/Engine/source/Verve/Core/Persistence/VPersistence.cpp new file mode 100644 index 000000000..daf3336a9 --- /dev/null +++ b/Engine/source/Verve/Core/Persistence/VPersistence.cpp @@ -0,0 +1,137 @@ +//----------------------------------------------------------------------------- +// 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/Persistence/VPersistence.h" + +#include "Verve/Core/VController.h" +#include "Verve/Core/VObject.h" + +namespace VPersistence +{ + //----------------------------------------------------------------------------- + // + // VController + // + //----------------------------------------------------------------------------- + + template <> + bool write( TiXmlElement *pElement, VController *pObject ) + { + // Write Properties. + if ( !writeProperties( pElement, pObject ) ) + { + return false; + } + + // Write Data Table. + if ( !pObject->writeDataTable( pElement ) ) + { + return false; + } + + // Write Objects. + return writeObjects( pElement, pObject ); + } + + template <> + bool read( TiXmlElement *pElement, VController *pObject ) + { + // Read Properties. + if ( !readProperties( pElement, pObject ) ) + { + // Invalid Properties. + return false; + } + + // Read Data Table. + if ( !pObject->readDataTable( pElement ) ) + { + // Invalid Data Table. + return false; + } + + // Read Objects. + if ( !readObjects( pElement, pObject ) ) + { + // Invalid Read. + return false; + } + + // Valid Read. + return true; + } + + //----------------------------------------------------------------------------- + // + // VObject + // + //----------------------------------------------------------------------------- + + template <> + bool write( TiXmlElement *pElement, VObject *pObject ) + { + // Create Element. + TiXmlElement *objectElement = new TiXmlElement( "VObject" ); + pElement->LinkEndChild( objectElement ); + + // Attributes. + objectElement->SetAttribute( "Type", pObject->getClassName() ); + + // Write Properties. + if ( !writeProperties( objectElement, pObject ) ) + { + return false; + } + + // Write Objects. + return writeObjects( objectElement, pObject ); + } + + template <> + bool read( TiXmlElement *pElement, VObject *pObject ) + { + // Read Properties. + if ( !readProperties( pElement, pObject ) ) + { + // Invalid Properties. + return false; + } + + // Set Name Unique. + pObject->setLabelUnique( pObject->getLabel() ); + + // Read Objects. + if ( !readObjects( pElement, pObject ) ) + { + // Invalid Objects. + return false; + } + +#ifdef VT_EDITOR + // Callback. + Con::executef( pObject, "onRead" ); +#endif + + // Valid Read. + return true; + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Core/Persistence/VPersistence.h b/Engine/source/Verve/Core/Persistence/VPersistence.h new file mode 100644 index 000000000..6c357681d --- /dev/null +++ b/Engine/source/Verve/Core/Persistence/VPersistence.h @@ -0,0 +1,286 @@ +//----------------------------------------------------------------------------- +// 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_VPERSISTENCE_H_ +#define _VT_VPERSISTENCE_H_ + +#ifndef TINYXML_INCLUDED +#include "tinyxml/tinyxml.h" +#endif + +#ifndef _SIMOBJECT_H_ +#include "console/simObject.h" +#endif + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- + +namespace VPersistence +{ + static const char *VSFVersionString = "0.0.0a"; + + // This object is used to filter fields which belong to SimObject's. + // There is no need to serialize these fields, so they are skipped + // entirely. + static SimObject DummySimObject; + + //------------------------------------------------------------------------- + + template bool writeFile( const char* pFileName, T *pObject ) + { + // Create Doc. + TiXmlDocument xmlDocument; + TiXmlDeclaration *xmlDeclaration = new TiXmlDeclaration( "1.0", "", "" ); + xmlDocument.LinkEndChild( xmlDeclaration ); + + // Create Root. + TiXmlElement *xmlRoot = new TiXmlElement( "VerveControllerSequence" ); + xmlDocument.LinkEndChild( xmlRoot ); + + // Write Version. + xmlRoot->SetAttribute( "Version", VSFVersionString ); + + // Write Object. + if ( !write( xmlRoot, pObject ) ) + { + Con::errorf( "VPersistence::writeFile() - Unable to Write Object." ); + return false; + } + + // Save File. + return xmlDocument.SaveFile( pFileName ); + }; + + template bool write( TiXmlElement *pElement, T *pObject ); + + template bool writeProperties( TiXmlElement *pElement, T *pObject ) + { + const AbstractClassRep::FieldList &fieldList = pObject->getFieldList(); + const AbstractClassRep::Field *field = NULL; + + // Create Property Root. + TiXmlElement *propertyRoot = new TiXmlElement( "Properties" ); + pElement->LinkEndChild( propertyRoot ); + + const S32 fieldCount = fieldList.size(); + for ( S32 i = 0; i < fieldCount; i++ ) + { + field = &fieldList[i]; + + if ( field->type >= AbstractClassRep::ARCFirstCustomField ) + { + // Ignore Special Fields. + continue; + } + + // Fetch the Field Name. + const char *fieldName = field->pFieldname; + // SimObject Field? + if ( DummySimObject.findField( fieldName ) != NULL ) + { + // Skip SimObject Fields. + continue; + } + + // Fetch the Field Value. + const char *fieldValue = ( *field->getDataFn )( pObject, Con::getData( field->type, ( void * ) ( ( ( const char * )pObject ) + field->offset ), 0, field->table, field->flag ) ); + + if ( fieldValue ) + { + // Create Element. + TiXmlElement *propertyElement = new TiXmlElement( fieldName ); + + // Apply Value. + propertyElement->InsertEndChild( TiXmlText( fieldValue ) ); + + // Add. + propertyRoot->LinkEndChild( propertyElement ); + } + } + + // Valid Write. + return true; + }; + + template bool writeObjects( TiXmlElement *pElement, T *pObject ) + { + for ( ITreeNode *node = pObject->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + // Write Group. + if ( !write( pElement, ( VObject* )node ) ) + { + // Invalid Write. + return false; + } + } + + // Valid Write. + return true; + } + + //------------------------------------------------------------------------- + + template bool readFile( const char* pFileName, T *pObject ) + { + TiXmlDocument xmlDocument; + if ( !xmlDocument.LoadFile( pFileName ) ) + { + Con::errorf( "VPersistence::readFile() - Unable to load file '%s'.", pFileName ); + return false; + } + + TiXmlElement *rootElement = xmlDocument.RootElement(); + if ( !rootElement ) + { + Con::errorf( "VPersistence::readFile() - Invalid Document '%s'.", pFileName ); + return false; + } + + const char *docVersion = rootElement->Attribute( "Version" ); + if ( !docVersion || dStrcmp( VSFVersionString, docVersion ) != 0 ) + { + Con::errorf( "VPersistence::readFile() - Invalid file version." ); + return false; + } + + // Read Object. + if ( !read( rootElement, pObject ) ) + { + // Invalid Read. + return false; + } + + // Valid. + return true; + }; + + template bool read( TiXmlElement *pElement, T *pObject ); + + template bool readProperties( TiXmlElement *pElement, T *pObject ) + { + TiXmlElement *propertyRoot = pElement->FirstChildElement( "Properties" ); + if ( propertyRoot ) + { + for ( TiXmlElement *child = propertyRoot->FirstChildElement(); child != NULL; child = child->NextSiblingElement() ) + { + // Get Field Data. + const char *fieldName = child->Value(); + const char *fieldValue = child->GetText(); + + if ( !fieldValue ) + { + // Clear Value. + pObject->setField( fieldName, "" ); + } + else + { + // Apply Field Value. + if ( !pObject->setField( fieldName, fieldValue ) ) + { + // Invalid. + Con::warnf( "VPersistence::readProperties() - Invalid property '%s'", fieldName ); + } + } + } + } + + // Valid Read. + return true; + }; + + template bool readObjects( TiXmlElement *pElement, T *pObject ) + { + for ( TiXmlElement *child = pElement->FirstChildElement( "VObject" ); child != NULL; child = child->NextSiblingElement( "VObject" ) ) + { + // Get Object Type. + const char *type = child->Attribute( "Type" ); + if ( !type || !AbstractClassRep::findClassRep( type ) ) + { + // Invalid Type. + Con::errorf( "VController::readObjects() - Invalid object type specified '%s'.", ( ( type ) ? type : "NULL" ) ); + + // Invalid Read. + return false; + } + + // Create Object. + VObject *object = dynamic_cast( ConsoleObject::create( type ) ); + +#ifdef VT_EDITOR + // Register SimObject. + if ( !object->registerObject() ) + { + // Delete. + delete object; + + // Invalid Read. + return false; + } +#endif + + // Add Reference. + object->addTo( pObject ); + +#ifdef VT_EDITOR + // Valid Method? + if ( object->isMethod( "onAdd" ) ) + { + // Callback. + const char *retValue = Con::executef( object, "onAdd" ); + if ( !dAtob( retValue ) ) + { + // Delete. + object->deleteObject(); + + // Invalid Read. + return false; + } + } +#endif + + // Read Object. + if ( !read( child, object ) ) + { +#ifdef VT_EDITOR + // Delete. + object->deleteObject(); +#else + // Delete. + delete object; +#endif + + // Invalid Read. + return false; + } + } + + // Valid Read. + return true; + }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPERSISTENCE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/Util/VSharedEnum.cpp b/Engine/source/Verve/Core/Util/VSharedEnum.cpp new file mode 100644 index 000000000..b4825de3f --- /dev/null +++ b/Engine/source/Verve/Core/Util/VSharedEnum.cpp @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// 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 "VSharedEnum.h" + +//----------------------------------------------------------------------------- + +// Implement the Action enum list. +ImplementEnumType( VActionToggle, "" ) + { VSharedEnum::k_ActionTurnOn, "ON" }, + { VSharedEnum::k_ActionTurnOff, "OFF" }, +EndImplementEnumType; \ No newline at end of file diff --git a/Engine/source/Verve/Core/Util/VSharedEnum.h b/Engine/source/Verve/Core/Util/VSharedEnum.h new file mode 100644 index 000000000..73df682d8 --- /dev/null +++ b/Engine/source/Verve/Core/Util/VSharedEnum.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// 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_VSHAREDENUM_H_ +#define _VT_VSHAREDENUM_H_ + +#ifndef _DYNAMIC_CONSOLETYPES_H_ +#include "console/dynamicTypes.h" +#endif + +namespace VSharedEnum +{ + enum eActionToggle + { + k_ActionTurnOn, + k_ActionTurnOff, + }; +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VSharedEnum::eActionToggle VActionToggle; + +// Declare Enum Types. +DefineEnumType( VActionToggle ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAREDENUM_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VController.cpp b/Engine/source/Verve/Core/VController.cpp new file mode 100644 index 000000000..d9c9daafd --- /dev/null +++ b/Engine/source/Verve/Core/VController.cpp @@ -0,0 +1,1160 @@ +//----------------------------------------------------------------------------- +// 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/VObject.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VTrack.h" + +#include "Verve/Extension/Director/VDirectorGroup.h" + +#include "console/consoleObject.h" +#include "console/consoleTypes.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VController ); +//----------------------------------------------------------------------------- + +VController::VController( void ) : + mStatus( ( k_StatusInit | k_StatusStopped ) ), + mTime( 0 ), + mLastTime( 0 ), + mTimeScale( 1.f ), + mDuration( 5000 ), + mLoop( false ), + mLoopBackwards( false ), + mLoopCount( -1 ), + mLoopIndex( 0 ), + mLoopDelay( 0 ), + mLoopDelayTime( 0 ), + mJump( k_JumpInvalid ), + mJumpTime( 0 ), + mResetOnCompletion( true ) +{ + // Don't Process Ticks. + setProcessTicks( false ); +} + +VController::~VController( void ) +{ + // Void. +} + +void VController::initPersistFields( void ) +{ + addGroup( "Controller" ); + addProtectedField( "Time", TypeS32, Offset( mTime, VController ), &setTime, &defaultProtectedGetFn, "Current position of the Controller (in milliseconds)." ); + addProtectedField( "Duration", TypeS32, Offset( mDuration, VController ), &setDuration, &defaultProtectedGetFn, "Total length of the sequence (in milliseconds)." ); + addProtectedField( "TimeScale", TypeF32, Offset( mTimeScale, VController ), &setTimeScale, &defaultProtectedGetFn, "Speed of playback. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |TimeScale| > 1.0, then playback will be faster than normal, while |TimeScale| < 1.0 will be slower." ); + + addField( "Loop", TypeBool, Offset( mLoop, VController ), "Instead of stopping once playback is complete, the Controller will reset and resume play." ); + addField( "LoopBackwards", TypeBool, Offset( mLoopBackwards, VController ), "When the sequence loops, reverse the direction of play." ); + addField( "LoopCount", TypeS32, Offset( mLoopCount, VController ), "The number of times the sequence loops before stopping. -1 will cause the sequence to loop indefinitely." ); + addField( "LoopDelay", TypeS32, Offset( mLoopDelay, VController ), "When the sequence loops, delay playback by this value (in milliseconds)." ); + + addField( "ResetOnCompletion", TypeBool, Offset( mResetOnCompletion, VController ), "When the sequence is completed, reset the state of the Controller." ); + endGroup( "Controller" ); + + // Parent Call. + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// ITickable Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::processTick(); +// +// This method controls the playback of the entire sequence. It integrates all +// of the groups and handles sequence looping and jumping. +// +//----------------------------------------------------------------------------- +void VController::processTick( void ) +{ + if ( mTimeScale == 0.f ) + { + // Pause. + pause(); + + // Exit. + return; + } + + // Calculate Delta. + const S32 time = Sim::getCurrentTime(); + S32 delta = ( time - mLastTime ); + mLastTime = time; + + // Reverse? + if ( mTimeScale < 0.f ) + { + // Negative Delta. + delta *= -1; + } + + if ( mLoopDelayTime > 0 ) + { + // Update Delay Time. + mLoopDelayTime -= getMin( mAbs( delta ), mLoopDelayTime ); + + // Exit. + return; + } + + // Jump Delta? + if ( mJump == k_JumpDelta ) + { + // Jump. + delta = mJumpTime; + + // Clear. + mJump = k_JumpInvalid; + mJumpTime = 0; + } + + if ( ( isPlayingForward() && ( mTime + delta ) > mDuration ) + || ( !isPlayingForward() && ( mTime + delta ) < 0 ) ) + { + // Clamp Delta. + delta = ( ( mTimeScale > 0.f ) * mDuration ) - mTime; + + // Note: If we are playing forwards, we're at the end of the + // sequence and we want to loop/reset the Controller, then we + // need to handle that now. + if ( delta == 0 ) + { + onPostTick(); + } + } + + // Valid Delta? + if ( delta == 0 ) + { + // Exit. + return; + } + + // Trigger Update. + mControllerUpdateSignal.trigger( mTime, delta ); + + // Update Time. + mTime += delta; + + // Perform Post Tick. + onPostTick(); +} + +//----------------------------------------------------------------------------- +// +// VController::onPostTick(); +// +// This method is called onces a tick has been processed. It will perform the +// the right checks to see if the Controller has finished playing. It also +// handles special cases like Looping or Resetting the Controller. +// +//----------------------------------------------------------------------------- +void VController::onPostTick( void ) +{ + // Jump Time? + if ( mJump == k_JumpTime ) + { + // Jump Post Update. + reset( mJumpTime ); + + // Clear. + mJump = k_JumpInvalid; + mJumpTime = 0; + } + + // Sequence Completed? + if ( isPlayingForward() && mTime >= mDuration + || !isPlayingForward() && mTime <= 0 ) + { + bool stopPlaying = true; + if ( mLoop ) + { + // Don't Stop. + stopPlaying = false; + + if ( mLoopBackwards ) + { + // Change Direction. + setTimeScale( -1.f * mTimeScale ); + } + else + { + // Reset Time. + reset(); + } + + if ( mLoopDelay > 0 ) + { + // Resume After Delay. + mLoopDelayTime = mLoopDelay; + } + + // At the Start of the Sequence? + if ( mTime <= 0 && mLoopCount >= 0 ) + { + // Stop Looping? + stopPlaying = ( ++mLoopIndex >= mLoopCount ); + } + + // Callback. + Con::executef( this, "onLoop" ); + + // Loop Signal. + postEvent( k_EventLoop ); + } + + // Stop? + if ( stopPlaying ) + { + // Stop Only. + stop( mResetOnCompletion ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::reset(); +// +// Reset the Controller to the start of the sequence. +// +//----------------------------------------------------------------------------- +void VController::reset( void ) +{ + // Reset. + reset( ( isPlayingForward() ) ? 0 : mDuration ); +} + +//----------------------------------------------------------------------------- +// +// VController::reset( pTime ); +// +// Reset the Controller to the target time. This is a very important method as +// it allows tracks and events to reset their state as well as prepare +// themselves for playback. +// +//----------------------------------------------------------------------------- +void VController::reset( const S32 &pTime ) +{ + // Reset Time. + mTime = pTime; + mLastTime = Sim::getCurrentTime(); + + // Reset Delay Time. + mLoopDelayTime = 0; + + // Post Event. + postEvent( k_EventReset ); +} + +//----------------------------------------------------------------------------- +// +// VController::play(); +// +// Start playing the sequence from the current time and execute a number of +// callbacks. +// +//----------------------------------------------------------------------------- +void VController::play( void ) +{ + if ( isPlaying() || mTime < 0 || mTime > mDuration ) + { + // Sanity! + return; + } + + // Reset Time. + mLastTime = Sim::getCurrentTime(); + + // Start Updating. + setProcessTicks( true ); + + if ( mStatus & k_StatusInit ) + { + // Init Signal. + postEvent( k_EventInit ); + + // Clear Init Status. + mStatus &= ~k_StatusInit; + } + + // Update Status. + updateStatus( k_StatusPlaying ); + + // Play Signal. + postEvent( k_EventPlay ); + + // Callback. + Con::executef( this, "onPlay" ); +} + +//----------------------------------------------------------------------------- +// +// VController::play( pTime ); +// +// Start playing the sequence from the desired time. +// +//----------------------------------------------------------------------------- +void VController::play( const S32 &pTime ) +{ + // Reset. + reset( pTime ); + + // Play. + play(); +} + +//----------------------------------------------------------------------------- +// +// VController::pause(); +// +// Cease playback of the sequence, but maintain the current time. +// +//----------------------------------------------------------------------------- +void VController::pause( void ) +{ + // Stop Updating. + setProcessTicks( false ); + + // Update Status. + updateStatus( k_StatusPaused ); + + // Pause Signal. + postEvent( k_EventPause ); + + // Callback. + Con::executef( this, "onPause" ); +} + +//----------------------------------------------------------------------------- +// +// VController::stop( pReset ); +// +// Stop playback altogether and reset the Controller to the start of the +// sequence. +// +//----------------------------------------------------------------------------- +void VController::stop( const bool &pReset ) +{ + // Stop Updating. + setProcessTicks( false ); + + // Reset Loop Index. + mLoopIndex = 0; + + // Update Status. + updateStatus( ( k_StatusInit | k_StatusStopped ) ); + + // Reset? + if ( pReset ) + { + // Reset. + reset(); + } + + // Stop Signal. + postEvent( k_EventStop ); + + // Callback. + Con::executef( this, "onStop" ); +} + +//----------------------------------------------------------------------------- +// +// VController::jump(); +// +// Jump the Controller time forward 1 tick (32ms). +// +//----------------------------------------------------------------------------- +void VController::jump( void ) +{ + // Jump 1 tick. + jump( k_JumpDelta, ( isPlayingForward() ) ? TickMs : -TickMs ); +} + +//----------------------------------------------------------------------------- +// +// VController::jump( pType, pDelta ); +// +// Jump the Controller time by the target Delta. +// +//----------------------------------------------------------------------------- +void VController::jump( const eControllerJumpType &pType, const S32 &pDelta ) +{ + // Jump. + mJump = pType; + mJumpTime = pDelta; +} + +//----------------------------------------------------------------------------- +// +// VController::updateStatus( pStatus ); +// +// Clear the regular playback states and add the updated state. +// +//----------------------------------------------------------------------------- +void VController::updateStatus( const S32 &pStatus ) +{ + // Clear Playback Status. + mStatus &= ~( k_StatusPlaying | k_StatusPaused | k_StatusStopped ); + + // Add New Status. + mStatus |= pStatus; +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::getObject( pLabel ); +// +// Returns the group with the given name. If no group belongs to the Controller +// with that name, then a NULL value is returned. +// +//----------------------------------------------------------------------------- +VGroup *VController::getObject( const String &pLabel ) +{ + VGroup *node = ( VGroup* )mChildNode; + while ( node ) + { + // Compare Names. + if ( node->getLabel().equal( pLabel, String::NoCase ) ) + { + // Valid. + return node; + } + + // Next Sibling. + node = ( VGroup* )node->mSiblingNextNode; + } + + // Invalid. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VController::getDirectorGroup(); +// +// Returns the DirectorGroup reference if the Controller has a one. +// +//----------------------------------------------------------------------------- +VDirectorGroup *VController::getDirectorGroup( void ) +{ + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + if ( VDirectorGroup *group = dynamic_cast( node ) ) + { + // Return Group. + return group; + } + } + + // Invalid Group. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VController::getDirectorTrack(); +// +// Returns the DirectorTrack reference if the DirectorGroup has one. +// +//----------------------------------------------------------------------------- +VDirectorTrack *VController::getDirectorTrack( void ) +{ + VDirectorGroup *group = getDirectorGroup(); + if ( !group ) + { + // Invalid Track. + return NULL; + } + + // Return Track. + return group->getDirectorTrack(); +} + +//----------------------------------------------------------------------------- +// +// VController::getDataValue( pFieldName, *pValue ); +// +// Returns true if the field is a DataTable member and can be correctly +// evaluated. If this is the case, then pValue will contain the result. +// +//----------------------------------------------------------------------------- +bool VController::getDataValue( const String &pFieldName, String &pValue ) +{ + return mDataTable.getValue( this, pFieldName, pValue ); +} + +//----------------------------------------------------------------------------- +// +// VController::clearData(); +// +// Clear the contents of the DataTable entirely. +// +//----------------------------------------------------------------------------- +void VController::clearData( void ) +{ + while ( mDataTable.getCount() > 0 ) + { + // Clear Item. + clearData( 0 ); + } +} + +//----------------------------------------------------------------------------- +// +// VController::clearData( pIndex ); +// +// Clear the DataTable entry with the given index. +// +//----------------------------------------------------------------------------- +void VController::clearData( const S32 &pIndex ) +{ + VDataTable::sDataItem data; + if ( mDataTable.getItem( pIndex, &data ) ) + { + // Clear Data. + clearData( data.FieldName ); + } +} + +//----------------------------------------------------------------------------- +// +// VController::clearData( pIndex ); +// +// Clear the DataTable entry with the given field name. +// +//----------------------------------------------------------------------------- +void VController::clearData( const String &pFieldName ) +{ + // Clear Dynamic Field. + setDataField( pFieldName, NULL, "" ); + + // Clear Item. + mDataTable.clear( pFieldName ); +} + +//----------------------------------------------------------------------------- +// +// VController::sort(); +// +// Sort each track in each of the child groups. +// +//----------------------------------------------------------------------------- +void VController::sort( void ) +{ + for ( ITreeNode *group = mChildNode; group != NULL; group = group->mSiblingNextNode ) + { + for ( ITreeNode *track = group->mChildNode; track != NULL; track = track->mSiblingNextNode ) + { + // Sort Track. + ( ( VTrack* )track )->sort(); + } + } +} + +//----------------------------------------------------------------------------- +// +// Write Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::writeDataTable( pElement ); +// +// Write the DataTable out to a TinyXML document. +// +//----------------------------------------------------------------------------- +bool VController::writeDataTable( TiXmlElement *pElement ) +{ + // Create Data Table Root. + TiXmlElement *dataTableRoot = new TiXmlElement( "DataTable" ); + pElement->LinkEndChild( dataTableRoot ); + + for ( VDataTable::VDataMap::Iterator itr = mDataTable.mDataMap.begin(); itr != mDataTable.mDataMap.end(); ++itr ) + { + // Fetch Data. + VDataTable::sDataItem *data = &itr->value; + + // Create Element. + TiXmlElement *dataElement = new TiXmlElement( "DataItem" ); + + // Apply Attributes. + dataElement->SetAttribute( "Type", VDataTable::getDataTypeDescription( data->Type ) ); + dataElement->SetAttribute( "Name", data->FieldName ); + dataElement->SetAttribute( "Value", getDataField( StringTable->insert( data->FieldName.c_str() ), NULL ) ); + + // Add. + dataTableRoot->LinkEndChild( dataElement ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Read Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::readDataTable( pElement ); +// +// Read the DataTable from a TinyXML document. +// +//----------------------------------------------------------------------------- +bool VController::readDataTable( TiXmlElement *pElement ) +{ + TiXmlElement *dataTableRoot = pElement->FirstChildElement( "DataTable" ); + if ( dataTableRoot ) + { + for ( TiXmlElement *child = dataTableRoot->FirstChildElement(); child != NULL; child = child->NextSiblingElement() ) + { + // Get Field Data. + const char *fieldType = child->Attribute( "Type" ); + const char *fieldName = child->Attribute( "Name" ); + const char *fieldValue = child->Attribute( "Value" ); + + // Add Data Item. + mDataTable.insert( VDataTable::getDataTypeEnum( fieldType ), fieldName ); + + // Set Field Value. + setDataField( StringTable->insert( fieldName ), NULL, fieldValue ); + } + } + + // Valid Read. + return true; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VController::postEvent( pEvent ); +// +// Process an event signal to all event subscribers. This method is used to +// signal changes in the Controller's status. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +void VController::postEvent( const eControllerEventType &pEvent ) +{ + // Signal Event. + mControllerEventSignal.trigger( pEvent ); +} + +//----------------------------------------------------------------------------- +// +// VController::setTimeScale( pTimeScale ); +// +// Set the speed of playback. In effect, a value of 0.5 will double the real +// time taken to complete the playback of the sequence, while a value of 2.0 +// will halve the time needed. +// +//----------------------------------------------------------------------------- +void VController::setTimeScale( const F32 &pTimeScale ) +{ + // Need an Update? + const bool update = ( pTimeScale != 0.f && ( mTimeScale == 0.f || ( ( mTimeScale > 0.f ) != ( pTimeScale > 0.f ) ) ) ); + + // Store. + mTimeScale = pTimeScale; + + // Update $timeScale Variable. + Con::setFloatVariable( "timeScale", mFabs( mTimeScale ) ); + + if ( update ) + { + // Reset. + reset( mTime ); + } +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VController, readFile, bool, (String fileName), (""), "( string pFileName ) - Clears the object and loads the new data from the given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Clear Sequence Lists. + object->clear(); + + // Clear Data Table. + object->clearData(); + + // Read Target File. + if ( !VPersistence::readFile( fileName, object ) ) + { + // Re-Clear. + object->clear(); + + // Invalid Read. + return false; + } + + // Initial Sort. + object->sort(); + + // Reset. + object->reset(); + + // Valid Read. + return true; +} + +DefineEngineMethod( VController, clear, void, (), , "( void ) - Detaches and deletes all of the child objects.\n" + "@return No return value." ) +{ + // Clear Sequence Lists. + object->clear(); + + // Clear Data Table. + object->clearData(); +} + +DefineEngineMethod( VController, reset, void, (S32 time), (-1), "( [int pTime] ) - Reset the Controller's and child object's state.\n" + "@param pTime The target time to reset to.\n" + "@return No return value." ) +{ + if (time != -1) + { + // Reset Sequence. + object->reset(time); + return; + } + + // Default Reset. + object->reset(); +} + +DefineEngineMethod( VController, isPlaying, bool, (), , "( void ) - Is the sequence currently playing?\n" + "@return Returns true if the Controller is playing." ) +{ + // Is Playing? + return ( object->isPlaying() ); +} + +DefineEngineMethod( VController, play, void, (S32 time), (-1), "( [int pTime] ) - Play the sequence. If a value for pTime is specified, the Controller is reset and played from that time.\n" + "@param pTime The time to start playing the sequence from.\n" + "@return No return value." ) +{ + S32 startTime = object->getTime(); + if (time != -1) + { + startTime = time; + } + + // Play From Specified Time. + object->play( startTime ); +} + +DefineEngineMethod( VController, step, void, (),, "( void ) - Step forward one frame.\n" + "@return No return value." ) +{ + if ( object->isPlaying() ) + { + // Sanity! + return; + } + + // Play. + object->play( object->getTime() ); + + // Jump. + object->jump(); + + // Step Forward One Frame. + object->processTick(); + + // Stop. + object->stop( false ); +} + +DefineEngineMethod( VController, isPaused, bool, (), , "( void ) - Is the sequence currently paused?\n" + "@return Returns true if the Controller is paused." ) +{ + // Is Paused? + return ( object->isPaused() ); +} + +DefineEngineMethod( VController, pause, void, (), , "( void ) - Pause the sequence. Playback can resume by calling VController::play().\n" + "@return No return value." ) +{ + // Pause Sequence. + object->pause(); +} + +DefineEngineMethod( VController, isStopped, bool, (), , "( void ) - Is the sequence currently stopped?\n" + "@return Returns true if the Controller is stopped." ) +{ + // Is Stopped? + return ( object->isStopped() ); +} + +DefineEngineMethod( VController, stop, void, (bool reset), (true), "( [bool pReset] ) - Stop the sequence and optionally reset it.\n" + "@param pReset Reset the Controller after stopping.\n" + "@return No return value." ) +{ + // Stop Sequence. + object->stop(reset); +} + +DefineEngineMethod( VController, getTimeScale, F32, (), , "( void ) - Get the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards.\n" + "@return Playback Speed." ) +{ + // Get Time Scale. + return object->getTimeScale(); +} + +DefineEngineMethod( VController, setTimeScale, void, (float timeScale), (1), "( float pTimeScale ) - Set the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |pTimeScale| > 1.0, then playback will be faster than normal, while |pTimeScale| < 1.0 will be slower.\n" + "@param pTimeScale Playback speed.\n" + "@return No return value." ) +{ + // Set Time Scale. + object->setTimeScale(timeScale); +} + +DefineEngineMethod( VController, isDataField, bool, (String fieldName), (""), "( string pFieldName ) - Is the field a member of the Data Table?\n" + "@param pFieldName The name of the dynamic field you wish to check.\n" + "@return Returns true if the field is a member of the Data Table." ) +{ + if (fieldName.isEmpty()) + { + return false; + } + + // Is Field. + return object->getDataTable().getItem(fieldName); +} + +DefineEngineMethod( VController, getDataFieldCount, S32, (), , "( void ) - Get the number of data elements in the Data Table.\n" + "@return Returns the size of the Data Table." ) +{ + // Return Count. + return object->getDataTable().getCount(); +} + +DefineEngineMethod( VController, getDataFieldName, const char *, (S32 index), (0), "( int pIndex ) - Get the name of the field given by the passed index.\n" + "@param pIndex The index of the data field you wish to check.\n" + "@return Returns the name of the field corresponding to the given index." ) +{ + VDataTable::sDataItem data; + if ( !object->getDataTable().getItem(index, &data ) || data.Type == VDataTable::k_TypeInvalid ) + { + // Invalid Field. + return ""; + } + + // Return Field Name. + return data.FieldName; +} + +DefineEngineMethod( VController, getDataFieldValue, const char *, (String fieldName), (""), "( string pFieldName ) - Get the evaluated data from the data field.\n" + "@param pFieldName The name of the field you wish to evaluate.\n" + "@return Returns the evaluated data from the field." ) +{ + String fieldValue; + if ( object->getDataValue(fieldName, fieldValue ) ) + { + // Create Buffer. + char *buffer = Con::getReturnBuffer( 256 ); + dStrcpy( buffer, fieldValue.c_str(), 256 ); + + // Return Value. + return buffer; + } + + // Return NULL. + return "0"; +} + +DefineEngineMethod( VController, getDataFieldType, const char *, (String fieldName), (""), "( string pFieldName ) - Get the type of data for the given field.\n" + "@param pFieldName The name of the field you wish to check.\n" + "@return Returns the data type." ) +{ + VDataTable::sDataItem data; + if ( !object->getDataTable().getItem(fieldName, &data ) || data.Type == VDataTable::k_TypeInvalid ) + { + // Invalid Field. + return ""; + } + + // Return Field Type. + return VDataTable::getDataTypeDescription( data.Type ); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VController, writeFile, bool, (String fileName), (""), "( string pFileName ) - Save to a given filename.\n" + "@param pFileName The target file to write to.\n" + "@return Returns true if the write was successful." ) +{ + // Write Target File. + return VPersistence::writeFile(fileName.c_str(), object ); +} + +DefineEngineMethod( VController, readTemplate, bool, (String fileName), (""), "( string pFileName ) - Load data from given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Read Target File. + return VPersistence::readFile(fileName.c_str(), object ); +} + +DefineEngineMethod( VController, getCount, S32, (),, "( void ) - Get the number of child objects.\n" + "@return Returns the number of child objects." ) +{ + // Size. + return object->size(); +} + +DefineEngineMethod( VController, getObject, S32, (S32 index), (0), "( int pIndex ) - Get the object corresponding to the given index.\n" + "@param pIndex The index of the object you wish to retrieve.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->at(index); + + // Return Group ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +DefineEngineMethod( VController, addObject, void, (SimObject* simObj), (nullAsType()), "( SimObject pObject ) - Add a child object to this node.\n" + "@param pObject The SimObjectID of the object to be added to this node.\n" + "@return No return value." ) +{ + if (simObj == nullptr) + return; + + VObject *child = dynamic_cast(simObj); + if ( child ) + { + // Add Child. + child->addTo( object ); + } +} + +DefineEngineMethod( VController, removeObject, void, (SimObject* simObj), (nullAsType()), "( SimObject pObject ) - Remove the target object from this node.\n" + "@param pObject The SimObjectID of the object to be removed from this node.\n" + "@return No return value." ) +{ + if (simObj == nullptr) + return; + + VObject *child = dynamic_cast(simObj); + if ( child && child->getParent() == object ) + { + child->remove(); + } +} + +DefineEngineMethod( VController, sortGroups, void, (),, "( void ) - Sort Groups by their Labels.\n" + "@return No return value." ) +{ + // Ensure that the Director Group is the First Group. + VDirectorGroup *directorGroup = object->getDirectorGroup(); + if ( directorGroup && directorGroup != object->mChildNode ) + { + // Detach. + directorGroup->remove(); + + // Add to the Front of the Controller. + directorGroup->addToFront( object ); + } + + const S32 count = object->size(); + for ( S32 j = 0; j < count; j++ ) + { + ITreeNode *node = object->mChildNode; + if ( dynamic_cast( node ) != NULL ) + { + // Skip Director Group. + node = node->mSiblingNextNode; + } + + for ( ; node != NULL; node = node->mSiblingNextNode ) + { + VGroup *groupA = ( VGroup* )node; + VGroup *groupB = ( VGroup* )node->mSiblingNextNode; + if ( !groupB ) + { + // No Node. + break; + } + + // Swap? + if ( dStrcmp( groupA->getLabel(), groupB->getLabel() ) > 0 ) + { + // Get Outer Siblings. + ITreeNode *prevNode = groupA->mSiblingPrevNode; + ITreeNode *nextNode = groupB->mSiblingNextNode; + + if ( groupA->mParentNode && groupA->mParentNode->mChildNode == groupA ) + { + // New Child Node. + groupA->mParentNode->mChildNode = groupB; + } + + // + // Move A. + + groupA->mSiblingPrevNode = groupB; + groupA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = groupA; + } + + // + // Move B. + + groupB->mSiblingPrevNode = prevNode; + groupB->mSiblingNextNode = groupA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = groupB; + } + } + } + } +} + +DefineEngineMethod( VController, sortTracks, void, (),, "( void ) - Sort Tracks by their Labels.\n" + "@return No return value." ) +{ + for ( ITreeNode *group = object->mChildNode; group != NULL; group = group->mSiblingNextNode ) + { + const S32 count = ( ( VGroup* )group )->size(); + for ( S32 j = 0; j < count; j++ ) + { + for ( ITreeNode *node = group->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VTrack *trackA = ( VTrack* )node; + VTrack *trackB = ( VTrack* )node->mSiblingNextNode; + if ( !trackB ) + { + // No Node. + break; + } + + // Swap? + if ( dStrcmp( trackA->getLabel(), trackB->getLabel() ) > 0 ) + { + // Get Outer Siblings. + ITreeNode *prevNode = trackA->mSiblingPrevNode; + ITreeNode *nextNode = trackB->mSiblingNextNode; + + if ( trackA->mParentNode && trackA->mParentNode->mChildNode == trackA ) + { + // New Child Node. + trackA->mParentNode->mChildNode = trackB; + } + + // + // Move A. + + trackA->mSiblingPrevNode = trackB; + trackA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = trackA; + } + + // + // Move B. + + trackB->mSiblingPrevNode = prevNode; + trackB->mSiblingNextNode = trackA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = trackB; + } + } + } + } + } +} + +DefineEngineMethod( VController, addDataField, void, (String fieldType, String fieldName), ("", ""), "( string pFieldType, string pFieldName ) - Add a new data entry to the Data Table.\n" + "@param pFieldType The method of evaluating the field's data.\n" + "@param pFieldName The name of the field to be added to the Data Table.\n" + "@return No return value." ) +{ + // Insert Data. + object->getDataTable().insert( VDataTable::getDataTypeEnum(fieldType), fieldName); +} + +DefineEngineMethod( VController, removeDataField, void, (String fieldName), (""), "( string pFieldName ) - Remove a data entry from the Data Table.\n" + "@param pFieldName The name of the field to be removed from the Data Table.\n" + "@return No return value." ) +{ + // Clear Data Item. + object->clearData(fieldName); +} +#endif diff --git a/Engine/source/Verve/Core/VController.h b/Engine/source/Verve/Core/VController.h new file mode 100644 index 000000000..f38a1cdf0 --- /dev/null +++ b/Engine/source/Verve/Core/VController.h @@ -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_VCONTROLLER_H_ +#define _VT_VCONTROLLER_H_ + +#ifndef _VT_VERVECONFIG_H_ +#include "Verve/VerveConfig.h" +#endif + +#ifndef _PLATFORM_H_ +#include "platform/platform.h" +#endif + +#ifndef _PROCESSLIST_H_ +#include "T3D/gameBase/processList.h" +#endif + +#ifndef _ITICKABLE_H_ +#include "core/iTickable.h" +#endif + +#ifndef _VT_VPERSISTENCE_H_ +#include "Verve/Core/Persistence/VPersistence.h" +#endif + +#ifndef _VT_VTREENODE_H_ +#include "Verve/Core/VTreeNode.h" +#endif + +#ifndef _VT_VDATATABLE_H_ +#include "Verve/Core/VDataTable.h" +#endif + +#ifndef _VT_TORQUE_CAMERA_H_ +#include "Verve/Torque/TCamera.h" +#endif + +//----------------------------------------------------------------------------- +class VObject; + +class VTrack; +class VEvent; +class VGroup; + +class VDirectorGroup; +class VDirectorTrack; + +typedef VectorPtr VTrackVector; +typedef VTrackVector::iterator VTrackIterator; + +typedef VectorPtr VEventVector; +typedef VEventVector::iterator VEventIterator; + +typedef VectorPtr VGroupVector; +typedef VGroupVector::iterator VGroupIterator; +//----------------------------------------------------------------------------- + +class VController : public SimObject, + public virtual ITickable, + public VTreeNode +{ + typedef SimObject Parent; + +public: + + enum eControllerStatus + { + k_StatusInit = BIT( 0 ), + + k_StatusPlaying = BIT( 1 ), + k_StatusPaused = BIT( 2 ), + k_StatusStopped = BIT( 3 ), + }; + + enum eControllerEventType + { + k_EventInit, + k_EventReset, + + k_EventPlay, + k_EventPause, + k_EventStop, + + k_EventLoop, + }; + + enum eControllerJumpType + { + k_JumpTime, + k_JumpDelta, + + k_JumpInvalid, + }; + + typedef Signal ControllerUpdateSignal; + typedef Signal ControllerEventSignal; + +private: + + // Data. + + VDataTable mDataTable; + + // Event Signal. + + ControllerUpdateSignal mControllerUpdateSignal; + ControllerEventSignal mControllerEventSignal; + + // Properties. + + S32 mStatus; + + S32 mTime; + U32 mLastTime; + S32 mDuration; + F32 mTimeScale; + + bool mLoop; + bool mLoopBackwards; + S32 mLoopCount; + S32 mLoopIndex; + S32 mLoopDelay; + S32 mLoopDelayTime; + + eControllerJumpType mJump; + S32 mJumpTime; + + bool mResetOnCompletion; + +public: + + VController(); + ~VController(); + + static void initPersistFields( void ); + + // ITickable. + + void interpolateTick( F32 pDelta ) { }; + void advanceTime( F32 pDelta ) { }; + void processTick( void ); + void onPostTick( void ); + + // Controller. + + void reset( void ); + void reset( const S32 &pTime ); + + void play( void ); + void play( const S32 &pTime ); + + void pause( void ); + void stop( const bool &pReset = true ); + + void jump( void ); + void jump( const eControllerJumpType &pType, const S32 &pDelta ); + + void updateStatus( const S32 &pStatus ); + + // Reference. + + VGroup *getObject( const String &pLabel ); + template inline bool getObject( const String &pLabel, T *&pObject ) + { + // Reference Group. + pObject = dynamic_cast( getObject( pLabel ) ); + + // Valid? + return ( pObject != NULL ); + } + + bool getDataValue( const String &pFieldName, String &pValue ); + void clearData( void ); + void clearData( const S32 &pIndex ); + void clearData( const String &pFieldName ); + + void sort( void ); + + // Saving. + + bool writeDataTable( TiXmlElement *pElement ); + + // Reading. + + bool readDataTable( TiXmlElement *pElement ); + + // Console Declaration. + + DECLARE_CONOBJECT( VController ); + +public: + + inline VDataTable &getDataTable( void ) { return mDataTable; }; + + inline ControllerUpdateSignal &getControllerUpdateSignal( void ) { return mControllerUpdateSignal; }; + inline ControllerEventSignal &getControllerEventSignal( void ) { return mControllerEventSignal; }; + void postEvent( const eControllerEventType &pEvent ); + + VDirectorGroup *getDirectorGroup( void ); + VDirectorTrack *getDirectorTrack( void ); + + inline void setTime( const S32 &pTime ) { mTime = pTime; }; + inline void setDuration( const S32 &pDuration ) { mDuration = pDuration; }; + void setTimeScale( const F32 &pTimeScale ); + + inline bool isLooping( void ) { return mLoop; }; + inline bool isPlaying( void ) { return ( mStatus & k_StatusPlaying ); }; + inline bool isPaused( void ) { return ( mStatus & k_StatusPaused ); }; + inline bool isStopped( void ) { return ( mStatus & k_StatusStopped ); }; + inline bool isPlayingForward( void ) { return ( mTimeScale > 0.f ); }; + + inline S32 getTime( void ) { return mTime; }; + inline S32 getDuration( void ) { return mDuration; }; + inline F32 getTimeScale( void ) { return mTimeScale; }; + inline S32 getLoopDelayTime( void ) { return mLoopDelayTime; }; + +protected: + + static bool setTime( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setTime( dAtoi( pData ) ); return false; }; + static bool setDuration( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setDuration( dAtoi( pData ) ); return false; }; + static bool setTimeScale( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setTimeScale( dAtof( pData ) ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VDataTable.cpp b/Engine/source/Verve/Core/VDataTable.cpp new file mode 100644 index 000000000..f338c5ac4 --- /dev/null +++ b/Engine/source/Verve/Core/VDataTable.cpp @@ -0,0 +1,253 @@ +//----------------------------------------------------------------------------- +// 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/VDataTable.h" + +#include "console/simObject.h" + +//----------------------------------------------------------------------------- + +// Implement the DataType enum list. +ImplementEnumType( VDataTableDataType, "" ) + { VDataTable::k_TypeExpression, "EXPRESSION" }, + { VDataTable::k_TypeStatic, "STATIC" }, + { VDataTable::k_TypeVariable, "VARIABLE" }, +EndImplementEnumType; + +VDataTable::eDataType VDataTable::getDataTypeEnum( const char *pLabel ) +{ + VDataTable::eDataType out; + if ( !castConsoleTypeFromString( out, pLabel ) ) + { + // Bah! + return VDataTable::k_TypeInvalid; + } + + // Return. + return out; +} + +const char *VDataTable::getDataTypeDescription( const VDataTable::eDataType pEnum ) +{ + // Return. + return castConsoleTypeToString( pEnum ); +} + +//----------------------------------------------------------------------------- + +VDataTable::VDataTable( void ) +{ + mDataMap.clear(); +} + +VDataTable::~VDataTable( void ) +{ + mDataMap.clear(); +} + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDataTable::insert( pType, pFieldName ); +// +// Add a DataTable entry, referencing the field name and assign it the given +// data type. +// +// For a full list of possible data types, see the 'eDataType' declaration in +// VDataTable.h. +// +//----------------------------------------------------------------------------- +void VDataTable::insert( eDataType pType, const String &pFieldName ) +{ + if ( mDataMap.contains( pFieldName ) ) + { + // Change Field Type. + mDataMap.find( pFieldName )->value.Type = pType; + + // Return. + return; + } + + // Insert Item. + mDataMap.insert( pFieldName, sDataItem( pType, pFieldName ) ); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::clear( pFieldName ); +// +// Clear the DataTable entry with the given field name. +// +//----------------------------------------------------------------------------- +void VDataTable::clear( const String &pFieldName ) +{ + // Clear Item. + mDataMap.erase( pFieldName ); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::clear(); +// +// Clear the contents of the DataTable entirely. +// +//----------------------------------------------------------------------------- +void VDataTable::clear( void ) +{ + // Clear. + mDataMap.clear(); +} + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDataTable::getCount(); +// +// Return the number of DataTable entries. +// +//----------------------------------------------------------------------------- +S32 VDataTable::getCount( void ) +{ + return mDataMap.size(); +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getItem( pIndex, *pDataItem ); +// +// Return the item with the given index. This method will return false if there +// is no valid data entry with that index. +// +//----------------------------------------------------------------------------- +bool VDataTable::getItem( const S32 &pIndex, sDataItem *pDataItem ) +{ + if ( pIndex < 0 || pIndex >= mDataMap.size() ) + { + // Invalid Field. + return false; + } + + S32 index = 0; + for ( VDataMap::Iterator itr = mDataMap.begin(); itr != mDataMap.end(); ++itr ) + { + if ( index == pIndex ) + { + if ( pDataItem ) + { + // Store Reference. + *pDataItem = ( itr->value ); + } + + // Valid Field. + return true; + } + + // Increment. + ++index; + } + + // Invalid Field. + return false; +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getItem( pFieldName, *pDataItem ); +// +// Return the item with the given field name. This method will return false if +// there is no valid data entry with that name. +// +//----------------------------------------------------------------------------- +bool VDataTable::getItem( const String &pFieldName, sDataItem *pDataItem ) +{ + if ( mDataMap.contains( pFieldName ) ) + { + if ( pDataItem ) + { + // Fetch Item + *pDataItem = mDataMap.find( pFieldName )->value; + } + + // Valid Field. + return true; + } + + // Invalid Field. + return false; +} + +//----------------------------------------------------------------------------- +// +// VDataTable::getValue( pObject, pFieldName, *pValue ); +// +// Evaluate and return the expression provided in the data field. +// +//----------------------------------------------------------------------------- +bool VDataTable::getValue( SimObject *pObject, const String &pFieldName, String &pValue ) +{ + if ( !pObject || pFieldName.isEmpty() ) + { + // Sanity! + return false; + } + + // Fetch Data. + sDataItem *data = &( mDataMap.find( pFieldName )->value ); + if ( !data ) + { + // No Field. + return false; + } + + // Field Value. + const char *fieldValue = pObject->getDataField( StringTable->insert( data->FieldName ), NULL ); + + switch ( data->Type ) + { + case VDataTable::k_TypeExpression : + { + // Evaluate. + pValue = Con::evaluate( fieldValue, false ).getStringValue(); + + } break; + + case VDataTable::k_TypeStatic : + { + // Use Value. + pValue = fieldValue; + + } break; + + case VDataTable::k_TypeVariable : + { + + // Fetch Variable. + pValue = Con::getVariable( fieldValue ); + + } break; + } + + // Valid Field. + return true; +} diff --git a/Engine/source/Verve/Core/VDataTable.h b/Engine/source/Verve/Core/VDataTable.h new file mode 100644 index 000000000..6b4cba90a --- /dev/null +++ b/Engine/source/Verve/Core/VDataTable.h @@ -0,0 +1,118 @@ +//----------------------------------------------------------------------------- +// 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_VDATATABLE_H_ +#define _VT_VDATATABLE_H_ + +#ifndef CORE_TDICTIONARY_H +#include "core/util/tDictionary.h" +#endif + +#ifndef _CONSOLE_H_ +#include "console/console.h" +#endif + +#ifndef _DYNAMIC_CONSOLETYPES_H_ +#include "console/dynamicTypes.h" +#endif + +#ifndef _STRINGTABLE_H_ +#include "core/stringTable.h" +#endif + +//----------------------------------------------------------------------------- + +class VDataTable +{ +public: + + enum eDataType + { + k_TypeExpression, + k_TypeStatic, + k_TypeVariable, + + k_TypeInvalid, + }; + + struct sDataItem + { + eDataType Type; + String FieldName; + + sDataItem( void ) : + Type( k_TypeInvalid ), + FieldName( String::EmptyString ) + { + // Void. + }; + + sDataItem( eDataType pType, const String &pFieldName ) : + Type( pType ), + FieldName( pFieldName ) + { + // Void. + }; + }; + + // Enum Lookup. + static VDataTable::eDataType getDataTypeEnum( const char *pLabel ); + static const char *getDataTypeDescription( const VDataTable::eDataType pEnum ); + + // Map Type. + typedef Map VDataMap; + +public: + + VDataMap mDataMap; + +public: + + VDataTable( void ); + ~VDataTable( void ); + + // Data. + + void insert( eDataType pType, const String &pFieldName ); + void clear( const String &pFieldName ); + void clear( void ); + + // Reference. + + S32 getCount( void ); + bool getItem( const S32 &pIndex, sDataItem *pDataItem = NULL ); + bool getItem( const String &pFieldName, sDataItem *pDataItem = NULL ); + + bool getValue( SimObject *pObject, const String &pFieldName, String &pValue ); +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VDataTable::eDataType VDataTableDataType; + +// Declare Enum Types. +DefineEnumType( VDataTableDataType ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VDATATABLE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VEvent.cpp b/Engine/source/Verve/Core/VEvent.cpp new file mode 100644 index 000000000..6b4e8ed54 --- /dev/null +++ b/Engine/source/Verve/Core/VEvent.cpp @@ -0,0 +1,406 @@ +//----------------------------------------------------------------------------- +// 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/VEvent.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VTrack.h" + +#include "console/consoleTypes.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEvent ); +//----------------------------------------------------------------------------- + +VEvent::VEvent( void ) : + mIsPlaying( false ), + mTriggered( false ), + mTriggerTime( 0 ), + mDuration( 0 ) +{ + setLabel( "DefaultEvent" ); +} + +void VEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "TriggerTime", TypeS32, Offset( mTriggerTime, VEvent ), &setTriggerTime, &defaultProtectedGetFn, "The time that this event is triggered." ); + addProtectedField( "Duration", TypeS32, Offset( mDuration, VEvent ), &setDuration, &defaultProtectedGetFn, "The total duration that this event plays for." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::onControllerReset( pTime, pForward ); +// +// Reset the status of the event. If the given time is between the event's +// start and finish times, then the isPlaying flag will be true. This means +// that the event is free to be triggered upon playback. +// +//----------------------------------------------------------------------------- +void VEvent::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Reset Status. + mIsPlaying = ( pTime > mTriggerTime && pTime < ( mTriggerTime + mDuration ) ); + mTriggered = false; +} + +//----------------------------------------------------------------------------- +// +// VEvent::onControllerUpdate( pTime, pDelta ) +// +// Integrate is only called when this event is the Next Event for the parent +// track. For each track, there is only ever *one* event being integrated - the +// event that needs to be triggered next. +// +// If the event has a duration greater than 0, then this event will continue to +// integrate until its time is up, or the controller finishes playing +// (whichever happens first). +// +// If a value of true is returned, then this event will continue to integrate +// until a value of false is returned to the parent track. When this happens, +// this event ceases to be the track's Next Event and will not continue +// updating. +// +//----------------------------------------------------------------------------- +bool VEvent::onControllerUpdate( const S32 &pTime, const S32 &pDelta ) +{ + if ( !isEnabled() ) + { + return false; + } + + const S32 newTime = ( pTime + pDelta ); + const S32 &startTime = getStartTime(); + const S32 &finishTime = getFinishTime(); + + if ( !mIsPlaying || !mTriggered ) + { + if ( !mIsPlaying ) + { + if ( ( pDelta > 0 && newTime < startTime ) + || ( pDelta < 0 && newTime > startTime ) ) + { + // Not Time to Trigger. + return true; + } + + if ( ( pDelta > 0 && pTime > startTime ) + || ( pDelta < 0 && pTime < startTime ) ) + { + //AssertFatal( false, "VEvent::onControllerUpdate() - Event has been skipped." ); + return false; + } + } + + if ( !mTriggered ) + { + // Play and Trigger. + mIsPlaying = ( mDuration > 0 ); + mTriggered = true; + + // Callback. + onTrigger( pTime, pDelta ); + + if ( mDuration == 0 ) + { + // Stop Integrating. + return false; + } + + // Return Here. + // Note: If Duration is non-zero this event will continue to update + // so that VEvent:: onUpdate is processed for the full event + // duration. + return ( mDuration != 0 ); + } + } + + // Complete? + const bool isComplete = ( ( pDelta > 0 && newTime > finishTime ) + || ( pDelta < 0 && newTime < finishTime ) ); + + if ( !isComplete ) + { + // Callback. + onUpdate( pTime, pDelta ); + } + else + { + // Complete. + mIsPlaying = false; + + // Callback. + onComplete( pTime, pDelta ); + } + + // Continue? + return !isComplete; +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::onTrigger( pTime, pDelta ); +// +// This method is called when an event is due to be triggered. This method is +// meant to be overloaded by derived classes. +// +// For examples of what an event might do, please refer to some of the included +// events with Verve. +// +//----------------------------------------------------------------------------- +void VEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// VEvent::onUpdate( pTime, pDelta ); +// +// This method is called each tick once an event has been triggered and ceases +// to be called when it is completed. This method is meant to be overloaded by +// derived classes. +// +//----------------------------------------------------------------------------- +void VEvent::onUpdate( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// VEvent::onComplete( pTime, pDelta ); +// +// This method is called once an event has finished being updated. It is not +// called on events that have a duration of 0. This method is meant to be +// overloaded by derived classes. +// +//----------------------------------------------------------------------------- +void VEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VEvent::getGroup(); +// +// Returns the parent group. +// +//----------------------------------------------------------------------------- +VGroup *VEvent::getGroup( void ) +{ + VTrack *track = getTrack(); + if ( track ) + { + return track->getGroup(); + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VEvent::getTrack(); +// +// Returns the parent track. +// +//----------------------------------------------------------------------------- +VTrack *VEvent::getTrack( void ) +{ + return dynamic_cast( mParentNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getNextEvent(); +// +// Returns the next event. +// +//----------------------------------------------------------------------------- +VEvent *VEvent::getNextEvent( void ) +{ + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( mSiblingPrevNode ); + } + + return dynamic_cast( mSiblingNextNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getPreviousEvent(); +// +// Returns the previous event. +// +//----------------------------------------------------------------------------- +VEvent *VEvent::getPreviousEvent( void ) +{ + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( mSiblingNextNode ); + } + + return dynamic_cast( mSiblingPrevNode ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getStartTime(); +// +// Returns the time, in milliseconds, that the event is due to trigger. +// +//----------------------------------------------------------------------------- +S32 VEvent::getStartTime( void ) +{ + return ( mTriggerTime + ( !isControllerPlayingForward() * mDuration ) ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::getFinishTime(); +// +// Returns the time, in milliseconds, that the event will cease updating. +// +//----------------------------------------------------------------------------- +S32 VEvent::getFinishTime( void ) +{ + return ( mTriggerTime + ( isControllerPlayingForward() * mDuration ) ); +} + +//----------------------------------------------------------------------------- +// +// VEvent::setTriggerTime( pTime ); +// +// Apply the given trigger time to the object. +// +// If the project was built using the VT_EDITOR preprocessor argument, then +// the validity of the passed value is verified. It also cannot be changed +// while the controller is playing. +// +//----------------------------------------------------------------------------- +void VEvent::setTriggerTime( const S32 &pTime ) +{ +#ifdef VT_EDITOR + + VTrack *track = getTrack(); + if ( !track ) + { + // Apply Time. + mTriggerTime = pTime; + + return; + } + + if ( track->isControllerPlaying() ) + { + // Don't Change While Playing. + return; + } + + /* + // Check For Overlap. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *event = ( VEvent* )node; + if ( event == this ) + { + // Skip. + continue; + } + + const U32 startTime = getStartTime(); + const U32 finishTime = getFinishTime(); + + if ( ( pTime > startTime && pTime < finishTime ) + || ( ( pTime + mDuration ) > startTime && ( pTime + mDuration ) < finishTime ) + || ( pTime < startTime && ( pTime + mDuration ) > finishTime ) ) + { + // Overlap! + return; + } + } + */ + + // Apply Time. + mTriggerTime = mClamp( pTime, 0, getControllerDuration() ); + + // Sort Events. + track->sort(); + + // Reset Track. + track->onControllerReset( getControllerTime(), isControllerPlayingForward() ); + +#else + + // Apply Time. + mTriggerTime = pTime; + +#endif +} + +//----------------------------------------------------------------------------- +// +// VEvent::setDuration( pDuration ); +// +// Apply the given duration time to the object. +// +// If the project was built using the VT_EDITOR preprocessor argument, then +// the validity of the passed value is verified. It also cannot be changed +// while the controller is playing. +// +//----------------------------------------------------------------------------- +void VEvent::setDuration( const S32 &pDuration ) +{ +#ifdef VT_EDITOR + + if ( isControllerPlaying() ) + { + // Don't Change While Playing. + return; + } + +#endif + + // Apply Duration. + mDuration = pDuration; +} \ No newline at end of file diff --git a/Engine/source/Verve/Core/VEvent.h b/Engine/source/Verve/Core/VEvent.h new file mode 100644 index 000000000..7a1914f04 --- /dev/null +++ b/Engine/source/Verve/Core/VEvent.h @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// 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_VEVENT_H_ +#define _VT_VEVENT_H_ + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- +class VGroup; +class VTrack; +//----------------------------------------------------------------------------- + +class VEvent : public VObject +{ + typedef VObject Parent; + +protected: + + bool mIsPlaying; + bool mTriggered; + + S32 mTriggerTime; + S32 mDuration; + +public: + + VEvent( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + virtual bool onControllerUpdate( const S32 &pTime, const S32 &pDelta ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onUpdate( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEvent ); + +public: + + // Property Methods. + + VGroup *getGroup( void ); + template inline bool getGroup( T *&pGroup ) + { + // Reference Group. + pGroup = dynamic_cast( getGroup() ); + // Validate. + return ( pGroup != NULL ); + } + + VTrack *getTrack( void ); + template inline bool getTrack( T *&pTrack ) + { + // Reference Track. + pTrack = dynamic_cast( getTrack() ); + // Validate. + return ( pTrack != NULL ); + } + + VEvent *getNextEvent( void ); + VEvent *getPreviousEvent( void ); + + inline bool isPlaying( void ) { return mIsPlaying; }; + inline S32 getTriggerTime( void ) { return mTriggerTime; }; + inline S32 getDuration( void ) { return mDuration; }; + + virtual S32 getStartTime( void ); + virtual S32 getFinishTime( void ); + + virtual void setTriggerTime( const S32 &pTime ); + virtual void setDuration( const S32 &pDuration ); + + static bool setTriggerTime( void *obj, const char *pArray, const char *data ) { static_cast( obj )->setTriggerTime( dAtoi( data ) ); return false; }; + static bool setDuration( void *obj, const char *pArray, const char *data ) { static_cast( obj )->setDuration( dAtoi( data ) ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VGroup.cpp b/Engine/source/Verve/Core/VGroup.cpp new file mode 100644 index 000000000..274d93775 --- /dev/null +++ b/Engine/source/Verve/Core/VGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VGroup ); +//----------------------------------------------------------------------------- + +VGroup::VGroup( void ) +{ + setLabel( "DefaultGroup" ); +}; \ No newline at end of file diff --git a/Engine/source/Verve/Core/VGroup.h b/Engine/source/Verve/Core/VGroup.h new file mode 100644 index 000000000..35d40dc4f --- /dev/null +++ b/Engine/source/Verve/Core/VGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VGROUP_H_ +#define _VT_VGROUP_H_ + +#ifndef _VT_VOBJECT_H_ +#include "Verve/Core/VObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VGroup : public VObject +{ + typedef VObject Parent; + +public: + + VGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VObject.cpp b/Engine/source/Verve/Core/VObject.cpp new file mode 100644 index 000000000..248ed5032 --- /dev/null +++ b/Engine/source/Verve/Core/VObject.cpp @@ -0,0 +1,489 @@ +//----------------------------------------------------------------------------- +// 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/VObject.h" +#include "Verve/Core/VController.h" +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VObject ); +//----------------------------------------------------------------------------- + +VObject::VObject( void ) : + mController( NULL ), + mLabel( String::EmptyString ), + mEnabled( true ) +{ + // Void. +}; + +VObject::~VObject( void ) +{ + // Remove. + remove(); +} + +void VObject::initPersistFields( void ) +{ + // Don't Use Parent Fields. + // Parent::initPersistFields(); + + addProtectedField( "Enabled", TypeBool, Offset( mEnabled, VObject ), &setEnabled, &defaultProtectedGetFn, "Enable or Disable the object from playback." ); + addProtectedField( "Label", TypeRealString, Offset( mLabel, VObject ), &setLabel, &defaultProtectedGetFn, "The label this object is referenced by." ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::getObject( pLabel ); +// +// Returns the object with the given label. If no object belongs to this object +// with that label, then a NULL value is returned. +// +//----------------------------------------------------------------------------- +VObject *VObject::getObject( const String &pLabel ) +{ + VObject *node = ( VObject* )mChildNode; + while ( node ) + { + // Compare Names. + if ( node->getLabel().equal( pLabel, String::NoCase ) ) + { + // Valid. + return node; + } + + // Next Sibling. + node = ( VObject* )node->mSiblingNextNode; + } + + // Invalid. + return NULL; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::isEnabled(); +// +// Returns whether this object is enabled. +// +//----------------------------------------------------------------------------- +bool VObject::isEnabled( void ) +{ + VObject *parent = dynamic_cast( getParent() ); + if ( parent && !parent->isEnabled() ) + { + return false; + } + + return mEnabled; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPlaying(); +// +// Returns whether the root controller is currently playing. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPlaying( void ) +{ + if ( getController() ) + { + return getController()->isPlaying(); + } + + return false; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPaused(); +// +// Returns whether the root controller is currently paused. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPaused( void ) +{ + if ( getController() ) + { + return getController()->isPaused(); + } + + return false; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerStopped(); +// +// Returns whether the root controller is currently stopped. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerStopped( void ) +{ + if ( getController() ) + { + return getController()->isStopped(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerPlayingForward(); +// +// Returns whether the root controller is currently playing forward. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerPlayingForward( void ) +{ + if ( getController() ) + { + return getController()->isPlayingForward(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::isControllerLooping(); +// +// Returns whether the root controller is looping the sequence. +// +//----------------------------------------------------------------------------- +bool VObject::isControllerLooping( void ) +{ + if ( getController() ) + { + return getController()->isLooping(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerTime(); +// +// Returns the current time of the root controller. +// +//----------------------------------------------------------------------------- +S32 VObject::getControllerTime( void ) +{ + if ( getController() ) + { + return getController()->getTime(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerTimeScale(); +// +// Returns the current timescale of the root controller. +// +//----------------------------------------------------------------------------- +F32 VObject::getControllerTimeScale( void ) +{ + if ( getController() ) + { + return getController()->getTimeScale(); + } + + return 1.f; +} + +//----------------------------------------------------------------------------- +// +// VObject::getControllerDuration(); +// +// Returns the duration of the root controller. +// +//----------------------------------------------------------------------------- +S32 VObject::getControllerDuration( void ) +{ + if ( getController() ) + { + return getController()->getDuration(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VObject::setLabel( pLabel ); +// +// Set the label property. +// +// If the project was built using the VT_EDITOR preprocessor argument, then the +// label will not be changed if the target name is already used in the parent +// object. +// +//----------------------------------------------------------------------------- +void VObject::setLabel( const String &pLabel ) +{ +#ifdef VT_EDITOR + if ( mParentNode ) + { + // Empty Label? + if ( mLabel.isEmpty() ) + { + // Set Uniqu Label. + setLabelUnique( pLabel ); + return; + } + + for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) + { + if ( walk != this ) + { + if ( pLabel == walk->getLabel() ) + { + // Exit. + return; + } + } + } + } +#endif + + // Set Label. + mLabel = pLabel; +} + +//----------------------------------------------------------------------------- +// +// VObject::setLabelUnique( pLabel ); +// +// If the label that has been passed is already in use, then a new label will +// be generated by appending an index to the label. For example: MyLabel +// becomes MyLabel0 ... MyLabelN +// +//----------------------------------------------------------------------------- +void VObject::setLabelUnique( const String &pLabel ) +{ + if ( mParentNode && pLabel.isNotEmpty() ) + { + for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) + { + if ( walk != this ) + { + if ( pLabel == walk->getLabel() ) + { + // Strip Trailing Number. + S32 i = -1; + String labelBase( String::GetTrailingNumber( pLabel, i ) ); + i++; + + // Construct New Name. + String labelBuffer = String::ToString( "%s%d", labelBase.c_str(), i ); + + // Set Name. + setLabelUnique( labelBuffer ); + + // Exit. + return; + } + } + } + } + + // Set Name. + mLabel = pLabel; +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VObject::onAttach(); +// +// Callback made when this object is attached to another node. +// +//----------------------------------------------------------------------------- +void VObject::onAttach( void ) +{ + VTreeNode::onAttach(); + + // Store Controller. + mController = dynamic_cast( getRoot() ); + +#ifdef VT_EDITOR + if ( isProperlyAdded() ) + { + Con::executef( this, "onAttach" ); + } +#endif +} + +//----------------------------------------------------------------------------- +// +// VObject::onDetach(); +// +// Callback made when this object is detached from a parent node. +// +//----------------------------------------------------------------------------- +void VObject::onDetach( void ) +{ + VTreeNode::onDetach(); + + // Clear Controller. + mController = NULL; + +#ifdef VT_EDITOR + if ( isProperlyAdded() ) + { + Con::executef( this, "onDetach" ); + } +#endif +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VObject, writeFile, bool, (String fileName), (""), "( string pFileName ) - Save to a given filename.\n" + "@param pFileName The target file to write to.\n" + "@return Returns true if the write was successful." ) +{ + // Write Target File. + return VPersistence::writeFile(fileName.c_str(), object ); +} + +DefineEngineMethod( VObject, readFile, bool, (String fileName), (""), "( string pFileName ) - Clears the object and loads the new data from the given filename.\n" + "@param pFileName The target file to read from.\n" + "@return Returns true if the read was successful." ) +{ + // Read Target File. + return VPersistence::readFile(fileName.c_str(), object ); +} + +DefineEngineMethod( VObject, getRoot, S32, (),, "( void ) - Get the root object.\n" + "@return Returns the SimObjectId for the root object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->getRoot(); + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +DefineEngineMethod( VObject, getParent, S32, (),, "( void ) - Get the parent object.\n" + "@return Returns the SimObjectId for the parent object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->mParentNode; + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +DefineEngineMethod( VObject, getIndex, S32, (),, "( void ) - Get the index of this object relative to its siblings.\n" + "@return Returns the index of this object." ) +{ + return object->getIndex(); +} + +DefineEngineMethod( VObject, getCount, S32, (),, "( void ) - Get the number of child objects.\n" + "@return Returns the number of child objects." ) +{ + return object->size(); +} + +DefineEngineMethod( VObject, getObject, S32, (S32 index), (0), "( int pIndex ) - Get the object corresponding to the given index.\n" + "@param pIndex The index of the object you wish to retrieve.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VObject *objectRef = ( VObject* )object->at(index); + + // Return Object ID. + return ( objectRef ) ? objectRef->getId() : 0; +} + +DefineEngineMethod( VObject, clear, void, (),, "( void ) - Detaches and deletes all of the child objects.\n" + "@return No return value." ) +{ + // Clear Sequence Lists. + object->clear(); +} + +DefineEngineMethod( VObject, addObject, void, (SimObject* simObj), (nullAsType()), "( SimObject pObject ) - Add a child object to this node.\n" + "@param pObject The SimObjectID of the object to be added to this node.\n" + "@return No return value." ) +{ + if (simObj == nullptr) + return; + + VObject *child = dynamic_cast(simObj); + if ( child ) + { + child->addTo( object ); + } +} + +DefineEngineMethod( VObject, removeObject, void, (SimObject* simObj), (nullAsType()), "( SimObject pObject ) - Remove the target object from this node.\n" + "@param pObject The SimObjectID of the object to be removed from this node.\n" + "@return No return value." ) +{ + if (simObj == nullptr) + return; + + VObject *child = dynamic_cast(simObj); + if ( child && child->getParent() == object ) + { + child->remove(); + } +} + +DefineEngineMethod( VObject, setLabelUnique, void, (String label), (""), "( string pLabel ) - Force this label to be unique.\n" + "@param pLabel The name you wish to reference this object by.\n" + "@return No return value." ) +{ + // Set Label. + object->setLabelUnique(label); +} +#endif diff --git a/Engine/source/Verve/Core/VObject.h b/Engine/source/Verve/Core/VObject.h new file mode 100644 index 000000000..a4fe22f18 --- /dev/null +++ b/Engine/source/Verve/Core/VObject.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// 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_VOBJECT_H_ +#define _VT_VOBJECT_H_ + +#ifndef _VT_VERVECONFIG_H_ +#include "Verve/VerveConfig.h" +#endif + +#ifdef VT_EDITOR + #ifndef _SIMOBJECT_H_ + #include "console/simObject.h" + #endif + + #define VObjectRep SimObject +#else + #ifndef _CONSOLEOBJECT_H_ + #include "console/consoleObject.h" + #endif + + #define VObjectRep ConsoleObject +#endif + +#ifndef _VT_VTREENODE_H_ +#include "Verve/Core/VTreeNode.h" +#endif + +#ifndef TINYXML_INCLUDED +#include "tinyxml/tinyxml.h" +#endif + +//----------------------------------------------------------------------------- +class VController; +//----------------------------------------------------------------------------- + +class VObject : public VObjectRep, + public VTreeNode +{ + typedef VObjectRep Parent; + +protected: + + VController *mController; + + String mLabel; + bool mEnabled; + +public: + + VObject( void ); + virtual ~VObject( void ); + + static void initPersistFields( void ); + + // Reference Methods. + + VObject *getObject( const String &pLabel ); + template inline bool getObject( const String &pLabel, T *&pObject ) + { + // Reference Object. + pObject = dynamic_cast( getObject( pLabel ) ); + + // Valid? + return ( pObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VObject ); + +public: + + // Property Methods. + + inline VController *getController( void ) { return mController; }; + + inline const String &getLabel( void ) const { return mLabel; }; + bool isEnabled( void ); + + bool isControllerPlaying( void ); + bool isControllerPaused( void ); + bool isControllerStopped( void ); + bool isControllerPlayingForward( void ); + bool isControllerLooping( void ); + S32 getControllerTime( void ); + F32 getControllerTimeScale( void ); + S32 getControllerDuration( void ); + + virtual void setLabel( const String &pLabel ); + void setLabelUnique( const String &pLabel ); + inline void setEnabled( const bool &pEnabled ) { mEnabled = pEnabled; }; + + // Callback Methods. + + virtual void onAttach( void ); + virtual void onDetach( void ); + + // Static Methods. + + static bool setEnabled( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setEnabled( dAtob( pData ) ); return false; }; + static bool setLabel( void *pObject, const char *pArray, const char *pData ) { static_cast( pObject )->setLabel( pData ); return false; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VOBJECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VTrack.cpp b/Engine/source/Verve/Core/VTrack.cpp new file mode 100644 index 000000000..6783faece --- /dev/null +++ b/Engine/source/Verve/Core/VTrack.cpp @@ -0,0 +1,448 @@ +//----------------------------------------------------------------------------- +// 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/VTrack.h" +#include "Verve/Core/VGroup.h" +#include "Verve/Core/VController.h" +#include "math/mMath.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VTrack ); +//----------------------------------------------------------------------------- + +VTrack::VTrack( void ) : + mNextEvent( NULL ) +{ + setLabel( "DefaultTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::onAttach(); +// +// This callback subscribes this object to the controller's event signal. +// +//----------------------------------------------------------------------------- +void VTrack::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller? + if ( getController() ) + { + // Subscribe to Updates. + getController()->getControllerUpdateSignal().notify( this, &VTrack::onControllerUpdate ); + + // Subscribe to Events. + getController()->getControllerEventSignal().notify( this, &VTrack::onControllerEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::onAttach(); +// +// This callback removes this object from the controller's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VTrack::onDetach( void ) +{ + // Valid Controller? + if ( getController() ) + { + // Remove Update Notification. + getController()->getControllerUpdateSignal().remove( this, &VTrack::onControllerUpdate ); + + // Remove Event Notification. + getController()->getControllerEventSignal().remove( this, &VTrack::onControllerEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerUpdate( pTime, pDelta ); +// +// The Next Event is integrated until has finished its execution. Once it has +// finished, the next event to be triggered becomes the Current Event. Doing +// this means that only one event is ever checked to see if it should be +// triggered. +// +//----------------------------------------------------------------------------- +void VTrack::onControllerUpdate( const S32 &pTime, const S32 &pDelta ) +{ + if ( !isEnabled() || !mNextEvent ) + { + // Don't Update. + return; + } + + // Update Next Event. + while ( !mNextEvent->onControllerUpdate( pTime, pDelta ) ) + { + // Next Event? + if ( !updateNextEvent() ) + { + // No Valid Events. + mNextEvent = NULL; + break; + } + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is reset the virtual method, onControllerReset is called. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VTrack::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { + case VController::k_EventReset : + { + + // Reset. + onControllerReset( getControllerTime(), isControllerPlayingForward() ); + + } break; + } + + // Continue Processing Events. + return true; +} + +//----------------------------------------------------------------------------- +// +// VTrack::onControllerReset( pTime, pForward ); +// +// Reset the status of the track. The Next Event is allocated here. +// +//----------------------------------------------------------------------------- +void VTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Clear Next Event. + mNextEvent = NULL; + + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *event = ( VEvent* )node; + + // Reset Event. + event->onControllerReset( pTime, pForward ); + + if ( ( event->isPlaying() ) + || ( pForward && event->getTriggerTime() >= pTime ) ) + { + if ( !mNextEvent ) + { + // Use as Next Event. + mNextEvent = event; + } + } + else if ( !pForward && pTime >= event->getTriggerTime() ) + { + VEvent *nextEvent = ( VEvent* )node->mSiblingNextNode; + if ( !nextEvent || pTime < nextEvent->getTriggerTime() ) + { + // Use as Next Event. + mNextEvent = event; + } + } + } +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::sort(); +// +// Sort the track's events by the event's trigger time. +// +//----------------------------------------------------------------------------- +void VTrack::sort( void ) +{ + const S32 count = size(); + for ( S32 j = 0; j < count; j++ ) + { + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *eventA = ( VEvent* )node; + VEvent *eventB = ( VEvent* )node->mSiblingNextNode; + if ( !eventB ) + { + // No Node. + break; + } + + // Swap? + if ( eventA->getTriggerTime() > eventB->getTriggerTime() ) + { + // Get Outer Siblings. + ITreeNode *prevNode = eventA->mSiblingPrevNode; + ITreeNode *nextNode = eventB->mSiblingNextNode; + + if ( eventA->mParentNode && eventA->mParentNode->mChildNode == eventA ) + { + // New Child Node. + eventA->mParentNode->mChildNode = eventB; + } + + // + // Move A. + eventA->mSiblingPrevNode = eventB; + eventA->mSiblingNextNode = nextNode; + + if ( nextNode ) + { + // Update Outer Sibling. + nextNode->mSiblingPrevNode = eventA; + } + + // + // Move B. + + eventB->mSiblingPrevNode = prevNode; + eventB->mSiblingNextNode = eventA; + + if ( prevNode ) + { + // Update Outer Sibling. + prevNode->mSiblingNextNode = eventB; + } + } + } + } +} + +//----------------------------------------------------------------------------- +// +// VTrack::updateNextEvent( pForward ); +// +// Point mNextEvent to the next valid event in the track's sequence. +// +//----------------------------------------------------------------------------- +bool VTrack::updateNextEvent( void ) +{ + if ( !mNextEvent ) + { + // Invalid Event. + return false; + } + + while ( ( mNextEvent = mNextEvent->getNextEvent() ) != NULL ) + { + if ( mNextEvent->isEnabled() ) + { + // Valid Event. + return true; + } + } + + // Invalid Event. + return false; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTrack::getGroup(); +// +// Returns the Track's parent group. +// +//----------------------------------------------------------------------------- +VGroup *VTrack::getGroup( void ) +{ + return dynamic_cast( mParentNode ); +} + +//----------------------------------------------------------------------------- +// +// VTrack::getNextEvent(); +// +// Returns the Event that the Track is currently observing. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getNextEvent( void ) +{ + return mNextEvent; +} + +//----------------------------------------------------------------------------- +// +// VTrack::getCurrentEvent(); +// +// Returns the Event that the Track is currently observing and playing. This +// will only ever be non-null when the track is observing an Event that has a +// non-zero duration and has been triggered. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getCurrentEvent( void ) +{ + if ( mNextEvent && mNextEvent->isPlaying() ) + { + return mNextEvent; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VTrack::getPreviousEvent(); +// +// Returns the Event that the Track was last intergrating. +// +//----------------------------------------------------------------------------- +VEvent *VTrack::getPreviousEvent( void ) +{ + if ( mNextEvent ) + { + return mNextEvent->getPreviousEvent(); + } + + if ( !isControllerPlayingForward() ) + { + return dynamic_cast( getChild() ); + } + + return dynamic_cast( getLastChild() ); +} + +//----------------------------------------------------------------------------- +// +// VTrack::calclateInterp( pTime ); +// +// This method returns the interp time between or within events. If the given +// time is between two events, the return time is: +// +// ( pTime - last_event_finish_time ) +// / ( next_event_start_time - last_event_finish_time ) +// +// If the given time is within an event, the return time is: +// +// ( pTime - event_start_time ) / ( event_duration ) +// +// The value returned here is between 0.0 and 1.0. +// +//----------------------------------------------------------------------------- +F32 VTrack::calculateInterp( S32 pTime ) +{ + if ( !isControllerPlayingForward() ) + { + return ( 1.f - _calculateInterp( pTime ) ); + } + + return _calculateInterp( pTime ); +} + +F32 VTrack::_calculateInterp( S32 pTime ) +{ + // Fetch Duration. + const S32 sequenceDuration = getControllerDuration(); + if ( sequenceDuration == 0 || pTime == sequenceDuration ) + { + // Sanity! + return 1.f; + } + + if ( !mChildNode ) + { + // Quick Interp. + return F32( pTime / sequenceDuration ); + } + + // Last Time. + S32 lastTime = 0; + + VEvent *walk = ( VEvent* )mChildNode; + while ( walk ) + { + const S32 startTime = walk->getStartTime(); + const S32 finishTime = walk->getFinishTime(); + + if ( pTime < startTime ) + { + return ( F32( pTime - lastTime ) / F32( startTime - lastTime ) ); + } + + // Update Last Time. + lastTime = startTime; + + if ( pTime < finishTime ) + { + return ( F32( pTime - lastTime ) / F32( finishTime - lastTime ) ); + } + + // Update Last Time. + lastTime = finishTime; + + // Fetch Next Node. + walk = ( VEvent* )walk->mSiblingNextNode; + } + + // Return. + return ( F32( pTime - lastTime ) / F32( sequenceDuration - lastTime ) ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Core/VTrack.h b/Engine/source/Verve/Core/VTrack.h new file mode 100644 index 000000000..eb2e576ce --- /dev/null +++ b/Engine/source/Verve/Core/VTrack.h @@ -0,0 +1,123 @@ +//----------------------------------------------------------------------------- +// 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_VTRACK_H_ +#define _VT_VTRACK_H_ + +#ifndef _VT_VCONTROLLER_H_ +#include "Verve/Core/VController.h" +#endif + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +//----------------------------------------------------------------------------- +class VGroup; +//----------------------------------------------------------------------------- + +class VTrack : public VObject +{ + typedef VObject Parent; + +public: + + // Controller Members. + + VEvent *mNextEvent; + +public: + + VTrack(); + + // Tree Methods. + + virtual void onAttach( void ); + virtual void onDetach( void ); + + // Controller Methods. + + virtual void onControllerUpdate( const S32 &pTime, const S32 &pDelta ); + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Reference Methods. + + void sort( void ); + bool updateNextEvent( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VTrack ); + +public: + + // Property Methods. + + VGroup *getGroup( void ); + template inline bool getGroup( T *&pGroup ) + { + // Reference Group. + pGroup = dynamic_cast( getGroup() ); + // Validate. + return ( pGroup != NULL ); + } + + VEvent *getNextEvent( void ); + template inline bool getNextEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getNextEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + VEvent *getCurrentEvent( void ); + template inline bool getCurrentEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getCurrentEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + VEvent *getPreviousEvent( void ); + template inline bool getPreviousEvent( T *&pEvent ) + { + // Reference Object. + pEvent = dynamic_cast( getPreviousEvent() ); + // Validate. + return ( pEvent != NULL ); + } + + F32 calculateInterp( S32 pTime ); + F32 _calculateInterp( S32 pTime ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Core/VTreeNode.cpp b/Engine/source/Verve/Core/VTreeNode.cpp new file mode 100644 index 000000000..29f4fa076 --- /dev/null +++ b/Engine/source/Verve/Core/VTreeNode.cpp @@ -0,0 +1,471 @@ +//----------------------------------------------------------------------------- +// 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/VTreeNode.h" +#include "console/simObject.h" +#include "platform/platform.h" + +//----------------------------------------------------------------------------- + +VTreeNode::VTreeNode( void ) +{ + mParentNode = NULL; + mChildNode = NULL; + mSiblingPrevNode = NULL; + mSiblingNextNode = NULL; +} + +VTreeNode::~VTreeNode( void ) +{ + // Delete Children. + clear(); + + // Detach. + remove(); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTreeNode::clear(); +// +// Delete all child nodes. +// +//----------------------------------------------------------------------------- +void VTreeNode::clear( void ) +{ + if ( !mChildNode ) + { + return; + } + + while ( mChildNode ) + { + // Fetch Child Node. + ITreeNode *node = mChildNode; + + // Clear It. + node->clear(); + + // Detach It. + node->remove(); + + // Delete It. + SimObject *object = dynamic_cast( node ); + if ( object ) + { + object->deleteObject(); + } + else + { + delete node; + } + } +} + +//----------------------------------------------------------------------------- +// +// ITreeNode Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VTreeNode::getRoot(); +// +// Returns the root object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getRoot( void ) +{ + ITreeNode *parent = this; + while ( parent->mParentNode ) + { + parent = parent->mParentNode; + } + + return parent; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getParent(); +// +// Returns the parent object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getParent( void ) +{ + return mParentNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getChild(); +// +// Returns the first child object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getChild( void ) +{ + return mChildNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getChild(); +// +// Returns the first child object. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getLastChild( void ) +{ + // Any Nodes? + if ( !mChildNode ) + { + // Null. + return NULL; + } + + // Front Node. + ITreeNode *lastNode = mChildNode; + + // Fetch Last Node. + while ( lastNode->mSiblingNextNode ) + { + lastNode = lastNode->mSiblingNextNode; + } + + // Return. + return lastNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getPrevSibling(); +// +// Returns the previous object in the linked list. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getPrevSibling( void ) +{ + return mSiblingPrevNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getNextSibling(); +// +// Returns the next object in the linked list. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::getNextSibling( void ) +{ + return mSiblingNextNode; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::size(); +// +// Returns the number of child objects. Only includes top level. +// +//----------------------------------------------------------------------------- +int VTreeNode::size( void ) +{ + int size = 0; + + ITreeNode *node = mChildNode; + while ( node ) + { + size++; + + node = node->mSiblingNextNode; + } + + return size; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::at( pIndex ); +// +// Returns the object at the given index. +// +//----------------------------------------------------------------------------- +ITreeNode *VTreeNode::at( const int pIndex ) +{ + int index = 0; + + ITreeNode *node = mChildNode; + while ( node ) + { + if ( index++ == pIndex ) + { + return node; + } + + node = node->mSiblingNextNode; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::getIndex(); +// +// Returns the index of the object in relation to the sibling nodes. +// +//----------------------------------------------------------------------------- +int VTreeNode::getIndex( void ) +{ + if ( !inTree() ) + { + // No Index. + return 0; + } + + ITreeNode *walk = NULL; + if ( mParentNode ) + { + walk = mParentNode->mChildNode; + } + else + { + walk = this; + while ( walk->mSiblingPrevNode ) + { + // Walk Up. + walk = walk->mSiblingPrevNode; + } + } + + for ( int i = 0; walk; walk = walk->mSiblingNextNode, i++ ) + { + if ( walk == this ) + { + return i; + } + } + + AssertFatal( false, "VTreeNode::getIndex() - Node List Broken?" ); + + return 0; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::addTo( pNode ); +// +// Attach this node to the back of the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::addTo( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Already In Tree. + return; + } + + // Set Parent. + mParentNode = pNode; + + if ( !pNode->mChildNode ) + { + // Store Child Node. + pNode->mChildNode = this; + } + else + { + // Front Node. + ITreeNode *headNode = pNode->mChildNode; + + // Fetch Head Node. + while ( headNode->mSiblingNextNode ) + { + headNode = headNode->mSiblingNextNode; + } + + // Reference Next Node. + headNode->mSiblingNextNode = this; + + // Reference Previous Node. + mSiblingPrevNode = headNode; + } + + // Callback. + onAttach(); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::addToFront( pNode ); +// +// Attach this node to the front of the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::addToFront( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Already In Tree. + return; + } + + // Set Parent. + mParentNode = pNode; + + if ( !pNode->mChildNode ) + { + // Store Child Node. + pNode->mChildNode = this; + } + else + { + // First Node. + ITreeNode *childNode = pNode->mChildNode; + + // Reference Previous Node. + childNode->mSiblingPrevNode = this; + + // Reference Next Node. + mSiblingNextNode = childNode; + + // Store Child Node. + pNode->mChildNode = this; + } + + // Callback. + onAttach(); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::remove(); +// +// Detach this node from the current parent node. +// +//----------------------------------------------------------------------------- +void VTreeNode::remove( void ) +{ + if ( !inTree() ) + { + return; + } + + // Callback. + onDetach(); + + if ( mParentNode && mParentNode->mChildNode == this ) + { + // Update Parent Reference. + mParentNode->mChildNode = mSiblingNextNode; + } + + if ( mSiblingNextNode ) + { + // Update Previous Node. + mSiblingNextNode->mSiblingPrevNode = mSiblingPrevNode; + } + + if ( mSiblingPrevNode ) + { + // Update Next Node. + mSiblingPrevNode->mSiblingNextNode = mSiblingNextNode; + } + + // Remove References. + mParentNode = mSiblingPrevNode = mSiblingNextNode = NULL; +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::moveTo( pNode ); +// +// Detach this node and attach it to the target node. +// +//----------------------------------------------------------------------------- +void VTreeNode::moveTo( ITreeNode *pNode ) +{ + if ( inTree() ) + { + // Remove from Tree. + remove(); + } + + // Add to tree. + addTo( pNode ); +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::onAttach(); +// +// This method will be called when this node, or a parent node, is attached to +// a node. +// +//----------------------------------------------------------------------------- +void VTreeNode::onAttach( void ) +{ + // Notify Children. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + node->onAttach(); + } +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::onDetach(); +// +// This method will be called when this node, or a parent node, is detached. +// +//----------------------------------------------------------------------------- +void VTreeNode::onDetach( void ) +{ + // Notify Children. + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + node->onDetach(); + } +} + +//----------------------------------------------------------------------------- +// +// VTreeNode::inTree(); +// +// Returns true if the node is the a member of a node tree. +// +//----------------------------------------------------------------------------- +bool VTreeNode::inTree( void ) +{ + return !( mParentNode == NULL && + mSiblingPrevNode == NULL && + mSiblingNextNode == NULL ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Core/VTreeNode.h b/Engine/source/Verve/Core/VTreeNode.h new file mode 100644 index 000000000..459e972ca --- /dev/null +++ b/Engine/source/Verve/Core/VTreeNode.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// 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_VTREENODE_H_ +#define _VT_VTREENODE_H_ + +#ifndef _VT_ITREENODE_H_ +#include "Verve/Core/ITreeNode.h" +#endif + +//----------------------------------------------------------------------------- + +class VTreeNode : public ITreeNode +{ + typedef ITreeNode Parent; + +public: + + VTreeNode( void ); + ~VTreeNode( void ); + + // Reference Methods. + + virtual void clear( void ); + + // ITreeNode Methods. + + virtual ITreeNode *getRoot( void ); + virtual ITreeNode *getParent( void ); + virtual ITreeNode *getChild( void ); + virtual ITreeNode *getLastChild( void ); + + virtual ITreeNode *getPrevSibling( void ); + virtual ITreeNode *getNextSibling( void ); + + virtual ITreeNode *at( const int pIndex ); + virtual int size( void ); + + virtual int getIndex( void ); + + virtual void addTo( ITreeNode *pNode ); + virtual void addToFront( ITreeNode *pNode ); + virtual void remove( void ); + virtual void moveTo( ITreeNode *pNode ); + + virtual void onAttach( void ); + virtual void onDetach( void ); + + virtual bool inTree( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTREENODE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.cpp b/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.cpp new file mode 100644 index 000000000..b40460871 --- /dev/null +++ b/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.cpp @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Animation/VShapeAnimationEvent.h" +#include "Verve/Extension/Animation/VShapeAnimationTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VShapeAnimationEvent ); +//----------------------------------------------------------------------------- + +VShapeAnimationEvent::VShapeAnimationEvent( void ) : + mAnimationData( String::EmptyString ), + mAutoDuration( true ) +{ + setLabel( "AnimationEvent" ); +} + +//----------------------------------------------------------------------------- + +void VShapeAnimationEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "AnimationData", TypeRealString, Offset( mAnimationData, VShapeAnimationEvent ), "The name of the Animation Sequence to play upon triggering." ); + addField( "AutoDuration", TypeBool, Offset( mAutoDuration, VShapeAnimationEvent ), "Force the Event's Duration to match the length of the Animation." ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::onTrigger( pTime, pDelta ); +// +// Play the desired animation. Also account for any offet in playtime, and +// timescale. +// +//----------------------------------------------------------------------------- +void VShapeAnimationEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::SceneObjectType *object = getSceneObject(); + VShapeAnimationTrack *track; + if ( !object || !getTrack( track ) ) + { + // Sanity! + return; + } + + // Play Animation. + VTorque::playAnimation( object, track->getThreadIndex(), mAnimationData ); + + // Set Position. + VTorque::setAnimationPosition( object, track->getThreadIndex(), getAnimationPosition( pTime + pDelta ) ); + + // Set Time Scale. + VTorque::setAnimationTimeScale( object, track->getThreadIndex(), ( ( pDelta > 0 ) ? 1.f : -1.f ) ); +} + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::onComplete( pTime, pDelta ); +// +// If the animation is cyclic, then it needs to be paused once the event has +// finished playing. +// +//----------------------------------------------------------------------------- +void VShapeAnimationEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + // Fetch Object. + VTorque::SceneObjectType *object = getSceneObject(); + VShapeAnimationTrack *track; + if ( object && VTorque::isAnimationLooping( object, mAnimationData ) && getTrack( track ) ) + { + // Pause Animation. + VTorque::pauseAnimation( object, track->getThreadIndex() ); + } +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationEvent::getAnimationPosition( pTime ); +// +// Returns the time that the animation should be positioned at, at the given +// time. This method considers whether the animation is cyclic or not and will +// return the appropriate time regardless. Time is expressed in seconds and not +// milliseconds. +// +//----------------------------------------------------------------------------- +F32 VShapeAnimationEvent::getAnimationPosition( const S32 &pTime ) +{ + // Fetch Object. + VSceneObjectTrack *track; + VTorque::SceneObjectType *object = getSceneObject(); + if ( !getTrack( track ) || !object ) + { + // Null. + return 0.f; + } + + // Fetch Interp. + F32 interp = track->calculateInterp( pTime ); + if ( !isControllerPlayingForward() ) + { + // Flip. + interp = ( 1.f - interp ); + } + + // Not Looping? + if ( !VTorque::isAnimationLooping( object, mAnimationData ) ) + { + // Return Interp. + return interp; + } + + // Fetch Sequence Duration. + const S32 duration = ( S32 )( 1000 * VTorque::getAnimationDuration( object, mAnimationData ) ); + + // Fetch Loop Interp. + const S32 loopInterp = S32( mDuration * interp ) % duration; + + return ( F32 )loopInterp / ( F32 )duration; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.h b/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.h new file mode 100644 index 000000000..9146836e9 --- /dev/null +++ b/Engine/source/Verve/Extension/Animation/VShapeAnimationEvent.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// 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_VSHAPEANIMATIONEVENT_H_ +#define _VT_VSHAPEANIMATIONEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_ANIMATION_H_ +#include "Verve/Torque/TAnimation.h" +#endif + +//----------------------------------------------------------------------------- + +class VShapeAnimationEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + +public: + + bool mAutoDuration; + String mAnimationData; + +public: + + VShapeAnimationEvent( void ); + + static void initPersistFields( void ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VShapeAnimationEvent ); + +public: + + // Property Methods. + + F32 getAnimationPosition( const S32 &pTime ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAPEANIMATIONEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.cpp b/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.cpp new file mode 100644 index 000000000..caeff5b38 --- /dev/null +++ b/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.cpp @@ -0,0 +1,185 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Animation/VShapeAnimationTrack.h" +#include "Verve/Extension/Animation/VShapeAnimationEvent.h" +#include "Verve/Core/VGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VShapeAnimationTrack ); +//----------------------------------------------------------------------------- + +VShapeAnimationTrack::VShapeAnimationTrack( void ) : + mThreadIndex( 0 ) +{ + setLabel( "AnimationTrack" ); +} + +//----------------------------------------------------------------------------- + +void VShapeAnimationTrack::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "ThreadIndex", TypeS32, Offset( mThreadIndex, VShapeAnimationTrack ), "The index of the Animation Thread to play." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VShapeAnimationTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is paused, or stops playing, then the animation will cease to +// play. If the controller resumes play, the animation will continue. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VShapeAnimationTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay : + { + + // Play Animation. + VTorque::setAnimationTimeScale( getSceneObject(), mThreadIndex, ( ( isControllerPlayingForward() ) ? 1.f : -1.f ) ); + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Stop Animation. + VTorque::setAnimationTimeScale( getSceneObject(), mThreadIndex, 0.f ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VShapeAnimationTrack::onControllerReset( pTime, pForward ); +// +// Reset the animation state of the target object. If there is a Next Event, +// then the animation is positioned accordingly. +// +//----------------------------------------------------------------------------- +void VShapeAnimationTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + VTorque::SceneObjectType *object = getSceneObject(); + if ( !object ) + { + // Parent Call. + Parent::onControllerReset( pTime, pForward ); + return; + } + + VShapeAnimationEvent *event; + if ( getCurrentEvent( event ) ) + { + // Stop Animation. + VTorque::stopAnimation( object, mThreadIndex ); + } + + // Parent Call. + Parent::onControllerReset( pTime, pForward ); + + if ( getCurrentEvent( event ) ) + { + // Play Animation. + VTorque::playAnimation( object, mThreadIndex, event->mAnimationData ); + + // Set Position. + VTorque::setAnimationPosition( object, mThreadIndex, event->getAnimationPosition( pTime ) ); + + // Stop Animation. + VTorque::setAnimationTimeScale( object, mThreadIndex, 0.f ); + } +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VShapeAnimationTrack, updateTrack, void, (),, "( void ) - Update the Track.\n" + "@return No return value." ) +{ + for ( ITreeNode *node = object->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VShapeAnimationEvent *currEvent = ( VShapeAnimationEvent* )node; + VShapeAnimationEvent *nextEvent = ( VShapeAnimationEvent* )node->mSiblingNextNode; + if ( !currEvent->mAutoDuration ) + { + // Skip. + continue; + } + + if ( VTorque::isAnimationLooping( object->getSceneObject(), currEvent->mAnimationData ) ) + { + if ( !nextEvent ) + { + // Update Duration. + currEvent->setDuration( object->getControllerDuration() - currEvent->getTriggerTime() ); + } + else + { + // Update Duration. + currEvent->setDuration( mAbs( nextEvent->getTriggerTime() - currEvent->getTriggerTime() ) ); + } + } + else + { + // Update Duration. + currEvent->setDuration( ( S32 )( 1000 * VTorque::getAnimationDuration( object->getSceneObject(), currEvent->mAnimationData ) ) ); + } + } +} +#endif diff --git a/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.h b/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.h new file mode 100644 index 000000000..3b9cf7bce --- /dev/null +++ b/Engine/source/Verve/Extension/Animation/VShapeAnimationTrack.h @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// 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_VSHAPEANIMATIONTRACK_H_ +#define _VT_VSHAPEANIMATIONTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_ANIMATION_H_ +#include "Verve/Torque/TAnimation.h" +#endif + +//----------------------------------------------------------------------------- + +class VShapeAnimationTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + + U32 mThreadIndex; + +public: + + VShapeAnimationTrack( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VShapeAnimationTrack ); + +public: + + inline U32 &getThreadIndex( void ) { return mThreadIndex; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSHAPEANIMATIONTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraGroup.cpp b/Engine/source/Verve/Extension/Camera/VCameraGroup.cpp new file mode 100644 index 000000000..14b2cb97c --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraGroup.cpp @@ -0,0 +1,224 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraGroup.h" +#include "Verve/Extension/Camera/VCameraTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraGroup ); +//----------------------------------------------------------------------------- + +VCameraGroup *VCameraGroup::mActiveGroup = NULL; +VCameraGroup::CameraChangeSignal VCameraGroup::mCameraChangeSignal; + +//----------------------------------------------------------------------------- + +VCameraGroup::VCameraGroup( void ) +{ + setLabel( "CameraGroup" ); +}; + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onAttach(); +// +// This callback subscribes this object to the controller's event signal. +// +//----------------------------------------------------------------------------- +void VCameraGroup::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller? + if ( getController() ) + { + // Subscribe to Events. + getController()->getControllerEventSignal().notify( this, &VCameraGroup::onControllerEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onAttach(); +// +// This callback removes this object from the controller's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VCameraGroup::onDetach( void ) +{ + // Valid Controller? + if ( getController() ) + { + // Remove Event Notification. + getController()->getControllerEventSignal().remove( this, &VCameraGroup::onControllerEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VCameraGroup::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VCameraGroup::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { +#ifdef VT_EDITOR + case VController::k_EventPause : +#endif + case VController::k_EventStop : + { + + // Clear the Camera. + clearActiveGroup(); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraGroup::setActive(); +// +// Set this Group to Active. +// +//----------------------------------------------------------------------------- +void VCameraGroup::setActive( void ) +{ + // Set Active. + setActiveGroup( this ); +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::clearActiveGroup(); +// +// Clear the Active Camera. +// +//----------------------------------------------------------------------------- +void VCameraGroup::clearActiveGroup( void ) +{ + if ( mActiveGroup ) + { + // Deactivate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventDeactivate ); + } + + // Store. + mActiveGroup = NULL; + + // Clear Camera Object. + VTorque::setCamera( NULL ); + + // Change Signal. + getCameraChangeSignal().trigger( NULL ); +} + +//----------------------------------------------------------------------------- +// +// VCameraGroup::setActiveGroup( pCameraGroup ); +// +// Change the current camera group. The actual camera object is the object that +// the group references. +// +// A NULL value of pCameraGroup will clear the active camera, which generally +// reverts to the connection's control object. The camera is also cleared when +// the Controller stops playing. +// +//----------------------------------------------------------------------------- +void VCameraGroup::setActiveGroup( VCameraGroup *pCameraGroup ) +{ + // Change Camera? + if ( pCameraGroup == mActiveGroup || + pCameraGroup && !pCameraGroup->isEnabled() ) + { + // Invalid Target. + return; + } + + if ( mActiveGroup ) + { + // Deactivate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventDeactivate ); + } + + // Store. + mActiveGroup = pCameraGroup; + + if ( mActiveGroup ) + { + // Set Camera Object. + VTorque::setCamera( mActiveGroup->getSceneObject() ); + + // Activate Signal. + mActiveGroup->getCameraEventSignal().trigger( k_EventActivate ); + } + else + { + // Clear Camera Object. + VTorque::setCamera( NULL ); + } + + // Change Signal. + getCameraChangeSignal().trigger( mActiveGroup ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraGroup.h b/Engine/source/Verve/Extension/Camera/VCameraGroup.h new file mode 100644 index 000000000..eea9a2f7b --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraGroup.h @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERAGROUP_H_ +#define _VT_VCAMERAGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +#ifndef _VT_VCONTROLLER_H +#include "Verve/Core/VController.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraGroup; + +//----------------------------------------------------------------------------- + +class VCameraGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + enum eCameraEventType + { + k_EventActivate, + k_EventDeactivate, + }; + + typedef Signal CameraEventSignal; + typedef Signal CameraChangeSignal; + +protected: + + static VCameraGroup *mActiveGroup; + static CameraChangeSignal mCameraChangeSignal; + + CameraEventSignal mCameraEventSignal; + +public: + + VCameraGroup( void ); + + // Tree Methods. + + void onAttach( void ); + void onDetach( void ); + + // Controller Methods. + + bool onControllerEvent( VController::eControllerEventType pEvent ); + + // Camera Methods. + + inline bool isActive( void ) { return ( bool )( this == getActiveGroup() ); }; + inline VCameraGroup *getActiveGroup( void ) { return mActiveGroup; }; + + void setActive( void ); + + static void clearActiveGroup( void ); + static void setActiveGroup( VCameraGroup *pCameraGroup ); + + // Signal Methods. + + static inline CameraChangeSignal &getCameraChangeSignal( void ) { return mCameraChangeSignal; }; + inline CameraEventSignal &getCameraEventSignal( void ) { return mCameraEventSignal; }; + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERAGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.cpp b/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.cpp new file mode 100644 index 000000000..88c528d27 --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.cpp @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------- +// 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/Camera/VCameraGroup.h" +#include "Verve/Extension/Camera/VCameraShakeEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraShakeEvent ); +//----------------------------------------------------------------------------- + +VCameraShakeEvent::VCameraShakeEvent( void ) : + mAmplitude( Point3F::Zero ), + mFalloff( 10.f ), + mFrequency( Point3F::Zero ) +{ + // Clear Label. + setLabel( "CameraShakeEvent" ); +} + +void VCameraShakeEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Amplitude", TypePoint3F, Offset( mAmplitude, VCameraShakeEvent ), "Amplitude of the Camera Shake event." ); + addField( "Falloff", TypeF32, Offset( mFalloff, VCameraShakeEvent ), "Falloff of the Camera Shake event." ); + addField( "Frequency", TypePoint3F, Offset( mFrequency, VCameraShakeEvent ), "Frequency of the Camera Shake event." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeEvent::onTrigger( pTime, pDelta ); +// +// Start shaking the camera. Also account for any offet in playtime, and +// timescale. +// +//----------------------------------------------------------------------------- +void VCameraShakeEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Group. + VCameraGroup *group; + if ( !getGroup( group ) || !group->isActive() ) + { + // Inactive. + return; + } + + // Duration. + //const F32 duration = ( mDuration - mAbs( pTime - getStartTime() ) ) / ( 1000.f * mFabs( getControllerTimeScale() ) ); + const F32 duration = ( mDuration - mAbs( pTime - getStartTime() ) ) / 1000.f; + + // Shake Camera. + VTorque::startCameraShake( duration, mFalloff, mAmplitude, mFrequency ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.h b/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.h new file mode 100644 index 000000000..9a8af7899 --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraShakeEvent.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERASHAKEEVENT_H_ +#define _VT_VCAMERASHAKEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraShakeEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VectorF mAmplitude; + F32 mFalloff; + VectorF mFrequency; + +public: + + VCameraShakeEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraShakeEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERASHAKEEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.cpp b/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.cpp new file mode 100644 index 000000000..4f6fb5e81 --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.cpp @@ -0,0 +1,114 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraShakeTrack.h" +#include "Verve/Extension/Camera/VCameraShakeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraShakeTrack ); +//----------------------------------------------------------------------------- + +VCameraShakeTrack::VCameraShakeTrack( void ) +{ + setLabel( "CameraShakeTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incoming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VCameraShakeTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + // Parent Call. + if ( !Parent::onCameraEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch( pEvent ) + { + case VCameraGroup::k_EventActivate : + { + + VCameraShakeEvent *event; + if ( getCurrentEvent( event ) ) + { + // Re-Trigger Event. + event->onTrigger( getControllerTime(), 0 ); + } + + } break; + + case VCameraGroup::k_EventDeactivate : + { + + // Stop Camera Shake. + VTorque::stopCameraShake(); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraShakeTrack::onControllerReset( pTime, pForward ); +// +// Stop all camera shake events. +// +//----------------------------------------------------------------------------- +void VCameraShakeTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + // Stop Camera Shake. + VTorque::stopCameraShake(); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.h b/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.h new file mode 100644 index 000000000..2c09900bc --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraShakeTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERASHAKETRACK_H_ +#define _VT_VCAMERASHAKETRACK_H_ + +#ifndef _VT_VCAMERATRACK_H_ +#include "Verve/Extension/Camera/VCameraTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraShakeTrack : public VCameraTrack +{ + typedef VCameraTrack Parent; + +public: + + VCameraShakeTrack( void ); + + // Camera Methods. + + bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Controller Methods. + + void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraShakeTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERASHAKETRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraTrack.cpp b/Engine/source/Verve/Extension/Camera/VCameraTrack.cpp new file mode 100644 index 000000000..47e734af9 --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraTrack.cpp @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Camera/VCameraTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VCameraTrack ); +//----------------------------------------------------------------------------- + +VCameraTrack::VCameraTrack( void ) +{ + setLabel( "CameraTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Tree Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onAttach(); +// +// This callback subscribes this object to the Camera Group's event signal. +// +//----------------------------------------------------------------------------- +void VCameraTrack::onAttach( void ) +{ + Parent::onAttach(); + + // Valid Controller & Group? + VCameraGroup *group; + if ( getController() && getGroup( group ) ) + { + // Add Event Notification. + group->getCameraEventSignal().notify( this, &VCameraTrack::onCameraEvent ); + } +} + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onAttach(); +// +// This callback removes this object from the Camera Group's event signal +// notification list. +// +//----------------------------------------------------------------------------- +void VCameraTrack::onDetach( void ) +{ + // Valid Controller & Group? + VCameraGroup *group; + if ( getController() && getGroup( group ) ) + { + // Clear Event Notification. + group->getCameraEventSignal().remove( this, &VCameraTrack::onCameraEvent ); + } + + Parent::onDetach(); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VCameraTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incomming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VCameraTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + if ( !getController() ) + { + AssertFatal( false, "VCameraTrack::onControllerEvent() - Invalid Controller." ); + return false; + } + + // Ok. + return true; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Camera/VCameraTrack.h b/Engine/source/Verve/Extension/Camera/VCameraTrack.h new file mode 100644 index 000000000..6866638a2 --- /dev/null +++ b/Engine/source/Verve/Extension/Camera/VCameraTrack.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VCAMERATRACK_H_ +#define _VT_VCAMERATRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_VCAMERAGROUP_H_ +#include "Verve/Extension/Camera/VCameraGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VCameraTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VCameraTrack( void ); + + // Tree Methods. + + void onAttach( void ); + void onDetach( void ); + + // Camera Methods. + + virtual bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Console Declaration. + + DECLARE_CONOBJECT( VCameraTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VCAMERATRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VDirectorEvent.cpp b/Engine/source/Verve/Extension/Director/VDirectorEvent.cpp new file mode 100644 index 000000000..9030b4018 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorEvent.cpp @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------- +// 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/Director/VDirectorEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorEvent ); +//----------------------------------------------------------------------------- + +VDirectorEvent::VDirectorEvent( void ) : + mTarget( String::EmptyString ) +{ + // Void. +} + +void VDirectorEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Target", TypeRealString, Offset( mTarget, VDirectorEvent ), "The name of the CameraGroup that will be activated upon triggering." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VDirectorEvent::onTrigger( pTime, pDelta ); +// +// Cut the camera to the target group. +// +//----------------------------------------------------------------------------- +void VDirectorEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Controller. + VController *controller = getController(); + + // Valid Target? + VCameraGroup *targetGroup = NULL; + if ( !controller->getObject( mTarget, targetGroup ) ) + { + Con::warnf( "VDirectorEvent::onTrigger() - Invalid Target Group specified." ); + return; + } + + // Change Camera. + targetGroup->setActive(); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VDirectorEvent.h b/Engine/source/Verve/Extension/Director/VDirectorEvent.h new file mode 100644 index 000000000..e890e5a06 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorEvent.h @@ -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_VDIRECTOREVENT_H_ +#define _VT_VDIRECTOREVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_VCAMERAGROUP_H_ +#include "Verve/Extension/Camera/VCameraGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + String mTarget; + +public: + + VDirectorEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTOREVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VDirectorGroup.cpp b/Engine/source/Verve/Extension/Director/VDirectorGroup.cpp new file mode 100644 index 000000000..4f8934124 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorGroup.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VDirectorGroup.h" +#include "Verve/Extension/Director/VDirectorTrack.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorGroup ); +//----------------------------------------------------------------------------- + +VDirectorGroup::VDirectorGroup( void ) : + mActiveCamera( NULL ) +{ + setLabel( "DirectorGroup" ); +}; + +//----------------------------------------------------------------------------- +// +// VDirectorGroup::getDirectorTrack(); +// +// Returns the DirectorTrack reference. +// +//----------------------------------------------------------------------------- +VDirectorTrack *VDirectorGroup::getDirectorTrack( void ) +{ + for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + if ( VDirectorTrack *track = dynamic_cast( node ) ) + { + // Return Track. + return track; + } + } + + // Invalid Track. + return NULL; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VDirectorGroup.h b/Engine/source/Verve/Extension/Director/VDirectorGroup.h new file mode 100644 index 000000000..bcf9b7a44 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorGroup.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// 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_VDIRECTORGROUP_H_ +#define _VT_VDIRECTORGROUP_H_ + +#ifndef _VT_VGROUP_H_ +#include "Verve/Core/VGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorTrack; +class VCameraGroup; + +//----------------------------------------------------------------------------- + +class VDirectorGroup : public VGroup +{ + typedef VGroup Parent; + +protected: + + // Camera. + VCameraGroup *mActiveCamera; + +public: + + VDirectorGroup( void ); + + VDirectorTrack *getDirectorTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTORGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VDirectorTrack.cpp b/Engine/source/Verve/Extension/Director/VDirectorTrack.cpp new file mode 100644 index 000000000..0867ac1f1 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VDirectorTrack.h" + +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VDirectorTrack ); +//----------------------------------------------------------------------------- + +VDirectorTrack::VDirectorTrack( void ) +{ + setLabel( "DirectorTrack" ); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VDirectorTrack, updateTrack, void, (),, "( void ) - Update the Track.\n" + "@return No return value." ) +{ + for ( ITreeNode *node = object->mChildNode; node != NULL; node = node->mSiblingNextNode ) + { + VEvent *currEvent = ( VEvent* )node; + VEvent *nextEvent = ( VEvent* )node->mSiblingNextNode; + + if ( !nextEvent ) + { + // Update Duration. + currEvent->setDuration( object->getControllerDuration() - currEvent->getTriggerTime() ); + } + else + { + // Update Duration. + currEvent->setDuration( mAbs( nextEvent->getTriggerTime() - currEvent->getTriggerTime() ) ); + } + } +} +#endif diff --git a/Engine/source/Verve/Extension/Director/VDirectorTrack.h b/Engine/source/Verve/Extension/Director/VDirectorTrack.h new file mode 100644 index 000000000..98b36a410 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VDirectorTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VDIRECTORTRACK_H_ +#define _VT_VDIRECTORTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VDirectorTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VDirectorTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VDirectorTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VDIRECTORTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSceneJumpEvent.cpp b/Engine/source/Verve/Extension/Director/VSceneJumpEvent.cpp new file mode 100644 index 000000000..09df231b1 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSceneJumpEvent.cpp @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSceneJumpEvent.h" +#include "Verve/Extension/Director/VDirectorGroup.h" +#include "Verve/Extension/Director/VDirectorTrack.h" +#include "Verve/Extension/Director/VDirectorEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneJumpEvent ); +//----------------------------------------------------------------------------- + +VSceneJumpEvent::VSceneJumpEvent( void ) : + mTarget( String::EmptyString ) +{ + setLabel( "SceneJumpEvent" ); +} + +void VSceneJumpEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Target", TypeRealString, Offset( mTarget, VSceneJumpEvent ), "The name of the Scene that the controller will jump to upon triggering." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneJumpEvent::onTrigger( pTime, pDelta ); +// +// Tell the controller to jump to a new scene. +// +//----------------------------------------------------------------------------- +void VSceneJumpEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VDirectorTrack *track = getController()->getDirectorTrack(); + if ( !track ) + { + // Invalid Track. + return; + } + + // Get Event. + VDirectorEvent *event; + if ( !track->getObject( mTarget, event ) ) + { + // Can't Jump. + return; + } + + // Go To Scene. + getController()->jump( VController::k_JumpTime, event->getTriggerTime() ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSceneJumpEvent.h b/Engine/source/Verve/Extension/Director/VSceneJumpEvent.h new file mode 100644 index 000000000..bf7b597bf --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSceneJumpEvent.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEJUMPEVENT_H_ +#define _VT_VSCENEJUMPEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneJumpEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + String mTarget; + +public: + + VSceneJumpEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneJumpEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEJUMPEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSceneJumpTrack.cpp b/Engine/source/Verve/Extension/Director/VSceneJumpTrack.cpp new file mode 100644 index 000000000..2a6e290d8 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSceneJumpTrack.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSceneJumpTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneJumpTrack ); +//----------------------------------------------------------------------------- + +VSceneJumpTrack::VSceneJumpTrack( void ) +{ + setLabel( "SceneJumpTrack" ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSceneJumpTrack.h b/Engine/source/Verve/Extension/Director/VSceneJumpTrack.h new file mode 100644 index 000000000..fefb4e4f6 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSceneJumpTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEJUMPTRACK_H_ +#define _VT_VSCENEJUMPTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneJumpTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSceneJumpTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneJumpTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEJUMPTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSlowMoEvent.cpp b/Engine/source/Verve/Extension/Director/VSlowMoEvent.cpp new file mode 100644 index 000000000..3427bda43 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSlowMoEvent.cpp @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSlowMoEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSlowMoEvent ); +//----------------------------------------------------------------------------- + +VSlowMoEvent::VSlowMoEvent( void ) : + mTimeScale( 1.f ), + mTimeScaleTickDelta( 0.f ) +{ + setLabel( "SlowMoEvent" ); +} + +void VSlowMoEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "TimeScale", TypeF32, Offset( mTimeScale, VSlowMoEvent ), "The Time Scale to be applied to the Root Controller." ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onTrigger( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Instant Update? + if ( getDuration() == 0 ) + { + // Apply & Return. + controller->setTimeScale( mTimeScale ); + return; + } + + // Determine the Number of Ticks. + const F32 tickCount = ( ( F32 )getDuration() ) / TickMs; + + // Determine the Tick Delta. + mTimeScaleTickDelta = ( mTimeScale - controller->getTimeScale() ) / tickCount; +} + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onUpdate( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onUpdate( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onUpdate( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Fetch Current Time Scale. + const F32 timeScale = controller->getTimeScale(); + + // Apply Update. + controller->setTimeScale( timeScale + mTimeScaleTickDelta ); +} + +//----------------------------------------------------------------------------- +// +// VSlowMoEvent::onComplete( pTime, pDelta ); +// +// +// +//----------------------------------------------------------------------------- +void VSlowMoEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onComplete( pTime, pDelta ); + + VController *controller = getController(); + if ( !controller ) + { + // Invalid Controller. + return; + } + + // Tidy Up. + controller->setTimeScale( mTimeScale ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSlowMoEvent.h b/Engine/source/Verve/Extension/Director/VSlowMoEvent.h new file mode 100644 index 000000000..1cdf75889 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSlowMoEvent.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VSLOWMOEVENT_H_ +#define _VT_VSLOWMOEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VSlowMoEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + F32 mTimeScale; + F32 mTimeScaleTickDelta; + +public: + + VSlowMoEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onUpdate( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSlowMoEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSLOWMOEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSlowMoTrack.cpp b/Engine/source/Verve/Extension/Director/VSlowMoTrack.cpp new file mode 100644 index 000000000..094acfa5e --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSlowMoTrack.cpp @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Director/VSlowMoTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSlowMoTrack ); +//----------------------------------------------------------------------------- + +VSlowMoTrack::VSlowMoTrack( void ) +{ + setLabel( "SlowMoTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSlowMoTrack::onControllerEvent( pEvent ); +// +// ... +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VSlowMoTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventStop : + { + + // Reset Time Scale. + getController()->setTimeScale( ( isControllerPlayingForward() ) ? 1.f : -1.f ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VSlowMoTrack::onControllerReset( pTime, pForward ); +// +// ... +// +//----------------------------------------------------------------------------- +void VSlowMoTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Parent Reset. + Parent::onControllerReset( pTime, pForward ); + + // Reset Time Scale. + getController()->setTimeScale( ( pForward ) ? 1.f : -1.f ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Director/VSlowMoTrack.h b/Engine/source/Verve/Extension/Director/VSlowMoTrack.h new file mode 100644 index 000000000..143203c99 --- /dev/null +++ b/Engine/source/Verve/Extension/Director/VSlowMoTrack.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_VSLOWMOTRACK_H_ +#define _VT_VSLOWMOTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VSlowMoTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSlowMoTrack( void ); + + // Controller Methods. + + bool onControllerEvent( VController::eControllerEventType pEvent ); + void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSlowMoTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSLOWMOTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/GUI/VFadeEvent.cpp b/Engine/source/Verve/Extension/GUI/VFadeEvent.cpp new file mode 100644 index 000000000..c8d0db6c0 --- /dev/null +++ b/Engine/source/Verve/Extension/GUI/VFadeEvent.cpp @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// 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/Extension/GUI/VFadeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeEvent ); +//----------------------------------------------------------------------------- + +VFadeEvent::VFadeEvent( void ) +{ + setLabel( "FadeEvent" ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeEvent::onTrigger( pTime, pDelta ); +// +// Start the fade sequence if a valid fade control can be found. +// +//----------------------------------------------------------------------------- +void VFadeEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + // Start Fade. + fadeControl->start( getFadeType(), mDuration ); + + // Set Elapsed Time. + fadeControl->mElapsedTime = mAbs( pTime - getStartTime() ); +} + +//----------------------------------------------------------------------------- +// +// VFadeEvent::onComplete( pTime, pDelta ); +// +// Tidy up the fade control once the event has finished. +// +//----------------------------------------------------------------------------- +void VFadeEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + // Set Elapsed Time. + fadeControl->mElapsedTime = mDuration; +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeEvent::getFadeType(); +// +// Returns the type of fade (in or out) that this event will use. Zero and Even +// indices will Fade Out, while Odd numbers will Fade In. +// +//----------------------------------------------------------------------------- +VFadeControl::eFadeType VFadeEvent::getFadeType( void ) +{ + if ( !isControllerPlayingForward() ) + { + return ( getIndex() % 2 == 0 ) ? VFadeControl::k_TypeOut : VFadeControl::k_TypeIn; + } + + return ( getIndex() % 2 == 0 ) ? VFadeControl::k_TypeIn : VFadeControl::k_TypeOut; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/GUI/VFadeEvent.h b/Engine/source/Verve/Extension/GUI/VFadeEvent.h new file mode 100644 index 000000000..78c8d7c5f --- /dev/null +++ b/Engine/source/Verve/Extension/GUI/VFadeEvent.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VFADEEVENT_H_ +#define _VT_VFADEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_VFADECONTROL_H_ +#include "Verve/GUI/VFadeControl.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VFadeEvent( void ); + + // Callback Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeEvent ); + +public: + + VFadeControl::eFadeType getFadeType( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADEEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/GUI/VFadeTrack.cpp b/Engine/source/Verve/Extension/GUI/VFadeTrack.cpp new file mode 100644 index 000000000..e293672db --- /dev/null +++ b/Engine/source/Verve/Extension/GUI/VFadeTrack.cpp @@ -0,0 +1,139 @@ +//----------------------------------------------------------------------------- +// 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/Extension/GUI/VFadeTrack.h" +#include "Verve/Extension/GUI/VFadeEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeTrack ); +//----------------------------------------------------------------------------- + +VFadeTrack::VFadeTrack( void ) +{ + setLabel( "FadeTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VFadeTrack::onControllerEvent( pEvent ); +// +// When the controller's state changes, this method is called. If the +// controller is paused, or stops playing, then the fade control will cease +// playing. If the controller resumes play, the fade control will continue. +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VFadeTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + // Fetch the next Event. + VFadeEvent *event; + if ( !getNextEvent( event ) ) + { + // No Event. + return true; + } + + // Fetch GUI Control. + VFadeControl *fadeControl = dynamic_cast( Sim::findObject( "VFadeControlGui" ) ); + if ( !fadeControl ) + { + // No Control. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay: + { + // Play? + const S32 &time = getControllerTime(); + fadeControl->mActive = ( time > event->getTriggerTime() + && time < event->getFinishTime() ) ; + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Pause. + fadeControl->mActive = false; + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VFadeTrack::onControllerReset( pTime, pForward ); +// +// Reset the fade state of the fade control. +// +//----------------------------------------------------------------------------- +void VFadeTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + Parent::onControllerReset( pTime, pForward ); + + // Fetch GUI Control. + VFadeControl *fadeControl; + if ( !Sim::findObject( "VFadeControlGUI", fadeControl ) ) + { + // Invalid. + return; + } + + VFadeEvent *event; + if ( !getNextEvent( event ) ) + { + // No Events. + return; + } + + // Apply Settings. + fadeControl->mActive = false; + fadeControl->mFadeType = event->getFadeType(); + fadeControl->mDuration = event->getDuration(); + fadeControl->mElapsedTime = getMax( pTime - event->getTriggerTime(), 0 ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/GUI/VFadeTrack.h b/Engine/source/Verve/Extension/GUI/VFadeTrack.h new file mode 100644 index 000000000..87ca4b9d8 --- /dev/null +++ b/Engine/source/Verve/Extension/GUI/VFadeTrack.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_VFADETRACK_H_ +#define _VT_VFADETRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VFadeTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADETRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.cpp b/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.cpp new file mode 100644 index 000000000..c08156e49 --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereGroup ); +//----------------------------------------------------------------------------- + +VSpawnSphereGroup::VSpawnSphereGroup( void ) +{ + setLabel( "SpawnSphereGroup" ); +}; \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.h b/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.h new file mode 100644 index 000000000..5a92713ca --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHEREGROUP_H_ +#define _VT_VSPAWNSPHEREGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VSpawnSphereGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHEREGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp new file mode 100644 index 000000000..92218060a --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.cpp @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereSpawnTargetEvent.h" +#include "Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereSpawnTargetEvent ); +//----------------------------------------------------------------------------- + +VSpawnSphereSpawnTargetEvent::VSpawnSphereSpawnTargetEvent( void ) +{ + setLabel( "SpawnTargetEvent" ); +} + +void VSpawnSphereSpawnTargetEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetEvent::onTrigger( pTime, pDelta ); +// +// Spawn the Target. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Track. + VSpawnSphereSpawnTargetTrack *track; + if ( !getTrack( track ) ) + { + return; + } + + // Spawn the Target. + track->spawnTarget(); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h new file mode 100644 index 000000000..60b39952d --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetEvent.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHERESPAWNTARGETEVENT_H_ +#define _VT_VSPAWNSPHERESPAWNTARGETEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_SPAWNSPHERE_H_ +#include "Verve/Torque/TSpawnSphere.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereSpawnTargetEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; +public: + + VSpawnSphereSpawnTargetEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereSpawnTargetEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHERESPAWNTARGETEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp new file mode 100644 index 000000000..d0cc2930a --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.cpp @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Game/VSpawnSphereSpawnTargetTrack.h" +#include "Verve/Torque/TSpawnSphere.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSpawnSphereSpawnTargetTrack ); +//----------------------------------------------------------------------------- + +VSpawnSphereSpawnTargetTrack::VSpawnSphereSpawnTargetTrack( void ) +{ + setLabel( "SpawnTargetTrack" ); +} + +void VSpawnSphereSpawnTargetTrack::initPersistFields( void ) +{ + // Parent Call. + Parent::initPersistFields(); + + addField( "DespawnOnLoop", TypeBool, Offset( mDespawnOnLoop, VSpawnSphereSpawnTargetTrack ), "Despawn all targets when the Controller loops?" ); + addField( "DespawnOnStop", TypeBool, Offset( mDespawnOnStop, VSpawnSphereSpawnTargetTrack ), "Despawn all targets when the Controller stops playing?" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::onControllerEvent( pEvent ); +// +// For a full list of possible events, see the 'eControllerEventType' +// declaration in VController.h. +// +//----------------------------------------------------------------------------- +bool VSpawnSphereSpawnTargetTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventLoop : + { + if ( mDespawnOnLoop ) + { + despawnTargets(); + } + + } break; + + case VController::k_EventStop : + { + if ( mDespawnOnStop ) + { + despawnTargets(); + } + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// Spawn Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::spawnTarget( pTime, pForward ); +// +// Spawn an Object. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetTrack::spawnTarget( void ) +{ + VTorque::SpawnSphereType *object; + if ( !getSceneObject( object ) ) + { + return; + } + + // Spawn the Object. + SimObject *spawnedObject = object->spawnObject(); + + // Scene Object? + VTorque::SceneObjectType *sceneObject = dynamic_cast( spawnedObject ); + if ( sceneObject ) + { + sceneObject->setPosition( object->getPosition() ); + } + + // Valid? + if ( spawnedObject ) + { + // Add Reference. + mSpawnList.addObject( spawnedObject ); + } +} + +//----------------------------------------------------------------------------- +// +// VSpawnSphereSpawnTargetTrack::despawnTargets(); +// +// Despawn all of the objects spawned by this track. +// +//----------------------------------------------------------------------------- +void VSpawnSphereSpawnTargetTrack::despawnTargets( void ) +{ + while( mSpawnList.size() > 0 ) + { + // Fetch the Last Object + SimObject *object = mSpawnList.last(); + // Remove it. + mSpawnList.popObject(); + + // Delete the Object. + object->deleteObject(); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h new file mode 100644 index 000000000..0df6f2ae5 --- /dev/null +++ b/Engine/source/Verve/Extension/Game/VSpawnSphereSpawnTargetTrack.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// 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_VSPAWNSPHERESPAWNTARGETTRACK_H_ +#define _VT_VSPAWNSPHERESPAWNTARGETTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VSpawnSphereSpawnTargetTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +protected: + + SimSet mSpawnList; + + bool mDespawnOnStop; + bool mDespawnOnLoop; + +public: + + VSpawnSphereSpawnTargetTrack( void ); + + static void initPersistFields( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + + // Spawn Methods. + + virtual void spawnTarget( void ); + virtual void despawnTargets( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSpawnSphereSpawnTargetTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSPAWNSPHERESPAWNTARGETTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp new file mode 100644 index 000000000..94f34c350 --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.cpp @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectAnimationEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectAnimationEvent ); +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +VLightObjectAnimationEvent::VLightObjectAnimationEvent( void ) : + mAnimationData( NULL ) +{ + setLabel( "AnimationEvent" ); +} + +void VLightObjectAnimationEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "AnimationData", TYPEID(), Offset( mAnimationData, VLightObjectAnimationEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationEvent::onTrigger( pTime, pDelta ); +// +// When this Event is triggered the light object will begin to play the target +// animation. +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Play the Animation. + VTorque::playAnimation( lightObject, mAnimationData ); + } +} + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationEvent::onComplete( pTime, pDelta ); +// +// The current animation played by the light object will be paused when this +// Event completes its updates. +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationEvent::onComplete( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Pause the Animation. + VTorque::pauseAnimation( lightObject ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.h b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.h new file mode 100644 index 000000000..18162ff2c --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationEvent.h @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTANIMATIONEVENT_H_ +#define _VT_VLIGHTOBJECTANIMATIONEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectAnimationEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + SimObjectPtr mAnimationData; + +public: + + VLightObjectAnimationEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + virtual void onComplete( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectAnimationEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTANIMATIONEVENT_H_ diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp new file mode 100644 index 000000000..fe2455f4f --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.cpp @@ -0,0 +1,118 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectAnimationTrack.h" +#include "Verve/Extension/LightObject/VLightObjectAnimationEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectAnimationTrack ); +//----------------------------------------------------------------------------- + +VLightObjectAnimationTrack::VLightObjectAnimationTrack( void ) +{ + setLabel( "AnimationTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationTrack::onControllerEvent( pEvent ); +// +// +// +//----------------------------------------------------------------------------- +bool VLightObjectAnimationTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( !getSceneObject( lightObject ) ) + { + // Skip. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPlay : + { + + // Play Animation? + VLightObjectAnimationEvent *event; + if ( getCurrentEvent( event ) ) + { + // Play. + VTorque::playAnimation( lightObject ); + } + + } break; + + case VController::k_EventPause : + case VController::k_EventStop : + { + + // Stop the Animation. + VTorque::pauseAnimation( lightObject ); + + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VLightObjectAnimationTrack::onControllerReset( pTime, pForward ); +// +// +// +//----------------------------------------------------------------------------- +void VLightObjectAnimationTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + // Fetch the Light Object. + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Stop the Animation. + VTorque::pauseAnimation( lightObject ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.h b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.h new file mode 100644 index 000000000..6485e8428 --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectAnimationTrack.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTANIMATIONTRACK_H_ +#define _VT_VLIGHTOBJECTANIMATIONTRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectAnimationTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VLightObjectAnimationTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectAnimationTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTANIMATIONTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.cpp b/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.cpp new file mode 100644 index 000000000..9db010fc2 --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectGroup ); +//----------------------------------------------------------------------------- + +VLightObjectGroup::VLightObjectGroup( void ) +{ + setLabel( "LightObjectGroup" ); +}; \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.h b/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.h new file mode 100644 index 000000000..16af01bcd --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTGROUP_H_ +#define _VT_VLIGHTOBJECTGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VLightObjectGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp new file mode 100644 index 000000000..4e1475a5f --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.cpp @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectToggleEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectToggleEvent ); +//----------------------------------------------------------------------------- + +VLightObjectToggleEvent::VLightObjectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VLightObjectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VLightObjectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectToggleEvent::onTrigger( pTime, pDelta ); +// +// Toggle the Light Object. +// +//----------------------------------------------------------------------------- +void VLightObjectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) ) + { + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle Light. + VTorque::setLightObjectOn( lightObject, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.h b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.h new file mode 100644 index 000000000..382aee1c7 --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTTOGGLEEVENT_H_ +#define _VT_VLIGHTOBJECTTOGGLEEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectToggleEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VLightObjectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp new file mode 100644 index 000000000..a4a5387eb --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/LightObject/VLightObjectToggleTrack.h" +#include "Verve/Extension/LightObject/VLightObjectToggleEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VLightObjectToggleTrack ); +//----------------------------------------------------------------------------- + +VLightObjectToggleTrack::VLightObjectToggleTrack( void ) +{ + setLabel( "ToggleTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VLightObjectToggleTrack::onControllerReset( pTime, pForward ); +// +// Enable or Disable the light object after a reset. +// +//----------------------------------------------------------------------------- +void VLightObjectToggleTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + VLightObjectToggleEvent *event; + VTorque::LightObjectType *lightObject; + if ( getSceneObject( lightObject ) && getPreviousEvent( event ) ) + { + // Turn On? + const bool turnOn = ( event->mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle the Light. + VTorque::setLightObjectOn( lightObject, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.h b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.h new file mode 100644 index 000000000..510c290bb --- /dev/null +++ b/Engine/source/Verve/Extension/LightObject/VLightObjectToggleTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VLIGHTOBJECTTOGGLETRACK_H_ +#define _VT_VLIGHTOBJECTTOGGLETRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_LIGHTOBJECT_H_ +#include "Verve/Torque/TLightObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VLightObjectToggleTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VLightObjectToggleTrack( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VLightObjectToggleTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VLIGHTOBJECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Motion/VMotionEvent.cpp b/Engine/source/Verve/Extension/Motion/VMotionEvent.cpp new file mode 100644 index 000000000..d972168ec --- /dev/null +++ b/Engine/source/Verve/Extension/Motion/VMotionEvent.cpp @@ -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( 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( 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; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Motion/VMotionEvent.h b/Engine/source/Verve/Extension/Motion/VMotionEvent.h new file mode 100644 index 000000000..2ef710e06 --- /dev/null +++ b/Engine/source/Verve/Extension/Motion/VMotionEvent.h @@ -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_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Motion/VMotionTrack.cpp b/Engine/source/Verve/Extension/Motion/VMotionTrack.cpp new file mode 100644 index 000000000..1042f5461 --- /dev/null +++ b/Engine/source/Verve/Extension/Motion/VMotionTrack.cpp @@ -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( 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( 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( 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. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VMotionTrack, getPath, S32, (),, "( 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 diff --git a/Engine/source/Verve/Extension/Motion/VMotionTrack.h b/Engine/source/Verve/Extension/Motion/VMotionTrack.h new file mode 100644 index 000000000..b0fc25c34 --- /dev/null +++ b/Engine/source/Verve/Extension/Motion/VMotionTrack.h @@ -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_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp new file mode 100644 index 000000000..00c30388c --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectGroup.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectGroup ); +//----------------------------------------------------------------------------- + +VParticleEffectGroup::VParticleEffectGroup( void ) +{ + setLabel( "ParticleEffectGroup" ); +}; \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.h b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.h new file mode 100644 index 000000000..aa7806366 --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectGroup.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEEFFECTGROUP_H_ +#define _VT_VPARTICLEEFFECTGROUP_H_ + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectGroup : public VSceneObjectGroup +{ + typedef VSceneObjectGroup Parent; + +public: + + VParticleEffectGroup( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEEFFECTGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp new file mode 100644 index 000000000..658f3b5d0 --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.cpp @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectToggleEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectToggleEvent ); +//----------------------------------------------------------------------------- + +VParticleEffectToggleEvent::VParticleEffectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VParticleEffectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VParticleEffectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VParticleEffectToggleEvent::onTrigger( pTime, pDelta ); +// +// Toggle the Particle Effect. +// +//----------------------------------------------------------------------------- +void VParticleEffectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + VTorque::ParticleEffectType *particleEffect; + if ( getSceneObject( particleEffect ) ) + { + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle Particle Effect. + VTorque::setParticleEffectOn( particleEffect, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h new file mode 100644 index 000000000..e4028413a --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEFFECTTOGGLEEVENT_H_ +#define _VT_VPARTICLEFFECTTOGGLEEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_PARTICLEEFFECT_H_ +#include "Verve/Torque/TParticleEffect.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectToggleEvent : public VSceneObjectEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VParticleEffectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEFFECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp new file mode 100644 index 000000000..30ce242f5 --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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/Extension/ParticleEffect/VParticleEffectToggleTrack.h" +#include "Verve/Extension/ParticleEffect/VParticleEffectToggleEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VParticleEffectToggleTrack ); +//----------------------------------------------------------------------------- + +VParticleEffectToggleTrack::VParticleEffectToggleTrack( void ) +{ + setLabel( "ToggleTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VParticleEffectToggleTrack::onControllerReset( pTime, pForward ); +// +// Enable or Disable the particle effect after a reset. +// +//----------------------------------------------------------------------------- +void VParticleEffectToggleTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + VParticleEffectToggleEvent *event; + VTorque::ParticleEffectType *particleEffect; + if ( getSceneObject( particleEffect ) && getPreviousEvent( event ) ) + { + // Turn On? + const bool turnOn = ( event->mEventType == VSharedEnum::k_ActionTurnOn ); + + // Toggle the Particle Effect. + VTorque::setParticleEffectOn( particleEffect, turnOn ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h new file mode 100644 index 000000000..5974dbeb8 --- /dev/null +++ b/Engine/source/Verve/Extension/ParticleEffect/VParticleEffectToggleTrack.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VPARTICLEEFFECTTOGGLETRACK_H_ +#define _VT_VPARTICLEEFFECTTOGGLETRACK_H_ + +#ifndef _VT_VSCENEOBJECTTRACK_H_ +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" +#endif + +#ifndef _VT_TORQUE_PARTICLEEFFECT_H_ +#include "Verve/Torque/TParticleEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VParticleEffectToggleTrack : public VSceneObjectTrack +{ + typedef VSceneObjectTrack Parent; + +public: + + VParticleEffectToggleTrack( void ); + + // Controller Methods. + + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VParticleEffectToggleTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPARTICLEEFFECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp new file mode 100644 index 000000000..5e5d65d40 --- /dev/null +++ b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/PostEffect/VPostEffectToggleEvent.h" +#include "Verve/Extension/PostEffect/VPostEffectToggleTrack.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPostEffectToggleEvent ); +//----------------------------------------------------------------------------- + +VPostEffectToggleEvent::VPostEffectToggleEvent( void ) : + mEventType( VSharedEnum::k_ActionTurnOn ) +{ + setLabel( "ToggleEvent" ); +} + +void VPostEffectToggleEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Action", TYPEID(), Offset( mEventType, VPostEffectToggleEvent ) ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VPostEffectToggleEvent::onTrigger( pTime, pDelta ); +// +// Only enable this effect if the parent group is currently active. +// +//----------------------------------------------------------------------------- +void VPostEffectToggleEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Parent Objects. + VCameraGroup *group; + VPostEffectToggleTrack *track; + if ( ( !getGroup( group ) || !group->isActive() ) || !getTrack( track ) ) + { + // Quit. + return; + } + + // Turn On? + const bool turnOn = ( mEventType == VSharedEnum::k_ActionTurnOn ); + + // Enable Effect. + VTorque::setPostEffectOn( track->getPostEffect(), turnOn ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.h b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.h new file mode 100644 index 000000000..66668307b --- /dev/null +++ b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleEvent.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPOSTEFFECTTOGGLEEVENT_H_ +#define _VT_VPOSTEFFECTTOGGLEEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VEvent.h" +#endif + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +#ifndef _VT_VSHAREDENUM_H_ +#include "Verve/Core/Util/VSharedEnum.h" +#endif + +//----------------------------------------------------------------------------- + +class VPostEffectToggleEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VSharedEnum::eActionToggle mEventType; + +public: + + VPostEffectToggleEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VPostEffectToggleEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPOSTEFFECTTOGGLEEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp new file mode 100644 index 000000000..ff2dd52a5 --- /dev/null +++ b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.cpp @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// 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/Extension/PostEffect/VPostEffectToggleTrack.h" +#include "Verve/Extension/PostEffect/VPostEffectToggleEvent.h" +#include "Verve/Extension/Camera/VCameraGroup.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPostEffectToggleTrack ); +//----------------------------------------------------------------------------- + +VPostEffectToggleTrack::VPostEffectToggleTrack( void ) : + mPostEffect( NULL ) +{ + setLabel( "PostEffectTrack" ); +} + +void VPostEffectToggleTrack::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "PostEffect", TYPEID(), Offset( mPostEffect, VPostEffectToggleTrack ), "The name of the PostEffect object to be triggered." ); +} + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VPostEffectToggleTrack::onCameraEvent( pEvent ); +// +// When the Camera changes, this method is called on both the outgoing and +// incoming Camera Groups. +// +// For a full list of possible events, see the 'eCameraEventType' declaration +// in VCameraGroup.h. +// +//----------------------------------------------------------------------------- +bool VPostEffectToggleTrack::onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ) +{ + // Parent Call. + if ( !Parent::onCameraEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() || !mPostEffect.isValid() ) + { + // Quit Now. + return true; + } + + switch( pEvent ) + { + case VCameraGroup::k_EventActivate : + { + + VPostEffectToggleEvent *event; + if ( getPreviousEvent( event ) && event->mEventType == VSharedEnum::k_ActionTurnOn ) + { + // Toggle Post Effect On. + VTorque::setPostEffectOn( mPostEffect, true ); + } + + } break; + + case VCameraGroup::k_EventDeactivate : + { + + // Turn Post Effect Off. + VTorque::setPostEffectOn( mPostEffect, false ); + + } break; + } + + return true; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.h b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.h new file mode 100644 index 000000000..24a531684 --- /dev/null +++ b/Engine/source/Verve/Extension/PostEffect/VPostEffectToggleTrack.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VPOSTEFFECTTOGGLETRACK_H_ +#define _VT_VPOSTEFFECTTOGGLETRACK_H_ + +#ifndef _VT_VCAMERATRACK_H_ +#include "Verve/Extension/Camera/VCameraTrack.h" +#endif + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VPostEffectToggleTrack : public VCameraTrack +{ + typedef VCameraTrack Parent; + +protected: + + SimObjectPtr mPostEffect; + +public: + + VPostEffectToggleTrack( void ); + + static void initPersistFields( void ); + + // Camera Methods. + + bool onCameraEvent( const VCameraGroup::eCameraEventType &pEvent ); + + // Console Declaration. + + DECLARE_CONOBJECT( VPostEffectToggleTrack ); + +public: + + VTorque::PostEffectType *getPostEffect( void ) { return mPostEffect; }; +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VPOSTEFFECTTOGGLETRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.cpp b/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.cpp new file mode 100644 index 000000000..11662508e --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectEvent ); +//----------------------------------------------------------------------------- + +VSceneObjectEvent::VSceneObjectEvent( void ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectEvent::getSceneObject(); +// +// Returns the parent group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectEvent::getSceneObject( void ) +{ + VSceneObjectGroup *group; + if ( !getGroup( group ) ) + { + // No Group! + return NULL; + } + + // Return Object. + return group->getSceneObject(); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VSceneObjectEvent, getSceneObject, S32, (),, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.h b/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.h new file mode 100644 index 000000000..5dd4bc7df --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectEvent.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTEVENT_H_ +#define _VT_VSCENEOBJECTEVENT_H_ + +#ifndef _VT_VEVENT_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectEvent : public VEvent +{ + typedef VEvent Parent; + +public: + + VSceneObjectEvent( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectEvent ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.cpp b/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.cpp new file mode 100644 index 000000000..83307cc7b --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.cpp @@ -0,0 +1,104 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Core/VController.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectGroup ); +//----------------------------------------------------------------------------- + +VSceneObjectGroup::VSceneObjectGroup( void ) : + mDataReference( String::EmptyString ), + mSceneObject( NULL ) +{ + setLabel( "SceneObjectGroup" ); +}; + +void VSceneObjectGroup::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "Reference", TypeRealString, Offset( mDataReference, VSceneObjectGroup ), "The name of the data field referencing the targeted object." ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectGroup::getObject(); +// +// Returns the group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectGroup::getSceneObject( void ) +{ +#ifndef VT_EDITOR + // Already Referenced? + if ( mSceneObject ) + { + // Return Object. + return mSceneObject; + } +#endif + + VController *controller = getController(); + if ( !controller ) + { + // No Controller! + return NULL; + } + + String fieldValue; + if ( controller->getDataValue( mDataReference, fieldValue ) ) + { + // Store Object. + mSceneObject = dynamic_cast( Sim::findObject( fieldValue ) ); + } + + // Return. + return mSceneObject; +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VSceneObjectGroup, getSceneObject, S32, (),, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.h b/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.h new file mode 100644 index 000000000..9af52eef6 --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectGroup.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTGROUP_H_ +#define _VT_VSCENEOBJECTGROUP_H_ + +#ifndef _VT_VGROUP_H_ +#include "Verve/Core/VGroup.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectGroup : public VGroup +{ + typedef VGroup Parent; + +public: + + // Reference Members. + + String mDataReference; + VTorque::SceneObjectType *mSceneObject; + +public: + + VSceneObjectGroup( void ); + + static void initPersistFields( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectGroup ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTGROUP_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.cpp b/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.cpp new file mode 100644 index 000000000..24052658e --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.cpp @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SceneObject/VSceneObjectGroup.h" +#include "Verve/Extension/SceneObject/VSceneObjectTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSceneObjectTrack ); +//----------------------------------------------------------------------------- + +VSceneObjectTrack::VSceneObjectTrack( void ) +{ + setLabel( "SceneObjectTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSceneObjectTrack::getSceneObject(); +// +// Returns the parent group's object reference. +// +//----------------------------------------------------------------------------- +VTorque::SceneObjectType *VSceneObjectTrack::getSceneObject( void ) +{ + VSceneObjectGroup *group; + if ( !getGroup( group ) ) + { + // No Group! + return NULL; + } + + // Return Object. + return group->getSceneObject(); +} + +#ifdef VT_EDITOR +//----------------------------------------------------------------------------- +// +// Debug Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VSceneObjectTrack, getSceneObject, S32, (),, "( void ) - Get the object this group references.\n" + "@return Returns the SimObjectID for the object." ) +{ + // Fetch Object. + VTorque::SceneObjectType *objReference = object->getSceneObject(); + + // Return. + return ( objReference ) ? objReference->getId() : 0; +} +#endif diff --git a/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.h b/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.h new file mode 100644 index 000000000..d07517862 --- /dev/null +++ b/Engine/source/Verve/Extension/SceneObject/VSceneObjectTrack.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// 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_VSCENEOBJECTTRACK_H_ +#define _VT_VSCENEOBJECTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_VSCENEOBJECTGROUP_H_ +#include "Verve/Extension/SceneObject/VSceneObjectGroup.h" +#endif + +//----------------------------------------------------------------------------- + +class VSceneObjectTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VSceneObjectTrack( void ); + + // Reference Methods. + + VTorque::SceneObjectType *getSceneObject( void ); + template inline bool getSceneObject( T *&pSceneObject ) + { + // Reference Scene Object. + pSceneObject = dynamic_cast( getSceneObject() ); + + // Valid? + return ( pSceneObject != NULL ); + } + + // Console Declaration. + + DECLARE_CONOBJECT( VSceneObjectTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCENEOBJECTTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Script/VScriptEvent.cpp b/Engine/source/Verve/Extension/Script/VScriptEvent.cpp new file mode 100644 index 000000000..69b477466 --- /dev/null +++ b/Engine/source/Verve/Extension/Script/VScriptEvent.cpp @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// 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/Core/VTrack.h" + +#include "Verve/Extension/Script/VScriptEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VScriptEvent ); +//----------------------------------------------------------------------------- + +// Implement the Command Type enum list. +ImplementEnumType( VScriptEventCommandType, "" ) + { VScriptEvent::k_TypeExpression, "EXPRESSION" }, + { VScriptEvent::k_TypeMethod, "METHOD" }, +EndImplementEnumType; + +//----------------------------------------------------------------------------- + +VScriptEvent::VScriptEvent( void ) : + mCommandType( k_TypeMethod ), + mCommand( String::EmptyString ) +{ + setLabel( "ScriptEvent" ); +} + +void VScriptEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "CommandType", TYPEID(), Offset( mCommandType, VScriptEvent ), "The type of command to be evaluated." ); + addField( "Command", TypeRealString, Offset( mCommand, VScriptEvent ), "The command to be evaluated." ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VScriptEvet::onTrigger( pTime, pDelta ); +// +// Execute a method or evaluate a command. +// +//----------------------------------------------------------------------------- +void VScriptEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + switch ( mCommandType ) + { + case k_TypeExpression : + { + + // Evaluate Expression. + Con::evaluate( mCommand, false, NULL ); + + } break; + + case k_TypeMethod : + { + + SimObject *object = getSceneObject(); + if ( object ) + { + // Execute Method. + Con::executef( object, mCommand.c_str() ); + } + else + { + // Execute Function. + Con::executef( mCommand.c_str()); + } + + } break; + } +} diff --git a/Engine/source/Verve/Extension/Script/VScriptEvent.h b/Engine/source/Verve/Extension/Script/VScriptEvent.h new file mode 100644 index 000000000..ee0b139ca --- /dev/null +++ b/Engine/source/Verve/Extension/Script/VScriptEvent.h @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// 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_VSCRIPTEVENT_H_ +#define _VT_VSCRIPTEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +//----------------------------------------------------------------------------- + +class VScriptEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + +public: + + enum eCommandType + { + k_TypeExpression, + k_TypeMethod, + + k_TypeInvalid, + }; + + eCommandType mCommandType; + String mCommand; + +public: + + VScriptEvent( void ); + + static void initPersistFields( void ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VScriptEvent ); +}; + +//----------------------------------------------------------------------------- + +// Define Types. +typedef VScriptEvent::eCommandType VScriptEventCommandType; + +// Declare Enum Types. +DefineEnumType( VScriptEventCommandType ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCRIPTEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Script/VScriptEventTrack.cpp b/Engine/source/Verve/Extension/Script/VScriptEventTrack.cpp new file mode 100644 index 000000000..142d7bc1b --- /dev/null +++ b/Engine/source/Verve/Extension/Script/VScriptEventTrack.cpp @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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/Extension/Script/VScriptEventTrack.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VScriptEventTrack ); +//----------------------------------------------------------------------------- + +VScriptEventTrack::VScriptEventTrack( void ) +{ + setLabel( "ScriptEventTrack" ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/Script/VScriptEventTrack.h b/Engine/source/Verve/Extension/Script/VScriptEventTrack.h new file mode 100644 index 000000000..e0360ab4f --- /dev/null +++ b/Engine/source/Verve/Extension/Script/VScriptEventTrack.h @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// 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_VSCRIPTEVENTTRACK_H_ +#define _VT_VSCRIPTEVENTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +//----------------------------------------------------------------------------- + +class VScriptEventTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VScriptEventTrack( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VScriptEventTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSCRIPTEVENTTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp new file mode 100644 index 000000000..92c352427 --- /dev/null +++ b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.cpp @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// 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/SoundEffect/VSoundEffectEvent.h" +#include "Verve/Extension/SoundEffect/VSoundEffectTrack.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSoundEffectEvent ); +//----------------------------------------------------------------------------- + +VSoundEffectEvent::VSoundEffectEvent( void ) : + mSoundEffect( NULL ) +{ + setLabel( "SoundEvent" ); +} + +void VSoundEffectEvent::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "SoundEffect", TYPEID(), Offset( mSoundEffect, VSoundEffectEvent ), &setSoundData, &defaultProtectedGetFn, "" ); +} + +//----------------------------------------------------------------------------- +// +// Callback Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectEvent::onTrigger( pTime, pDelta ); +// +// Play the target sound effect. If this track belongs to a SceneObjectGroup, +// then the sound will play with the reference object's transform. If this is +// not the case, then a 2D sound will be played. +// +//----------------------------------------------------------------------------- +void VSoundEffectEvent::onTrigger( const S32 &pTime, const S32 &pDelta ) +{ + Parent::onTrigger( pTime, pDelta ); + + // Fetch Track. + VSoundEffectTrack *track; + if ( !getTrack( track ) ) + { + return; + } + + // Position & Pitch. + U32 position = mAbs( ( pTime + pDelta ) - getStartTime() ); + F32 pitch = mFabs( getControllerTimeScale() ); + if ( position < SFXStartBuffer ) + { + // Zero. + position = 0; + } + + VSceneObjectGroup *group; + if ( getGroup( group ) ) + { + // Play Sound With Reference. + track->mSource = VTorque::playSound( mSoundEffect, group->getSceneObject(), position, pitch ); + } + else + { + // Play Sound. + track->mSource = VTorque::playSound( mSoundEffect, position, pitch ); + } +} + +//----------------------------------------------------------------------------- +// +// Property Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectEvent::setDuration( pDuration ); +// +// This event's duration is always set to the sound object's duration. +// +//----------------------------------------------------------------------------- +void VSoundEffectEvent::setDuration( const S32 &pDuration ) +{ + // Clear Duration. + mDuration = VTorque::getSoundDuration( mSoundEffect ); +} + +//----------------------------------------------------------------------------- +// +// Static Field Methods. +// +//----------------------------------------------------------------------------- + +bool VSoundEffectEvent::setSoundData( void *pObject, const char *pArray, const char *pData ) +{ + // Fetch Event. + VSoundEffectEvent *event = static_cast( pObject ); + + // Use Object. + event->mSoundEffect = dynamic_cast( Sim::findObject( pData ) ); + + // Set Duration. + event->setDuration( 0 ); + + return false; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.h b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.h new file mode 100644 index 000000000..79ea79d65 --- /dev/null +++ b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectEvent.h @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// 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_VSOUNDEFFECTEVENT_H_ +#define _VT_VSOUNDEFFECTEVENT_H_ + +#ifndef _VT_VSCENEOBJECTEVENT_H_ +#include "Verve/Extension/SceneObject/VSceneObjectEvent.h" +#endif + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VSoundEffectEvent : public VSceneObjectEvent +{ + typedef VSceneObjectEvent Parent; + + enum + { + SFXStartBuffer = 100, + }; + +public: + + SimObjectPtr mSoundEffect; + +public: + + VSoundEffectEvent( void ); + + static void initPersistFields( void ); + + static bool setSoundData( void *pObject, const char *pArray, const char *pData ); + + // Event Methods. + + virtual void onTrigger( const S32 &pTime, const S32 &pDelta ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSoundEffectEvent ); + +public: + + // Property Methods. + + virtual void setDuration( const S32 &pDuration ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSOUNDEFFECTEVENT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp new file mode 100644 index 000000000..040040d31 --- /dev/null +++ b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.cpp @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// 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/Extension/SoundEffect/VSoundEffectTrack.h" +#include "Verve/Extension/SoundEffect/VSoundEffectEvent.h" + +#include "console/consoleTypes.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VSoundEffectTrack ); +//----------------------------------------------------------------------------- + +VSoundEffectTrack::VSoundEffectTrack( void ) : + mSource( NULL ) +{ + setLabel( "SoundTrack" ); +} + +//----------------------------------------------------------------------------- +// +// Controller Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VSoundEffectTrack::onControllerEvent( pEvent ); +// +// If the controller ceases playback and the track has a valid reference to a +// source provider, then the sound is stopped. +// +//----------------------------------------------------------------------------- +bool VSoundEffectTrack::onControllerEvent( VController::eControllerEventType pEvent ) +{ + if ( !Parent::onControllerEvent( pEvent ) ) + { + // Skip. + return false; + } + + // Enabled? + if ( !isEnabled() ) + { + // Continue Processing Events. + return true; + } + + switch ( pEvent ) + { + case VController::k_EventPause : + case VController::k_EventStop : + { +#ifdef VT_EDITOR + + if ( mSource ) + { + // Stop Sound. + VTorque::stopSound( mSource ); + + // Clear Source. + mSource = NULL; + } + +#endif + } break; + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VSoundEffectTrack::onControllerReset( pTime, pForward ); +// +// If the track is reset and it has a valid reference to a source provider, +// then the sound is stopped. +// +//----------------------------------------------------------------------------- +void VSoundEffectTrack::onControllerReset( const S32 &pTime, const bool &pForward ) +{ + // Default Reset. + Parent::onControllerReset( pTime, pForward ); + + if ( mSource ) + { + // Stop Sound. + VTorque::stopSound( mSource ); + } + + // Clear Source. + mSource = NULL; +} \ No newline at end of file diff --git a/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.h b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.h new file mode 100644 index 000000000..1b4eccb24 --- /dev/null +++ b/Engine/source/Verve/Extension/SoundEffect/VSoundEffectTrack.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VSOUNDEFFECTTRACK_H_ +#define _VT_VSOUNDEFFECTTRACK_H_ + +#ifndef _VT_VTRACK_H_ +#include "Verve/Core/VTrack.h" +#endif + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +//----------------------------------------------------------------------------- + +class VSoundEffectTrack : public VTrack +{ + typedef VTrack Parent; + +public: + + VTorque::SoundSourceType *mSource; + +public: + + VSoundEffectTrack( void ); + + // Controller Methods. + + virtual bool onControllerEvent( VController::eControllerEventType pEvent ); + virtual void onControllerReset( const S32 &pTime, const bool &pForward ); + + // Console Declaration. + + DECLARE_CONOBJECT( VSoundEffectTrack ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VSOUNDEFFECTTRACK_H_ \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VEditorButton.cpp b/Engine/source/Verve/GUI/VEditorButton.cpp new file mode 100644 index 000000000..3c32424b4 --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorButton.cpp @@ -0,0 +1,216 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorButton.h" +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gui/core/guiCanvas.h" +#include "gui/core/guiDefaultControlRender.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorButton ); +//----------------------------------------------------------------------------- + +VEditorButton::VEditorButton( void ) : + mIsDraggable( false ) +{ + // Void. +} + +void VEditorButton::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "IsDraggable", TypeBool, Offset( mIsDraggable, VEditorButton ) ); +} + +//----------------------------------------------------------------------------- + +void VEditorButton::onMouseDown( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseDown( pEvent ); + + onMouseEvent( "onMouseDown", pEvent ); +} + +void VEditorButton::onMouseUp( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseUp( pEvent ); + + if ( mIsDraggable && isMouseLocked() ) + { + // Unlock. + mouseUnlock(); + } + + onMouseEvent( "onMouseUp", pEvent ); +} + +void VEditorButton::onMouseDragged( const GuiEvent &pEvent ) +{ + if ( !mActive || !mIsDraggable ) + { + return; + } + + Parent::onMouseDragged( pEvent ); + + if ( !isMouseLocked() ) + { + GuiCanvas *canvas = getRoot(); + if ( canvas->getMouseLockedControl() ) + { + GuiEvent event; + canvas->getMouseLockedControl()->onMouseLeave( event ); + canvas->mouseUnlock( canvas->getMouseLockedControl() ); + } + + // Lock. + mouseLock(); + } + + onMouseEvent( "onMouseDragged", pEvent ); +} + +void VEditorButton::onRightMouseDown( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onRightMouseDown( pEvent ); + + onMouseEvent( "onRightMouseDown", pEvent ); +} + +void VEditorButton::onRightMouseUp( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onRightMouseUp( pEvent ); + + onMouseEvent( "onRightMouseUp", pEvent ); +} + +void VEditorButton::onMouseEnter( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseEnter( pEvent ); + + onMouseEvent( "onMouseEnter", pEvent ); +} + +void VEditorButton::onMouseLeave( const GuiEvent &pEvent ) +{ + if ( !mActive ) + { + return; + } + + Parent::onMouseLeave( pEvent ); + + onMouseEvent( "onMouseLeave", pEvent ); +} + +void VEditorButton::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- + +void VEditorButton::onRender( Point2I offset, const RectI& updateRect ) +{ + // Fetch Texture. + GFXTexHandle texture = getTextureForCurrentState(); + + // Valid? + if ( texture ) + { + GFX->getDrawUtil()->clearBitmapModulation(); + GFX->getDrawUtil()->drawBitmapStretch( texture, RectI( offset, getExtent() ) ); + } + else + { + if ( mProfile->mBorder != 0 ) + { + RectI boundsRect( offset, getExtent() ); + + if ( mDepressed || mStateOn || mMouseOver ) + { + renderFilledBorder( boundsRect, mProfile->mBorderColorHL, mProfile->mFillColorHL ); + } + else + { + renderFilledBorder( boundsRect, mProfile->mBorderColor, mProfile->mFillColor ); + } + } + } + + // Render Text. + GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor ); + renderJustifiedText( offset + mProfile->mTextOffset, getExtent(), mButtonText ); + + renderChildControls( offset, updateRect); +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VEditorButton, getState, bool, (), , "()" ) +{ + return object->getStateOn(); +} diff --git a/Engine/source/Verve/GUI/VEditorButton.h b/Engine/source/Verve/GUI/VEditorButton.h new file mode 100644 index 000000000..15b3e0dfa --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorButton.h @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORBUTTON_H_ +#define _VT_VEDITORBUTTON_H_ + +#ifndef _GUIBITMAPBUTTON_H_ +#include "gui/buttons/guiBitmapButtonCtrl.h" +#endif + +class VEditorButton : public GuiBitmapButtonTextCtrl +{ + typedef GuiBitmapButtonTextCtrl Parent; + +public: + + bool mIsDraggable; + +public: + + VEditorButton(); + + static void initPersistFields( void ); + + void onMouseDown( const GuiEvent &pEvent ); + void onMouseUp( const GuiEvent &pEvent ); + void onMouseDragged( const GuiEvent &pEvent ); + + void onRightMouseDown( const GuiEvent &pEvent ); + void onRightMouseUp( const GuiEvent &pEvent ); + + void onMouseEnter( const GuiEvent &pEvent ); + void onMouseLeave( const GuiEvent &pEvent ); + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + void onRender( Point2I offset, const RectI &updateRect ); + +public: + + DECLARE_CONOBJECT( VEditorButton ); +}; + +#endif //_VT_VEDITORBUTTON_H_ \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VEditorScrollControl.cpp b/Engine/source/Verve/GUI/VEditorScrollControl.cpp new file mode 100644 index 000000000..b503ed0d6 --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorScrollControl.cpp @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorScrollControl.h" +#include "gfx/gfxDrawUtil.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorScrollControl ); +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Mouse Methods. +// +//----------------------------------------------------------------------------- + +void VEditorScrollControl::onMouseUp( const GuiEvent &pEvent ) +{ + Parent::onMouseUp( pEvent ); + + // Event. + onMouseEvent( "onMouseUp", pEvent ); +} + +void VEditorScrollControl::onRightMouseUp( const GuiEvent &pEvent ) +{ + Parent::onMouseUp( pEvent ); + + // Event. + onMouseEvent( "onRightMouseUp", pEvent ); +} + +void VEditorScrollControl::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + const S32 offsetX = ( mHasVScrollBar ) ? mScrollBarThickness : 0; + const S32 offsetY = ( mHasHScrollBar ) ? mScrollBarThickness : 0; + + const RectI contentRect( 2, 2, getWidth() - offsetX - 4 - 1, getHeight() - offsetY - 4 - ( mHasHScrollBar ) ); + if ( !contentRect.pointInRect( pEvent.mousePoint ) ) + { + // Return! + return; + } + + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VEditorScrollControl::onRender( Point2I pOffset, const RectI &pUpdateRect ) +{ + Parent::onRender( pOffset, pUpdateRect ); + + const S32 offsetX = ( mHasVScrollBar ) ? mScrollBarThickness : 1; + const S32 offsetY = ( mHasHScrollBar ) ? mScrollBarThickness : 1; + + RectI contentRect( pOffset.x + 1, pOffset.y + 1, getWidth() - offsetX - 1, getHeight() - offsetY - 1 ); + contentRect.intersect( pUpdateRect ); + + GFX->getDrawUtil()->drawRect( contentRect, mProfile->mBorderColor ); +} \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VEditorScrollControl.h b/Engine/source/Verve/GUI/VEditorScrollControl.h new file mode 100644 index 000000000..5d3e1d72e --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorScrollControl.h @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORSCROLLCONTROL_H_ +#define _VT_VEDITORSCROLLCONTROL_H_ + +#ifndef _GUISCROLLCTRL_H_ +#include "gui/containers/guiScrollCtrl.h" +#endif + +//----------------------------------------------------------------------------- + +class VEditorScrollControl : public GuiScrollCtrl +{ + typedef GuiScrollCtrl Parent; + +public: + + // Mouse. + + virtual void onMouseUp( const GuiEvent &pEvent ); + virtual void onRightMouseUp( const GuiEvent &pEvent ); + + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + // Rendering. + + void onRender( Point2I pOffset, const RectI &pUpdateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEditorScrollControl ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEDITORSCROLLCONTROL_H_ \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VEditorWindow.cpp b/Engine/source/Verve/GUI/VEditorWindow.cpp new file mode 100644 index 000000000..b5e9c1e07 --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorWindow.cpp @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VEditorWindow.h" +#include "gfx/gfxInit.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VEditorWindow ); +//----------------------------------------------------------------------------- + +bool VEditorWindow::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + GFXAdapter *adapter = GFXInit::getBestAdapterChoice(); + if ( adapter && adapter->mType != NullDevice ) + { + mPlatformWindow->setMinimumWindowSize( Point2I( 904, 287 ) ); + } + + return true; +} + +//----------------------------------------------------------------------------- + +DefineEngineMethod( VEditorWindow, resetCursor, void, (),, "( )" ) +{ + S32 currCursor = PlatformCursorController::curArrow; + if ( object->mCursorChanged == currCursor ) + { + return; + } + + PlatformWindow *window = object->getPlatformWindow(); + PlatformCursorController *controller = window->getCursorController(); + + if( object->mCursorChanged != -1) + { + controller->popCursor(); + } + + controller->pushCursor(currCursor); + object->mCursorChanged = currCursor; + + Platform::setWindowLocked( false ); +} + +DefineEngineMethod( VEditorWindow, setVideoMode, void, (S32 width, S32 height, bool fullscreen, S32 bitDepth, S32 refreshRate, S32 antiAliasLevel), + (800,600,false,32,60, 0), + "(int width, int height, bool fullscreen, [int bitDepth], [int refreshRate])\n" + "Change the video mode of this canvas. This method has the side effect of setting the $pref::Video::mode to the new values.\n\n" + "\\param width The screen width to set.\n" + "\\param height The screen height to set.\n" + "\\param fullscreen Specify true to run fullscreen or false to run in a window\n" + "\\param bitDepth [optional] The desired bit-depth. Defaults to the current setting. This parameter is ignored if you are running in a window.\n" + "\\param refreshRate [optional] The desired refresh rate. Defaults to the current setting. This parameter is ignored if you are running in a window" + "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) +{ + if (!object->getPlatformWindow()) + return; + + // Update the video mode and tell the window to reset. + GFXVideoMode vm = object->getPlatformWindow()->getVideoMode(); + + bool changed = false; + if (width == 0 && height > 0) + { + // Our width is 0 but our height isn't... + // Try to find a matching width + for(S32 i=0; igetPlatformWindow()->getGFXDevice()->getVideoModeList()->size(); i++) + { + const GFXVideoMode &newVm = (*(object->getPlatformWindow()->getGFXDevice()->getVideoModeList()))[i]; + + if(newVm.resolution.y == height) + { + width = newVm.resolution.x; + changed = true; + break; + } + } + } + else if (height == 0 && width > 0) + { + // Our height is 0 but our width isn't... + // Try to find a matching height + for(S32 i=0; igetPlatformWindow()->getGFXDevice()->getVideoModeList()->size(); i++) + { + const GFXVideoMode &newVm = (*(object->getPlatformWindow()->getGFXDevice()->getVideoModeList()))[i]; + + if(newVm.resolution.x == width) + { + height = newVm.resolution.y; + changed = true; + break; + } + } + } + + if (width == 0 || height == 0) + { + // Got a bad size for both of our dimensions or one of our dimensions and + // didn't get a match for the other default back to our current resolution + width = vm.resolution.x; + height = vm.resolution.y; + + changed = true; + } + + if (changed) + Con::errorf("GuiCanvas::setVideoMode(): Error - Invalid resolution of (%d, %d) - attempting (%d, %d)", width, height, width, height); + + vm.resolution = Point2I(width, height); + vm.fullScreen = fullscreen; + + vm.bitDepth = bitDepth; + vm.refreshRate = refreshRate; + + vm.antialiasLevel = antiAliasLevel; + +#ifndef TORQUE_OS_XENON + object->getPlatformWindow()->setVideoMode(vm); +#endif +} diff --git a/Engine/source/Verve/GUI/VEditorWindow.h b/Engine/source/Verve/GUI/VEditorWindow.h new file mode 100644 index 000000000..938c909e9 --- /dev/null +++ b/Engine/source/Verve/GUI/VEditorWindow.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// 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_VEDITORWINDOW_H_ +#define _VT_VEDITORWINDOW_H_ + +#ifndef _GUICANVAS_H_ +#include "gui/core/guiCanvas.h" +#endif + +//----------------------------------------------------------------------------- + +class VEditorWindow : public GuiCanvas +{ + typedef GuiCanvas Parent; + +public: + + // Properties. + + virtual bool onAdd( void ); + + // Console Declaration. + + DECLARE_CONOBJECT( VEditorWindow ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VEDITORWINDOW_H_ \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VFadeControl.cpp b/Engine/source/Verve/GUI/VFadeControl.cpp new file mode 100644 index 000000000..16ea3af2f --- /dev/null +++ b/Engine/source/Verve/GUI/VFadeControl.cpp @@ -0,0 +1,114 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VFadeControl.h" + +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "math/mMathFn.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VFadeControl ); +//----------------------------------------------------------------------------- + +VFadeControl::VFadeControl( void ) : + mActive( false ), + mFadeType( k_TypeInvalid ), + mElapsedTime( 0 ), + mDuration( 1000 ), + mLastTime( 0 ) +{ + // Void. +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VFadeControl::onRender( Point2I pOffset, const RectI &pUpdateRect ) +{ + Parent::onRender( pOffset, pUpdateRect ); + + if ( mFadeType == k_TypeInvalid ) + { + // Invalid Fade State. + return; + } + + // Fetch Time. + const U32 time = Platform::getRealMilliseconds(); + // Fetch Delta. + const U32 delta = ( time - mLastTime ); + // Store Time. + mLastTime = time; + + if ( mActive ) + { + // Update Elapsed Time. + mElapsedTime += delta; + } + + F32 alpha = 1.f - mClampF( F32( mElapsedTime ) / F32( mDuration ), 0.f, 1.f ); + + if ( mFadeType == k_TypeOut ) + { + // Flip. + alpha = 1.f - alpha; + } + + if ( alpha > 0.f ) + { + // Render. + GFX->getDrawUtil()->drawRectFill( pOffset, pOffset + getExtent(), ColorI( 0, 0, 0, alpha * 255 ) ); + } + + if ( mElapsedTime >= mDuration ) + { + // Stop. + mActive = false; + } +} + +//----------------------------------------------------------------------------- +// +// Control Methods. +// +//----------------------------------------------------------------------------- + +void VFadeControl::start( eFadeType pType, S32 pDuration ) +{ + mActive = true; + + mFadeType = pType; + + mElapsedTime = 0; + mDuration = pDuration; + + mLastTime = Platform::getRealMilliseconds(); +} + +void VFadeControl::pause( void ) +{ + mActive = false; +} diff --git a/Engine/source/Verve/GUI/VFadeControl.h b/Engine/source/Verve/GUI/VFadeControl.h new file mode 100644 index 000000000..d26cdb97f --- /dev/null +++ b/Engine/source/Verve/GUI/VFadeControl.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// 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_VFADECONTROL_H_ +#define _VT_VFADECONTROL_H_ + +#ifndef _GUICONTROL_H_ +#include "gui/core/guiControl.h" +#endif + +//----------------------------------------------------------------------------- + +class VFadeControl : public GuiControl +{ + typedef GuiControl Parent; + +public: + + enum eFadeType + { + k_TypeIn, + k_TypeOut, + + k_TypeInvalid, + }; + + bool mActive; + eFadeType mFadeType; + + S32 mElapsedTime; + S32 mDuration; + S32 mLastTime; + +public: + + VFadeControl( void ); + + // Render Methods. + + virtual void onRender( Point2I pOffset, const RectI &pUpdateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VFadeControl ); + +public: + + void start( eFadeType pType, S32 pDuration ); + void pause( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VFADECONTROL_H_ \ No newline at end of file diff --git a/Engine/source/Verve/GUI/VTimeLineControl.cpp b/Engine/source/Verve/GUI/VTimeLineControl.cpp new file mode 100644 index 000000000..9bfc7ccfc --- /dev/null +++ b/Engine/source/Verve/GUI/VTimeLineControl.cpp @@ -0,0 +1,476 @@ +//----------------------------------------------------------------------------- +// 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/GUI/VTimeLineControl.h" +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gui/core/guiCanvas.h" + +//----------------------------------------------------------------------------- + +const S32 gUnitsPerSec = 200; + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VTimeLineControl ); +//----------------------------------------------------------------------------- + +VTimeLineControl::VTimeLineControl( void ) : + mIsController( true ), + mController( NULL ), + mDurationOffset( 50 ) +{ + mSelection.Active = false; + mSelection.StartTime = 0; + mSelection.EndTime = 0; +} + +void VTimeLineControl::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "IsController", TypeBool, Offset( mIsController, VTimeLineControl ) ); + addField( "Controller", TYPEID(), Offset( mController, VTimeLineControl ) ); + addField( "DurationOffset", TypeS32, Offset( mDurationOffset, VTimeLineControl ) ); +} + +//----------------------------------------------------------------------------- +// +// Mouse Methods. +// +//----------------------------------------------------------------------------- + +void VTimeLineControl::onMouseDown( const GuiEvent &pEvent ) +{ + Parent::onMouseDown( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + if ( !isMouseLocked() ) + { + GuiCanvas *canvas = getRoot(); + if ( canvas->getMouseLockedControl() ) + { + GuiEvent event; + canvas->getMouseLockedControl()->onMouseLeave( event ); + canvas->mouseUnlock( canvas->getMouseLockedControl() ); + } + + // Lock. + mouseLock(); + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + // Selection? + if ( pEvent.modifier & SI_SHIFT ) + { + if ( !mSelection.Active ) + { + // Selection Active. + mSelection.Active = true; + mSelection.StartTime = mController->getTime(); + mSelection.EndTime = time; + } + else + { + // Update Selection. + mSelection.EndTime = time; + } + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + + // Set First Responder. + setFirstResponder(); + + if ( pEvent.modifier & SI_CTRL ) + { + // Set Time, No Reset. + mController->setTime( time ); + } + else + { + // Reset. + mController->reset( time ); + } +} + +void VTimeLineControl::onMouseUp( const GuiEvent &pEvent ) +{ + if ( isMouseLocked() ) + { + // Unlock. + mouseUnlock(); + } + + if ( mIsController && mController && !mController->isPlaying() ) + { + // Stop without Reset. + mController->stop( false ); + } +} + +void VTimeLineControl::onMouseDragged( const GuiEvent &pEvent ) +{ + Parent::onMouseDragged( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + if ( pEvent.modifier & SI_SHIFT ) + { + if ( mSelection.Active ) + { + // Update Selection. + mSelection.EndTime = time; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + + if ( pEvent.modifier & SI_CTRL ) + { + // Set Time, No Reset. + mController->setTime( time ); + } + else if ( !mSelection.Active ) + { + // Reset. + mController->reset( time ); + } +} + +void VTimeLineControl::onRightMouseDown( const GuiEvent &pEvent ) +{ + Parent::onRightMouseDown( pEvent ); + + if ( !mIsController || !mController || mController->isPlaying() ) + { + return; + } + + // Calculate Time. + const Point2I hitPoint = globalToLocalCoord( pEvent.mousePoint ); + const S32 time = mClamp( toTime( hitPoint.x ), 0, mController->getDuration() ); + + // Set First Responder. + setFirstResponder(); + + if ( mSelection.Active ) + { + const S32 minTime = getMin( mSelection.StartTime, mSelection.EndTime ); + const S32 maxTime = getMax( mSelection.StartTime, mSelection.EndTime ); + if ( time >= minTime && time <= maxTime ) + { + // Callback. + onMouseEvent( "onSelectionRightClick", pEvent ); + + // Don't Update Time. + return; + } + else + { + if ( mSelection.Active ) + { + // Selection Invalid. + mSelection.Active = false; + + // Callback. + Con::executef( this, "onSelectionUpdate" ); + } + } + } + + // Reset. + mController->reset( time ); +} + +void VTimeLineControl::onMouseEvent( const char *pEventName, const GuiEvent &pEvent ) +{ + // Argument Buffers. + char argBuffer[3][32]; + + // Format Event-Position Buffer. + dSprintf( argBuffer[0], 32, "%d %d", pEvent.mousePoint.x, pEvent.mousePoint.y ); + + // Format Event-Modifier Buffer. + dSprintf( argBuffer[1], 32, "%d", pEvent.modifier ); + + // Format Mouse-Click Count Buffer. + dSprintf( argBuffer[2], 32, "%d", pEvent.mouseClickCount ); + + // Call Scripts. + Con::executef( this, pEventName, argBuffer[0], argBuffer[1], argBuffer[2] ); +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VTimeLineControl::onPreRender( void ) +{ + setUpdate(); +} + +void VTimeLineControl::onRender( Point2I offset, const RectI &updateRect ) +{ + if ( !mController ) + { + // Default Render. + Parent::onRender( offset, updateRect ); + + // Quit. + return; + } + + // Render Properties. + const S32 tickOffset = toPoint( 0 ); + const S32 timeLineWidth = toPoint( mController->getDuration() ) - tickOffset; + const F32 tickStep = 0.5f; + const S32 tickInterval = ( mIsController ) ? getWidth() : timeLineWidth; + const S32 tickIntervalCount = ( S32 )mFloor( tickInterval / ( gUnitsPerSec * tickStep ) ) + 1; + + // Tick Render Proeprties. + const Point2I tickExtent( 0, getHeight() - 1 ); + + // Text Render Properties. + const Point2I textExtent( gUnitsPerSec, mProfile->mFontSize ); + const Point2I textOffset( 4, -mProfile->mFontSize ); + + // Render Border. + GFX->getDrawUtil()->drawRectFill( RectI( offset + Point2I( tickOffset + 1, 1 ), Point2I( timeLineWidth - 1, getHeight() - 1 ) ), mProfile->mFillColorHL ); + + // Font Color. + GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor ); + + for ( S32 i = 0; i < tickIntervalCount; i++ ) + { + // Tick Position. + const Point2I tickPosition = offset + Point2I( tickOffset + i * ( gUnitsPerSec * tickStep ), 0 ); + + // Line Color. + const ColorI lineColor = ( ( i % 2 ) ) ? mProfile->mBorderColorHL : mProfile->mBorderColor; + + // Draw Line. + GFX->getDrawUtil()->drawLine( tickPosition, tickPosition + tickExtent, lineColor ); + + if ( mIsController ) + { + // Render Times. + renderJustifiedText( tickPosition + tickExtent + textOffset, textExtent, avar( "%.2f", ( F32 )( i * tickStep ) ) ); + } + } + + // Render Children + renderChildControls( offset, updateRect ); + + if ( mSelection.Active ) + { + // Selection Width. + const S32 selectionWidth = mCeil( mAbs( toPoint( mSelection.EndTime ) - toPoint( mSelection.StartTime ) ) ); + + // Selection Position. + const S32 selectionPositionX = toPoint( getMin( mSelection.StartTime, mSelection.EndTime ) ); + + // Selection Properties. + const Point2I selectionExtent( selectionWidth, getHeight() ); + const Point2I selectionPosition = offset + Point2I( selectionPositionX, 0 ); + + // Render Time Cue. + GFX->getDrawUtil()->drawRectFill( RectI( selectionPosition, selectionExtent ), ColorI( 0, 0, 0, 128 ) ); + + if ( mIsController ) + { + // Buffer. + char buffer[2][128]; + dSprintf( buffer[0], 128, "%.2f", ( F32 )( mSelection.StartTime / 1000.f ) ); + dSprintf( buffer[1], 128, "%.2f", ( F32 )( mSelection.EndTime / 1000.f ) ); + + if ( mSelection.StartTime < mSelection.EndTime ) + { + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer[0] ); + + // Text Position. + const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 ); + const Point2I endText = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( startText, textExtent, buffer[0] ); + renderJustifiedText( endText, textExtent, buffer[1] ); + } + else + { + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer[1] ); + + // Text Position. + const Point2I startText = Point2I( getMax( ( S32 )( selectionPosition.x - ( textWidth + 2 ) ), updateRect.point.x + 4 ), selectionPosition.y + 2 ); + const Point2I endText = Point2I( getMin( ( S32 )( selectionPosition.x + selectionWidth + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), selectionPosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( startText, textExtent, buffer[1] ); + renderJustifiedText( endText, textExtent, buffer[0] ); + } + } + } + + if ( mController && !mSelection.Active ) + { + // Time Cue Properties. + const Point2I timeCueExtent( ( mIsController ) ? 4 : 2, getHeight() ); + const Point2I timeCuePosition = offset + Point2I( toPoint( mController->getTime() ) - ( timeCueExtent.x / 2 ), 0 ); + + // Render Time Cue. + GFX->getDrawUtil()->drawRectFill( RectI( timeCuePosition, timeCueExtent ), ColorI( 0,0,0,128 ) ); + + if ( mIsController ) + { + // Buffer. + char buffer[128]; + dSprintf( buffer, 128, "%.2f", ( F32 )( mController->getTime() / 1000.f ) ); + + // Fetch Width. + const S32 textWidth = mProfile->mFont->getStrWidth( buffer ); + + // Text Position. + const Point2I textPosition( getMin( getMax( timeCuePosition.x + 6, updateRect.point.x + 4 ), updateRect.point.x + updateRect.extent.x - ( textWidth + 2 ) ), timeCuePosition.y + 2 ); + + // Render Time Text. + renderJustifiedText( textPosition, textExtent, buffer ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Console Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VTimeLineControl, toPoint, S32, (S32 time), (0), "( pTime )" ) +{ + return object->toPoint(time); +} + +S32 VTimeLineControl::toTime( const S32 &pPoint ) +{ + return ( ( S32 )( 1000.f * ( F32 )pPoint / gUnitsPerSec ) - mDurationOffset ); +} + +DefineEngineMethod( VTimeLineControl, toTime, S32, (S32 point), (0), "( pPoint )" ) +{ + return object->toTime(point); +} + +S32 VTimeLineControl::toPoint( const S32 &pTime ) +{ + return ( S32 )( gUnitsPerSec * ( ( F32 )( pTime + mDurationOffset ) / 1000.f ) ); +} + +DefineEngineMethod( VTimeLineControl, getSelection, const char *, (),, "( )" ) +{ + const S32 minTime = getMin( object->mSelection.StartTime, object->mSelection.EndTime ); + const S32 maxTime = getMax( object->mSelection.StartTime, object->mSelection.EndTime ); + + // Fetch Return Buffer. + char *retBuffer = Con::getReturnBuffer( 256 ); + + // Write. + dSprintf( retBuffer, 256, "%d %d %d", object->mSelection.Active, minTime, maxTime - minTime ); + + // Return. + return retBuffer; +} + +DefineEngineMethod( VTimeLineControl, setSelection, void, (bool active, S32 time, S32 duration), (true, -1, 1), "( pActive, [pTime, pDuration] )" ) +{ + object->mSelection.Active = active; + if (time != -1) + { + object->mSelection.StartTime = time; + object->mSelection.EndTime = object->mSelection.StartTime + duration; + } +} + +DefineEngineMethod( VTimeLineControl, updateDuration, void, (),, "( )" ) +{ + object->updateDuration(); +} + +void VTimeLineControl::updateDuration( void ) +{ + if ( !mController ) + { + // No Controller. + return; + } + + // Add 500ms. + const S32 length = toPoint( mController->getDuration() + 500 ); + + // Set Min Extent. + setMinExtent( Point2I( length, getHeight() ) ); + + if ( getWidth() < length ) + { + // Conform to Min Extent. + setExtent( length, getHeight() ); + } +} diff --git a/Engine/source/Verve/GUI/VTimeLineControl.h b/Engine/source/Verve/GUI/VTimeLineControl.h new file mode 100644 index 000000000..1dd1b9851 --- /dev/null +++ b/Engine/source/Verve/GUI/VTimeLineControl.h @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// 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_VTIMELINECONTROL_H_ +#define _VT_VTIMELINECONTROL_H_ + +#ifndef _GUICONTROL_H_ +#include "gui/core/guiControl.h" +#endif + +#ifndef _VT_VCONTROLLER_H_ +#include "Verve/Core/VController.h" +#endif + +//----------------------------------------------------------------------------- + +class VTimeLineControl : public GuiControl +{ + typedef GuiControl Parent; + +public: + + struct sSelection + { + bool Active; + S32 StartTime; + S32 EndTime; + }; + + bool mIsController; + VController *mController; + + S32 mDurationOffset; + + sSelection mSelection; + +public: + + VTimeLineControl( void ); + + static void initPersistFields( void ); + + // Mouse. + + virtual void onMouseDown( const GuiEvent &pEvent ); + virtual void onMouseUp( const GuiEvent &pEvent ); + virtual void onMouseDragged( const GuiEvent &pEvent ); + + virtual void onRightMouseDown( const GuiEvent &pEvent ); + + void onMouseEvent( const char *pEventName, const GuiEvent &pEvent ); + + // Rendering. + + void onPreRender( void ); + void onRender( Point2I offset, const RectI &updateRect ); + + // Console Declaration. + + DECLARE_CONOBJECT( VTimeLineControl ); + +public: + + S32 toTime( const S32 &pPoint ); + S32 toPoint( const S32 &pTime ); + + void updateDuration( void ); +}; + +//----------------------------------------------------------------------------- + +#endif // _VT_VTIMELINECONTROL_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TAnimation.h b/Engine/source/Verve/Torque/TAnimation.h new file mode 100644 index 000000000..4c5307bec --- /dev/null +++ b/Engine/source/Verve/Torque/TAnimation.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_ANIMATION_H_ +#define _VT_TORQUE_ANIMATION_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + bool isAnimationLooping( SceneObjectType *pObject, const char *pData ); + + String getAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + F32 getAnimationDuration( SceneObjectType *pObject, const char *pData ); + void setAnimationPosition( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pPosition ); + void setAnimationTimeScale( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pTimeScale ); + + void playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex, const char *pData ); + void playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + void stopAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); + void pauseAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ); +}; + +#endif // _VT_TORQUE_ANIMATION_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TCamera.h b/Engine/source/Verve/Torque/TCamera.h new file mode 100644 index 000000000..329bf093b --- /dev/null +++ b/Engine/source/Verve/Torque/TCamera.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_CAMERA_H_ +#define _VT_TORQUE_CAMERA_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +#ifndef _CAMERAFXMGR_H_ +#include "T3D/fx/cameraFXMgr.h" +#endif + +namespace VTorque +{ + bool isCamera( SceneObjectType *pObject ); + void setCamera( SceneObjectType *pObject ); + + void startCameraShake( const F32 &pDuration, const F32 &pFalloff, const VectorF &pAmplitude, const VectorF &pFrequency ); + void stopCameraShake( void ); +}; + +#endif // _VT_TORQUE_CAMERA_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TLightObject.h b/Engine/source/Verve/Torque/TLightObject.h new file mode 100644 index 000000000..0b44cd607 --- /dev/null +++ b/Engine/source/Verve/Torque/TLightObject.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_LIGHTOBJECT_H_ +#define _VT_TORQUE_LIGHTOBJECT_H_ + +#ifndef _LIGHTBASE_H_ +#include "T3D/lightBase.h" +#endif + +#ifndef _LIGHTANIMDATA_H_ +#include "T3D/lightAnimData.h" +#endif + +namespace VTorque +{ + + typedef LightBase LightObjectType; + typedef LightAnimData LightAnimationDataType; + + bool isLightObjectEnabled( LightObjectType *pLightObject ); + void setLightObjectOn( LightObjectType *pLightObject, const bool &pStatus ); + + void playAnimation( LightObjectType *pLightObject, LightAnimationDataType *pLightAnimationData ); + void playAnimation( LightObjectType *pLightObject ); + void pauseAnimation( LightObjectType *pLightObject ); +}; + +#endif // _VT_TORQUE_LIGHTOBJECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TMotion.h b/Engine/source/Verve/Torque/TMotion.h new file mode 100644 index 000000000..d77118945 --- /dev/null +++ b/Engine/source/Verve/Torque/TMotion.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_MOTION_H_ +#define _VT_TORQUE_MOTION_H_ + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +#ifndef _VT_VPATH_H_ +#include "Verve/VPath/VPath.h" +#endif + +namespace VTorque +{ + typedef VPath PathObjectType; + + bool isMovable( SimObject *pObject ); + bool isPath( SimObject *pObject ); + bool isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject ); + + F32 getPathNodeLength( PathObjectType *pPath, const S32 &pNode ); + + void attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ); + void detachPathObject( PathObjectType *pPath, SceneObjectType *pObject ); + + void setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive ); + void setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp ); + void setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset ); + void setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed ); + void setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData = String::EmptyString ); + void setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward ); + void setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ); + void setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ); +}; + +#endif // _VT_TORQUE_MOTION_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TParticleEffect.h b/Engine/source/Verve/Torque/TParticleEffect.h new file mode 100644 index 000000000..c1350af0e --- /dev/null +++ b/Engine/source/Verve/Torque/TParticleEffect.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_PARTICLEEFFECT_H_ +#define _VT_TORQUE_PARTICLEEFFECT_H_ + +#ifndef _H_PARTICLE_EMITTER +#include "T3D/fx/particleEmitter.h" +#endif + +#ifndef _PARTICLEEMITTERDUMMY_H_ +#include "T3D/fx/particleEmitterNode.h" +#endif + +namespace VTorque +{ + + typedef ParticleEmitterNode ParticleEffectType; + + bool isParticleEffectEnabled( ParticleEffectType *pParticleEffect ); + void setParticleEffectOn( ParticleEffectType *pParticleEffect, const bool &pStatus ); +}; + +#endif // _VT_TORQUE_PARTICLEEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TPostEffect.h b/Engine/source/Verve/Torque/TPostEffect.h new file mode 100644 index 000000000..58edcf43e --- /dev/null +++ b/Engine/source/Verve/Torque/TPostEffect.h @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_POSTEFFECT_H_ +#define _VT_TORQUE_POSTEFFECT_H_ + +#ifndef _POST_EFFECT_H_ +#include "postFx/postEffect.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef PostEffect PostEffectType; + + bool isPostEffectEnabled( PostEffectType *pPostEffect ); + void setPostEffectOn( PostEffectType *pPostEffect, const bool &pStatus ); +}; + +#endif // _VT_TORQUE_POSTEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TSceneObject.h b/Engine/source/Verve/Torque/TSceneObject.h new file mode 100644 index 000000000..8f487b3b0 --- /dev/null +++ b/Engine/source/Verve/Torque/TSceneObject.h @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SCENEOBJECT_H_ +#define _VT_TORQUE_SCENEOBJECT_H_ + +#ifndef _SCENEOBJECT_H_ +#include "scene/sceneObject.h" +#endif + +namespace VTorque +{ + typedef SceneObject SceneObjectType; +}; + +#endif // _VT_TORQUE_SCENEOBJECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TSoundEffect.h b/Engine/source/Verve/Torque/TSoundEffect.h new file mode 100644 index 000000000..3c3aa9fbc --- /dev/null +++ b/Engine/source/Verve/Torque/TSoundEffect.h @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SOUNDEFFECT_H_ +#define _VT_TORQUE_SOUNDEFFECT_H_ + +#ifndef _SFXPROFILE_H_ +#include "sfx/sfxProfile.h" +#endif + +#ifndef _SFXSOUND_H_ +#include "sfx/sfxSound.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef SFXProfile SoundEffectType; + typedef SFXSound SoundSourceType; + + bool isSoundLooping( SoundEffectType *pSoundProfile ); + S32 getSoundDuration( SoundEffectType *pSoundProfile ); + + SoundSourceType *playSound( SoundEffectType *pSoundProfile, const U32 &pPosition, const F32 &pPitch ); + SoundSourceType *playSound( SoundEffectType *pSoundProfile, SceneObjectType *pObject, const U32 &pPosition, const F32 &pPitch ); + + void playSound( SoundSourceType *pSource ); + void pauseSound( SoundSourceType *pSource ); + void stopSound( SoundSourceType *pSource ); + + void setSoundPosition( SoundSourceType *pSource, const U32 &pPosition ); + void setSoundPitch( SoundSourceType *pSource, const F32 &pPitch ); +}; + +#endif // _VT_TORQUE_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque/TSpawnSphere.h b/Engine/source/Verve/Torque/TSpawnSphere.h new file mode 100644 index 000000000..e9899d87d --- /dev/null +++ b/Engine/source/Verve/Torque/TSpawnSphere.h @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// 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_TORQUE_SPAWNSPHERE_H_ +#define _VT_TORQUE_SPAWNSPHERE_H_ + +#ifndef _MISSIONMARKER_H_ +#include "T3D/missionMarker.h" +#endif + +#ifndef _VT_TORQUE_SCENEOBJECT_H_ +#include "Verve/Torque/TSceneObject.h" +#endif + +namespace VTorque +{ + typedef SpawnSphere SpawnSphereType; +}; + +#endif // _VT_TORQUE_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VAnimation.cpp b/Engine/source/Verve/Torque3D/VAnimation.cpp new file mode 100644 index 000000000..38eaf983e --- /dev/null +++ b/Engine/source/Verve/Torque3D/VAnimation.cpp @@ -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. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TAnimation.h" + +#include "T3D/shapeBase.h" + +//----------------------------------------------------------------------------- +// +// Animation Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isAnimationLooping( SceneObjectType *pObject, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return false; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return false; + } + + // Return Cyclic. + return shape->getShape()->sequences[sequenceIndex].isCyclic(); +} + +String VTorque::getAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return ""; + } + + // Return Name. + return shape->getThreadSequenceName( pThreadIndex ); +} + +F32 VTorque::getAnimationDuration( SceneObjectType *pObject, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return 0.f; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return 0.f; + } + + // Return Duration. + return shape->getShape()->sequences[sequenceIndex].duration; +} + +void VTorque::setAnimationPosition( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pPosition ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Set Position. + shape->setThreadPosition( 0, pPosition ); +} + +void VTorque::setAnimationTimeScale( SceneObjectType *pObject, const U32 &pThreadIndex, const F32 &pTimeScale ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Set TimeScale. + shape->setThreadTimeScale( pThreadIndex, pTimeScale ); +} + +void VTorque::playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex, const char *pData ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape || !shape->getShape() ) + { + // Sanity! + return; + } + + // Find Sequence. + const S32 sequenceIndex = shape->getShape()->findSequence( pData ); + if ( sequenceIndex == -1 ) + { + // Invalid Sequence. + return; + } + + // Play Sequence. + shape->setThreadSequence( pThreadIndex, sequenceIndex ); +} + +void VTorque::playAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Play Sequence. + shape->playThread( pThreadIndex ); +} + +void VTorque::stopAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Pause Thread. + shape->stopThread( pThreadIndex ); +} + +void VTorque::pauseAnimation( SceneObjectType *pObject, const U32 &pThreadIndex ) +{ + ShapeBase *shape = dynamic_cast( pObject ); + if ( !shape ) + { + // Sanity! + return; + } + + // Pause Thread. + shape->pauseThread( pThreadIndex ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VCamera.cpp b/Engine/source/Verve/Torque3D/VCamera.cpp new file mode 100644 index 000000000..4e01e5516 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VCamera.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque/TCamera.h" +#include "Verve/Torque3D/VCameraShake.h" + +#include "T3D/gameBase/gameConnection.h" + +//----------------------------------------------------------------------------- +// +// Camera Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isCamera( SceneObjectType *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +void VTorque::setCamera( SceneObjectType *pObject ) +{ + // Fetch Game Base. + GameBase *object = dynamic_cast( pObject ); + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + GameConnection *connection = dynamic_cast( *itr ); + if ( connection ) + { + // Set Camera Object. + connection->setCameraObject( object ); + } + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VCameraShake.cpp b/Engine/source/Verve/Torque3D/VCameraShake.cpp new file mode 100644 index 000000000..233bf8ca4 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VCameraShake.cpp @@ -0,0 +1,231 @@ +//----------------------------------------------------------------------------- +// 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/Torque3D/VCameraShake.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VCameraShakeNetEvent ); +//----------------------------------------------------------------------------- + +// ShakeCamera( 1, 10, "1 0 0", "1 0 0" ); +DefineEngineFunction( ShakeCamera, void, (F32 duration, F32 falloff, VectorF amplitude, VectorF frequency), (0,0,VectorF::Zero, VectorF::Zero), "( pDuration, pFalloff, pAmplitude, pFrequency )" ) +{ + // Shake Camera. + VTorque::startCameraShake( duration, falloff, amplitude, frequency ); +} + +void VTorque::startCameraShake( const F32 &pDuration, const F32 &pFalloff, const VectorF &pAmplitude, const VectorF &pFrequency ) +{ +#ifdef VT_EDITOR + + // Create FX Event + CameraShake *camShake = new CameraShake(); + + // Set Duration. + camShake->setDuration( pDuration ); + + // Set Falloff. + camShake->setFalloff( pFalloff ); + + // Set Amplitude. + VectorF amp = pAmplitude; + camShake->setAmplitude( amp ); + + // Set Frequency. + VectorF freq = pFrequency; + camShake->setFrequency( freq ); + + // Initialise. + camShake->init(); + + // Add to Manager. + gCamFXMgr.addFX( camShake ); + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VCameraShakeNetEvent *event = new VCameraShakeNetEvent(); + + // Setup Event. + event->mEventType |= ( VCameraShakeNetEvent::k_TypeClear | VCameraShakeNetEvent::k_TypeMake ); + event->mDuration = pDuration; + event->mFalloff = pFalloff; + event->mAmplitude = pAmplitude; + event->mFrequency = pFrequency; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +void VTorque::stopCameraShake( void ) +{ +#ifdef VT_EDITOR + + // Clear Manager. + gCamFXMgr.clear(); + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VCameraShakeNetEvent *event = new VCameraShakeNetEvent(); + + // Setup Event. + event->mEventType |= VCameraShakeNetEvent::k_TypeClear; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +//----------------------------------------------------------------------------- + +VCameraShakeNetEvent::VCameraShakeNetEvent( void ) : mEventType( 0 ), + mDuration( 0.f ), + mFalloff( 10.f ), + mAmplitude( Point3F::Zero ), + mFrequency( Point3F::Zero ) +{ + // Void. +} + +void VCameraShakeNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VCameraShakeNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Clear Manager? + pStream->write( mEventType & k_TypeClear ); + + // Make Event? + if ( pStream->write( mEventType & k_TypeMake ) ) + { + // Duration. + pStream->write( mDuration ); + + // Falloff. + pStream->write( mFalloff ); + + // Amplitude. + pStream->write( mAmplitude.x ); + pStream->write( mAmplitude.y ); + pStream->write( mAmplitude.z ); + + // Frequency. + pStream->write( mFrequency.x ); + pStream->write( mFrequency.y ); + pStream->write( mFrequency.z ); + } +} + +void VCameraShakeNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Clear Manager? + if ( pStream->readFlag() ) + { + // Update State. + mEventType |= k_TypeClear; + } + + // Make Event? + if ( pStream->readFlag() ) + { + // Update State. + mEventType |= k_TypeMake; + + // Duration. + pStream->read( &mDuration ); + + // Falloff. + pStream->read( &mFalloff ); + + // Amplitude. + pStream->read( &mAmplitude.x ); + pStream->read( &mAmplitude.y ); + pStream->read( &mAmplitude.z ); + + // Frequency. + pStream->read( &mFrequency.x ); + pStream->read( &mFrequency.y ); + pStream->read( &mFrequency.z ); + } +} + +void VCameraShakeNetEvent::process( NetConnection *pConnection ) +{ + if ( mEventType & k_TypeClear ) + { + // Clear Manager. + gCamFXMgr.clear(); + } + + if ( mEventType & k_TypeMake ) + { + // Create FX Event + CameraShake *camShake = new CameraShake(); + + // Set Duration. + camShake->setDuration( mDuration ); + + // Set Falloff. + camShake->setFalloff( mFalloff ); + + // Set Amplitude. + camShake->setAmplitude( mAmplitude ); + + // Set Frequency. + camShake->setFrequency( mFrequency ); + + // Initialise. + camShake->init(); + + // Add to Manager. + gCamFXMgr.addFX( camShake ); + } +} diff --git a/Engine/source/Verve/Torque3D/VCameraShake.h b/Engine/source/Verve/Torque3D/VCameraShake.h new file mode 100644 index 000000000..2e40359d1 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VCameraShake.h @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_CAMERASHAKE_H_ +#define _VT_VTORQUE3D_CAMERASHAKE_H_ + +#ifndef _VT_TORQUE_CAMERA_H_ +#include "Verve/Torque/TCamera.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VCameraShakeNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + enum eEventType + { + k_TypeClear = BIT( 0 ), + k_TypeMake = BIT( 1 ), + }; + + U32 mEventType; + + F32 mDuration; + F32 mFalloff; + VectorF mAmplitude; + VectorF mFrequency; + +public: + + VCameraShakeNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VCameraShakeNetEvent ); +}; + +#endif // _VT_VTORQUE3D_CAMERASHAKE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VLightObject.cpp b/Engine/source/Verve/Torque3D/VLightObject.cpp new file mode 100644 index 000000000..dcf1d016e --- /dev/null +++ b/Engine/source/Verve/Torque3D/VLightObject.cpp @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TLightObject.h" + +//----------------------------------------------------------------------------- +// +// Light Object Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isLightObjectEnabled( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return false; + } + + // Get Enabled. + return pLightObject->getLightEnabled(); +} + +void VTorque::setLightObjectOn( LightObjectType *pLightObject, const bool &pStatus ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Set Enabled. + pLightObject->setLightEnabled( pStatus ); +} + +void VTorque::playAnimation( LightObjectType *pLightObject, LightAnimationDataType *pLightAnimationData ) +{ + if ( !pLightObject || !pLightAnimationData ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->playAnimation( pLightAnimationData ); +} + +void VTorque::playAnimation( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->playAnimation(); +} + +void VTorque::pauseAnimation( LightObjectType *pLightObject ) +{ + if ( !pLightObject ) + { + // Sanity! + return; + } + + // Play Animation. + pLightObject->pauseAnimation(); +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VMotion.cpp b/Engine/source/Verve/Torque3D/VMotion.cpp new file mode 100644 index 000000000..54bff56e5 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VMotion.cpp @@ -0,0 +1,458 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TMotion.h" +#include "Verve/VPath/VPath.h" + +//----------------------------------------------------------------------------- + +// Sync the local connection when editing path objects? +// Note: This was originally done so that editing was very smooth, but it turns +// out that any lag was due to errors in the pathing operations +// themselves. If issues persist, then uncomment this definition and you +// might see a marked improvement in performance while editing in Verve. +//#define VT_SYNC_LOCALCLIENT + +//----------------------------------------------------------------------------- +// +// Utility Methods. +// +//----------------------------------------------------------------------------- + +NetObject *getClientObject( NetObject *pObject ) +{ + if ( !pObject ) + { + return NULL; + } + + NetConnection *toServer = NetConnection::getConnectionToServer(); + NetConnection *toClient = NetConnection::getLocalClientConnection(); + if ( !toServer || !toClient ) + { + return NULL; + } + + const S32 ghostIndex = toClient->getGhostIndex( pObject ); + if ( ghostIndex == -1 ) + { + return NULL; + } + + return toServer->resolveGhost( ghostIndex ); +} + +void _attachPathObject( VPath *pPath, SceneObject *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) +{ + if ( pOrientation == String::EmptyString ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex ); + // Quit. + return; + } + + // Fetch Orientation. + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, NULL ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Object. + SceneObject *lookAtObject = dynamic_cast( Sim::findObject( pOrientationData ) ); + // Valid Object? + if ( lookAtObject != NULL ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtObject ); + } + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + if ( dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ) == 3 ) + { + // Attach Object. + pPath->attachObject( pObject, pForward, 0.f, pRelative, pStartNodeIndex, pEndNodeIndex, type, (void*)lookAtPoint ); + } + + } break; + } +} + +//----------------------------------------------------------------------------- +// +// Path Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isMovable( SimObject *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +bool VTorque::isPath( SimObject *pObject ) +{ + return ( dynamic_cast( pObject ) != NULL ); +} + +bool VTorque::isPathObjectAttached( PathObjectType *pPath, SceneObjectType *pObject ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return false; + } + + // Return. + return pPath->isObjectAttached( pObject ); +} + +F32 VTorque::getPathNodeLength( PathObjectType *pPath, const S32 &pNode ) +{ + if ( !pPath ) + { + // Sanity! + return false; + } + + // Normalize Node Index. + S32 nodeIndex = pNode; + pPath->normalizeNodeIndex( nodeIndex ); + + // Fetch Node. + VPathNode *node = pPath->getNode( nodeIndex ); + + // Return Length. + return node->getLength(); +} + +void VTorque::attachPathObject( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward, const bool &pRelative, const S32 &pStartNodeIndex, const S32 &pEndNodeIndex, const String &pOrientation, const String &pOrientationData ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Attach Object. + _attachPathObject( pPath, pObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Attach Object. + _attachPathObject( clientPath, clientObject, pForward, pRelative, pStartNodeIndex, pEndNodeIndex, pOrientation, pOrientationData ); + } + +#endif +} + +void VTorque::detachPathObject( PathObjectType *pPath, SceneObjectType *pObject ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Detach Object. + pPath->detachObject( pObject ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Detach Object. + clientPath->detachObject( clientObject ); + } + +#endif +} + +void VTorque::setPathObjectActive( PathObjectType *pPath, SceneObjectType *pObject, const bool &pActive ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object State. + pPath->setPathObjectActive( pObject, pActive ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object State. + clientPath->setPathObjectActive( clientObject, pActive ); + } + +#endif +} + +void VTorque::setPathObjectInterp( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pInterp ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Interp. + pPath->setPathObjectInterp( pObject, pInterp ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectInterp( clientObject, pInterp ); + } + +#endif +} + +void VTorque::setPathObjectOffset( PathObjectType *pPath, SceneObjectType *pObject, const Point3F &pOffset ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Offset. + pPath->setPathObjectOffset( pObject, pOffset ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectOffset( clientObject, pOffset ); + } + +#endif +} + +void VTorque::setPathObjectSpeed( PathObjectType *pPath, SceneObjectType *pObject, const F32 &pSpeed ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Speed. + pPath->setPathObjectSpeed( pObject, pSpeed ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectSpeed( clientObject, pSpeed ); + } + +#endif +} + +void VTorque::setPathObjectOrientation( PathObjectType *pPath, SceneObjectType *pObject, const String &pOrientation, const String &pOrientationData ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Set the orientation mode. + // Note: Call the console method so we don't have to handle all the different modes here. + Con::executef( pPath, "setPathObjectOrientationMode", pObject->getIdString(), pOrientation, pOrientationData ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // TODO: Handle synching the client path immediately. + +#endif + + /* + // Set the Default Mode. + if ( pOrientation == String::EmptyString ) + { + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, VPathObject::k_OrientationToPath ); + return; + } + + // Fetch Orientation. + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( pOrientation ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + + // Fetch Object. + SceneObjectType *lookAtObject; + if ( !Sim::findObject( pOrientationData, lookAtObject ) ) + { + // Invalid Object. + return; + } + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type, lookAtObject ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( pOrientationData, "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + pPath->setPathObjectOrientationMode( pObject, type, lookAtPoint ); + + } break; + } + */ +} + +void VTorque::setPathObjectForward( PathObjectType *pPath, SceneObjectType *pObject, const bool &pForward ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Path Object Forward. + pPath->setPathObjectForward( pObject, pForward ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Apply the same action. + clientPath->setPathObjectForward( clientObject, pForward ); + } + +#endif +} + +void VTorque::setPathObjectNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object Current Node. + pPath->setPathObjectNode( pObject, pNode ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object Current Node. + clientPath->setPathObjectNode( clientObject, pNode ); + } + +#endif +} + +void VTorque::setPathObjectEndNode( PathObjectType *pPath, SceneObjectType *pObject, const S32 &pNode ) +{ + if ( !pPath || !pObject ) + { + // Sanity! + return; + } + + // Update Object End Node. + pPath->setPathObjectEndNode( pObject, pNode ); + +#if defined( VT_EDITOR ) && defined( VT_SYNC_LOCALCLIENT ) + + // Fetch the client Path. + VPath *clientPath = dynamic_cast( getClientObject( pPath ) ); + SceneObjectType *clientObject = dynamic_cast( getClientObject( pObject ) ); + if ( clientPath && clientObject ) + { + // Update Object End Node. + clientPath->setPathObjectEndNode( clientObject, pNode ); + } + +#endif +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VParticleEffect.cpp b/Engine/source/Verve/Torque3D/VParticleEffect.cpp new file mode 100644 index 000000000..b1e35b5a1 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VParticleEffect.cpp @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) 2014 - Violent Tulip +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "Verve/Torque/TParticleEffect.h" + +//----------------------------------------------------------------------------- +// +// Particle Effect Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isParticleEffectEnabled( ParticleEffectType *pParticleEffect ) +{ + if ( !pParticleEffect ) + { + // Sanity! + return false; + } + + // Get Active. + return pParticleEffect->getActive(); +} + +void VTorque::setParticleEffectOn( ParticleEffectType *pParticleEffect, const bool &pStatus ) +{ + if ( !pParticleEffect ) + { + // Sanity! + return; + } + + // Set Active. + pParticleEffect->setActive( pStatus ); +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VPostEffect.cpp b/Engine/source/Verve/Torque3D/VPostEffect.cpp new file mode 100644 index 000000000..e9f245790 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VPostEffect.cpp @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque3D/VPostEffect.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +// +// Post Effect Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isPostEffectEnabled( PostEffectType *pPostEffect ) +{ + if ( !pPostEffect ) + { + // Sanity! + return false; + } + + return pPostEffect->isEnabled(); +} + +void VTorque::setPostEffectOn( PostEffectType *pPostEffect, const bool &pStatus ) +{ + if ( !pPostEffect ) + { + // Sanity! + return; + } + +#ifdef VT_EDITOR + + if ( pStatus ) + { + // Enable Effect. + pPostEffect->enable(); + } + else + { + // Disable Effect. + pPostEffect->disable(); + } + +#else + + // Fetch Name. + StringTableEntry name = pPostEffect->getName(); + if ( !name || name == StringTable->insert( "" ) ) + { + Con::warnf( "VTorque::setPostEffectOn() - Invalid Object Name." ); + return; + } + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VPostEffectNetEvent *event = new VPostEffectNetEvent(); + + // Setup Event. + event->mPostEffect = name; + event->mEnabled = pStatus; + + // Post Event. + connection->postNetEvent( event ); + } + } + +#endif +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VPostEffectNetEvent ); +//----------------------------------------------------------------------------- + +VPostEffectNetEvent::VPostEffectNetEvent( void ) : mPostEffect( StringTable->insert( "" ) ), + mEnabled( false ) +{ + // Void. +} + +void VPostEffectNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VPostEffectNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Object Name. + pStream->writeString( mPostEffect ); + + // Status. + pStream->writeFlag( mEnabled ); +} + +void VPostEffectNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Object Name. + mPostEffect = pStream->readSTString(); + + // Status. + mEnabled = pStream->readFlag(); +} + +void VPostEffectNetEvent::process( NetConnection *pConnection ) +{ + PostEffect *postEffect; + if ( !Sim::findObject( mPostEffect, postEffect ) ) + { + Con::warnf( "VPostEffectNetEvent::process() - Unable to find PostEffect Object '%s'", mPostEffect ); + return; + } + + if ( mEnabled ) + { + // Enable Effect. + postEffect->enable(); + } + else + { + // Disable Effect. + postEffect->disable(); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VPostEffect.h b/Engine/source/Verve/Torque3D/VPostEffect.h new file mode 100644 index 000000000..bbb64aecc --- /dev/null +++ b/Engine/source/Verve/Torque3D/VPostEffect.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_POSTEFFECT_H_ +#define _VT_VTORQUE3D_POSTEFFECT_H_ + +#ifndef _VT_TORQUE_POSTEFFECT_H_ +#include "Verve/Torque/TPostEffect.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VPostEffectNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + StringTableEntry mPostEffect; + bool mEnabled; + +public: + + VPostEffectNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VPostEffectNetEvent ); +}; + +#endif // _VT_VTORQUE3D_POSTEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VSoundEffect.cpp b/Engine/source/Verve/Torque3D/VSoundEffect.cpp new file mode 100644 index 000000000..8dda926c3 --- /dev/null +++ b/Engine/source/Verve/Torque3D/VSoundEffect.cpp @@ -0,0 +1,354 @@ +//----------------------------------------------------------------------------- +// 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/VerveConfig.h" +#include "Verve/Torque3D/VSoundEffect.h" + +#include "T3D/gameBase/gameConnection.h" +#include "core/stream/bitStream.h" +#include "math/mathIO.h" +#include "sfx/sfxSystem.h" +#include "sfx/sfxDescription.h" + +//----------------------------------------------------------------------------- +// +// Sound Methods. +// +//----------------------------------------------------------------------------- + +bool VTorque::isSoundLooping( SoundEffectType *pSoundProfile ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return false; + } + + // Return Looping. + return pSoundProfile->getDescription()->mIsLooping; +} + +S32 VTorque::getSoundDuration( SoundEffectType *pSoundProfile ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return 0; + } + + // Return Duration. + return pSoundProfile->getSoundDuration(); +} + +VTorque::SoundSourceType *VTorque::playSound( SoundEffectType *pSoundProfile, const U32 &pPosition, const F32 &pPitch ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return NULL; + } + +#ifdef VT_EDITOR + + // Play Sound. + SFXSound *source = ( SFXSound* )SFX->playOnce( pSoundProfile ); + + if ( source ) + { + // Set Position. + source->setPosition( pPosition ); + + // Set Pitch. + source->setPitch( pPitch ); + } + + // Return Source. + return source; + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VSoundEffectNetEvent *event = new VSoundEffectNetEvent(); + + // Setup Event. + event->mProfile = pSoundProfile; + event->mPosition = pPosition; + event->mPitch = pPitch; + event->mIs3D = false; + + // Post Event. + connection->postNetEvent( event ); + } + } + + return NULL; + +#endif +} + +VTorque::SoundSourceType *VTorque::playSound( SoundEffectType *pSoundProfile, SceneObjectType *pObject, const U32 &pPosition, const F32 &pPitch ) +{ + if ( !pSoundProfile ) + { + // Sanity! + return NULL; + } + +#ifdef VT_EDITOR + + // Fetch Reference Transform. + const MatrixF &transform = pObject->getTransform(); + + // Play Sound. + SFXSound *source = ( SFXSound* )SFX->playOnce( pSoundProfile, &transform ); + + if ( source ) + { + // Set Position. + source->setPosition( pPosition ); + + // Set Pitch. + source->setPitch( pPitch ); + } + + // Return Source. + return source; + +#else + + // Fetch Client Group. + SimGroup* clientGroup = Sim::getClientGroup(); + + for ( SimGroup::iterator itr = clientGroup->begin(); itr != clientGroup->end(); itr++ ) + { + NetConnection *connection = static_cast( *itr ); + if ( connection ) + { + // Create Event. + VSoundEffectNetEvent *event = new VSoundEffectNetEvent(); + + // Setup Event. + event->mProfile = pSoundProfile; + event->mPosition = pPosition; + event->mPitch = pPitch; + event->mIs3D = true; + event->mTransform = pObject->getTransform(); + + // Post Event. + connection->postNetEvent( event ); + } + } + + return NULL; + +#endif +} + +void VTorque::playSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Play. + pSource->play(); +} + +void VTorque::pauseSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Pause. + pSource->pause(); +} + +void VTorque::stopSound( SoundSourceType *pSource ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Stop. + pSource->stop(); +} + +void VTorque::setSoundPosition( SoundSourceType *pSource, const U32 &pPosition ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Set Position. + pSource->setPosition( pPosition ); +} + +void VTorque::setSoundPitch( SoundSourceType *pSource, const F32 &pPitch ) +{ + if ( !pSource ) + { + // Sanity! + return; + } + + // Set Pitch. + pSource->setPitch( pPitch ); +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_CLIENTEVENT_V1( VSoundEffectNetEvent ); +//----------------------------------------------------------------------------- + +VSoundEffectNetEvent::VSoundEffectNetEvent( void ) : mProfile( NULL ), + mPosition( 0.f ), + mPitch( 1.f ), + mIs3D( false ), + mTransform( MatrixF::Identity ) +{ + // Void. +} + +void VSoundEffectNetEvent::write( NetConnection *pConnection, BitStream *pStream ) +{ + // Void. +} + +void VSoundEffectNetEvent::pack( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid? + if ( !pStream->writeFlag( mProfile != NULL ) ) + { + return; + } + + // Profile. + pStream->writeInt( mProfile->getId() - DataBlockObjectIdFirst, DataBlockObjectIdBitSize ); + + // Position. + pStream->write( mPosition ); + + // Pitch. + pStream->write( mPitch ); + + // 3D? + if ( pStream->writeFlag( mIs3D ) ) + { + // Rotation. + SFXDescription* description = mProfile->getDescription(); + if ( pStream->writeFlag( description->mConeInsideAngle || description->mConeOutsideAngle ) ) + { + // Entire Transform. + pStream->writeAffineTransform( mTransform ); + } + else + { + // Position. + mathWrite( *pStream, mTransform.getColumn3F( 3 ) ); + } + } +} + +void VSoundEffectNetEvent::unpack( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid? + if ( !pStream->readFlag() ) + { + return; + } + + // Profile. + Sim::findObject( pStream->readInt( DataBlockObjectIdBitSize ) + DataBlockObjectIdFirst, mProfile ); + + // Position. + pStream->read( &mPosition ); + + // Pitch. + pStream->read( &mPitch ); + + // 3D? + if ( pStream->readFlag() ) + { + // Yup! + mIs3D = true; + + // Rotation? + if ( pStream->readFlag() ) + { + // Transform. + pStream->readAffineTransform( &mTransform ); + } + else + { + // Position. + Point3F pos; + mathRead( *pStream, &pos ); + mTransform.setColumn( 3, pos ); + } + } +} + +void VSoundEffectNetEvent::process( NetConnection *pConnection ) +{ + // Valid? + if ( !mProfile ) + { + return; + } + + SFXSound *source = NULL; + if ( mIs3D ) + { + // Play 3D Sound. + source = ( SFXSound* )SFX->playOnce( mProfile, &mTransform ); + } + else + { + // Play 2D Sound. + source = ( SFXSound* )SFX->playOnce( mProfile ); + } + + if ( source ) + { + // Set Position. + source->setPosition( mPosition ); + + // Set Pitch. + source->setPitch( mPitch ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VSoundEffect.h b/Engine/source/Verve/Torque3D/VSoundEffect.h new file mode 100644 index 000000000..812f8f89c --- /dev/null +++ b/Engine/source/Verve/Torque3D/VSoundEffect.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// 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_VTORQUE3D_SOUNDEFFECT_H_ +#define _VT_VTORQUE3D_SOUNDEFFECT_H_ + +#ifndef _VT_TORQUE_SOUNDEFFECT_H_ +#include "Verve/Torque/TSoundEffect.h" +#endif + +#ifndef _NETCONNECTION_H_ +#include "sim/netConnection.h" +#endif + +class VSoundEffectNetEvent : public NetEvent +{ + typedef NetEvent Parent; + +public: + + SFXProfile *mProfile; + + F32 mPosition; + F32 mPitch; + + bool mIs3D; + MatrixF mTransform; + +public: + + VSoundEffectNetEvent( void ); + + void write( NetConnection *pConnection, BitStream *pStream ); + void pack( NetConnection *pConnection, BitStream *pStream ); + void unpack( NetConnection *pConnection, BitStream *pStream ); + void process( NetConnection *pConnection ); + + DECLARE_CONOBJECT( VSoundEffectNetEvent ); +}; + +#endif // _VT_VTORQUE3D_SOUNDEFFECT_H_ \ No newline at end of file diff --git a/Engine/source/Verve/Torque3D/VSpawnSphere.cpp b/Engine/source/Verve/Torque3D/VSpawnSphere.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.cpp new file mode 100644 index 000000000..240c4d0b0 --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.cpp @@ -0,0 +1,259 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActor.h" + +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VHumanoidActor ); +//----------------------------------------------------------------------------- + +VHumanoidActor::VHumanoidActor( void ) +{ + // Void. +} + +VHumanoidActor::~VHumanoidActor( void ) +{ + // Void. +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::onNewDataBlock( pDataBlock ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::onNewDataBlock( GameBaseData *pDataBlock, bool pReload ) +{ + // Store DataBlock Reference. + mDataBlock = dynamic_cast( pDataBlock ); + + // Valid Data? + if ( !mDataBlock || !Parent::onNewDataBlock( pDataBlock, pReload ) ) + { + // Invalid Data. + return false; + } + + // Initialise the Controllers. + if ( !initAnimationController() || !initPhysicsController() ) + { + // Invalid. + return false; + } + + // Initialise the Base Animation Thread. + mAnimationController.initBaseAnimation( VHumanoidActorData::k_IdleAnimation, 0.f, 1.f ); + // Initialise the Arm Animation Thread. + mAnimationController.initArmAnimation( VHumanoidActorData::k_ArmsUpDownAnimation, 0.5f, 1.f ); + + /* + // Initialise Head Threads. + initAnimationSequence( VHumanoidActorData::k_HeadHorizontalAnimation, mHeadAnimation.HThread, 0.5f ); + initAnimationSequence( VHumanoidActorData::k_HeadVerticalAnimation, mHeadAnimation.VThread, 0.5f ); + */ + + // Valid Data. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::processTick( pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::processTick( const Move *pMove ) +{ + // Parent Call. + Parent::processTick( pMove ); + + // Update Physics. + mPhysicsController.update( TickSec, pMove ); + + // Update Container. + updateContainer(); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::interpolateTick( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::interpolateTick( F32 pDelta ) +{ + // Parent Call. + Parent::interpolateTick( pDelta ); + + // Update Physics. + mPhysicsController.interpolateTick( pDelta ); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::advanceTime( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::advanceTime( F32 pDelta ) +{ + // Parent Call. + Parent::advanceTime( pDelta ); + + // Valid Animation Controller? + if ( getAnimationController() ) + { + // Update Animations. + getAnimationController()->update( pDelta ); + } +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VHumanoidActor::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Parent Call. + U32 retMask = Parent::packUpdate( pConnection, pMask, pStream ); + + // Physics Controller? + if ( pStream->writeFlag( pMask & PhysicsMask ) ) + { + // Pack Physics. + retMask &= mPhysicsController.packUpdate( pConnection, pMask, pStream ); + } + + return retMask; +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VHumanoidActor::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Parent Call. + Parent::unpackUpdate( pConnection, pStream ); + + // Physics Controller? + if ( pStream->readFlag() ) + { + // Unpack Physics. + mPhysicsController.unpackUpdate( pConnection, pStream ); + } +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::initAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::initAnimationController( void ) +{ + // Reference Object. + mAnimationController.setObject( this ); + // Initialise. + return mAnimationController.initAnimationTable(); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::getAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +VActorAnimationController *VHumanoidActor::getAnimationController( void ) +{ + return &mAnimationController; +} + + + + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::initPhysicsController(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VHumanoidActor::initPhysicsController( void ) +{ + // Initialise. + return mPhysicsController.initPhysicsController( this ); +} + +//----------------------------------------------------------------------------- +// +// VHumanoidActor::getAnimationController(); +// +// ... +// +//----------------------------------------------------------------------------- +VActorPhysicsController *VHumanoidActor::getPhysicsController( void ) +{ + return &mPhysicsController; +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.h new file mode 100644 index 000000000..65ecb22bf --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActor.h @@ -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_VHUMANOIDACTOR_H_ +#define _VT_VHUMANOIDACTOR_H_ + +#ifndef _VT_VACTOR_H_ +#include "../VActor.h" +#endif + +#ifndef _VT_VHUMANOIDACTORDATA_H_ +#include "VHumanoidActorData.h" +#endif + +#ifndef _VT_VHUMANOIDACTORANIMATIONCONTROLLER_H_ +#include "VHumanoidActorAnimationController.h" +#endif + +#ifndef _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ +#include "VHumanoidActorPhysicsController.h" +#endif + +//----------------------------------------------------------------------------- + +class VHumanoidActor : public VActor +{ + typedef VActor Parent; + +protected: + + VHumanoidActorAnimationController mAnimationController; + VHumanoidActorPhysicsController mPhysicsController; + +public: + + VHumanoidActor( void ); + ~VHumanoidActor( void ); + + // Initialisation Methods. + + bool onNewDataBlock( GameBaseData *pDataBlock, bool pReload ); + + // Update Methods. + + void processTick( const Move *pMove ); + void interpolateTick( F32 pDelta ); + void advanceTime( F32 pDelta ); + + U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); + + // Animation Methods. + + bool initAnimationController( void ); + VActorAnimationController *getAnimationController( void ); + + // Physics Methods. + + bool initPhysicsController( void ); + VActorPhysicsController *getPhysicsController( void ); + + DECLARE_CONOBJECT( VHumanoidActor ); +}; + +#endif // _VT_VHUMANOIDACTOR_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp new file mode 100644 index 000000000..e6a1e4521 --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.cpp @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorAnimationController.h" + +//----------------------------------------------------------------------------- + +VHumanoidActorAnimationController::VHumanoidActorAnimationController( void ) +{ + // Void. +} + +VHumanoidActorAnimationController::~VHumanoidActorAnimationController( void ) +{ + // Void. +} + +//----------------------------------------------------------------------------- + +bool VHumanoidActorAnimationController::initArmAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Initialise Animation Ref. + return initAnimation( mArmAnimation, pIndex, pPosition, pTimeScale ); +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods +// +//----------------------------------------------------------------------------- + +void VHumanoidActorAnimationController::update( const F32 &pDelta ) +{ + // Parent Call. + VActorAnimationController::update( pDelta ); + + // Update the Look Thread. + if ( mArmAnimation.Thread ) + { + // Set Position. + getShapeInstance()->setPos( mArmAnimation.Thread, 0.5f ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h new file mode 100644 index 000000000..adf77fc0d --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorAnimationController.h @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORANIMATIONCONTROLLER_H_ +#define _VT_VHUMANOIDACTORANIMATIONCONTROLLER_H_ + +#ifndef _VT_VACTORANIMATIONCONTROLLER_H_ +#include "../VActorAnimationController.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VHumanoidActorAnimationController : public VActorAnimationController +{ +public: + + /* + struct sHeadAnimation + { + S32 HSequence; + TSThread *HThread; + Range HRange; + + S32 VSequence; + TSThread *VThread; + Range VRange; + + S32 FaceSequence; + TSThread *FaceThread; + + sHeadAnimation( void ) : + HSequence( -1 ), + HThread( NULL ), + HRange( 0.f, 1.f ), + VSequence( -1 ), + VThread( NULL ), + VRange( 0.f, 1.f ) + { + // Void. + } + }; + */ + +protected: + + //sHeadAnimation mHeadAnimation; + + sAnimationRef mHeadHAnimation; + sAnimationRef mHeadVAnimation; + sAnimationRef mArmAnimation; + +public: + + VHumanoidActorAnimationController( void ); + virtual ~VHumanoidActorAnimationController( void ); + + // Initialisation Methods. + + bool initArmAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + // Animation Methods. + + void update( const F32 &pDelta ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.cpp new file mode 100644 index 000000000..46a9eb448 --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.cpp @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorData.h" +#include "VHumanoidAnimationStates.h" +#include "VHumanoidPhysicsStates.h" + +//----------------------------------------------------------------------------- +// Animation Table. +//----------------------------------------------------------------------------- + +static VActorData::sAnimationSequence animSequenceLookup[] = + { + // State Based Animations. + { VHumanoidActorData::k_IdleAnimation, "root", 0.0f, ActorAnimationStateInstance( HumanoidIdle ) }, + + { VHumanoidActorData::k_WalkForwardAnimation, "walk", 0.1f, ActorAnimationStateInstance( HumanoidWalkForward ) }, + { VHumanoidActorData::k_WalkBackwardAnimation, "walkback", 0.1f, ActorAnimationStateInstance( HumanoidWalkBackward ) }, + + { VHumanoidActorData::k_RunForwardAnimation, "run", 0.1f, ActorAnimationStateInstance( HumanoidRunForward ) }, + { VHumanoidActorData::k_RunBackwardAnimation, "runback", 0.1f, ActorAnimationStateInstance( HumanoidRunBackward ) }, + + { VHumanoidActorData::k_SwimIdleAnimation, "swimroot", 1.0f, ActorAnimationStateInstance( HumanoidSwimIdle ) }, + { VHumanoidActorData::k_SwimForwardAnimation, "swim", 1.0f, ActorAnimationStateInstance( HumanoidSwimForward ) }, + { VHumanoidActorData::k_SwimBackwardAnimation, "swimback", 1.0f, ActorAnimationStateInstance( HumanoidSwimBackward ) }, + + // Support Animations. + { VHumanoidActorData::k_HeadHorizontalAnimation, "headside" }, + { VHumanoidActorData::k_HeadVerticalAnimation, "head" }, + + { VHumanoidActorData::k_ArmsUpDownAnimation, "look" }, + }; + +//----------------------------------------------------------------------------- +// Physics Table. +//----------------------------------------------------------------------------- + +static VActorData::sPhysicsState physStateLookup[] = + { + { VHumanoidActorData::k_OnGroundPhysics, 0.f, ActorPhysicsStateInstance( HumanoidOnGround ) }, + { VHumanoidActorData::k_InAirPhysics, 0.f, ActorPhysicsStateInstance( HumanoidInAir ) }, + { VHumanoidActorData::k_InWaterPhysics, 0.f, ActorPhysicsStateInstance( HumanoidInWater ) }, + }; + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_DATABLOCK_V1( VHumanoidActorData ); +//----------------------------------------------------------------------------- + +VHumanoidActorData::VHumanoidActorData( void ) +{ + // Void. +}; + +bool VHumanoidActorData::preload( bool pServer, String &pErrorStr ) +{ + if ( !Parent::preload( pServer, pErrorStr ) ) + { + return false; + } + + // Initialise Animation List. + if ( !initAnimationSequenceList( sizeof( animSequenceLookup ) / sizeof( VActorData::sAnimationSequence ), &animSequenceLookup[0] ) ) + { + Con::errorf( "VHumanoidActorData::preload() - Failed to Initialise Actor Animations." ); + return false; + } + + // Initialise Physics State List. + if ( !initPhysicsStateList( sizeof( physStateLookup ) / sizeof( VActorData::sPhysicsState ), &physStateLookup[0] ) ) + { + Con::errorf( "VHumanoidActorData::preload() - Failed to Initialise Actor Physics States." ); + return false; + } + + // Valid Load. + return true; +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.h new file mode 100644 index 000000000..0a5aa4b8c --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorData.h @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORDATA_H_ +#define _VT_VHUMANOIDACTORDATA_H_ + +#ifndef _VT_VACTORDATA_H_ +#include "../VActorData.h" +#endif + +//----------------------------------------------------------------------------- + +struct VHumanoidActorData : public VActorData +{ +private: + + typedef VActorData Parent; + friend class VHumanoidActor; + +public: + + enum eAnimationList + { + k_IdleAnimation = Parent::k_NextAnimation + 0, + + k_WalkForwardAnimation = Parent::k_NextAnimation + 1, + k_WalkBackwardAnimation = Parent::k_NextAnimation + 2, + + k_RunForwardAnimation = Parent::k_NextAnimation + 3, + k_RunBackwardAnimation = Parent::k_NextAnimation + 4, + + k_SwimIdleAnimation = Parent::k_NextAnimation + 5, + k_SwimForwardAnimation = Parent::k_NextAnimation + 6, + k_SwimBackwardAnimation = Parent::k_NextAnimation + 7, + + k_HeadHorizontalAnimation = Parent::k_NextAnimation + 8, + k_HeadVerticalAnimation = Parent::k_NextAnimation + 9, + + k_ArmsUpDownAnimation = Parent::k_NextAnimation + 10, + + k_NextAnimation = Parent::k_NextAnimation + 11, + }; + + enum ePhysicsStateList + { + k_OnGroundPhysics = Parent::k_NextPhysicsState + 0, + k_InAirPhysics = Parent::k_NextPhysicsState + 1, + k_InWaterPhysics = Parent::k_NextPhysicsState + 2, + + k_NextPhysicsState = Parent::k_NextPhysicsState + 3, + }; + +public: + + VHumanoidActorData( void ); + + virtual bool preload( bool pServer, String &pErrorStr ); + + DECLARE_CONOBJECT( VHumanoidActorData ); +}; + +#endif // _VT_VHUMANOIDACTORDATA_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp new file mode 100644 index 000000000..ae205c5cf --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.cpp @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidActorPhysicsController.h" + +//----------------------------------------------------------------------------- + +VHumanoidActorPhysicsController::VHumanoidActorPhysicsController( void ) +{ + // Void. +} + +VHumanoidActorPhysicsController::~VHumanoidActorPhysicsController( void ) +{ + // Void. +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h new file mode 100644 index 000000000..ef984210a --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidActorPhysicsController.h @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDACTORPHYSICSCONTROLLER_H_ +#define _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ + +#ifndef _VT_VACTORPHYSICSCONTROLLER_H_ +#include "../VActorPhysicsController.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VHumanoidActorPhysicsController : public VActorPhysicsController +{ +public: + + VHumanoidActorPhysicsController( void ); + ~VHumanoidActorPhysicsController( void ); +}; + +#endif // _VT_VHUMANOIDACTORPHYSICSCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp new file mode 100644 index 000000000..3ca29f7ce --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.cpp @@ -0,0 +1,213 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidAnimationStates.h" +#include "VHumanoidActor.h" + +#include "../VActorAnimationController.h" +#include "../VActorPhysicsController.h" + +//----------------------------------------------------------------------------- +// +// Implement Animation States. +// +//----------------------------------------------------------------------------- + +ImplementActorAnimationState( HumanoidIdle, VHumanoidActorData::k_IdleAnimation ); + +ImplementActorAnimationState( HumanoidWalkForward, VHumanoidActorData::k_WalkForwardAnimation ); +ImplementActorAnimationState( HumanoidWalkBackward, VHumanoidActorData::k_WalkBackwardAnimation ); + +ImplementActorAnimationState( HumanoidRunForward, VHumanoidActorData::k_RunForwardAnimation ); +ImplementActorAnimationState( HumanoidRunBackward, VHumanoidActorData::k_RunBackwardAnimation ); + +ImplementActorAnimationState( HumanoidSwimIdle, VHumanoidActorData::k_SwimIdleAnimation ); +ImplementActorAnimationState( HumanoidSwimForward, VHumanoidActorData::k_SwimForwardAnimation ); +ImplementActorAnimationState( HumanoidSwimBackward, VHumanoidActorData::k_SwimBackwardAnimation ); + + + + +//----------------------------------------------------------------------------- +// +// Execute Animation States. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// OnGround Animation States +// +//----------------------------------------------------------------------------- + +ExecuteActorAnimationState( HumanoidIdle ) +{ + // Always Enter. + return true; +} + +ExecuteActorAnimationState( HumanoidWalkForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Forward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Forward & Slow Enough? + return ( ( physicsController->getMoveState() & k_ForwardMove ) && + ( moveSpeed < pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidWalkBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Backward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Backward? + return ( ( physicsController->getMoveState() & k_BackwardMove ) && + ( moveSpeed < pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidRunForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Forward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Forward? + return ( ( physicsController->getMoveState() & k_ForwardMove ) && + ( moveSpeed >= pObject->getDataBlock()->getRunSpeed() ) ); +} + +ExecuteActorAnimationState( HumanoidRunBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_OnGroundPhysics ) + { + // Can't Run Backward. + return false; + } + + // Fetch Velocity. + const VectorF &velocity = physicsController->getVelocity(); + // Determine Move Speed. + const F32 moveSpeed = mSqrt( velocity.x * velocity.x + velocity.y * velocity.y ); + + // Moving Backward? + return ( ( physicsController->getMoveState() & k_BackwardMove ) && + ( moveSpeed >= pObject->getDataBlock()->getRunSpeed() ) ); +} + + + + +//----------------------------------------------------------------------------- +// +// InWater Animation States +// +//----------------------------------------------------------------------------- + +ExecuteActorAnimationState( HumanoidSwimIdle ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Idle? + return ( physicsController->getMoveState() & k_NullMove ); +} + +ExecuteActorAnimationState( HumanoidSwimForward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Moving Around? + return ( physicsController->getMoveState() & ( k_ForwardMove | + k_UpMove | + k_DownMove ) ); +} + +ExecuteActorAnimationState( HumanoidSwimBackward ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Water? + if ( physicsController->getPhysicsState() != VHumanoidActorData::k_InWaterPhysics ) + { + // Can't Swim. + return false; + } + + // Moving Backward? + return ( physicsController->getMoveState() & k_BackwardMove ); +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.h new file mode 100644 index 000000000..d71967d54 --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidAnimationStates.h @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDANIMATIONSTATES_H_ +#define _VT_VHUMANOIDANIMATIONSTATES_H_ + +#ifndef _VT_VACTORANIMATIONSTATES_H_ +#include "../VActorAnimationStates.h" +#endif + +//----------------------------------------------------------------------------- + +DeclareActorAnimationState( HumanoidIdle ); + +DeclareActorAnimationState( HumanoidWalkForward ); +DeclareActorAnimationState( HumanoidWalkBackward ); + +DeclareActorAnimationState( HumanoidRunForward ); +DeclareActorAnimationState( HumanoidRunBackward ); + +DeclareActorAnimationState( HumanoidSwimIdle ); +DeclareActorAnimationState( HumanoidSwimForward ); +DeclareActorAnimationState( HumanoidSwimBackward ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VHUMANOIDANIMATIONSTATES_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp b/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp new file mode 100644 index 000000000..c2b8492ba --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.cpp @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// 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 "VHumanoidPhysicsStates.h" +#include "VHumanoidActor.h" + +#include "../VActorPhysicsController.h" + +//----------------------------------------------------------------------------- +// +// Implement Physics States. +// +//----------------------------------------------------------------------------- + +ImplementActorPhysicsState( HumanoidOnGround, VHumanoidActorData::k_OnGroundPhysics ); +ImplementActorPhysicsState( HumanoidInAir, VHumanoidActorData::k_InAirPhysics ); +ImplementActorPhysicsState( HumanoidInWater, VHumanoidActorData::k_InWaterPhysics ); + + + + +//----------------------------------------------------------------------------- +// +// Execute Animation States. +// +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidOnGround ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // On the Ground? + if ( !physicsController->isOnGround() ) + { + // No. + return false; + } + + // On Ground. + return true; +} + +ProcessActorPhysicsState( HumanoidOnGround ) +{ + // Void. +} + +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidInAir ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // In the Air? + if ( !physicsController->isInAir() ) + { + // No. + return false; + } + + // In Air. + return true; +} + +ProcessActorPhysicsState( HumanoidInAir ) +{ + // Apply Gravity for the Tick. + pObject->getPhysicsController()->applyGravity( pElapsedTime ); +} + +//----------------------------------------------------------------------------- + +ExecuteActorPhysicsState( HumanoidInWater ) +{ + // Fetch Controller. + VActorPhysicsController *physicsController = pObject->getPhysicsController(); + + // Sumberged? + if ( !physicsController->isInWater() ) + { + // No. + return false; + } + + // Swimming + return true; +} + +ProcessActorPhysicsState( HumanoidInWater ) +{ + // Void. +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h b/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h new file mode 100644 index 000000000..8020d53f5 --- /dev/null +++ b/Engine/source/Verve/VActor/Humanoid/VHumanoidPhysicsStates.h @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// 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_VHUMANOIDPHYSICSSTATES_H_ +#define _VT_VHUMANOIDPHYSICSSTATES_H_ + +#ifndef _VT_VACTORPHYSICSSTATES_H_ +#include "../VActorPhysicsStates.h" +#endif + +//----------------------------------------------------------------------------- + +DeclareActorPhysicsState( HumanoidOnGround ); +DeclareActorPhysicsState( HumanoidInAir ); +DeclareActorPhysicsState( HumanoidInWater ); + +//----------------------------------------------------------------------------- + +#endif // _VT_VHUMANOIDPHYSICSSTATES_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Types/VEnumerators.h b/Engine/source/Verve/VActor/Types/VEnumerators.h new file mode 100644 index 000000000..2300330db --- /dev/null +++ b/Engine/source/Verve/VActor/Types/VEnumerators.h @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// 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_ENUMERATORS_H_ +#define _VT_ENUMERATORS_H_ + +//----------------------------------------------------------------------------- + +enum eMove +{ + k_NullMove = 0, + + k_ForwardMove = ( 1 << 0 ), + k_BackwardMove = ( 1 << 1 ), + k_LeftMove = ( 1 << 2 ), + k_RightMove = ( 1 << 3 ), + k_UpMove = ( 1 << 4 ), + k_DownMove = ( 1 << 5 ), + + k_XMove = ( k_LeftMove | k_RightMove ), + k_YMove = ( k_ForwardMove | k_BackwardMove ), + k_ZMove = ( k_UpMove | k_DownMove ), +}; + +enum eControlState +{ + k_NullControlState = 0, + + k_PathControlState, + k_GoToControlState, +}; + +#endif // _VT_ENUMERATORS_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Types/VRange.h b/Engine/source/Verve/VActor/Types/VRange.h new file mode 100644 index 000000000..bb28a27e5 --- /dev/null +++ b/Engine/source/Verve/VActor/Types/VRange.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// 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_TYPERANGE_H_ +#define _VT_TYPERANGE_H_ + +#ifndef _TORQUE_TYPES_H_ +#include "platform/types.h" +#endif + +class Range +{ +public: + + Range( void ) : + Min( 0.f ), + Max( 1.f ), + Delta( 1.f ) + { + // Void. + }; + + Range( F32 pMin, F32 pMax ) : + Min( pMin ), + Max( pMax ), + Delta( pMax - pMin ) + { + // Void. + }; + + F32 Min; + F32 Max; + F32 Delta; +}; + +#endif // _VT_TYPERANGE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/Types/VTypes.h b/Engine/source/Verve/VActor/Types/VTypes.h new file mode 100644 index 000000000..cc6c4918d --- /dev/null +++ b/Engine/source/Verve/VActor/Types/VTypes.h @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// 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_TYPES_H_ +#define _VT_TYPES_H_ + +#ifndef _VT_ENUMERATORS_H_ +#include "VEnumerators.h" +#endif + +#ifndef _VT_TYPERANGE_H_ +#include "VRange.h" +#endif + +#endif // _VT_TYPES_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActor.cpp b/Engine/source/Verve/VActor/VActor.cpp new file mode 100644 index 000000000..97dcb0257 --- /dev/null +++ b/Engine/source/Verve/VActor/VActor.cpp @@ -0,0 +1,232 @@ +//----------------------------------------------------------------------------- +// 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 "VActor.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VActor ); +//----------------------------------------------------------------------------- + +VActor::VActor( void ) : + mDataBlock( NULL ) +{ + // Void. +} + +VActor::~VActor( void ) +{ + // Void. +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::onAdd(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActor::onAdd( void ) +{ + if ( !Parent::onAdd() || !mDataBlock ) + { + return false; + } + + // Add to Scene. + addToScene(); + + if ( isServerObject() ) + { + // Script Callback. + scriptOnAdd(); + } + + return true; +} + +//----------------------------------------------------------------------------- +// +// VActor::onRemove(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onRemove( void ) +{ + // Script Callback. + scriptOnRemove(); + + // Remove From Scene. + removeFromScene(); + + Parent::onRemove(); +} + +//----------------------------------------------------------------------------- +// +// VActor::onNewDataBlock( pDataBlock ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActor::onNewDataBlock( GameBaseData *pDataBlock, bool pReload ) +{ + // Store DataBlock Reference. + mDataBlock = dynamic_cast( pDataBlock ); + + if ( !mDataBlock ) + { + // Invalid Data. + return false; + } + + // Parent Call. + return Parent::onNewDataBlock( pDataBlock, pReload ); +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::processTick( pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::processTick( const Move *pMove ) +{ + // Parent Call. + Parent::processTick( pMove ); + + // Triggers? + if ( pMove && mDamageState == Enabled ) + { + // Handle each Image Trigger. + const U32 imageCount = getMin( ShapeBase::MaxMountedImages, MaxTriggerKeys ); + for ( U32 i = 0; i < imageCount; i++ ) + { + setImageTriggerState( i, pMove->trigger[i] ); + } + } +} + +//----------------------------------------------------------------------------- +// +// VActor::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActor::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Parent Call. + return Parent::packUpdate( pConnection, pMask, pStream ); +} + +//----------------------------------------------------------------------------- +// +// VActor::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Parent Call. + Parent::unpackUpdate( pConnection, pStream ); +} + + + + +//----------------------------------------------------------------------------- +// +// Physics Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActor::setTransform( pMatrix ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::setTransform( const MatrixF &pMatrix ) +{ + Parent::setTransform( pMatrix ); + + // Server Object? + if ( isServerObject() ) + { + // Move Object. + setMaskBits( MoveMask ); + } +} + +//----------------------------------------------------------------------------- +// +// VActor::onMount( pObject, pNode ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onMount( SceneObject *pObject, S32 pNode ) +{ + // Parent Call. + Parent::onMount( pObject, pNode ); + + // Post Event. + mEventSignal.trigger( k_MountEvent ); +} + +//----------------------------------------------------------------------------- +// +// VActor::onUnmount( pObject, pNode ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActor::onUnmount( SceneObject *pObject, S32 pNode ) +{ + // Parent Call. + Parent::onUnmount( pObject, pNode ); + + // Post Event. + mEventSignal.trigger( k_UnmountEvent ); +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActor.h b/Engine/source/Verve/VActor/VActor.h new file mode 100644 index 000000000..3b0446f18 --- /dev/null +++ b/Engine/source/Verve/VActor/VActor.h @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// 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_VACTOR_H_ +#define _VT_VACTOR_H_ + +#ifndef _VT_VACTORDATA_H_ +#include "VActorData.h" +#endif + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +//----------------------------------------------------------------------------- +class VActorAnimationController; +class VActorPhysicsController; +//----------------------------------------------------------------------------- + +class VActor : public ShapeBase +{ + typedef ShapeBase Parent; + +public: + + enum eMaskBits + { + // Physics Bits. + MoveMask = Parent::NextFreeMask << 0, + PhysicsMask = ( MoveMask ), + + NextFreeMask = Parent::NextFreeMask << 1, + }; + + enum eEventType + { + k_MountEvent, + k_UnmountEvent, + }; + + typedef Signal tEventSignal; + +protected: + + VActorData *mDataBlock; + + // Event Signal. + tEventSignal mEventSignal; + +public: + + VActor( void ); + ~VActor( void ); + + // Initialisation Methods. + + bool onAdd( void ); + void onRemove( void ); + + bool onNewDataBlock( GameBaseData *pDataBlock, bool pReload ); + + // Update Methods. + + virtual void processTick( const Move *pMove ); + + virtual U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + virtual void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); + + DECLARE_CONOBJECT( VActor ); + +public: + + // Accessor Methods. + + inline VActorData *getDataBlock( void ) { return mDataBlock; }; + inline tEventSignal &getEventSignal( void ) { return mEventSignal; }; + + // Animation Methods. + + /// Get Animation Controller. + virtual VActorAnimationController *getAnimationController( void ) { return NULL; }; + + // Physics Methods. + + /// Set Transform. + virtual void setTransform( const MatrixF &pMatrix ); + + /// Get Physics Controller. + virtual VActorPhysicsController *getPhysicsController( void ) { return NULL; }; + + /// On Mount. + virtual void onMount( SceneObject *pObject, S32 pNode ); + /// On Unmount. + virtual void onUnmount( SceneObject *pObject, S32 pNode ); +}; + +#endif // _VT_VACTOR_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorAnimationController.cpp b/Engine/source/Verve/VActor/VActorAnimationController.cpp new file mode 100644 index 000000000..b740c566a --- /dev/null +++ b/Engine/source/Verve/VActor/VActorAnimationController.cpp @@ -0,0 +1,354 @@ +//----------------------------------------------------------------------------- +// 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 "VActorAnimationController.h" + +#include "VActor.h" +#include "VActorData.h" +#include "VActorAnimationStates.h" + +//----------------------------------------------------------------------------- + +VActorAnimationController::VActorAnimationController( void ) : + mObject( NULL ) +{ + // Void. +} + +VActorAnimationController::~VActorAnimationController( void ) +{ + // Clear Table. + mAnimationTable.clear(); +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimationTable(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimationTable( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No, Quit Now. + return false; + } + + // Clear the Table. + mAnimationTable.clear(); + + // Fetch Sequence List. + VActorData::tAnimationSequenceVector *sequenceList = getObject()->getDataBlock()->getAnimationList(); + + // Initialise the Animation States. + for ( VActorData::tAnimationSequenceVector::iterator itr = sequenceList->begin(); + itr != sequenceList->end(); + itr++ ) + { + // Fetch Sequence Definition. + const VActorData::sAnimationSequence &animSequence = ( *itr ); + + // Valid State? + if ( animSequence.State ) + { + // Register Animation. + mAnimationTable.registerState( animSequence.State, animSequence.Priority ); + } + } + + // Sort the Table. + mAnimationTable.sort(); + + // Valid. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimation( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimation( sAnimationRef &pAnimation, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Valid Object & Sequence? + if ( !isValidObject() || !isAnimationSequence( pIndex ) ) + { + // No, Quit Now. + return false; + } + + // Store as Current Animation. + pAnimation.Index = pIndex; + + // Initialise Thread. + return initAnimationThread( pAnimation.Thread, pAnimation.Index, pPosition, pTimeScale ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initAnimationThread( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initAnimationThread( TSThread *&pThread, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + // Valid Object & Sequence? + if ( !isValidObject() || !isAnimationSequence( pIndex ) ) + { + // No, Quit Now. + return false; + } + + // Valid Thread? + if ( !pThread ) + { + // Create a Thread. + pThread = getShapeInstance()->addThread(); + } + + // Init the Sequence. + getShapeInstance()->setSequence( pThread, getAnimationSequence( pIndex ), pPosition ); + + // Set Initial Time Scale. + getShapeInstance()->setTimeScale( pThread, pTimeScale ); + + // Valid. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::initBaseAnimation( pThread, pIndex, pPosition, pTimeScale ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::initBaseAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ) +{ + return initAnimation( mBaseAnimation, pIndex, pPosition, pTimeScale ); +} + + + + +//----------------------------------------------------------------------------- +// +// Accessor Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::isValidObject(); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::isValidObject( void ) +{ + return ( mObject != NULL && mObject->getDataBlock() != NULL ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getObject(); +// +// ... +// +//----------------------------------------------------------------------------- +VActor *VActorAnimationController::getObject( void ) +{ + return mObject; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::setObject( pObject ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorAnimationController::setObject( VActor *pObject ) +{ + // Set Object. + mObject = pObject; + + // Set Table's Reference. + mAnimationTable.setObject( pObject ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getShape(); +// +// ... +// +//----------------------------------------------------------------------------- +const TSShape *VActorAnimationController::getShape( void ) +{ + if ( !isValidObject() ) + { + return NULL; + } + + return mObject->getShape(); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getShapeInstance(); +// +// ... +// +//----------------------------------------------------------------------------- +TSShapeInstance *VActorAnimationController::getShapeInstance( void ) +{ + if ( !isValidObject() ) + { + return NULL; + } + + return mObject->getShapeInstance(); +} + + + + +//----------------------------------------------------------------------------- +// +// Animation Methods +// +//----------------------------------------------------------------------------- + +void VActorAnimationController::update( const F32 &pDelta ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No, Quit Now. + return; + } + + // Update Animation State. + mAnimationTable.execute(); + + // Advance Threads. + getShapeInstance()->advanceTime( pDelta, mBaseAnimation.Thread ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::isAnimationSequence( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorAnimationController::isAnimationSequence( const U32 &pIndex ) +{ + return ( getAnimationSequence( pIndex ) != -1 ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getAnimationSequence( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +S32 VActorAnimationController::getAnimationSequence( const U32 &pIndex ) +{ + // Valid Object? + if ( !mObject || !mObject->getDataBlock() ) + { + // No, Invalid Sequence. + return -1; + } + + // Return Sequence. + return mObject->getDataBlock()->getAnimationSequence( pIndex ); +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::getAnimation( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActorAnimationController::getAnimation( void ) +{ + // Base Animation Initialised? + if ( !mBaseAnimation.Thread ) + { + // Null. + return U32_MAX; + } + + // Return Current Animation. + return mBaseAnimation.Index; +} + +//----------------------------------------------------------------------------- +// +// VActorAnimationController::setAnimation( pIndex ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorAnimationController::setAnimation( const U32 &pIndex ) +{ + // Base Animation Initialised? + if ( !mBaseAnimation.Thread || mBaseAnimation.Index == pIndex ) + { + // Don't Update. + return; + } + + // Store as Current Animation. + mBaseAnimation.Index = pIndex; + + // Fetch the Sequence. + const S32 &sequence = getAnimationSequence( pIndex ); + + // Valid? + if ( sequence != -1 ) + { + // Play the Sequence. + getShapeInstance()->transitionToSequence( mBaseAnimation.Thread, sequence, 0.f, 0.15f, true ); + //getShapeInstance()->setSequence( mBaseAnimation.Thread, sequence, 0.f ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorAnimationController.h b/Engine/source/Verve/VActor/VActorAnimationController.h new file mode 100644 index 000000000..660248b8b --- /dev/null +++ b/Engine/source/Verve/VActor/VActorAnimationController.h @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// 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_VACTORANIMATIONCONTROLLER_H_ +#define _VT_VACTORANIMATIONCONTROLLER_H_ + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSSHAPEINSTANCE_H_ +#include "ts/tsShapeInstance.h" +#endif + +//----------------------------------------------------------------------------- + +class VActor; +class VActorStateTable; + +//----------------------------------------------------------------------------- + +class VActorAnimationController +{ +public: + + struct sAnimationRef + { + U32 Index; + TSThread *Thread; + + sAnimationRef( void ) : + Index( U32_MAX ), + Thread( NULL ) + { + // Void. + } + }; + +protected: + + VActor *mObject; + + VActorStateTable mAnimationTable; + sAnimationRef mBaseAnimation; + +public: + + VActorAnimationController( void ); + virtual ~VActorAnimationController( void ); + + // Initialisation Methods. + + bool initAnimationTable( void ); + bool initAnimation( sAnimationRef &pAnimation, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + bool initAnimationThread( TSThread *&pThread, const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + bool initBaseAnimation( const U32 &pIndex, const F32 &pPosition, const F32 &pTimeScale ); + + // Accessor Methods. + + bool isValidObject( void ); + VActor *getObject( void ); + void setObject( VActor *pObject ); + + const TSShape *getShape( void ); + TSShapeInstance *getShapeInstance( void ); + + // Animation Methods. + + virtual void update( const F32 &pDelta ); + + bool isAnimationSequence( const U32 &pIndex ); + S32 getAnimationSequence( const U32 &pIndex ); + + U32 getAnimation( void ); + void setAnimation( const U32 &pIndex ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorAnimationStates.h b/Engine/source/Verve/VActor/VActorAnimationStates.h new file mode 100644 index 000000000..f1e0c44a6 --- /dev/null +++ b/Engine/source/Verve/VActor/VActorAnimationStates.h @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// 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_VACTORANIMATIONSTATES_H_ +#define _VT_VACTORANIMATIONSTATES_H_ + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSINGLETON_H_ +#include "core/util/tSingleton.h" +#endif + +//----------------------------------------------------------------------------- + +class VActorAnimationState : public VActorState +{ +public: + + virtual void exit( VActor *pObject ) {}; +}; + +//----------------------------------------------------------------------------- + +#define DeclareActorAnimationState( name ) \ + class VActor##name##AnimationState : public VActorAnimationState \ + { \ + public: \ + void enter( VActor *pObject ); \ + bool execute( VActor *pObject ); \ + } + +#define ActorAnimationStateInstance( name ) \ + Singleton::instance() + +#define ImplementActorAnimationState( name, sequence ) \ + void VActor##name##AnimationState::enter( VActor *pObject ) { pObject->getAnimationController()->setAnimation( sequence ); } + +#define ExecuteActorAnimationState( name ) \ + bool VActor##name##AnimationState::execute( VActor *pObject ) + +//----------------------------------------------------------------------------- + +#endif // _VT_VACTORANIMATIONSTATES_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorData.cpp b/Engine/source/Verve/VActor/VActorData.cpp new file mode 100644 index 000000000..24d3b54d1 --- /dev/null +++ b/Engine/source/Verve/VActor/VActorData.cpp @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------------- +// 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 "VActorData.h" + +#include "console/consoleTypes.h" +#include "core/stream/bitStream.h" + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_DATABLOCK_V1( VActorData ); +//----------------------------------------------------------------------------- + +VActorData::VActorData( void ) : + mMaxStepHeight( 1.f ), + mRunSpeed( 6.f ), + mSubmergeCoverage( 0.25f ) +{ + // Setup Shadowing. + shadowEnable = true; + shadowSize = 256; + shadowProjectionDistance = 14.0f; + + VECTOR_SET_ASSOCIATION( mAnimationSequenceList ); + VECTOR_SET_ASSOCIATION( mPhysicsList ); +} + +VActorData::~VActorData( void ) +{ + // Void. +} + +void VActorData::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addField( "MaxStepHeight", TypeF32, Offset( mMaxStepHeight, VActorData ) ); + addField( "RunSpeed", TypeF32, Offset( mRunSpeed, VActorData ) ); + + addField( "SubmergeCoverage", TypeF32, Offset( mSubmergeCoverage, VActorData ) ); +} + +//----------------------------------------------------------------------------- + +bool VActorData::initAnimationSequenceList( const S32 &pSize, const sAnimationSequence *pTable ) +{ + if ( !mShape ) + { + // Sanity! + return false; + } + + // Clear the List. + mAnimationSequenceList.clear(); + + // Initialise each Animation Sequence. + for ( U32 i = 0; i < pSize; i++ ) + { + // Fetch Sequence Definition. + const sAnimationSequence &animSequenceDef = pTable[i]; + + // Update Animation Details. + sAnimationSequence animSequence = animSequenceDef; + // Find Sequence. + animSequence.Sequence = mShape->findSequence( animSequenceDef.Name ); + + // Store. + mAnimationSequenceList.push_back( animSequence ); + } + + return true; +} + +bool VActorData::initAnimationTransitionList( const S32 &pSize, const sAnimationTransition *pTable ) +{ + if ( !mShape ) + { + // Sanity! + return false; + } + + // Clear the List. + mAnimationTransitionList.clear(); + + // Store each Animation Transition. + for ( U32 i = 0; i < pSize; i++ ) + { + // Store. + mAnimationTransitionList.push_back( pTable[i] ); + } + + return true; +} + +bool VActorData::initPhysicsStateList( const S32 &pSize, const sPhysicsState *pTable ) +{ + // Clear the List. + mPhysicsList.clear(); + + // Initialise each Animation Sequence. + for ( U32 i = 0; i < pSize; i++ ) + { + // Store. + mPhysicsList.push_back( pTable[i] ); + } + + return true; +} + +//----------------------------------------------------------------------------- + +void VActorData::packData( BitStream *pStream ) +{ + Parent::packData( pStream ); + + pStream->write( mMaxStepHeight ); + pStream->write( mRunSpeed ); + + pStream->write( mSubmergeCoverage ); +} + +void VActorData::unpackData( BitStream *pStream ) +{ + Parent::unpackData( pStream ); + + pStream->read( &mMaxStepHeight ); + pStream->read( &mRunSpeed ); + + pStream->read( &mSubmergeCoverage ); +} + +//----------------------------------------------------------------------------- + +S32 VActorData::getAnimationSequence( const U32 &pIndex ) +{ + // Iterate over the Registered Animations. + for ( tAnimationSequenceVector::iterator itr = mAnimationSequenceList.begin(); itr != mAnimationSequenceList.end(); itr++ ) + { + // Fetch Sequence Defintion. + const sAnimationSequence &animSequence = ( *itr ); + + // Target Index? + if ( animSequence.Index == pIndex ) + { + // Return Sequence ID. + return animSequence.Sequence; + } + } + + // Invalid Sequence. + return -1; +}; \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorData.h b/Engine/source/Verve/VActor/VActorData.h new file mode 100644 index 000000000..2aaf0fc58 --- /dev/null +++ b/Engine/source/Verve/VActor/VActorData.h @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------- +// 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_VACTORDATA_H_ +#define _VT_VACTORDATA_H_ + +#ifndef _SHAPEBASE_H_ +#include "T3D/shapeBase.h" +#endif + +//----------------------------------------------------------------------------- +class VActor; +class VActorStateTable; +class VActorAnimationState; +class VActorPhysicsState; +//----------------------------------------------------------------------------- + +struct VActorData : public ShapeBaseData +{ +private: + + typedef ShapeBaseData Parent; + friend class VActor; + +public: + + // Animation Data. + + enum eAnimationList + { + k_NextAnimation = 0, + }; + + struct sAnimationSequence + { + U32 Index; + const char *Name; + F32 Priority; + + VActorAnimationState *State; + S32 Sequence; + }; + + struct sAnimationTransition + { + U32 FromIndex; + U32 ToIndex; + + F32 Duration; + + bool Ordered; + U32 Sequence; + }; + + typedef Vector tAnimationSequenceVector; + typedef Vector tAnimationTransitionVector; + + // Physics Data. + + enum ePhysicsStateList + { + k_NextPhysicsState = 0, + }; + + struct sPhysicsState + { + U32 Index; + F32 Priority; + + VActorPhysicsState *State; + }; + typedef Vector tPhysicsStateVector; + +protected: + + tAnimationSequenceVector mAnimationSequenceList; + tAnimationTransitionVector mAnimationTransitionList; + tPhysicsStateVector mPhysicsList; + + F32 mMaxStepHeight; + F32 mRunSpeed; + + F32 mSubmergeCoverage; + +public: + + VActorData( void ); + ~VActorData( void ); + + static void initPersistFields( void ); + + virtual bool initAnimationSequenceList( const S32 &pSize, const sAnimationSequence *pTable ); + virtual bool initAnimationTransitionList( const S32 &pSize, const sAnimationTransition *pTable ); + virtual bool initPhysicsStateList( const S32 &pSize, const sPhysicsState *pTable ); + + virtual void packData( BitStream *pStream ); + virtual void unpackData( BitStream *pStream ); + + DECLARE_CONOBJECT( VActorData ); + +public: + + tAnimationSequenceVector *getAnimationList( void ) { return &mAnimationSequenceList; }; + S32 getAnimationSequence( const U32 &pIndex ); + + tPhysicsStateVector *getPhysicsStateList( void ) { return &mPhysicsList; }; + + inline const F32 &getMaxStepHeight( void ) const { return mMaxStepHeight; }; + inline const F32 &getRunSpeed( void ) const { return mRunSpeed; }; + inline const F32 &getSumbergeCoverage( void ) const { return mSubmergeCoverage; }; +}; + +#endif // _VT_VACTORDATA_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorPhysicsController.cpp b/Engine/source/Verve/VActor/VActorPhysicsController.cpp new file mode 100644 index 000000000..5e3332d59 --- /dev/null +++ b/Engine/source/Verve/VActor/VActorPhysicsController.cpp @@ -0,0 +1,1277 @@ +//----------------------------------------------------------------------------- +// 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 "VActorPhysicsController.h" + +#include "VActor.h" +#include "VActorData.h" +#include "VActorPhysicsStates.h" + +#include "Verve/VPath/VPath.h" + +#include "collision/clippedPolyList.h" +#include "collision/earlyOutPolyList.h" +#include "collision/extrudedPolyList.h" +#include "core/stream/bitStream.h" +#include "environment/waterObject.h" + +//----------------------------------------------------------------------------- + +static const U32 sGroundCollisionMask = ( StaticObjectType | StaticShapeObjectType | TerrainObjectType ); +static const U32 sMoveCollisionMask = ( PlayerObjectType | VehicleObjectType ); +static const U32 sCollisionMask = ( sGroundCollisionMask | sMoveCollisionMask ); + +//----------------------------------------------------------------------------- + +VActorPhysicsController::VActorPhysicsController( void ) : + mObject( NULL ), + mMountedPath( NULL ), + mPhysicsState( 0 ), + mControlState( k_NullControlState ), + mMoveState( k_NullMove ), + mVelocity( VectorF::Zero ), + mGravity( 0.f, 0.f, -9.8f ) +{ + // Void. +} + +VActorPhysicsController::~VActorPhysicsController( void ) +{ + // Clear Object. + clearObject(); +} + + + + +//----------------------------------------------------------------------------- +// +// Initialisation Methods. +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::initPhysicsController(); +// +// Initialise the physics table and setup the interface between the Controller +// and the reference object. +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::initPhysicsController( VActor *pObject ) +{ + // Valid Object? + if ( !pObject ) + { + // Assert & Quit. + AssertFatal( false, "VActorPhysicsController::initPhysicsController() - Invalid Object Specified." ); + return false; + } + + // Set Object. + mObject = pObject; + // Register for Actor Events. + mObject->getEventSignal().notify( this, &VActorPhysicsController::onActorEvent ); + + // Set Table's Reference. + mPhysicsStateTable.setObject( pObject ); + + // Init the Convex Box. + mConvex.init( pObject ); + + // Reset Interp. + mInterpController.resetDelta( pObject->getTransform() ); + + // Validate. + return initPhysicsTable(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::initPhysicsTable(); +// +// Register the available physics states which this controller may utilize. +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::initPhysicsTable( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No, Quit Now. + return false; + } + + // Clear the Table. + mPhysicsStateTable.clear(); + + // Fetch Sequence List. + VActorData::tPhysicsStateVector *stateList = getObjectDataBlock()->getPhysicsStateList(); + + // Initialise the Physics States. + for ( VActorData::tPhysicsStateVector::iterator itr = stateList->begin(); + itr != stateList->end(); + itr++ ) + { + // Fetch Sequence Definition. + const VActorData::sPhysicsState &physState = ( *itr ); + + // Valid State? + if ( physState.State ) + { + // Register State. + mPhysicsStateTable.registerState( physState.State, physState.Priority ); + } + } + + // Sort the Table. + mPhysicsStateTable.sort(); + + // Valid. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// Accessor Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isValidObject(); +// +// Do we have a valid reference object? +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::isValidObject( void ) +{ + return ( mObject && mObject->getDataBlock() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getObject(); +// +// Return the reference object. +// +//----------------------------------------------------------------------------- +VActor *VActorPhysicsController::getObject( void ) +{ + return mObject; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getObjectDataBlock(); +// +// Get the Actor Data for the reference object. +// +//----------------------------------------------------------------------------- +VActorData *VActorPhysicsController::getObjectDataBlock( void ) +{ + // Valid Object? + if ( !mObject ) + { + // No. + return NULL; + } + + // Return DataBlock. + return mObject->getDataBlock(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearObject(); +// +// Clear the reference object. Note that this should *never* be called outside +// of the controller's destructor! +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearObject( void ) +{ + // Valid Object? + if ( !mObject ) + { + // No. + return; + } + + // Clear Notify. + mObject->getEventSignal().remove( this, &VActorPhysicsController::onActorEvent ); + + // Clear Object. + mObject = NULL; + + // Clear Table. + mPhysicsStateTable.setObject( NULL ); + mPhysicsStateTable.clear(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getControlState(); +// +// Get the current Control State. +// +//----------------------------------------------------------------------------- +const U32 VActorPhysicsController::getControlState( void ) +{ + return mControlState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearControlState( pControlState ); +// +// Clear the Control State of a particular mask. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearControlState( const U32 &pControlState ) +{ + mControlState &= ( ~pControlState ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setControlState( pControlState ); +// +// Set the Control State. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setControlState( const U32 &pControlState ) +{ + mControlState = pControlState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isMoving(); +// +// Is the Actor currently Moving? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isMoving( void ) +{ + return ( !mIsZero( getVelocity().lenSquared() ) ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isMoving( pMoveState ); +// +// Is the Actor currently moving with the desired state? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isMoving( const U32 &pMoveState ) +{ + // Moving? + return ( ( getMoveState() & pMoveState ) && isMoving() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getMoveState(); +// +// Get the current Move State. +// +//----------------------------------------------------------------------------- +const U32 VActorPhysicsController::getMoveState( void ) +{ + // Return Move State. + return mMoveState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearMoveState( pMoveState ); +// +// Clear the Move State of a particular mask. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearMoveState( const U32 &pMoveState ) +{ + // Set Move State. + mMoveState &= ( ~pMoveState ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setMoveState( pMoveState ); +// +// Set the Move State. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setMoveState( const U32 &pMoveState ) +{ + // Set Move State. + mMoveState = pMoveState; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isPathing(); +// +// Is the Actor Pathing? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isPathing( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return false; + } + + return ( mMountedPath != NULL ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getPathObject(); +// +// Get the Path Object the Actor is mounted to. +// +//----------------------------------------------------------------------------- +VPath *VActorPhysicsController::getPathObject( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return NULL; + } + + return mMountedPath; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isOnGround(); +// +// Is the Actor On the Ground? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isOnGround( void ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No. + return false; + } + + // On Ground? + return ( mOnGround && mGroundObject && !isInWater() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isInAir(); +// +// Is the Actor in the Air? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isInAir( void ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No. + return false; + } + + // In Air? + return ( !isOnGround() && !isInWater() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::isInWater(); +// +// Is the Actor in the Water? +// +//----------------------------------------------------------------------------- +const bool VActorPhysicsController::isInWater( void ) +{ + // Valid Objects? + if ( !isValidObject() || !getWaterObject() ) + { + // No. + return false; + } + + // Submerged? + return ( ( mObject->getWaterCoverage() + POINT_EPSILON ) >= mObject->getDataBlock()->getSumbergeCoverage() ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getWaterObject(); +// +// Get the current Water Object the Actor is in. +// +//----------------------------------------------------------------------------- +WaterObject *VActorPhysicsController::getWaterObject( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return NULL; + } + + return mObject->getCurrentWaterObject(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getTransform(); +// +// Get the Actor's Transform. +// +//----------------------------------------------------------------------------- +MatrixF VActorPhysicsController::getTransform( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return MatrixF::Identity; + } + + // Return Transform. + return mObject->getTransform(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setTransform( pTransform ); +// +// Set the Actor's Transform. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setTransform( const MatrixF &pTransform ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return; + } + + // Apply Transform. + mObject->setTransform( pTransform ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getPosition(); +// +// Get the Actor's Position. +// +//----------------------------------------------------------------------------- +Point3F VActorPhysicsController::getPosition( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return Point3F::Zero; + } + + // Return Position. + return mObject->getPosition(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setPosition( pPosition ); +// +// Set the Actor's Position. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setPosition( const Point3F &pPosition ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return; + } + + // Apply Position. + mObject->setPosition( pPosition ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::applyGravity( pElapsedTime ); +// +// Apply gravity for the elapsed period. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::applyGravity( const F32 &pElapsedTime ) +{ + // Get Velocity. + VectorF velocity = getVelocity(); + // Add Tick Gravity. + velocity += getGravity() * pElapsedTime; + // Apply. + setVelocity( velocity ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::getVelocity(); +// +// Get the Actor's Velocity. +// +//----------------------------------------------------------------------------- +VectorF VActorPhysicsController::getVelocity( void ) +{ + // Valid Object? + if ( !isValidObject() ) + { + // No. + return VectorF::Zero; + } + + // Return Velocity. + return mVelocity; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::setVelocity( pVelocity ); +// +// Set the Actor's Velocity. +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::setVelocity( const VectorF &pVelocity ) +{ + // Set Velocity. + mVelocity = pVelocity; +} + + + + +//----------------------------------------------------------------------------- +// +// Physics Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::update( pDelta, pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::update( const F32 &pDelta, const Move *pMove ) +{ + // Valid Objects? + if ( !isValidObject() ) + { + // No, Quit Now. + return; + } + + // Pre-tick Update. + preTickUpdate( pDelta ); + + // Integrate Tick Update. + integrateTickUpdate( pDelta, pMove ); + + // Post-tick Update. + postTickUpdate( pDelta ); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::preTickUpdate( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::preTickUpdate( const F32 &pDelta ) +{ + // Pop Delta. + mInterpController.popDelta(); + + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::preTickUpdate() - Invalid Path State." ); + + // Fetch Mount Velocity. + const VectorF &mountVelocity = mMountedPath->getMountVelocity( mObject->getMountNode() ); + + // Use X & Y Velocity. + VectorF velocity = getVelocity(); + velocity.x = mountVelocity.x; + velocity.y = mountVelocity.y; + + // Apply Updates. + setVelocity( velocity ); + + } break; + } + + // Update Move State. + updateMoveState(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::integrateTickUpdate( pDelta, pMove ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::integrateTickUpdate( const F32 &pDelta, const Move *pMove ) +{ + // Update Collision Set. + updateWorkingCollisionSet(); + // Ground Ground Status. + updateGroundStatus(); + + // Execute Physics Table. + VActorPhysicsState *physState = dynamic_cast( mPhysicsStateTable.execute() ); + // Assert. + AssertFatal( physState, "VActorPhysicsController::update() - Invalid Physics State in the Table." ); + + // Process the State. + physState->processTick( mObject, pDelta, pMove ); + + // Process Collisions. + processCollisions(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::postTickUpdate( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::postTickUpdate( const F32 &pDelta ) +{ + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." ); + + // Fetch Mount Transform. + MatrixF transform; + mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform ); + // Fetch Mount Position. + const Point3F &mountPosition = transform.getPosition(); + + // Update X & Y Position. + Point3F position = getPosition(); + position.x = mountPosition.x; + position.y = mountPosition.y; + + // In Water? + bool underWater = false; + if ( isInWater() ) + { + // Fetch Body of Water. + WaterObject *waterBody = getWaterObject(); + + // Fetch Surface Position. + const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) ); + // Fetch Submersion Position. + const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() ); + + // Choose a Z Value. + // Note: This is done so that the Actor will either path under the + // water, or it will swim along the water's surface. + position.z = getMin( mountPosition.z, sumbersionPosition ); + + // Under Water? + underWater = ( position.z < sumbersionPosition ); + } + + // Under Water? + if ( !underWater ) + { + // Fetch Y Column. + VectorF forwardVector; + transform.getColumn( 1, &forwardVector ); + + // Determine Angle. + const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y ); + + // Reset Transform. + transform.set( EulerF( 0.f, 0.f, angle ) ); + + // In the air? + if ( !isOnGround() ) + { + // Apply z-axis force. + position.z += ( getVelocity().z * pDelta ); + } + } + + // Update Transform. + transform.setPosition( position ); + + // Apply Update. + setTransform( transform ); + + } break; + + default : + { + // Fetch Transform. + MatrixF transform = getTransform(); + + // Determine the Post-Tick Position. + Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta ); + // Set the Post Tick Position. + transform.setPosition( postTickPosition ); + + // Apply the Transform. + setTransform( transform ); + + } break; + } + + // Push Delta. + mInterpController.pushDelta( getTransform() ); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::interpolateTick( pDelta ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::interpolateTick( const F32 &pDelta ) +{ + // Fetch Interpolated Transform. + const MatrixF transform = mInterpController.getTransform( pDelta ); + // Apply Render Transform. + mObject->setRenderTransform( transform ); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateWorkingCollisionSet(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateWorkingCollisionSet() +{ + // Contstruct Bounding Box. + const Box3F boundingBox = mConvex.getBoundingBox( getTransform(), mObject->getScale() ); + + // Determine Sweep Vector. + const VectorF sweepVector = ( getVelocity() * TickSec ); + + // Construct Swept Box. + Box3F sweptBox = boundingBox; + sweptBox.minExtents.setMin( boundingBox.minExtents + sweepVector ); + sweptBox.maxExtents.setMax( boundingBox.maxExtents + sweepVector ); + + // Update Collision List. + mObject->disableCollision(); + mConvex.updateWorkingList( sweptBox, sCollisionMask ); + mObject->enableCollision(); +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateMoveState(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateMoveState( void ) +{ + switch( mControlState ) + { + case k_PathControlState : + { + AssertFatal( isPathing(), "VActorPhysicsController::updateMoveState() - Invalid Path State." ); + + // Update Move State. + VPathObject *pathObject = mMountedPath->getPathObject( mObject ); + if ( !pathObject->isActive() ) + { + // Idle. + setMoveState( k_NullMove ); + } + else + { + // Set Movement Direction. + setMoveState( ( pathObject->isForward() ) ? k_ForwardMove : k_BackwardMove ); + } + + } break; + + default : + { + // Set Idle. + setMoveState( k_NullMove ); + + } break; + } +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::clearGroundStatus(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::clearGroundStatus( void ) +{ + // Clear Grounding. + mOnGround = false; + mGroundObject = NULL; + mGroundNormal.zero(); +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::updateGroundStatus(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::updateGroundStatus( void ) +{ + // Submerged? + if ( isInWater() ) + { + // Clear Ground Status. + clearGroundStatus(); + return; + } + + // Check for Grounding. + SceneObject *groundObject; + Point3F groundPoint; + VectorF groundNormal; + if ( !findGroundContact( groundObject, groundPoint, groundNormal ) ) + { + // Clear Ground Status. + clearGroundStatus(); + return; + } + + // Tidy up the Contact Position. + // Note: This basically "clamps" the Actor to the surface of the ground + // object. + const Point3F objPosition = getPosition(); + setPosition( objPosition - Point3F( 0.f, 0.f, ( objPosition.z - groundPoint.z ) ) ); + + // Clear Z-Axis Velocity. + mVelocity.z = 0.f; + + // Store Details. + mOnGround = true; + mGroundObject = groundObject; + mGroundNormal = groundNormal; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::findGroundContact( pContactObject, pContactPoint, pContactNormal ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal ) +{ + // Setup Collision List. + static CollisionList sCollisionList; + sCollisionList.clear(); + + static Polyhedron sBoxPolyhedron; + static ExtrudedPolyList sExtrudedPolyList; + + // Fetch Max Step Height. + const F32 stepHeight = mObject->getDataBlock()->getMaxStepHeight(); + + // Determine Positions. + const Point3F preTickPosition = getPosition() + Point3F( 0.f, 0.f, stepHeight ); + const VectorF preTickVelocity = getVelocity() + mGravity - VectorF( 0.f, 0.f, stepHeight / TickSec ); + const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec ); + const VectorF postTickVector = postTickPosition - preTickPosition; + + // Construct Scaled Box. + Box3F scaledBox = mObject->getObjBox(); + scaledBox.minExtents.convolve( mObject->getScale() ); + scaledBox.maxExtents.convolve( mObject->getScale() ); + + // Setup Polyherdron. + MatrixF collisionMatrix( true ); + collisionMatrix.setPosition( preTickPosition ); + sBoxPolyhedron.buildBox( collisionMatrix, scaledBox ); + + // Setup Extruded Poly List. + sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector ); + sExtrudedPolyList.setVelocity( preTickVelocity ); + sExtrudedPolyList.setCollisionList( &sCollisionList ); + + // Construct World Convex Box & Adjust for Sweep. + Box3F convexBox = scaledBox; + getTransform().mul( convexBox ); + convexBox.minExtents += postTickVector; + convexBox.maxExtents += postTickVector; + + // Build List of Contacts. + CollisionWorkingList &rList = mConvex.getWorkingList(); + for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext ) + { + Convex *convexShape = pList->mConvex; + + // Ground Object? + if ( !( convexShape->getObject()->getTypeMask() & sGroundCollisionMask ) ) + { + // No, Continue. + continue; + } + + // Overlap? + const Box3F &collisionConvexBox = convexShape->getBoundingBox(); + if ( convexBox.isOverlapped( collisionConvexBox ) ) + { + // Build Contact Information. + convexShape->getPolyList( &sExtrudedPolyList ); + } + } + + // Valid Collision? + if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() < 0.f || sCollisionList.getTime() > 1.f ) + { + // No, Quit Now. + return false; + } + + // Use First Collision. + Collision *collision = &sCollisionList[0]; + + // More Collisions? + if ( sCollisionList.getCount() > 1 ) + { + // Check for Better Contacts. + for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ ) + { + if ( cp->faceDot > collision->faceDot ) + { + // Use this One. + collision = cp; + } + } + } + + // Set Properties. + pContactObject = collision->object; + //pContactPoint = collision->point; + pContactPoint = ( preTickPosition + ( preTickVelocity * TickSec * sCollisionList.getTime() ) ); + pContactNormal = collision->normal; + + // Valid Contact. + return true; +} + + + + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::processCollisions(); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::processCollisions( void ) +{ + // Find & Resolve Collisions. + Collision *collision; + if ( findCollision( collision ) ) + { + // Solve the Collision. + solveCollision( collision ); + } +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::findCollision( pCollision ); +// +// ... +// +//----------------------------------------------------------------------------- +bool VActorPhysicsController::findCollision( Collision *&pCollision ) +{ + // Setup Collision List. + static CollisionList sCollisionList; + sCollisionList.clear(); + + static Polyhedron sBoxPolyhedron; + static ExtrudedPolyList sExtrudedPolyList; + + // Determine Positions. + const Point3F preTickPosition = getPosition(); + const VectorF preTickVelocity = getVelocity(); + const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec ); + const VectorF postTickVector = postTickPosition - preTickPosition; + + // Construct Scaled Box. + Box3F scaledBox = mObject->getObjBox(); + scaledBox.minExtents.convolve( mObject->getScale() ); + scaledBox.maxExtents.convolve( mObject->getScale() ); + + // Setup Polyherdron. + MatrixF collisionMatrix( true ); + collisionMatrix.setPosition( preTickPosition ); + sBoxPolyhedron.buildBox( collisionMatrix, scaledBox ); + + // Setup Extruded Poly List. + sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector ); + sExtrudedPolyList.setVelocity( preTickVelocity ); + sExtrudedPolyList.setCollisionList( &sCollisionList ); + + // Construct World Convex Box & Adjust for Sweep. + Box3F convexBox = scaledBox; + getTransform().mul( convexBox ); + convexBox.minExtents += postTickVector; + convexBox.maxExtents += postTickVector; + + // Determine the Collision Mask. + const U32 collisionMask = ( isInWater() ) ? ( sGroundCollisionMask | sMoveCollisionMask ) : sMoveCollisionMask; + + // Build List of Contacts. + CollisionWorkingList &rList = mConvex.getWorkingList(); + for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext ) + { + Convex *convexShape = pList->mConvex; + + // Valid Collision Target? + if ( !( convexShape->getObject()->getTypeMask() & collisionMask ) ) + { + // No, Continue. + continue; + } + + // Overlap? + const Box3F &collisionConvexBox = convexShape->getBoundingBox(); + if ( convexBox.isOverlapped( collisionConvexBox ) ) + { + // Build Contact Information. + convexShape->getPolyList( &sExtrudedPolyList ); + } + } + + // Valid Collision? + if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() > 1.f ) + { + // No, Quit Now. + return false; + } + + // Use First Collision. + Collision *collision = &sCollisionList[0]; + + // More Collisions? + if ( sCollisionList.getCount() > 1 ) + { + // Check for Better Contacts. + for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ ) + { + if ( cp->faceDot > collision->faceDot ) + { + // Use this One. + collision = cp; + } + } + } + + // Store Reference. + pCollision = collision; + + // Valid Collision. + return true; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::solveCollision( pCollision ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::solveCollision( Collision *pCollision ) +{ + // Fetch Velocity. + VectorF velocity = getVelocity(); + // Resolve Collision. + velocity -= ( pCollision->normal * mDot( getVelocity(), pCollision->normal ) ); + + // Pathing? + if ( isPathing() ) + { + // Clear X & Y Velocity Adjustments. + // Note: This means that any collisions made during pathing will not + // be solved, unless they only affect Z position. It is up to the + // user to construct Paths which avoid obsticles! + velocity.x = velocity.y = 0.f; + } + + // Set Velocity. + setVelocity( velocity ); +} + + + + +//----------------------------------------------------------------------------- +// +// Update Methods +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::onActorEvent( pEvent ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::onActorEvent( const VActor::eEventType &pEvent ) +{ + switch( pEvent ) + { + case VActor::k_MountEvent : + { + // Set Control State. + setControlState( k_PathControlState ); + + // Store Path. + mMountedPath = dynamic_cast( mObject->getObjectMount() ); + + } break; + + case VActor::k_UnmountEvent : + { + // Clear Control State. + clearControlState( k_PathControlState ); + + // Clear Path. + mMountedPath = NULL; + // Clear X & Y Velocity. + setVelocity( VectorF( 0.f, 0.f, mVelocity.z ) ); + + } break; + } +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::packUpdate( pConnection, pMask, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +U32 VActorPhysicsController::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + // Return Mask. + U32 retMask = 0; + + // Valid Object? + if ( !pStream->writeFlag( isValidObject() ) ) + { + return retMask; + } + + // Write Move? + const bool writeMove = ( pMask & VActor::MoveMask ) && !isPathing(); + if ( pStream->writeFlag( writeMove ) ) + { + // Write Position. + const Point3F &position = getPosition(); + pStream->write( position.x ); + pStream->write( position.y ); + pStream->write( position.z ); + } + + return retMask; +} + +//----------------------------------------------------------------------------- +// +// VActorPhysicsController::unpackUpdate( pConnection, pStream ); +// +// ... +// +//----------------------------------------------------------------------------- +void VActorPhysicsController::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + // Valid Object? + if ( !pStream->readFlag() ) + { + return; + } + + // Read Move? + if ( pStream->readFlag() ) + { + // Read Position. + Point3F position; + pStream->read( &position.x ); + pStream->read( &position.y ); + pStream->read( &position.z ); + + // Apply. + setPosition( position ); + } +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorPhysicsController.h b/Engine/source/Verve/VActor/VActorPhysicsController.h new file mode 100644 index 000000000..3e4a2912e --- /dev/null +++ b/Engine/source/Verve/VActor/VActorPhysicsController.h @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------- +// 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_VACTORPHYSICSCONTROLLER_H_ +#define _VT_VACTORPHYSICSCONTROLLER_H_ + +#ifndef _VT_TYPES_H_ +#include "Types/VTypes.h" +#endif + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _VT_VACTOR_H_ +#include "VActor.h" +#endif + +#ifndef _VT_VINTERPCONTROLLER_H_ +#include "VInterpController.h" +#endif + +#ifndef _BOXCONVEX_H_ +#include "collision/boxConvex.h" +#endif + +//----------------------------------------------------------------------------- + +class VPath; + +//----------------------------------------------------------------------------- + +class VActorPhysicsController +{ +protected: + + SimObjectPtr mObject; + SimObjectPtr mMountedPath; + + VActorStateTable mPhysicsStateTable; + + VInterpController mInterpController; + + U32 mPhysicsState; + U32 mControlState; + U32 mMoveState; + + OrthoBoxConvex mConvex; + + VectorF mGravity; + VectorF mVelocity; + + bool mOnGround; + SimObjectPtr mGroundObject; + VectorF mGroundNormal; + +public: + + VActorPhysicsController( void ); + virtual ~VActorPhysicsController( void ); + + // Initialisation Methods. + + bool initPhysicsController( VActor *pObject ); + bool initPhysicsTable( void ); + + // Accessor Methods. + + bool isValidObject( void ); + VActor *getObject( void ); + VActorData *getObjectDataBlock( void ); + void clearObject( void ); + + virtual const U32 getControlState( void ); + virtual void clearControlState( const U32 &pControlState ); + virtual void setControlState( const U32 &pControlState ); + + virtual const bool isMoving( void ); + virtual const bool isMoving( const U32 &pMoveState ); + virtual const U32 getMoveState( void ); + virtual void clearMoveState( const U32 &pMoveState ); + virtual void setMoveState( const U32 &pMoveState ); + + virtual const bool isPathing( void ); + virtual VPath *getPathObject( void ); + + virtual const bool isInWater( void ); + virtual WaterObject *getWaterObject( void ); + + virtual const bool isOnGround( void ); + virtual const bool isInAir( void ); + inline SceneObject *getGroundObject( void ) { return mGroundObject; }; + inline const VectorF &getGroundNormal( void ) { return mGroundNormal; }; + + inline const U32 &getPhysicsState( void ) { return mPhysicsState; }; + inline void setPhysicsState( const U32 &pState ) { mPhysicsState = pState; }; + + virtual MatrixF getTransform( void ); + virtual void setTransform( const MatrixF &pTransform ); + + virtual Point3F getPosition( void ); + virtual void setPosition( const Point3F &pPosition ); + + inline VectorF getGravity( void ) { return mGravity; }; + inline void setGravity( VectorF &pGravity ) { mGravity = pGravity; }; + virtual void applyGravity( const F32 &pElapsedTime ); + + virtual VectorF getVelocity( void ); + virtual void setVelocity( const VectorF &pVelocity ); + + // Physics Methods. + + void update( const F32 &pDelta, const Move *pMove ); + + virtual void preTickUpdate( const F32 &pDelta ); + virtual void integrateTickUpdate( const F32 &pDelta, const Move *pMove ); + virtual void postTickUpdate( const F32 &pDelta ); + + void interpolateTick( const F32 &pDelta ); + + void updateWorkingCollisionSet( void ); + + void updateMoveState( void ); + + void clearGroundStatus( void ); + void updateGroundStatus( void ); + bool findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal ); + + void processCollisions( void ); + bool findCollision( Collision *&pCollision ); + void solveCollision( Collision *pCollision ); + + // Updates Methods. + + void onActorEvent( const VActor::eEventType &pEvent ); + + U32 packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ); + void unpackUpdate( NetConnection *pConnection, BitStream *pStream ); +}; + +#endif // _VT_VACTORANIMATIONCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorPhysicsStates.h b/Engine/source/Verve/VActor/VActorPhysicsStates.h new file mode 100644 index 000000000..24585b07a --- /dev/null +++ b/Engine/source/Verve/VActor/VActorPhysicsStates.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// 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_VACTORPHYSICSSTATES_H_ +#define _VT_VACTORPHYSICSSTATES_H_ + +#ifndef _VT_VACTORSTATETABLE_H_ +#include "VActorStateTable.h" +#endif + +#ifndef _TSINGLETON_H_ +#include "core/util/tSingleton.h" +#endif + +//----------------------------------------------------------------------------- +struct Move; +//----------------------------------------------------------------------------- + +class VActorPhysicsState : public VActorState +{ +public: + + virtual void exit( VActor *pObject ) {}; + + virtual void processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ) = 0; +}; + +//----------------------------------------------------------------------------- + +#define DeclareActorPhysicsState( name ) \ + class VActor##name##PhysicsState : public VActorPhysicsState \ + { \ + public: \ + void enter( VActor *pObject ); \ + bool execute( VActor *pObject ); \ + void processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ); \ + } + +#define ActorPhysicsStateInstance( name ) \ + Singleton::instance() + +#define ImplementActorPhysicsState( name, state ) \ + void VActor##name##PhysicsState::enter( VActor *pObject ) { pObject->getPhysicsController()->setPhysicsState( state ); } + +#define ExecuteActorPhysicsState( name ) \ + bool VActor##name##PhysicsState::execute( VActor *pObject ) + +#define ProcessActorPhysicsState( name ) \ + void VActor##name##PhysicsState::processTick( VActor *pObject, const F32 &pElapsedTime, const Move *pMove ) + +//----------------------------------------------------------------------------- + +#endif // _VT_VACTORPHYSICSSTATES_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorStateTable.cpp b/Engine/source/Verve/VActor/VActorStateTable.cpp new file mode 100644 index 000000000..a2c065ce7 --- /dev/null +++ b/Engine/source/Verve/VActor/VActorStateTable.cpp @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// 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 "VActorStateTable.h" +#include "VActor.h" + +//----------------------------------------------------------------------------- + +bool VActorStateTable::isRegisteredState( VActorState *pState ) +{ + for ( tStateConstIterator itr = mStateVector.begin(); itr != mStateVector.end(); itr++ ) + { + // Target State? + if ( ( *itr ).State == pState ) + { + // Yes. + return true; + } + } + + // No. + return false; +} + +void VActorStateTable::clear( void ) +{ + // Clear the States. + mLastState = NULL; + mCurrentState = NULL; + + // Clear the State Vector. + mStateVector.clear(); +}; + +void VActorStateTable::sort( void ) +{ + mStateVector.sort( &_onSortCallback ); +} + +void VActorStateTable::registerState( VActorState *pState, const F32 &pPriority ) +{ + // Already a State? + if ( isRegisteredState( pState ) ) + { + // Exit Now. + return; + } + + // Create the Reference. + sStateRef entry; + entry.State = pState; + entry.Priority = pPriority; + + // Push to Back. + mStateVector.push_back( entry ); + + // Set Current? + if ( mStateVector.size() == 1 ) + { + // Set State. + setState( pState ); + } +}; + +void VActorStateTable::setState( VActorState *pState ) +{ + if ( !mObject || !pState || pState == mCurrentState ) + { + // Invalid. + return; + } + + if ( mCurrentState ) + { + // Exit. + exit(); + + // Exit the Old State. + mCurrentState->exit( mObject ); + } + + // Update States. + mLastState = mCurrentState; + mCurrentState = pState; + + // Enter. + enter(); + + // Enter the New State. + pState->enter( mObject ); +}; + +VActorState *VActorStateTable::execute( void ) +{ + if ( !mObject || !mCurrentState ) + { + // Invalid. + return NULL; + } + + for ( tStateConstIterator itr = mStateVector.begin(); itr != mStateVector.end(); itr++ ) + { + // Fetch State Reference. + const sStateRef &stateRef = ( *itr ); + + // Enter State? + if ( stateRef.State->execute( mObject ) ) + { + // Set the State. + setState( stateRef.State ); + + // Return. + return stateRef.State; + } + } + + // No Valid Entries, Ouch! + Con::warnf( "VActorStateTable::execute() - No Valid Entries." ); + + // Return Current State. + return mCurrentState; +} + +S32 QSORT_CALLBACK VActorStateTable::_onSortCallback( const VActorStateTable::sStateRef *pA, const VActorStateTable::sStateRef *pB ) +{ + if ( pB->Priority > pA->Priority ) + { + return 1; + } + else if ( pB->Priority < pA->Priority ) + { + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VActorStateTable.h b/Engine/source/Verve/VActor/VActorStateTable.h new file mode 100644 index 000000000..6a514a2fc --- /dev/null +++ b/Engine/source/Verve/VActor/VActorStateTable.h @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------------- +// 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_VACTORSTATETABLE_H_ +#define _VT_VACTORSTATETABLE_H_ + +#ifndef _TVECTOR_H +#include "core/util/tVector.h" +#endif + +//----------------------------------------------------------------------------- +class VActor; +class VActorStateTable; +//----------------------------------------------------------------------------- + +class VActorState +{ +public: + + VActorState( void ) { }; + virtual ~VActorState( void ) { }; + + virtual void enter( VActor *pObject ) = 0; + virtual bool execute( VActor *pObject ) = 0; + virtual void exit( VActor *pObject ) = 0; +}; + +//----------------------------------------------------------------------------- + +class VActorStateTable +{ +public: + + struct sStateRef + { + VActorState *State; + F32 Priority; + }; + + typedef Vector tStateVector; + typedef tStateVector::iterator tStateIterator; + typedef tStateVector::const_iterator tStateConstIterator; + +protected: + + tStateVector mStateVector; + + VActor *mObject; + + VActorState *mLastState; + VActorState *mCurrentState; + +public: + + VActorStateTable( void ) : + mObject( NULL ), + mLastState( NULL ), + mCurrentState( NULL ) + { + VECTOR_SET_ASSOCIATION( mStateVector ); + }; + + virtual ~VActorStateTable( void ) + { + // Clear Table. + clear(); + }; + + void registerState( VActorState *pState, const F32 &pPriority = 0.5f ); + + virtual void enter( void ) { }; + virtual VActorState *execute( void ); + virtual void exit( void ) { }; + + //------------------------------------------------------------------------- + // + // Gets + // + //------------------------------------------------------------------------- + + inline VActor *getObject( void ) { return mObject; }; + + bool isRegisteredState( VActorState *pState ); + + inline VActorState *getCurrentState( void ) { return mCurrentState; }; + inline VActorState *getLastState( void ) { return mLastState; }; + + //------------------------------------------------------------------------- + // + // Sets + // + //------------------------------------------------------------------------- + + void clear( void ); + void sort( void ); + + inline void setObject( VActor *pObject ) { mObject = pObject; }; + void setState( VActorState *pState ); + + //------------------------------------------------------------------------- + // + // Accessors + // + //------------------------------------------------------------------------- + + tStateConstIterator begin( void ) const { return mStateVector.begin(); }; + tStateConstIterator end( void ) const { return mStateVector.end(); }; + S32 size( void ) const { return mStateVector.size(); }; + +protected: + + static S32 QSORT_CALLBACK _onSortCallback( const VActorStateTable::sStateRef *pA, const VActorStateTable::sStateRef *pB ); +}; + +#endif // _VT_VACTORSTATETABLE_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VActor/VInterpController.h b/Engine/source/Verve/VActor/VInterpController.h new file mode 100644 index 000000000..3b9f34a1c --- /dev/null +++ b/Engine/source/Verve/VActor/VInterpController.h @@ -0,0 +1,207 @@ +//----------------------------------------------------------------------------- +// 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_VINTERPCONTROLLER_H_ +#define _VT_VINTERPCONTROLLER_H_ + +#ifndef _MATH_H_ +#include "math/mMath.h" +#endif + +//----------------------------------------------------------------------------- + +class VInterpController +{ +protected: + + Point3F mPosition[2]; + QuatF mRotation[2]; + +public: + + //------------------------------------------------------------------------- + // Interpolation Methods. + //------------------------------------------------------------------------- + + /// Get Position. + Point3F getPosition( const F32 &pDelta ) + { + // Interpolate Position. + Point3F interpPosition; + interpPosition.interpolate( mPosition[1], mPosition[0], pDelta ); + // Return Interpolated Point. + return interpPosition; + }; + + /// Get Rotation. + QuatF getRotation( const F32 &pDelta ) + { + // Interpolate Rotation. + QuatF interpRotation; + interpRotation.interpolate( mRotation[1], mRotation[0], pDelta ); + // Return Interpolated Quat. + return interpRotation; + }; + + /// Get Transform. + MatrixF getTransform( const F32 &pDelta ) + { + // Get Position. + const Point3F interpPosition = getPosition( pDelta ); + // Get Rotation. + const QuatF interpRotation = getRotation( pDelta ); + + // Setup Matrix. + MatrixF transform; + interpRotation.setMatrix( &transform ); + // Set Position. + transform.setPosition( interpPosition ); + + // Return Matrix. + return transform; + }; + + //------------------------------------------------------------------------- + // Delta Methods. + //------------------------------------------------------------------------- + + /// Reset Delta. + void resetDelta( const Point3F &pPosition, const QuatF &pRotation ) + { + mPosition[0] = mPosition[1] = pPosition; + mRotation[0] = mRotation[1] = pRotation; + }; + + /// Reset Delta. + void resetDelta( const MatrixF &pMatrix ) + { + // Setup Quat. + QuatF rotationQuat( pMatrix ); + // Reset Delta. + resetDelta( pMatrix.getPosition(), rotationQuat ); + }; + + /// Reset Delta (Vector) + void resetDelta( const Point3F &pPosition, const VectorF &pForwardVector ) + { + // Assert. + AssertFatal( pForwardVector.isUnitLength(), "VInterpController::resetDelta() - Forward Vector hasn't been Normalized." ); + + // Static Up Vector. + static const VectorF sUpVector( 0.f, 0.f, 1.f ); + + // X-Axis. + VectorF xVec = mCross( pForwardVector, sUpVector ); + xVec.normalize(); + // Z-Axis. + VectorF zVec = mCross( xVec, pForwardVector ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF transform; + transform.setColumn( 0, xVec ); + transform.setColumn( 1, pForwardVector ); + transform.setColumn( 2, zVec ); + transform.setColumn( 3, pPosition ); + + // Reset Delta. + resetDelta( transform ); + }; + + /// Reset Delta (AngAxis) + void resetDelta( const Point3F &pPosition, const AngAxisF &pAngAxis ) + { + // Setup Matrix. + MatrixF transform; + pAngAxis.setMatrix( &transform ); + // Set Position. + transform.setPosition( pPosition ); + + // Reset Delta. + resetDelta( transform ); + }; + + /// Push Delta. + void pushDelta( const Point3F &pPosition, const QuatF &pRotation ) + { + mPosition[1] = pPosition; + mRotation[1] = pRotation; + }; + + /// Push Delta (Matrix) + void pushDelta( const MatrixF &pMatrix ) + { + // Setup Quat. + QuatF rotationQuat( pMatrix ); + // Push Delta. + pushDelta( pMatrix.getPosition(), rotationQuat ); + }; + + /// Push Delta (Vector) + void pushDelta( const Point3F &pPosition, const VectorF &pForwardVector ) + { + // Assert. + AssertFatal( pForwardVector.isUnitLength(), "VInterpController::pushDelta() - Forward Vector hasn't been Normalized." ); + + // Static Up Vector. + static const VectorF sUpVector( 0.f, 0.f, 1.f ); + + // X-Axis. + VectorF xVec = mCross( pForwardVector, sUpVector ); + xVec.normalize(); + // Z-Axis. + VectorF zVec = mCross( xVec, pForwardVector ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF transform; + transform.setColumn( 0, xVec ); + transform.setColumn( 1, pForwardVector ); + transform.setColumn( 2, zVec ); + transform.setColumn( 3, pPosition ); + + // Push Delta. + pushDelta( transform ); + }; + + /// Push Delta (AngAxis) + void pushDelta( const Point3F &pPosition, const AngAxisF &pAngAxis ) + { + // Setup Matrix. + MatrixF transform; + pAngAxis.setMatrix( &transform ); + // Set Position. + transform.setPosition( pPosition ); + + // Push Delta. + pushDelta( transform ); + }; + + /// Pop Delta. + void popDelta( void ) + { + mPosition[0] = mPosition[1]; + mRotation[0] = mRotation[1]; + }; +}; + +#endif // _VT_VINTERPCONTROLLER_H_ \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VNetState.cpp b/Engine/source/Verve/VPath/VNetState.cpp new file mode 100644 index 000000000..d08c2ea0d --- /dev/null +++ b/Engine/source/Verve/VPath/VNetState.cpp @@ -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; + } +} \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VNetState.h b/Engine/source/Verve/VPath/VNetState.h new file mode 100644 index 000000000..9cecef0a7 --- /dev/null +++ b/Engine/source/Verve/VPath/VNetState.h @@ -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 Connection; + U32 Mask; + + VNetStateInfo( void ) : + Connection( NULL ), + Mask( 0 ) + { + // Void. + }; + + VNetStateInfo( NetConnection *pConnection, U32 pMask ) + { + Connection = pConnection; + Mask = pMask; + }; +}; + +//----------------------------------------------------------------------------- + +class VNetState : public Vector +{ +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_ \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPath.cpp b/Engine/source/Verve/VPath/VPath.cpp new file mode 100644 index 000000000..21a874869 --- /dev/null +++ b/Engine/source/Verve/VPath/VPath.cpp @@ -0,0 +1,3375 @@ +//----------------------------------------------------------------------------- +// 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 "VPath.h" + +#include "console/consoleTypes.h" +#include "core/iTickable.h" +#include "core/stream/bitStream.h" +#include "math/mMathFn.h" +#include "math/mathIO.h" +#include "math/mTransform.h" + +//----------------------------------------------------------------------------- + +// Uncomment this definition to debug the network information. +//#define VPATH_DEBUG_NET + +// Uncomment this definition to debug the time step information +//#define VPATH_DEBUG_STEP + +//----------------------------------------------------------------------------- + +SimObjectPtr VPath::gServerSet = NULL; + +U32 VPath::gMaxNodeTransmit = 16; +U32 VPath::gMaxNodeBits = 8; +U32 VPath::gMaxNodeCount = 1 << gMaxNodeBits; // 256 + +U32 VPath::gMaxObjectTransmit = 4; +U32 VPath::gMaxObjectBits = 4; +U32 VPath::gMaxObjectCount = 1 << gMaxObjectBits; // 16 + +Point3F VPath::gBezierAxis( 0.f, 1.f, 0.f ); +Point3F VPath::gBezierUp( 0.f, 0.f, 1.f ); + +//----------------------------------------------------------------------------- + +static U32 gPathTypeBits = getBinLog2( getNextPow2( VPath::k_PathTypeSize ) ); +static F32 gBezierInterpStep = 0.0001f; + +//----------------------------------------------------------------------------- +// Path Type Table. +//----------------------------------------------------------------------------- + +// Implement the Path Type enum list. +ImplementEnumType( VPathType, "" ) + { VPath::k_PathBezier, "BEZIER" }, + { VPath::k_PathLinear, "LINEAR" }, +EndImplementEnumType; + +static VPath::ePathType getPathTypeEnum( const char *pLabel ) +{ + VPath::ePathType out; + if ( !castConsoleTypeFromString( out, pLabel ) ) + { + // Bah! + return VPath::k_PathInvalid; + } + + // Return. + return out; +} + +//----------------------------------------------------------------------------- +IMPLEMENT_CO_NETOBJECT_V1( VPath ); +//----------------------------------------------------------------------------- + +VPath::VPath( void ) : + mPathType( k_PathBezier ) +{ + // Marker Type. + mTypeMask = MarkerObjectType; + + // Ghost & Scope. + mNetFlags.set( Ghostable | ScopeAlways ); + + // Process Ticks. + setProcessTick( true ); + + VECTOR_SET_ASSOCIATION( mNodeList ); + VECTOR_SET_ASSOCIATION( mObjectList ); +} + +VPath::~VPath( void ) +{ + // Void. +} + +bool VPath::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + // Add to Scene. + addToScene(); + + if ( isServerObject() ) + { + // Read Fields. + readFields(); + + // Add to Set. + getServerSet()->addObject( this ); + } + + return true; +} + +void VPath::onDeleteNotify( SimObject *pObject ) +{ + // Parent Notify. + Parent::onDeleteNotify( pObject ); + + if ( SceneObject *sceneObject = dynamic_cast( pObject ) ) + { + // Detach Object. + detachObject( sceneObject ); + + // Exit. + return; + } + + if ( NetConnection *connection = dynamic_cast( pObject ) ) + { + // Clear Connection References. + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Erase Connection. + ( *itr )->clearConnection( connection ); + } + + // Exit. + return; + } +} + +void VPath::onRemove( void ) +{ + // Remove From Scene. + removeFromScene(); + + // Clear Everything. + clear(); + + Parent::onRemove(); +} + +void VPath::initPersistFields( void ) +{ + Parent::initPersistFields(); + + addProtectedField( "PathType", TYPEID(), Offset( mPathType, VPath ), &setPathType, &defaultProtectedGetFn, "The type of path this is." ); +} + +SimSet *VPath::getServerSet( void ) +{ + if ( !gServerSet ) + { + gServerSet = new SimSet(); + gServerSet->registerObject( "ServerPathSet" ); + Sim::getRootGroup()->addObject( gServerSet ); + } + + return gServerSet; +} + +DefineEngineFunction( getServerPathSet, S32, (),, "( void )" ) +{ + return VPath::getServerSet()->getId(); +} + +//----------------------------------------------------------------------------- +// +// Editor Methods. +// +//----------------------------------------------------------------------------- + +bool VPath::collideBox( const Point3F &pStart, const Point3F &pEnd, RayInfo* pInfo ) +{ + if ( mObjBox.isContained( pStart ) ) + { + pInfo->t = 0.f; + pInfo->object = this; + pInfo->normal = VectorF( 0.f, 0.f, 1.f ); + pInfo->material = NULL; + + return true; + } + + return Parent::collideBox( pStart, pEnd, pInfo ); +} + +//----------------------------------------------------------------------------- +// +// Update Methods. +// +//----------------------------------------------------------------------------- + +F32 VPath::getUpdatePriority( CameraScopeQuery *pFocusObject, U32 pUpdateMask, S32 pUpdateSkips ) +{ + if ( mObjectList.size() > 0 ) + { + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Fetch Object. + VPathObject *pathObject = ( *itr ); + if ( pathObject->isActive() ) + { + // High Priority. + return 100.f; + } + } + } + + // Normal Priority. + return 0.f; +} + +void VPath::updateContainer( void ) +{ + if ( mNodeList.size() == 0 ) + { + // Sanity!. + return; + } + + // Init Min / Max. + mObjBox.minExtents = ( mNodeList[0]->getLocalPosition() ); + mObjBox.maxExtents = mObjBox.minExtents; + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Node Position. + const Point3F &nodeLocalPosition = node->getLocalPosition(); + + // Update Object Box. + mObjBox.minExtents.setMin( nodeLocalPosition ); + mObjBox.maxExtents.setMax( nodeLocalPosition ); + } + + // Adjust. + mObjBox.minExtents -= Point3F( 1.f, 1.f, 1.f ); + mObjBox.maxExtents += Point3F( 1.f, 1.f, 1.f ); + + // Reset Box. + resetWorldBox(); + resetRenderWorldBox(); +} + +void VPath::updateNodeTransforms( void ) +{ + // Fetch Transform Details. + const MatrixF &pathTransform = getTransform(); + const QuatF &pathRotation( pathTransform ); + const VectorF &pathScale = getScale(); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Fetch Node Spatials. + const Point3F &nodePosition = node->getLocalPosition(); + const QuatF &nodeRotation = node->getLocalRotation(); + + // Calculate the new Position. + Point3F newPosition = nodePosition; + newPosition.convolve( pathScale ); + pathTransform.mulP( newPosition ); + + // Calculate the new Rotation. + QuatF newRotation; + newRotation.mul( nodeRotation, pathRotation ); + + // Apply. + node->setWorldPosition( newPosition ); + node->setWorldRotation( newRotation ); + } +} + +void VPath::setTransform( const MatrixF &pMatrix ) +{ + // Parent Call. + Parent::setTransform( pMatrix ); + + // Update Nodes. + updateNodeTransforms(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +void VPath::setScale( const VectorF &pScale ) +{ + // Parent Call. + Parent::setScale( pScale ); + + // Update Nodes. + updateNodeTransforms(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +DefineEngineMethod( VPath, setPathType, void, (String pathType), ("LINEAR"), "( string pPathType ) - The path type dictates how attached objects move between nodes. There are currently two supported path types, \"BEZIER\" and \"LINEAR\".\n" + "@return No return value." ) +{ + // Fetch Enum. + const VPath::ePathType &type = getPathTypeEnum(pathType); + + // Update. + object->setPathType( type ); +} + +void VPath::setPathType( const ePathType &pType ) +{ + // Apply Value. + mPathType = pType; + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Update Path. + setMaskBits( PathUpdateMask ); + } +} + +bool VPath::setPathType( void *pObject, const char *pArray, const char *pData ) +{ + // Apply Type. + static_cast( pObject )->setPathType( getPathTypeEnum( pData ) ); + return false; +} + +//----------------------------------------------------------------------------- +// +// Mounting Methods. +// +//----------------------------------------------------------------------------- + +bool VPath::isMountIndex( const U32 &pIndex ) +{ + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + // Yes. + return true; + } + } + + // No. + return false; +} + +U32 VPath::getAvailableMountIndex( void ) +{ + U32 i = 0; + while( isMountIndex( i ) ) + { + // Increment. + i++; + } + + // Return Index. + return i; +} + +void VPath::mountObject( SceneObject *pObject, S32 pIndex, const MatrixF &pTransform ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::mountObject() %d | %d, IsAttached %d", isServerObject(), pObject->getId(), isObjectAttached( pObject ) ); +#endif + + // Attached? + if ( !isObjectAttached( pObject ) ) + { + if ( isServerObject() ) + { + // Shouldn't Use this Method. + Con::warnf( "VPath::mountObject() - Use 'attachObject' instead." ); + } + + // Not Attached. + return; + } + + // Parent Call. + Parent::mountObject( pObject, pIndex, pTransform ); + + // Clear the mounted mask. + // Note: This is so that we send the mounting information via the VPath + // packets instead of letting T3D handle it. + pObject->clearMaskBits( SceneObject::MountedMask ); +} + +void VPath::unmountObject( SceneObject *pObject ) +{ + // Fetch Path Object. + VPathObject *pathObject = getPathObject( pObject ); + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::unmountObject() %d | %d, IsAttached %d", isServerObject(), pObject->getId(), pathObject != NULL ); +#endif + + // Valid? + if ( !pathObject || pObject->getObjectMount() != this ) + { + // Warn. + Con::warnf( "VPath::unmountObject() - Object is not attached to this Path. %d", pObject->getId() ); + // Not Mounted Here! + return; + } + + // Parent Call. + Parent::unmountObject( pObject ); + + // Clear the mounted mask. + // Note: This is so that we send the mounting information via the VPath + // packets instead of letting T3D handle it. + pObject->clearMaskBits( SceneObject::MountedMask ); +} + +void VPath::getMountTransform( S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Reset Transform. + *pTransform = pInTransform; + // Sanity! + return; + } + + // Advance the Object. + advanceObject( pathObject, TickSec ); + + // Apply Transform. + *pTransform = pathObject->getTransform(); +} + +void VPath::getRenderMountTransform( F32 pDelta, S32 pIndex, const MatrixF &pInTransform, MatrixF *pTransform ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Reset Transform. + *pTransform = pInTransform; + // Sanity! + return; + } + + // Apply Transform. + *pTransform = pathObject->getRenderTransform( pDelta ); +} + +VectorF VPath::getMountVelocity( const U32 &pIndex ) +{ + // Fetch the Scene Object. + VPathObject *pathObject = NULL; + for ( SceneObject *itr = getMountList(); itr != NULL; itr = itr->getMountLink() ) + { + if ( itr->getMountNode() == pIndex ) + { + pathObject = getPathObject( itr ); + break; + } + } + + if ( !pathObject ) + { + // Sanity! + return VectorF::Zero; + } + + // Determine Velocity. + return ( pathObject->getOrientation() * pathObject->getSpeed() ); +} + +//----------------------------------------------------------------------------- +// +// Persistence Methods. +// +//----------------------------------------------------------------------------- + +void VPath::readFields( void ) +{ + const char *nodeData = ""; + for ( S32 nodeIndex = 0; dStrcmp( nodeData = getDataField( StringTable->insert( avar( "Node%d", nodeIndex ) ), NULL ), "" ) != 0; nodeIndex++ ) + { + // Create Node. + VPathNode *node = createNode(); + // Deserialize the Node. + node->fromString( nodeData ); + // Add the Node. + addNode( node ); + + // Clear Field. + setDataField( StringTable->insert( avar( "Node%d", nodeIndex ) ), NULL, "" ); + } + + // Update Transforms. + updateNodeTransforms(); + + // Update Size. + updateContainer(); + + // Calculate Path. + calculatePath(); +} + +void VPath::writeFields( Stream &pStream, U32 pTabStop ) +{ + // Field Name. + StringTableEntry fieldName = StringTable->insert( "node" ); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Set Field. + setDataField( fieldName, avar( "%d" , ( itr - mNodeList.begin() ) ), ( *itr )->toString().c_str() ); + } + + // Write Fields. + Parent::writeFields( pStream, pTabStop ); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + // Clear Field. + setDataField( fieldName, avar( "%d" , ( itr - mNodeList.begin() ) ), "" ); + } +} + +U32 VPath::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream ) +{ + U32 retMask = Parent::packUpdate( pConnection, pMask, pStream ); + + if ( pMask & InitialUpdateMask ) + { + // Delete Notify. + deleteNotify( pConnection ); + } + + if ( pStream->writeFlag( pMask & PathUpdateMask ) ) + { + // Write Path Type. + pStream->writeInt( mPathType, gPathTypeBits ); + + // Write Transform. + mathWrite( *pStream, mObjToWorld ); + // Write Scale. + mathWrite( *pStream, mObjScale ); + } + + if ( pStream->writeFlag( pMask & NodeUpdateMask ) ) + { + // Path needs recalculating? + bool needsCalculating = false; + + // Delete Vector. + Vector deleteVector; + // Update Vector. + Vector updateVector; + + for ( U32 i = 0; i < mNodeList.size(); i++ ) + { + // Fetch Node. + VPathNode *node = mNodeList[i]; + + // Already In Map? + if ( !node->isConnection( pConnection ) ) + { + // Insert. + node->addConnection( pConnection ); + } + + // Fetch State. + VNetStateInfo *state = node->getState( pConnection ); + + // Delete new node? + if ( state->Mask & VPathNode::k_StateDelete + && state->Mask & VPathNode::k_StateCreate ) + { + // Remove Node. + removeNode( i-- ); + // Flag true. + needsCalculating = true; + } + + // Delete? + else if ( state->Mask & VPathNode::k_StateDelete ) + { + // Add To List. + deleteVector.push_front( i ); + } + + // Update? + else if ( state->Mask & VPathNode::k_StateUpdate ) + { + if ( updateVector.size() < gMaxNodeTransmit ) + { + // Add To List. + updateVector.push_back( i ); + } + } + } + + // More Updates? + if ( updateVector.size() == gMaxNodeTransmit ) + { + // More Updates. + retMask |= NodeUpdateMask; + } + + // Write Count. + pStream->writeInt( updateVector.size(), gMaxNodeBits + 1 ); + + for ( Vector::iterator itr = updateVector.begin(); itr != updateVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxNodeBits ); + // Pack Update. + retMask |= mNodeList[index]->packNode( pConnection, pStream ); + } + + // Write Count. + pStream->writeInt( deleteVector.size(), gMaxNodeBits + 1 ); + + if ( deleteVector.size() > 0 ) + { + for ( Vector::iterator itr = deleteVector.begin(); itr != deleteVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxNodeBits ); + // Remove Node. + removeNode( index ); + } + + // Flag true. + needsCalculating = true; + // Clear Vector. + deleteVector.clear(); + } + + // Recalculate path? + if ( needsCalculating ) + { + // Update Size. + updateContainer(); + // Calculate Path. + calculatePath(); + } + } + + if ( pStream->writeFlag( pMask & ObjectUpdateMask ) ) + { + // Detach Vector. + Vector detachVector; + // Update Vector. + Vector updateVector; + + for ( U32 i = 0; i < mObjectList.size(); i++ ) + { + // Fetch Node. + VPathObject *pathObject = mObjectList[i]; + + // Already In Map? + if ( !pathObject->isConnection( pConnection ) ) + { + // Insert. + pathObject->addConnection( pConnection ); + } + + // Fetch State. + VNetStateInfo *state = pathObject->getState( pConnection ); + + // Detach newly attached object? + if ( state->Mask & VPathObject::k_StateAttach + && state->Mask & VPathObject::k_StateDetach ) + { + // Process Detach. + onDetachObject( pathObject ); + // Decrease index. + i -= 1; + + // Skip. + continue; + } + + // Update? + if ( state->Mask & VPathObject::k_StateUpdate ) + { + if ( updateVector.size() < gMaxObjectTransmit ) + { + // Add To List. + updateVector.push_back( i ); + } + } + + // Detach? + if ( state->Mask & VPathObject::k_StateDetach ) + { + // Add To List. + detachVector.push_front( i ); + } + } + + // More Updates? + if ( updateVector.size() == gMaxObjectTransmit ) + { + // More Updates. + retMask |= ObjectUpdateMask; + } + + // Write Count. + pStream->writeInt( updateVector.size(), gMaxObjectBits + 1 ); + + for ( Vector::iterator itr = updateVector.begin(); itr != updateVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + + // Write Index. + pStream->writeInt( index, gMaxObjectBits ); + + // Fetch the object. + VPathObject *pathObject = mObjectList[index]; + // Fetch State. + VNetStateInfo *state = pathObject->getState( pConnection ); + + // Was the Object Attached? + if ( pStream->writeFlag( state->Mask & VPathObject::k_StateAttach ) ) + { +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::packUpdate() - Attached - %d | %d", isServerObject(), index ); +#endif + + // Clear Update. + state->Mask &= ~VPathObject::k_StateAttach; + } + + // Pack Object. + retMask |= mObjectList[index]->packUpdate( pConnection, pStream ); + } + + // Write Count. + pStream->writeInt( detachVector.size(), gMaxObjectBits + 1 ); + + if ( detachVector.size() > 0 ) + { + for ( Vector::iterator itr = detachVector.begin(); itr != detachVector.end(); itr++ ) + { + // Fetch Index. + const U32 index = ( *itr ); + // Write Index. + pStream->writeInt( index, gMaxObjectBits ); + // Process Detach. + onDetachObject( mObjectList[index] ); + } + + // Clear Vector. + detachVector.clear(); + } + } + + // Return. + return retMask; +} + +void VPath::unpackUpdate( NetConnection *pConnection, BitStream *pStream ) +{ + Parent::unpackUpdate( pConnection, pStream ); + + // Update Path? + if ( pStream->readFlag() ) + { + // Read Path Type. + mPathType = pStream->readInt( gPathTypeBits ); + + // Read Transform. + mathRead( *pStream, &mObjToWorld ); + // Read Scale. + mathRead( *pStream, &mObjScale ); + + // Update Nodes. + updateNodeTransforms(); + // Calculate Path. + calculatePath(); + } + + // Update Nodes? + if ( pStream->readFlag() ) + { + // Number To Update. + const U32 updateCount = pStream->readInt( gMaxNodeBits + 1 ); + + for ( U32 i = 0; i < updateCount; i++ ) + { + // Read Index. + const U32 nodeIndex = pStream->readInt( gMaxNodeBits ); + + // Was the Node Created? + if ( pStream->readFlag() ) + { + // Create Node. + VPathNode *node = createNode(); + // Add the Node. + addNode( node, nodeIndex ); + } + + // Reference Node. + VPathNode *node = mNodeList[nodeIndex]; + // Apply Update. + node->unpackNode( pConnection, pStream ); + } + + // Number To Delete. + const U32 deleteCount = pStream->readInt( gMaxNodeBits + 1 ); + + for ( U32 i = 0; i < deleteCount; i++ ) + { + // Remove Node. + removeNode( pStream->readInt( gMaxNodeBits ) ); + } + + // Update Size. + updateContainer(); + // Calculate Path. + calculatePath(); + } + + // Update Objects? + if ( pStream->readFlag() ) + { + // Number To Update. + const U32 updateCount = pStream->readInt( gMaxObjectBits + 1 ); + + for ( U32 i = 0; i < updateCount; i++ ) + { + // Read Index. + const U32 objectIndex = pStream->readInt( gMaxObjectBits ); + + // Read Attached. + // Note: The editor handles the both the server and client side attachment calls. + // This is dangerous because there could be a mix up in indices, but it is + // needed to ensure the editor runs smoothly :( + const bool wasAttached = pStream->readFlag(); + if ( wasAttached && objectIndex >= mObjectList.size() ) + { +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::unpackUpdate() - WasAttached - %d | %d", isServerObject(), objectIndex ); +#endif + + // Create & Add to the List. + attachObject( new VPathObject() ); + } + + // Reference Node. + VPathObject *pathObject = mObjectList[objectIndex]; + + // Unpack Update. + pathObject->unpackUpdate( pConnection, pStream ); + + // Object Attached this Unpack? + if ( wasAttached ) + { + // Reset. + setPathObjectInterp( pathObject, pathObject->getTimeInterp() ); + } + } + + // Number To Detach. + const U32 detachCount = pStream->readInt( gMaxObjectBits + 1 ); + + for ( U32 i = 0; i < detachCount; i++ ) + { + // Fetch the path object. + VPathObject *pathObject = mObjectList[pStream->readInt( gMaxObjectBits )]; + // Detach callback. + onDetachObject( pathObject ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Node Methods. +// +//----------------------------------------------------------------------------- + +VPathNode *VPath::createNode( void ) +{ + return new VPathNode(); +} + +void VPath::deleteNode( VPathNode *pNode ) +{ + delete pNode; +} + +void VPath::clear( void ) +{ + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + VPathObject *pathObject = ( *itr ); + + // Fetch the attached object. + SceneObject *refObject = pathObject->getObject(); + // Unmount Object. + unmountObject( refObject ); + + // Delete the Path Object. + delete pathObject; + } + + // Clear Object List. + mObjectList.clear(); + + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + deleteNode( ( *itr ) ); + } + + // Clear Node List. + mNodeList.clear(); + + if ( isServerObject() ) + { + // Update. + setMaskBits( NodeUpdateMask ); + } +} + +VPathNode *VPath::getNode( const S32 &pNodeIndex ) +{ + // Sanity! + AssertFatal( pNodeIndex >= 0 && pNodeIndex < mNodeList.size(), "VPath::getNode() - Invalid Index" ); + + // Return Node. + return mNodeList[pNodeIndex]; +} + +DefineEngineMethod( VPath, addNode, void, (TransformF transform, F32 weight, S32 location), (MatrixF::Identity, 1.0, -1), + "( transform pTransform, float pWeight, [int pLocation] ) - Add a node with the given properties. Nodes represent physical points that attached objects move towards or between, but the PathType determines \"how\" they move between them.\n" + "@param pTransform The position and rotation of the new node.\n" + "@param pWeight The weight of the new node.\n" + "@param pLocation The index of the new node.\n" + "@return No return value.") +{ + // Fetch Invers Path Transform. + MatrixF pathTransformInv = object->getTransform(); + pathTransformInv.setPosition( Point3F::Zero ); + pathTransformInv.inverse(); + + Point3F pos; + QuatF rot; + AngAxisF aa; + + pos = transform.mPosition; + aa = transform.mOrientation; + + // Set Rotation. + rot.set( aa ); + + // World to Local Position. + Point3F nodePosition = ( pos - object->getPosition() ); + pathTransformInv.mulP( nodePosition ); + + // World to Local Rotation. + MatrixF nodeRotationMat; + rot.setMatrix( &nodeRotationMat ); + pathTransformInv.mul( nodeRotationMat ); + + // Set Quat. + QuatF nodeRotation; + nodeRotation.set( nodeRotationMat ); + + // Add Node. + VPathNode *node = object->addNode( nodePosition, nodeRotation, weight, location ); + + // Valid Node? + if ( node ) + { + // Update Size. + object->updateContainer(); + + // Calculate Path. + object->calculatePath(); + } +} + +VPathNode *VPath::addNode( const Point3F &pPosition, const QuatF &pRotation, const F32 &pWeight, const S32 &pLocation ) +{ + // Reference Object. + VPathNode *pathNode = createNode(); + + // Store Properties. + pathNode->setLocalPosition( pPosition ); + pathNode->setLocalRotation( pRotation ); + pathNode->setWeight( pWeight ); + + // Add Node. + return addNode( pathNode, pLocation ); +} + +VPathNode *VPath::addNode( VPathNode *pNode, const S32 &pLocation ) +{ + if ( pNode->getPath() ) + { + // Error. + Con::errorf( "VPath::addNode() - Node already belongs to a Path, '%d'", pNode->getPath()->getId() ); + + return NULL; + } + else if ( mNodeList.size() == gMaxNodeCount ) + { + // Error. + Con::errorf( "VPath::addNode() - Reached Max Nodes (%d)", gMaxNodeCount ); + + // Delete Node. + deleteNode( pNode ); + + return NULL; + } + + // Set Path. + pNode->setPath( this ); + + // Update World Data. + pNode->updateWorldData(); + + if ( pLocation < 0 ) + { + // Push Back. + mNodeList.push_back( pNode ); + } + else + { + // Fetch Size. + const S32 nodeCount = mNodeList.size(); + + if ( pLocation >= nodeCount ) + { + // Push Back. + mNodeList.push_back( pNode ); + } + else + { + // Insert. + mNodeList.insert( ( mNodeList.address() + pLocation ), pNode ); + } + } + + if ( isServerObject() ) + { + // Update. + setMaskBits( NodeUpdateMask ); + } + + // Return Node. + return pNode; +} + +DefineEngineMethod( VPath, deleteNode, void, (S32 nodeIndex), (0), "( int pNodeIndex ) - Delete the node with the given index. If you delete a node that an attached object is moving to, or from then the object's movement will adjust so that it has a valid path.\n" + "@param pNodeIndex The index of the node to be deleted.\n" + "@return No return value." ) +{ + // Apply Update. + object->deleteNode( nodeIndex ); +} + +void VPath::deleteNode( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::deleteNode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Remove Node References. + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Fetch Object. + VPathObject *pathObject = ( *itr ); + + if ( ( pathObject->getSourceNode() >= pNodeIndex ) || ( pathObject->getDestinationNode() >= pNodeIndex ) ) + { + S32 srcNode = pathObject->getSourceNode(); + S32 dstNode = pathObject->getDestinationNode(); + + if ( pathObject->isForward() ) + { + if ( srcNode >= pNodeIndex ) + { + srcNode -= 1; + } + + if ( dstNode > pNodeIndex ) + { + dstNode -= 1; + } + } + else + { + if ( srcNode > pNodeIndex ) + { + srcNode -= 1; + } + + if ( dstNode >= pNodeIndex ) + { + dstNode -= 1; + } + } + + // Normalize indices. + normalizeNodeIndex( srcNode, ( mNodeList.size() - 1 ) ); + normalizeNodeIndex( dstNode, ( mNodeList.size() - 1 ) ); + + // Apply Update. + pathObject->setNode( srcNode, dstNode ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + } + } + } + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + + // Flag for Deletion. + node->setMaskBits( VPathNode::k_StateDelete ); + } +} + +void VPath::removeNode( const S32 &pNodeIndex ) +{ + // Fetch the node. + VPathNode *node = getNode( pNodeIndex ); + if ( !node ) + { + // Quit. + return; + } + + // Delete Node. + deleteNode( node ); + // Erase Node. + mNodeList.erase( pNodeIndex ); +} + +S32 VPath::normalizeNodeIndex( S32 &pNodeIndex ) +{ + const S32 nodeCount = mNodeList.size(); + if ( nodeCount == 0 ) + { + // No Nodex. + pNodeIndex = 0; + } + else + { + while ( pNodeIndex < 0 ) + { + // Wrap Backwards. + pNodeIndex += nodeCount; + } + + // Wrap Forwards. + pNodeIndex %= nodeCount; + } + + // Return Index. + return pNodeIndex; +} + +S32 VPath::normalizeNodeIndex( const S32 &pNodeIndex ) +{ + // Temp. + S32 nodeIndex = pNodeIndex; + + // Return Index. + return normalizeNodeIndex( nodeIndex ); +} + +S32 VPath::normalizeNodeIndex( S32 &pNodeIndex, const S32 &pNodeCount ) +{ + if ( pNodeCount == 0 ) + { + // No Nodex. + pNodeIndex = 0; + } + else + { + while ( pNodeIndex < 0 ) + { + // Wrap Backwards. + pNodeIndex += pNodeCount; + } + + // Wrap Forwards. + pNodeIndex %= pNodeCount; + } + + // Return Index. + return pNodeIndex; +} + +//----------------------------------------------------------------------------- +// +// Object Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VPath, isObjectAttached, bool, (SceneObject* sceneObject), (nullAsType()), "( SimObject pObject ) - Is the object attached to this path?\n" + "@param pObject The SimObjectID of the object you wish to check.\n" + "@return Returns true if the object is attached to this path." ) +{ + if (sceneObject== nullptr) + { + Con::errorf( "VPath::isObjectAttached() - Invalid Target Object." ); + return false; + } + + // Attached? + return object->isObjectAttached( sceneObject ); +} + +bool VPath::isObjectAttached( SceneObject *pObject ) +{ + // Valid Object? + return ( getPathObject( pObject ) != NULL ); +} + +VPathObject *VPath::getPathObject( SceneObject *pObject ) +{ + for ( VPathObjectIterator itr = mObjectList.begin(); itr != mObjectList.end(); itr++ ) + { + // Correct Object? + if ( ( *itr )->getObject() == pObject ) + { + // Yes. + return ( *itr ); + } + } + + return NULL; +} + +DefineEngineStringlyVariadicMethod( VPath, attachObject, void, 7, 8, "( SimObject pObject, bool pForward, float pSpeed, bool pRelative, int pStartNode, [int pEndNode] ) - Attach an object to this path with the given properties. If the object is already attached to a path, then a warning will be displayed and the object will *not* be attached to this path.\n" + "@param pObject The SimObjectID of the object to be attached.\n" + "@param pForward Should the object be moving forward?\n" + "@param pSpeed The speed that the object will travel around the path.\n" + "@param pRelative Offset the object based on the difference between the start node and its current position.\n" + "@param pStartNode The index of the node this object starts pathing from.\n" + "@param pEndNode The index of the node this object will stop pathing at." + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::attachObject() - Invalid Target Object." ); + return; + } + + // Fetch Direction. + const bool forward = dAtob( argv[3] ); + // Fetch Speed. + const F32 speed = dAtof( argv[4] ); + // Fetch Relativity. + const bool relative = dAtob( argv[5] ); + // Fetch Start Node. + const S32 startNode = dAtoi( argv[6] ); + // Fetch End Node. + const S32 endNode = ( argc >= 8 ) ? dAtoi( argv[7] ) : -1; + + // Attach Object. + object->attachObject( sceneObject, forward, speed, relative, startNode, endNode ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode ) +{ + attachObject( pObject, pForward, pSpeed, pRelative, pStartNode, pEndNode, VPathObject::k_OrientationToPath, NULL ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode ) +{ + attachObject( pObject, pForward, pSpeed, pRelative, pStartNode, pEndNode, pOrientationMode, NULL ); +} + +void VPath::attachObject( SceneObject *pObject, const bool &pForward, const F32 &pSpeed, const bool &pRelative, const S32 &pStartNode, const S32 &pEndNode, const VPathObject::eOrientationType &pOrientationMode, void *pOrientationData ) +{ + // Already Pathing? + if ( isObjectAttached( pObject ) ) + { + Con::warnf( "VPath::attachObject() - Object Already Attached to a Path." ); + return; + } + + // Determine Target Nodes. + const S32 srcNode = normalizeNodeIndex( pStartNode ); + const S32 dstNode = normalizeNodeIndex( ( pForward ) ? pStartNode + 1 : pStartNode - 1 ); + const S32 endNode = ( pEndNode == -1 ) ? pEndNode : normalizeNodeIndex( pEndNode ); + + // Valid Source Node? + if ( getNodeCount() == 0 || !getNode( srcNode ) ) + { + Con::warnf( "VPath::attachObject() - Invalid Start Node." ); + return; + } + + VPathObject *pathObject = new VPathObject(); + + // Init Properties. + pathObject->setActive( true ); + pathObject->setObject( pObject ); + + pathObject->setForward( pForward ); + + pathObject->setTimeInterp( 0.f ); + pathObject->setPathInterp( 0.f ); + pathObject->setOffset( Point3F::Zero ); + pathObject->setSpeed( pSpeed ); + + switch( pOrientationMode ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + pathObject->setOrientationMode( pOrientationMode ); + + } break; + + case VPathObject::k_OrientationToObject : + { + pathObject->setOrientationMode( pOrientationMode, (SceneObject*)pOrientationData ); + + } break; + + case VPathObject::k_OrientationToPoint : + { + pathObject->setOrientationMode( pOrientationMode, ( *(Point3F*)pOrientationData ) ); + + } break; + } + + pathObject->setNode( srcNode, dstNode ); + pathObject->setStartNode( srcNode ); + pathObject->setEndNode( endNode ); + + // Fetch Init Node. + VPathNode *node = mNodeList[srcNode]; + + // Relative Position? + if ( pRelative ) + { + // Set Position Offset. + pathObject->setOffset( pObject->getPosition() - node->getWorldPosition() ); + } + + // Set info. + setPathObjectInterp( pathObject, 0.f ); + + // Attach. + attachObject( pathObject ); +} + +void VPath::attachObject( VPathObject *pPathObject ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::attachObject() - %d", isServerObject() ); +#endif + + if ( mObjectList.size() == gMaxObjectCount ) + { + Con::errorf( "VPath::attachObject() - Reached Max Objects (%d)", gMaxObjectCount ); + return; + } + + // Add to List. + mObjectList.push_back( pPathObject ); + + // Callback. + onAttachObject( pPathObject ); + + if ( isServerObject() ) + { + // Update. + setMaskBits( ObjectUpdateMask ); + } +} + +void VPath::onAttachObject( VPathObject *pPathObject ) +{ + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject ) + { + return; + } + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::onAttachObject() - %d | %d", isServerObject(), refObject->getId() ); +#endif + + // Delete Notify. + deleteNotify( refObject ); + + if ( isServerObject() ) + { + // Fetch the Available Mount Index. + U32 mountIndex = getAvailableMountIndex(); + // Mount the Object to this Path. + mountObject( refObject, mountIndex ); + + // Return Buffer. + char buffer[1][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + + // Callback. + // VPath::onAttachObject( %object ); + Con::executef( this, "onAttachObject", buffer[0] ); + } +} + +DefineEngineMethod( VPath, detachObject, void, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Detach the object from this path in place.\n" + "@param pObject The SimObjectID of the object to be detached.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::detachObject() - Invalid Target Object." ); + return; + } + + // Detach Object. + object->detachObject( sceneObject ); +} + +void VPath::detachObject( SceneObject *pObject ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::detachObject() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Detach. + detachObject( pathObject ); +} + +void VPath::detachObject( VPathObject *pPathObject ) +{ +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::detachObject() - %d", isServerObject() ); +#endif + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Detach. + pPathObject->setMaskBits( VPathObject::k_StateDetach ); + } + + /* + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( refObject ) + { + // Unmount Object. + unmountObject( refObject ); + } + */ +} + +void VPath::onDetachObject( VPathObject *pPathObject ) +{ + // Valid Object? + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject ) + { + return; + } + +#ifdef VPATH_DEBUG_NET + Con::printf( "VPath::onDetachObject() - %d | %d", isServerObject(), refObject->getId() ); +#endif + + // Reset. + setPathObjectInterp( pPathObject, pPathObject->getTimeInterp() ); + // Unmount Object. + unmountObject( refObject ); + + // Delete the Path Object. + delete pPathObject; + // Remove from the Set. + mObjectList.erase( mObjectList.find_next( pPathObject ) ); + + // Clear Delete Notify. + clearNotify( refObject ); + + if ( isServerObject() ) + { + // Return Buffer. + char buffer[1][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + + // Callback. + // VPath::onDetachObject( %object ); + Con::executef( this, "onDetachObject", buffer[0] ); + } +} + +void VPath::processTick( const Move *pMove ) +{ +} + +void VPath::advanceObject( VPathObject *pPathObject, const F32 &pDelta ) +{ + SceneObject *refObject = pPathObject->getObject(); + if ( !refObject || mIsZero( pDelta ) ) + { + // Ignore. + return; + } + + // Spatial Delta. + pPathObject->popDelta(); + + // Active and Moving? + if ( !pPathObject->isActive() || mIsZero( pPathObject->getSpeed() ) ) + { + // Update Delta. + pPathObject->pushDelta( refObject->getPosition(), refObject->getTransform().getForwardVector() ); + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + VPathNode *lenNode = ( pPathObject->isForward() ) ? srcNode : dstNode; + + // Calculate Interp Delta. + const F32 stepDistance = ( pPathObject->getSpeed() * pDelta ); + const F32 speedMod = ( pPathObject->getSpeed() / lenNode->getLength() ); + F32 timeInterp = pPathObject->getTimeInterp(); + F32 timeInterpDelta = ( speedMod * pDelta ); + F32 pathInterp = pPathObject->getPathInterp(); + F32 pathInterpDelta = 0.f; + + // Fetch the old position. + const Point3F oldPosition = pPathObject->getPosition(); + // Calculate the new position and path delta. + Point3F newPosition = getAdvancedPathPosition( pPathObject, stepDistance, pathInterpDelta ); + + // Finished? + if ( ( timeInterp + timeInterpDelta ) >= 1.f ) + { + // Finished? + if ( pPathObject->getDestinationNode() == pPathObject->getEndNode() ) + { + // Stop Updates. + pPathObject->setActive( false ); + } + else + { + // Update Nodes. + const S32 srcNodeIndex = pPathObject->getDestinationNode(); + const S32 dstNodeIndex = normalizeNodeIndex( ( pPathObject->isForward() ) ? srcNodeIndex + 1 : srcNodeIndex - 1 ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::errorf( "Change Node:\n Source, %d\n Destination, %d", srcNodeIndex, dstNodeIndex ); +#endif + + // Apply Changes. + pPathObject->setNode( srcNodeIndex, dstNodeIndex ); + pPathObject->setTimeInterp( 0.f ); + pPathObject->setPathInterp( 0.f ); + pPathObject->setPosition( newPosition ); + + // Reset local interp information. + timeInterp = 0.f; + timeInterpDelta = 0.f; + pathInterp = 0.f; + pathInterpDelta = 0.f; + + // Fetch the distance we've travelled. + const F32 &advanceDistance = ( newPosition - oldPosition ).len(); + // Any remaining distance? + if ( ( stepDistance - advanceDistance ) > 0.0001f ) + { + // Determine how much more we need to move. + Point3F newPosition0 = newPosition; + newPosition = getAdvancedPathPosition( pPathObject, ( stepDistance - advanceDistance ), pathInterpDelta ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::errorf( "Transition Step: %f\nTransition Distance: %f + %f = %f", pathInterpDelta, advanceDistance, ( newPosition - newPosition0 ).len(), advanceDistance + ( newPosition - newPosition0 ).len() ); +#endif + } + } + + if ( isServerObject() ) + { + // Return Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", refObject->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pPathObject->isActive() ? pPathObject->getSourceNode() : pPathObject->getDestinationNode() ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", !pPathObject->isActive() ); + + // Callback. + // VPath::onReachNode( %object, %node, %finished ); + Con::executef( this, "onReachNode", buffer[0], buffer[1], buffer[2] ); + } + } + + // Update Object Interp. + timeInterp = mClampF( timeInterp + timeInterpDelta, 0.f, 1.f ); + pathInterp = mClampF( pathInterp + pathInterpDelta, 0.f, 1.f ); + + // Apply Changes. + pPathObject->setTimeInterp( timeInterp ); + pPathObject->setPathInterp( pathInterp ); + pPathObject->setPosition( newPosition ); + +#ifdef VPATH_DEBUG_STEP + if ( isServerObject() ) + Con::printf( "Time / Distance: %f %f / %f %f", timeInterp, pathInterp, stepDistance, ( newPosition - oldPosition ).len() ); +#endif + + switch ( pPathObject->getOrientationMode().Type ) + { + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToObject : + case VPathObject::k_OrientationToPoint : + { + // Update Orientation. + updateOrientation( pPathObject ); + + } break; + + case VPathObject::k_OrientationToPath : + { + // Determine the path orientation. + VectorF pathOrientation = ( newPosition - oldPosition ); + pathOrientation.normalize(); + + // Update Orientation. + updateOrientation( pPathObject, pathOrientation ); + + } break; + } + + // Update Delta. + pPathObject->pushDelta( pPathObject->getPosition(), pPathObject->getOrientation() ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Update This Object. + pPathObject->setMaskBits( VPathObject::k_StateUpdatePosition ); + } +} + +void VPath::updatePosition( VPathObject *pPathObject ) +{ + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Fetch Position. + F32 pathInterp = 0.f; + const Point3F newPosition = getPathPosition( srcNode, dstNode, pPathObject->getTimeInterp(), pPathObject->isForward(), pathInterp ); + + // Apply Position. + pPathObject->setPosition( newPosition ); + pPathObject->setPathInterp( pathInterp ); +} + +void VPath::updateOrientation( VPathObject *pPathObject ) +{ + // Update Orientation? + if ( pPathObject->getOrientationMode().Type == VPathObject::k_OrientationFree ) + { + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Determine Path Orientation. + VectorF pathOrientation; + switch ( pPathObject->getOrientationMode().Type ) + { + case VPathObject::k_OrientationInterpolate : + { + // Interpolate Between Transforms. + QuatF rot; + rot.interpolate( srcNode->getWorldRotation(), dstNode->getWorldRotation(), pPathObject->getPathInterp() ); + + // Set Matrix. + MatrixF mat; + rot.setMatrix( &mat ); + + // Fetch Orientation. + pathOrientation = mat.getColumn3F( 1 ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Orientation. + pathOrientation = ( pPathObject->getOrientationMode().Object->getPosition() - pPathObject->getWorldPosition() ); + pathOrientation.normalizeSafe(); + + } break; + + case VPathObject::k_OrientationToPoint : + { + // Fetch Orientation. + pathOrientation = ( pPathObject->getOrientationMode().Point - pPathObject->getWorldPosition() ); + pathOrientation.normalizeSafe(); + + } break; + + case VPathObject::k_OrientationToPath : + { + // Fetch Orientation. + pathOrientation = getPathOrientation( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->isForward() ); + + } break; + } + + // Update. + updateOrientation( pPathObject, pathOrientation ); +} + +void VPath::updateOrientation( VPathObject *pPathObject, const Point3F &pPathOrientation ) +{ + // Update Orientation? + if ( pPathObject->getOrientationMode().Type == VPathObject::k_OrientationFree ) + { + // Skip. + return; + } + + // Fetch Nodes. + VPathNode *srcNode = getNode( pPathObject->getSourceNode() ); + VPathNode *dstNode = getNode( pPathObject->getDestinationNode() ); + + // Determine Source Orientation. + VectorF srcOrientation; + switch ( srcNode->getOrientationMode().Type ) + { + case VPathNode::k_OrientationToPoint : + { + // Fetch Orientation. + srcOrientation = ( srcNode->getOrientationMode().Point - pPathObject->getWorldPosition() ); + srcOrientation.normalize(); + + } break; + + default : + { + // Use Path Orientation. + srcOrientation = pPathOrientation; + + } break; + } + + // Determine Destination Orientation. + VectorF dstOrientation; + switch ( dstNode->getOrientationMode().Type ) + { + case VPathNode::k_OrientationToPoint : + { + // Fetch Orientation. + dstOrientation = ( dstNode->getOrientationMode().Point - pPathObject->getWorldPosition() ); + dstOrientation.normalize(); + + } break; + + default : + { + // Use Path Orientation. + dstOrientation = pPathOrientation; + + } break; + } + + // Determine Actual Orientation. + VectorF orientation; + orientation.interpolate( srcOrientation, dstOrientation, pPathObject->getTimeInterp() ); + + // Apply. + pPathObject->setOrientation( orientation ); +} + +//----------------------------------------------------------------------------- +// +// Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculatePath( void ) +{ + if ( mNodeList.size() < 2 ) + { + // No Path. + return; + } + + switch ( mPathType ) + { + case k_PathLinear : + { + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + if ( itr == ( mNodeList.end() - 1 ) ) + { + // Head, Front. + calculateLinearPath( ( *itr ), ( *( mNodeList.begin() ) ) ); + } + else + { + // Head, Next. + calculateLinearPath( ( *itr ), ( *( itr + 1 ) ) ); + } + } + + } break; + + case k_PathBezier : + { + for ( VPathNodeIterator itr = mNodeList.begin(); itr != mNodeList.end(); itr++ ) + { + if ( itr == ( mNodeList.end() - 1 ) ) + { + // Head, Prev, Front. + calculateBezierPath( ( *itr ), ( *( mNodeList.begin() ) ) ); + } + else + { + // Head, Prev, Next. + calculateBezierPath( ( *itr ), ( *( itr + 1 ) ) ); + } + } + + } break; + } +} + +Point3F VPath::getAdvancedPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + switch( mPathType ) + { + case k_PathLinear : + { + return getAdvancedLinearPathPosition( pPathObject, pTargetDistance, pPathInterpDelta ); + + } break; + + case k_PathBezier : + { + return getAdvancedBezierPathPosition( pPathObject, pTargetDistance, pPathInterpDelta ); + + } break; + } + + // Sanity! + AssertFatal( false, "Invalid path type!" ); + return Point3F::Zero; +} + +DefineEngineMethod( VPath, getPathTransform, const char *, (S32 srcNodeIndex, S32 dstNodeIndex, F32 timeInterp), (0,0,1.0), "( int pSrcNodeIndex, int pDstNodeIndex, float pTimeInterp ) - Get the transform of the path at the interp point between two nodes.\n" + "@param pSrcNodeIndex The first node.\n" + "@param pDstNodeIndex The second node.\n" + "@param pTimeInterp The time to interp between the two nodes. Value is between 0.0 and 1.0.\n" + "@return Returns the transform of the interp time between the two given nodes." ) +{ + // Fetch Nodes. + VPathNode *srcNode = object->getNode(srcNodeIndex); + VPathNode *dstNode = object->getNode(dstNodeIndex); + + // Interp Time. + const F32 &interp = timeInterp; + + // Fetch Position & Orientation. + const Point3F position = object->getPathPosition( srcNode, dstNode, interp, true ); + const VectorF orientation = object->getPathOrientation( srcNode, dstNode, interp, true ); + + // Y-Axis. + VectorF yVec = orientation; + yVec.normalize(); + + // X-Axis. + VectorF xVec = mCross( yVec, VPath::gBezierUp ); + xVec.normalize(); + + // Z-Axis. + VectorF zVec = mCross( xVec, yVec ); + zVec.normalize(); + + // Setup Object Transform. + MatrixF mat( true ); + mat.setColumn( 0, xVec ); + mat.setColumn( 1, yVec ); + mat.setColumn( 2, zVec ); + + // AngAxis. + AngAxisF aa( mat ); + + // Return Buffer; + char *buffer = Con::getReturnBuffer( 256 ); + dSprintf( buffer, 256, "%g %g %g %g %g %g %g", position.x, position.y, position.z, + aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + // Return. + return buffer; +} + +DefineEngineMethod( VPath, getPathPosition, const char *, (S32 srcNodeIndex, S32 dstNodeIndex, F32 timeInterp), (0, 0, 1.0), "( int pSrcNodeIndex, int pDstNodeIndex, int pTimeInterp ) - Get the world position of the path at the interp point between two nodes.\n" + "@param pSrcNodeIndex The first node.\n" + "@param pDstNodeIndex The second node.\n" + "@param pTimeInterp The time to interp between the two nodes. Value is between 0.0 and 1.0.\n" + "@return Returns the world position of the interp time between the two given nodes." ) +{ + // Fetch Nodes. + VPathNode *srcNode = object->getNode(srcNodeIndex); + VPathNode *dstNode = object->getNode(dstNodeIndex); + + // Interp Time. + const F32 &interp = timeInterp; + + // Find Position. + const Point3F position = object->getPathPosition( srcNode, dstNode, interp, true ); + + // Return Buffer; + char *buffer = Con::getReturnBuffer( 128 ); + dSprintf( buffer, 128, "%g %g %g", position.x, position.y, position.z ); + + // Return. + return buffer; +} + +Point3F VPath::getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + F32 pathInterp = 0.f; + return getPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pathInterp ); +} + +Point3F VPath::getPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + switch( mPathType ) + { + case k_PathBezier : + { + return getBezierPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pPathInterp ); + + } break; + + case k_PathLinear : + { + return getLinearPathPosition( pSourceNode, pDestinationNode, pTimeInterp, pForward, pPathInterp ); + + } break; + } + + // NULL. + return Point3F::Zero; +} + +VectorF VPath::getPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + switch( mPathType ) + { + case k_PathBezier : + { + return getBezierPathOrientation( pSourceNode, pDestinationNode, pTimeInterp, pForward ); + + } break; + + case k_PathLinear : + { + return getLinearPathOrientation( pSourceNode, pDestinationNode, pTimeInterp, pForward ); + + } break; + } + + // NULL. + return VectorF::Zero; +} + +//----------------------------------------------------------------------------- +// +// Linear Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculateLinearPath( VPathNode *pNode, VPathNode *pNextNode ) +{ + // Calculate Segment Length. + pNode->setLength( ( pNextNode->getWorldPosition() - pNode->getWorldPosition() ).len() ); +} + +Point3F VPath::getAdvancedLinearPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + + // Fetch the length of the segment. + const F32 length = ( pPathObject->isForward() ) ? srcNode->getLength() : dstNode->getLength(); + + // Set the interp delta. + pPathInterpDelta = ( pTargetDistance / length ); + + // Return the position. + F32 pathInterp = 0.f; + return getLinearPathPosition( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->isForward(), pathInterp ); +} + +Point3F VPath::getLinearPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + // Set path interp to the time interp. + pPathInterp = pTimeInterp; + + if ( pTimeInterp <= 0.f ) + { + // Source Node. + return pSourceNode->getWorldPosition(); + } + else if ( pTimeInterp >= 1.f ) + { + // Destination Node. + return pDestinationNode->getWorldPosition(); + } + + // Calculate Position. + Point3F position; + position.interpolate( pSourceNode->getWorldPosition(), pDestinationNode->getWorldPosition(), pTimeInterp ); + + // Return. + return position; +} + +VectorF VPath::getLinearPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + // Calculate Orientation. + VectorF newOrientation = ( pDestinationNode->getWorldPosition() - pSourceNode->getWorldPosition() ); + newOrientation.normalizeSafe(); + + // Return. + return newOrientation; +} + +//----------------------------------------------------------------------------- +// +// Bezier Path Methods. +// +//----------------------------------------------------------------------------- + +void VPath::calculateBezierPath( VPathNode *pNode, VPathNode *pNextNode ) +{ + // Reset Length. + F32 segmentLength = 0.f; + + // Positions. + const Point3F &pt0 = pNode->getWorldPosition(); + const Point3F &pt3 = pNextNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pNode->getWorldRotation().setMatrix( &mat0 ); + pNextNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pNode->getWeight() ); + Point3F pt2( -gBezierAxis * pNextNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Initial Position. + Point3F ptA = pt0; + const F32 i = gBezierInterpStep; + for ( F32 t = 0.f, it = ( 1.f - t ); t <= 1.f; t += i, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F ptB = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + + // Add Segment. + segmentLength += ( ptB - ptA ).len(); + + // Store Position. + ptA = ptB; + } + + // Apply Update. + pNode->setLength( segmentLength ); +} + +Point3F VPath::getAdvancedBezierPathPosition( VPathObject *pPathObject, const F32 &pTargetDistance, F32 &pPathInterpDelta ) +{ + // Fetch Nodes. + VPathNode *srcNode = mNodeList[pPathObject->getSourceNode()]; + VPathNode *dstNode = mNodeList[pPathObject->getDestinationNode()]; + + // Fetch the delta position. + return getBezierPathPosition( srcNode, dstNode, pPathObject->getPathInterp(), pPathObject->getPosition(), pTargetDistance, pPathObject->isForward(), true, pPathInterpDelta ); +} + +Point3F VPath::getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward, F32 &pPathInterp ) +{ + // Fetch the length of the segment. + const F32 length = ( pForward ) ? pSourceNode->getLength() : pDestinationNode->getLength(); + + // Determine the real interp time for the distance fraction. + return getBezierPathPosition( pSourceNode, pDestinationNode, 0.f, pSourceNode->getWorldPosition(), ( length * pTimeInterp ), pForward, false, pPathInterp ); +} + +Point3F VPath::getBezierPathPosition( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const Point3F &pReferencePosition, const F32 &pTargetDistance, const bool &pForward, const bool &pRelativeToReference, F32 &pPathInterpDelta ) +{ + // Positions. + const Point3F &pt0 = pSourceNode->getWorldPosition(); + const Point3F &pt3 = pDestinationNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pSourceNode->getWorldRotation().setMatrix( &mat0 ); + pDestinationNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pSourceNode->getWeight() ); + Point3F pt2( -gBezierAxis * pDestinationNode->getWeight() ); + + if ( !pForward ) + { + pt1 *= -1.f; + pt2 *= -1.f; + } + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Move Position. + Point3F movePosition = pReferencePosition; + // Movement Distance. + F32 moveDistance = 0.f; + + // Determine the Real Delta. + const F32 i = gBezierInterpStep; + for ( F32 t = ( pTimeInterp + i ), it = ( 1.f - t ); t <= 1.f; t += i, it = ( 1.f - t ) ) + { + // Calculate Step. + const Point3F stepPosition = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + // Step Length. + const F32 &stepDistance = ( stepPosition - movePosition ).len(); + + if ( pRelativeToReference ) + { + // Calculate Distance. + moveDistance = ( pReferencePosition - stepPosition ).len(); + + // Moved Target Distance? + if ( moveDistance >= pTargetDistance ) + { + // Interpolate Step. + const F32 stepInterp = ( moveDistance - pTargetDistance ) / moveDistance; + // Store Interp Delta. + pPathInterpDelta = ( t - pTimeInterp ) * ( 1.f - stepInterp ); + + // Interpolate the step. + Point3F outPosition; + outPosition.interpolate( pReferencePosition, stepPosition, ( 1.f - stepInterp ) ); + // Return the position. + return outPosition; + } + } + else + { + // Calculate Distance. + moveDistance += stepDistance; + + // Moved Target Distance? + if ( moveDistance >= pTargetDistance ) + { + // Interpolate Step. + const F32 stepInterp = ( moveDistance - pTargetDistance ) / stepDistance; + // Store Interp Delta. + pPathInterpDelta = ( t - pTimeInterp ) - ( stepInterp * i ); + + // Interpolate the step. + Point3F outPosition; + outPosition.interpolate( movePosition, stepPosition, ( 1.f - stepInterp ) ); + // Return the position. + return outPosition; + } + } + + // Apply New Position. + movePosition = stepPosition; + } + + // Update. + pPathInterpDelta = ( 1.f - pTimeInterp ); + // At the destination node? + return pt3; +} + +VectorF VPath::getBezierPathOrientation( VPathNode *pSourceNode, VPathNode *pDestinationNode, const F32 &pTimeInterp, const bool &pForward ) +{ + // Positions. + const Point3F &pt0 = pSourceNode->getWorldPosition(); + const Point3F &pt3 = pDestinationNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + pSourceNode->getWorldRotation().setMatrix( &mat0 ); + pDestinationNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( gBezierAxis * pSourceNode->getWeight() ); + Point3F pt2( -gBezierAxis * pDestinationNode->getWeight() ); + + if ( !pForward ) + { + pt1 *= -1.f; + pt2 *= -1.f; + } + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + const F32 halfStep = ( gBezierInterpStep / 2.f ); + if ( ( pTimeInterp - halfStep ) <= 0.f ) + { + // Orientation From Node Tangent. + pt1.normalize(); + + // Return. + return pt1; + } + else if ( ( pTimeInterp + halfStep ) >= 1.f ) + { + // Orientation From Node Tangent. + pt2.normalize(); + + // Return. + return -pt2; + } + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + // Interp Times. + const F32 t0 = ( pTimeInterp - halfStep ); + const F32 it0 = ( 1.f - t0 ); + + const F32 t1 = ( pTimeInterp + halfStep ); + const F32 it1 = ( 1.f - t1 ); + + // Calculate Position. + Point3F d0 = ( pt0 * it0 * it0 * it0 ) + ( 3 * pt1 * it0 * it0 * t0 ) + ( 3 * pt2 * it0 * t0 * t0 ) + ( pt3 * t0 * t0 * t0 ); + Point3F d1 = ( pt0 * it1 * it1 * it1 ) + ( 3 * pt1 * it1 * it1 * t1 ) + ( 3 * pt2 * it1 * t1 * t1 ) + ( pt3 * t1 * t1 * t1 ); + + // Set Orientation. + Point3F orientation = ( d1 - d0 ); + orientation.normalizeSafe(); + + // Return. + return orientation; +} + +//----------------------------------------------------------------------------- +// +// Path Node Property Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VPath, getNodeCount, S32, (),, "() - Get the number of nodes in this path.\n" + "@return Returns the number of nodes." ) +{ + // Return Count. + return object->getNodeCount(); +} + +S32 VPath::getNodeCount( void ) +{ + // Return the Size of the Node List. + return mNodeList.size(); +} + +DefineEngineMethod( VPath, getNodeLocalTransform, const char *, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the local transform (local position and rotation) of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the transform of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeLocalPosition(nodeIndex); + + // Fetch Rotation. + const QuatF &rotation = object->getNodeLocalRotation(nodeIndex); + + // Angle & Axis. + AngAxisF aa( rotation ); + + // Return Buffer. + char *buffer = Con::getReturnBuffer( 256 ); + dSprintf( buffer, 128, "%.3g %.3g %.3g %.3g %.3g %.3g %.3g", position.x, position.y, position.z, aa.axis.x, aa.axis.y, aa.axis.z, aa.angle ); + + return buffer; +} + +DefineEngineMethod( VPath, getNodeLocalPosition, Point3F, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + " @return Returns the Local Position of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeLocalPosition(nodeIndex); + + return position; +} + +Point3F VPath::getNodeLocalPosition( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLocalPosition() - Invalid Index Specified (%d).", pNodeIndex ); + return Point3F::Zero; + } + + return mNodeList[pNodeIndex]->getLocalPosition(); +} + +DefineEngineMethod( VPath, getNodeLocalRotation, AngAxisF, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the Local Rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the Local Rotation of the given node." ) +{ + // Fetch Rotation. + const QuatF &rotation = object->getNodeLocalRotation(nodeIndex); + + // Angle & Axis. + AngAxisF aa( rotation ); + + return aa; +} + +QuatF VPath::getNodeLocalRotation( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLocalRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return QuatF( Point3F::Zero, 0.f ); + } + + return mNodeList[pNodeIndex]->getLocalRotation(); +} + +DefineEngineMethod( VPath, getNodeWorldTransform, TransformF, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the World Transform (position and rotation) of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the transform of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeWorldPosition(nodeIndex); + + // Fetch Rotation. + const QuatF &rotation = object->getNodeWorldRotation(nodeIndex); + + // Angle & Axis. + AngAxisF aa( rotation ); + + TransformF trans; + trans.mPosition = position; + trans.mOrientation = aa; + + return trans; +} + +DefineEngineMethod( VPath, getNodeWorldPosition, Point3F, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the World Position of the given node." ) +{ + // Fetch Position. + const Point3F &position = object->getNodeWorldPosition(nodeIndex); + + return position; +} + +Point3F VPath::getNodeWorldPosition( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWorldPosition() - Invalid Index Specified (%d).", pNodeIndex ); + return Point3F::Zero; + } + + return mNodeList[pNodeIndex]->getWorldPosition(); +} + +DefineEngineMethod( VPath, getNodeWorldRotation, AngAxisF, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the World Rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the World Rotation of the given node." ) +{ + // Fetch Rotation. + const QuatF &rotation = object->getNodeWorldRotation(nodeIndex); + + // Angle & Axis. + AngAxisF aa( rotation ); + + return aa; +} + +QuatF VPath::getNodeWorldRotation( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWorldRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return QuatF( Point3F::Zero, 0.f ); + } + + return mNodeList[pNodeIndex]->getWorldRotation(); +} + +DefineEngineMethod( VPath, getNodeWeight, F32, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the weight of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the weight of the given node." ) +{ + // Fetch Weight. + return object->getNodeWeight(nodeIndex); +} + +F32 VPath::getNodeWeight( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeWeight() - Invalid Index Specified (%d).", pNodeIndex ); + return 0.f; + } + + return mNodeList[pNodeIndex]->getWeight(); +} + +DefineEngineMethod( VPath, getNodeLength, F32, (S32 nodeIndex), (0), "( int pNodeIndex ) - Get the length of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns the length of the given node." ) +{ + // Fetch Length. + return object->getNodeLength( nodeIndex ); +} + +F32 VPath::getNodeLength( const S32 &pNodeIndex ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::getNodeLength() - Invalid Index Specified (%d).", pNodeIndex ); + return 0.f; + } + + return mNodeList[pNodeIndex]->getLength(); +} + +DefineEngineMethod( VPath, setNodeTransform, void, (S32 nodeIndex, TransformF transform), (0, MatrixF::Identity), "( int pNodeIndex, matrix pTransform ) - Set the transform of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pTransform The new transform to be applied to the node.\n" + "@return No return value." ) +{ + // Fetch Position & Rotation. + Point3F position = transform.mPosition; + AngAxisF aa = transform.mOrientation; + QuatF rotation; + + // Set Rotation. + rotation.set( aa ); + + // Apply Update. + object->setNodePosition( nodeIndex, position ); + object->setNodeRotation( nodeIndex, rotation ); +} + +DefineEngineMethod( VPath, setNodePosition, void, (S32 nodeIndex, Point3F position), (0, Point3F::Zero), "( int pNodeIndex, vector pPosition ) - Set the position of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pPosition The new position to be applied to the node.\n" + "@return No return value." ) +{ + // Apply Update. + object->setNodePosition( nodeIndex, position ); +} + +void VPath::setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodePosition() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setLocalPosition( pPosition ); + + // Update Size. + updateContainer(); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +DefineEngineMethod( VPath, setNodeRotation, void, (S32 nodeIndex, AngAxisF aa), (0, AngAxisF()), "( int pNodeIndex, angAxis pRotation ) - Set the rotation of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pRotation The new rotation to be applied to the node.\n" + "@return No return value." ) +{ + QuatF rotation; + + // Set Rotation. + rotation.set( aa ); + + // Apply Update. + object->setNodeRotation( nodeIndex, rotation ); +} + +void VPath::setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeRotation() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setLocalRotation( pRotation ); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +DefineEngineMethod( VPath, setNodeWeight, void, (S32 nodeIndex, F32 nodeWeight), (0, 1.0), "( int pNodeIndex, float pWeight ) - Set the weight of the given node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pWeight The new weight to be applied to the node.\n" + "@return No return value." ) +{ + // Apply Update. + object->setNodeWeight( nodeIndex, nodeWeight ); +} + +void VPath::setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeWeight() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply Update. + node->setWeight( pWeight ); + + // Calculate Path. + calculatePath(); + + if ( isServerObject() ) + { + // Network Flags. + setMaskBits( NodeUpdateMask ); + } +} + +DefineEngineMethod( VPath, getNodeOrientationMode, const char *, (S32 nodeIndex), (0), "( int pNodeIndex ) - Gets the current orientation mode of the node.\n" + "@param pNodeIndex The index of the node.\n" + "@return Returns a string indicating the orientation mode and its properties." ) +{ + if ( nodeIndex < 0 || nodeIndex >= object->getNodeCount() ) + { + // Woops! + Con::warnf( "VPath::getNodeOrientationMode() - Invalid Index Specified (%d).", nodeIndex ); + return ""; + } + + // Fetch Object + VPathNode *node = object->getNode( nodeIndex ); + + // Fetch Orientation Mode. + const VPathNode::sOrientation &orientation = node->getOrientationMode(); + + // Determine the Type. + StringTableEntry type = VPathNode::getOrientationTypeLabel( orientation.Type ); + + // Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + + switch( orientation.Type ) + { + case VPathNode::k_OrientationFree : + { + // Buffer String. + dSprintf( buffer, 128, "%s", type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + // Fetch Point. + const Point3F &lookAtPoint = orientation.Point; + // Buffer String. + dSprintf( buffer, 128, "%s\t%.2f %.2f %.2f", type, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z ); + + } break; + } + + // Return Buffer. + return buffer; +} + +DefineEngineStringlyVariadicMethod( VPath, setNodeOrientationMode, void, 4, 5, "( int pNodeIndex, string pOrientationType, [vector pPoint] ) - Set the orientation mode of the node.\n" + "@param pNodeIndex The index of the node.\n" + "@param pOrientationType The new orientation type of the object.\n" + "@param pPoint If the orientation type is set to POINT, this parameter must be a vector.\n" + "@return No return value." ) +{ + // Fetch Index. + const S32 nodeIndex = dAtoi( argv[2] ); + + // Orient? + const VPathNode::eOrientationType type = VPathNode::getOrientationTypeEnum( argv[3] ); + + switch ( type ) + { + case VPathNode::k_OrientationFree : + { + // Apply Mode. + object->setNodeOrientationMode( nodeIndex, type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( argv[4], "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + object->setNodeOrientationMode( nodeIndex, type, lookAtPoint ); + + } break; + + default : + { + AssertFatal( false, "VPath::setNodeOrientationMode() - Invalid Orientation Mode Specified." ); + + } break; + } +} + +void VPath::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeOrientationMode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply. + node->setOrientationMode( pType ); + + // Network Flags. + setMaskBits( NodeUpdateMask ); +} + +void VPath::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F pPoint ) +{ + if ( pNodeIndex < 0 || pNodeIndex >= mNodeList.size() ) + { + // Woops! + Con::warnf( "VPath::setNodeOrientationMode() - Invalid Index Specified (%d).", pNodeIndex ); + return; + } + + // Fetch Node. + VPathNode *node = mNodeList[pNodeIndex]; + + // Apply. + node->setOrientationMode( pType, pPoint ); + + // Network Flags. + setMaskBits( NodeUpdateMask ); +} + +//----------------------------------------------------------------------------- +// +// Path Object Property Methods. +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VPath, isPathObjectActive, bool, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Is the object actively traveling around this path?\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns true of the object is active." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::isPathObjectActive() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->isActive(); +} + +DefineEngineMethod( VPath, setPathObjectActive, void, (SceneObject *sceneObject, bool isActive), (nullAsType(), true), "( SimObject pObject, bool pActive ) - Enable or disable the object from traveling around this path. Inactive objects are still attached to the path, but are not updated.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pActive The new status of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectActive() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectActive( sceneObject, isActive); +} + +void VPath::setPathObjectActive( SceneObject *pObject, const bool &pActive ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectActive() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setActive( pActive ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, getPathObjectInterp, F32, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Get the current interp position of the path object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the current interp position." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectInterp() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getTimeInterp(); +} + +DefineEngineMethod( VPath, setPathObjectInterp, void, (SceneObject *sceneObject, F32 timeInterp), (nullAsType(), 1.0), "( SimObject pObject, float pTimeInterp ) - Set the interp position of the object between its current nodes.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pTimeInterp The new interp position of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectInterp() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectInterp( sceneObject, timeInterp); +} + +void VPath::setPathObjectInterp( SceneObject *pObject, const F32 &pTimeInterp ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectInterp() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Update. + setPathObjectInterp( pathObject, pTimeInterp ); +} + +void VPath::setPathObjectInterp( VPathObject *pPathObject, const F32 &pTimeInterp ) +{ + // Set Interp Time. + pPathObject->setTimeInterp( pTimeInterp ); + + // Update Position. + updatePosition( pPathObject ); + // Update Orientation. + updateOrientation( pPathObject ); + // Reset the delta. + pPathObject->resetDelta(); + + // Set the object transform. + pPathObject->getObject()->setTransform( pPathObject->getTransform() ); + + if ( isServerObject() ) + { + // Update Objects. + setMaskBits( ObjectUpdateMask ); + + // Update This Object. + pPathObject->setMaskBits( VPathObject::k_StateUpdatePosition ); + } +} + +DefineEngineMethod( VPath, getPathObjectOffset, const char *, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Get the position offset assigned to this object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the position offset." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectOffset() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Fetch Offset. + const Point3F &offset = pathObject->getOffset(); + + // Buffer. + char *buffer = Con::getReturnBuffer( 64 ); + dSprintf( buffer, 64, "%f %f %f", offset.x, offset.y, offset.z ); + return buffer; +} + +DefineEngineMethod( VPath, setPathObjectOffset, void, (SceneObject *sceneObject, Point3F offset), (nullAsType(), Point3F::Zero), "( SimObject pObject, vector pOffset ) - Set the position offset of the object. As the object is moving along the path, its position is offset by this value. Setting the \"Relative\" parameter while attaching an object will automatically apply an offset value.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pOffset The new position offset of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectOffset() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectOffset( sceneObject, offset ); +} + +void VPath::setPathObjectOffset( SceneObject *pObject, const Point3F &pOffset ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOffset() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOffset( pOffset ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, getPathObjectSpeed, F32, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Get the speed this object is traveling along the path at.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the speed of the object." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectSpeed() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getSpeed(); +} + +DefineEngineMethod( VPath, setPathObjectSpeed, void, (SceneObject *sceneObject, F32 speed), (nullAsType(), 1.0), "( SimObject pObject, float pSpeed ) - Set the speed of the object.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pSpeed The new speed of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectSpeed() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectSpeed( sceneObject, speed ); +} + +void VPath::setPathObjectSpeed( SceneObject *pObject, const F32 &pSpeed ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectSpeed() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setSpeed( mFabs( pSpeed ) ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, getPathObjectOrientationMode, const char *, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Gets the current orientation mode of the object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns a string indicating the orientation mode and its properties." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectOrientationMode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Fetch Orientation Mode. + const VPathObject::sOrientation &orientation = pathObject->getOrientationMode(); + + // Determine the Type. + StringTableEntry type = VPathObject::getOrientationTypeLabel( orientation.Type ); + + // Buffer. + char *buffer = Con::getReturnBuffer( 128 ); + + switch( orientation.Type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Buffer String. + dSprintf( buffer, 128, "%s", type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch the Object ID. + const S32 objId = ( ( orientation.Object ) ? orientation.Object->getId() : 0 ); + // Buffer String. + dSprintf( buffer, 128, "%s %d", type, objId ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + const Point3F &lookAtPoint = orientation.Point; + // Buffer String. + dSprintf( buffer, 128, "%s %f %f %f", type, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z ); + + } break; + } + + // Return Buffer. + return buffer; +} + +DefineEngineStringlyVariadicMethod( VPath, setPathObjectOrientationMode, void, 4, 5, "( SimObject pObject, string pOrientationType, [SimObject pObject / vector pPoint] ) - Set the orientation mode of the object. This property affects the rotation of the object. If you wish to ignore the object's rotation altogether, set the mode to \"FREE\".\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pOrientationType The new orientation type of the object.\n" + "@param pObject If the orientation type is set to OBJECT, this parameter must be the SimObjectID of a scene object.\n" + "@param pPoint If the orientation type is set to POINT, this parameter must be a vector.\n" + "@return No return value." ) +{ + // Fetch Object. + SceneObject *sceneObject; + if ( !Sim::findObject( argv[2], sceneObject ) ) + { + Con::errorf( "VPath::setPathObjectOrientationMode() - Invalid Target Object." ); + return; + } + + // Orient? + const VPathObject::eOrientationType type = VPathObject::getOrientationTypeEnum( argv[3] ); + + switch ( type ) + { + case VPathObject::k_OrientationFree : + case VPathObject::k_OrientationInterpolate : + case VPathObject::k_OrientationToPath : + { + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type ); + + } break; + + case VPathObject::k_OrientationToObject : + { + // Fetch Object. + SceneObject *lookAtObject = dynamic_cast( Sim::findObject( argv[4] ) ); + if ( !lookAtObject ) + { + Con::errorf( "VPath::setPathObjectOrientationMode() - Invalid LookAt Object." ); + return; + } + + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type, lookAtObject ); + + } break; + + case VPathObject::k_OrientationToPoint: + { + // Fetch Point. + Point3F lookAtPoint( 0.f, 0.f, 0.f ); + dSscanf( argv[4], "%g %g %g", &lookAtPoint.x, &lookAtPoint.y, &lookAtPoint.z ); + + // Apply Mode. + object->setPathObjectOrientationMode( sceneObject, type, lookAtPoint ); + + } break; + + default : + { + AssertFatal( false, "VPath::setPathObjectOrientationMode() - Invalid Orientation Mode Specified." ); + + } break; + } +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, SceneObject *pLookAtObject ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType, pLookAtObject ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +void VPath::setPathObjectOrientationMode( SceneObject *pObject, const VPathObject::eOrientationType &pType, const Point3F pPoint ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectOrientationMode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setOrientationMode( pType, pPoint ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, isPathObjectForward, bool, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Get if this object is traveling forwards along the path.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns true if the object is traveling forwards." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::isPathObjectForward() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->isForward(); +} + +DefineEngineMethod( VPath, setPathObjectForward, void, (SceneObject *sceneObject, bool forward), (nullAsType(), true), "( SimObject pObject, bool pForward ) - Set the travel direction of the object.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pForward The direction of the object.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectForward() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectForward( sceneObject, forward); +} + +void VPath::setPathObjectForward( SceneObject *pObject, const bool &pForward ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectForward() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Apply. + pathObject->setForward( pForward ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, getPathObjectNode, S32, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Gets the last node of the object.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the node index." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectNode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getSourceNode(); +} + +DefineEngineMethod( VPath, setPathObjectNode, void, (SceneObject *sceneObject, S32 nodeIndex), (nullAsType(), 0), "( SimObject pObject, bool pNodeIndex ) - Move the object to the node's position. You may also want to observe the \"setPathObjectInterp\" method.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pNodeIndex The index of the node that the object will reposition to.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectNode() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectNode( sceneObject, nodeIndex); +} + +void VPath::setPathObjectNode( SceneObject *pObject, const S32 &pNodeIndex ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectNode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Source & Destination Nodes. + const S32 srcNode = pNodeIndex; + const S32 dstNode = ( pathObject->isForward() ) ? ( pNodeIndex + 1 ) : ( pNodeIndex - 1 ); + + // Set Current Node. + pathObject->setNode( normalizeNodeIndex( srcNode ), normalizeNodeIndex( dstNode ) ); + + // Reset Interp. + pathObject->setTimeInterp( 0.f ); + pathObject->setPathInterp( 0.f ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} + +DefineEngineMethod( VPath, getPathObjectEndNode, S32, (SceneObject *sceneObject), (nullAsType()), "( SimObject pObject ) - Get the index of the node this object is meant to stop upon reaching.\n" + "@param pObject The SimObjectID of the object being observed.\n" + "@return Returns the node index." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::getPathObjectEndNode() - Invalid Target Object." ); + return false; + } + + // Fetch Object + VPathObject *pathObject = object->getPathObject( sceneObject ); + + // Return. + return pathObject->getEndNode(); +} + +DefineEngineMethod( VPath, setPathObjectEndNode, void, (SceneObject *sceneObject, S32 nodeIndex), (nullAsType(), 0), "( SimObject pObject, bool pNodeIndex ) - Set end node of the path object. If a value of \"-1\" is applied, the object will path indefinitely.\n" + "@param pObject The SimObjectID of the object being altered.\n" + "@param pNodeIndex The index of the node that the object will cease pathing upon reaching.\n" + "@return No return value." ) +{ + // Fetch Object. + if (sceneObject == nullptr) + { + Con::errorf( "VPath::setPathObjectEndNode() - Invalid Target Object." ); + return; + } + + // Apply. + object->setPathObjectEndNode( sceneObject, nodeIndex); +} + +void VPath::setPathObjectEndNode( SceneObject *pObject, const S32 &pNodeIndex ) +{ + VPathObject *pathObject = getPathObject( pObject ); + if ( !pathObject ) + { + Con::warnf( "VPath::setPathObjectEndNode() - Object (%d) Not Attached to Path.", pObject->getId() ); + return; + } + + // Set index. + S32 index = pNodeIndex; + + if ( index != -1 ) + { + // Normalize index. + normalizeNodeIndex( index ); + } + + // Apply. + pathObject->setEndNode( index ); + + // Network Flags. + setMaskBits( ObjectUpdateMask ); +} diff --git a/Engine/source/Verve/VPath/VPath.h b/Engine/source/Verve/VPath/VPath.h new file mode 100644 index 000000000..925d88d78 --- /dev/null +++ b/Engine/source/Verve/VPath/VPath.h @@ -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 VPathNodeVector; +typedef VPathNodeVector::iterator VPathNodeIterator; + +typedef Vector VPathObjectVector; +typedef VPathObjectVector::iterator VPathObjectIterator; + +//----------------------------------------------------------------------------- + +class VPath : public SceneObject +{ + typedef SceneObject Parent; + + friend class VPathEditor; + +public: + + // Static Members. + + static SimObjectPtr 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_ \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPathEditor.cpp b/Engine/source/Verve/VPath/VPathEditor.cpp new file mode 100644 index 000000000..6315e6560 --- /dev/null +++ b/Engine/source/Verve/VPath/VPathEditor.cpp @@ -0,0 +1,2190 @@ +//----------------------------------------------------------------------------- +// 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 "VPathEditor.h" + +#include "console/consoleTypes.h" +#include "gfx/gfxDrawUtil.h" +#include "gfx/primBuilder.h" +#include "gui/worldEditor/worldEditor.h" +#include "math/mathUtils.h" +#include "sim/netConnection.h" + +//----------------------------------------------------------------------------- + +static F32 gProjectDistance = 2000.f; +static F32 gSelectionDistance = 2.f; + +static ColorI gPathColor( 255, 255, 255 ); +static ColorI gPathColorSel( 0, 255, 255 ); +static ColorI gNodeLookAtPointColor( 255, 127, 39 ); + +//----------------------------------------------------------------------------- + +// Implement the Edit Mode enum list. +ImplementEnumType( VPathEditorMode, "" ) + { VPathEditor::k_Gizmo, "GIZMO" }, + { VPathEditor::k_AddNode, "ADDNODE" }, + { VPathEditor::k_DeleteNode, "DELETENODE" }, +EndImplementEnumType; + +//----------------------------------------------------------------------------- +IMPLEMENT_CONOBJECT( VPathEditor ); +//----------------------------------------------------------------------------- + +VPathEditor::VPathEditor( void ) : + mIsDirty( false ), + mEditMode( k_Gizmo ), + mEditWeight( false ), + mEditWeightHandle( -1 ) +{ + // Void. +} + +bool VPathEditor::onAdd( void ) +{ + if ( !Parent::onAdd() ) + { + return false; + } + + // Assign Gizmo Name. + mGizmo->assignName( "VPathEditorGizmo" ); + + return true; +} + +bool VPathEditor::onWake( void ) +{ + // Clear Selection. + updateSelection( NULL, -1 ); + + // Return Parent Value. + return Parent::onWake(); +} + +void VPathEditor::initPersistFields( void ) +{ + addField( "IsDirty", TypeBool, Offset( mIsDirty, VPathEditor ) ); + addField( "EditMode", TYPEID(), Offset( mEditMode, VPathEditor ) ); + + Parent::initPersistFields(); +} + +//----------------------------------------------------------------------------- +// +// Gui Events +// +//----------------------------------------------------------------------------- + +void VPathEditor::on3DMouseDown( const Gui3DMouseEvent &pEvent ) +{ + // Using the Gizmo? + if ( mEditMode != k_Gizmo ) + { + // No, Quit Now. + return; + } + + // Gizmo Event. + mGizmo->on3DMouseDown( pEvent ); + + if ( isValidSelection() ) + { + // Store Node Information. + pushNodeEdit(); + + switch( mGizmoProfile->mode ) + { + case MoveMode: + case RotateMode: + { + if ( mGizmo->getSelection() != Gizmo::None ) + { + // Using Gizmo. + return; + } + + } break; + + case ScaleMode: + { + if ( isEditingWeight( pEvent ) ) + { + // Editing Weights. + return; + } + + } break; + } + } + else if ( mSelection.Path ) + { + // Store Path Information. + pushPathEdit(); + + if ( mGizmo->getSelection() != Gizmo::None ) + { + // Using Gizmo. + return; + } + } + + // Update Selection. + if ( !updateSelection( pEvent ) ) + { + // Clear Selection. + updateSelection( NULL, -1 ); + } +} + +void VPathEditor::on3DMouseUp( const Gui3DMouseEvent &pEvent ) +{ + switch ( mEditMode ) + { + case k_Gizmo : + { + // Gizmo Event. + mGizmo->on3DMouseUp( pEvent ); + + // Handle History Actions. + popPathEdit(); + popNodeEdit(); + + // Clear Editing. + mEditWeight = false; + + } break; + + case k_AddNode : + { + if ( mSelection.Path != NULL ) + { + // Add New! + addNode( pEvent ); + + // Dirty. + mIsDirty = true; + } + + } break; + + case k_DeleteNode : + { + // Update Selection. + if ( updateSelection( pEvent ) ) + { + if ( isValidSelection() ) + { + // Delete Node. + deleteNode( mSelection.Node ); + + // Dirty. + mIsDirty = true; + } + + // Clear Node Selection. + updateSelection( mSelection.Path, -1 ); + } + + } break; + } +} + +void VPathEditor::on3DMouseMove( const Gui3DMouseEvent &pEvent ) +{ + // Update? + if ( mEditMode != k_Gizmo || !mSelection.Path ) + { + return; + } + + // Update Gizmo? + if ( mSelection.Node == -1 || mGizmoProfile->mode != ScaleMode ) + { + // Gizmo Event. + mGizmo->on3DMouseMove( pEvent ); + } +} + +void VPathEditor::on3DMouseDragged( const Gui3DMouseEvent &pEvent ) +{ + // Update? + if ( mEditMode != k_Gizmo || !mSelection.Path ) + { + return; + } + + // Update Gizmo? + if ( mSelection.Node == -1 || mGizmoProfile->mode != ScaleMode ) + { + // Gizmo Event. + mGizmo->on3DMouseDragged( pEvent ); + + // Handle Gizmo? + if ( mGizmo->getSelection() == Gizmo::None ) + { + // Return. + return; + } + } + + // Editing the Path? + if ( mSelection.Node == -1 ) + { + switch ( mGizmoProfile->mode ) + { + case MoveMode : + { + // Fetch Node Position. + const Point3F oldPosition = mSelection.Path->getPosition(); + // Determine New Position. + const Point3F newPosition = ( oldPosition + mGizmo->getOffset() ); + + // Apply New Position. + setPathPosition( newPosition ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + /* + case RotateMode : + { + + // Rotation Delta. + MatrixF deltaRotation( EulerF( mGizmo->getDeltaRot() ) ); + + // Fetch Current Transform. + MatrixF mat = mSelection.Path->getTransform(); + mat.mul( deltaRotation ); + + // Apply New Transform. + setPathTransform( mat ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + + case ScaleMode : + { + + // Apply New Scale. + setPathScale( mGizmo->getScale() ); + + // Dirty. + mIsDirty = true; + mPathEdit.Dirty = true; + + } break; + */ + } + } + + // No, Editing a Node + else + { + switch ( mGizmoProfile->mode ) + { + case MoveMode : + { + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Fetch Node Position. + const Point3F oldPosition = node->getLocalPosition(); + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + Point3F deltaPosition = mGizmo->getOffset(); + pathTransform.mulP( deltaPosition ); + + // Apply New Position. + setNodePosition( mSelection.Node, ( oldPosition + deltaPosition ) ); + + } break; + + case RotateMode : + { + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + // Rotation Delta. + MatrixF deltaRotation( EulerF( mGizmo->getDeltaRot() ) ); + pathTransform.mul( deltaRotation ); + + // Fetch Current Transform. + MatrixF mat = node->getWorldTransform(); + mat.mul( deltaRotation ); + + // Construct Quat. + QuatF newRotation; + newRotation.set( mat ); + + // Apply New Rotation. + setNodeRotation( mSelection.Node, newRotation ); + + } break; + + case ScaleMode : + { + + if ( isEditingWeight() ) + { + // Edit Weight. + updateWeight( pEvent ); + } + + } break; + } + } +} + +//----------------------------------------------------------------------------- +// +// Reference Methods. +// +//----------------------------------------------------------------------------- + +VPath *VPathEditor::getClientPath( VPath *pPath ) +{ + if ( !pPath ) + { + return NULL; + } + + NetConnection *toServer = NetConnection::getConnectionToServer(); + NetConnection *toClient = NetConnection::getLocalClientConnection(); + if ( !toServer || !toClient ) + { + return NULL; + } + + const S32 ghostIndex = toClient->getGhostIndex( pPath ); + if ( ghostIndex == -1 ) + { + return NULL; + } + + return dynamic_cast( toServer->resolveGhost( ghostIndex ) ); +} + +//----------------------------------------------------------------------------- +// +// Selection Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::updateSelection( const Gui3DMouseEvent &pEvent ) +{ + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + RayInfo ri; + if ( !gServerContainer.collideBox( pt0, pt1, MarkerObjectType, &ri ) ) + { + // No Object. + return false; + } + + VPath *path = dynamic_cast( ri.object ); + if ( !path ) + { + // No Path Object. + return false; + } + + // No Node. + S32 nodeIndex = -1; + + for ( VPathNodeIterator itr = path->mNodeList.begin(); itr != path->mNodeList.end(); itr++ ) + { + VPathNode *node = ( *itr ); + + Point3F projPosition; + project( node->getWorldPosition(), &projPosition ); + + if ( projPosition.z <= 0.0f ) + { + continue; + } + + const Point2I rectHalfSize( 8, 8 ); + const Point2I screenPosition( ( S32 )projPosition.x, ( S32 )projPosition.y ); + const RectI screenRect( screenPosition - rectHalfSize, 2 * rectHalfSize ); + + // Mouse Close Enough? + if ( screenRect.pointInRect( pEvent.mousePoint ) ) + { + // Select Node. + nodeIndex = ( itr - path->mNodeList.begin() ); + } + } + + // Set Selection. + updateSelection( path, nodeIndex ); + + // Valid Selection. + return true; +} + +void VPathEditor::updateSelection( VPath *pPathObject, const S32 &pNodeIndex ) +{ + // Store Selection. + mSelection.Path = pPathObject; + mSelection.Node = pNodeIndex; + + // Quick Update. + updateSelection(); + + // Return Buffer. + char buffer[2][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", ( pPathObject ) ? pPathObject->getId() : 0 ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + + // Callback. + Con::executef( this, "onUpdateSelection", buffer[0], buffer[1] ); +} + +void VPathEditor::updateSelection( void ) +{ + if ( !isValidSelection() ) + { + // No Further Updates. + return; + } + + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Fetch Node Rotation Matrix. + MatrixF mat; + node->getWorldRotation().setMatrix( &mat ); + + // Determine Tangent Axis. + Point3F pt0( VPath::gBezierAxis * node->getWeight() ); + Point3F pt1( -VPath::gBezierAxis * node->getWeight() ); + + // Rotate Axis. + mat.mulP( pt0 ); + mat.mulP( pt1 ); + + // Offset Points. + pt0 += node->getWorldPosition(); + pt1 += node->getWorldPosition(); + + // Store Points. + mSelection.TangentHandle[0] = pt0; + mSelection.TangentHandle[1] = pt1; +} + +DefineEngineMethod( VPathEditor, clearSelection, void, (),, "( void )" ) +{ + // Clear Selection. + object->updateSelection( NULL, -1 ); +} + +DefineEngineMethod(VPathEditor, setSelection, void, (SceneObject* sceneObject, S32 nodeIndex), (nullAsType(), -1), "( pObject, [pNodeIndex] )") +{ + if (sceneObject == nullptr) + { + Con::errorf("VPathEditor::setSelection() - Unable to select target Object."); + return; + } + // Fetch Path. + VPath *path = dynamic_cast(sceneObject); + if ( !path ) + { + Con::errorf( "VPathEditor::setSelection() - Unable to select target Object." ); + return; + } + + object->updateSelection( path, nodeIndex); +} + +DefineEngineMethod( VPathEditor, isValidSelection, bool, (),, "( void )" ) +{ + return object->isValidSelection(); +} + +DefineEngineMethod( VPathEditor, getSelectedPath, S32, (),, "( void )" ) +{ + // Fetch Path. + VPath *path = object->mSelection.Path; + + // Return ID. + return ( path ) ? path->getId() : 0; +} + +DefineEngineMethod( VPathEditor, getSelectedNode, S32, (),, "( void )" ) +{ + // Return Node Index. + return ( object->mSelection.Path ) ? object->mSelection.Node : -1; +} + +DefineEngineMethod( VPathEditor, deleteSelection, void, (),, "( void )" ) +{ + // Valid Selection? + if ( object->isValidSelection() ) + { + object->deleteNode( object->mSelection.Node ); + } +} + +//----------------------------------------------------------------------------- +// +// Weight Editing Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::isEditingWeight( const Gui3DMouseEvent &pEvent ) +{ + if ( !isValidSelection() || mSelection.Path->mPathType != VPath::k_PathBezier ) + { + // False. + mEditWeight = false; + + // Invalid Selection. + return false; + } + + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + // Min Index. + S32 minNode = -1; + F32 minDistance = F32_MAX; + + for ( S32 i = 0; i < 2; i++ ) + { + Point3F pt; + if ( !Utility::FindNearestPointOnLine( mSelection.TangentHandle[i], pt0, pt1, &pt ) ) + { + // Skip. + continue; + } + + // Distance. + const F32 ptDistance = ( pt - mSelection.TangentHandle[i] ).len(); + if ( ptDistance < minDistance ) + { + // Store Index. + minNode = i; + + // Store Distance. + minDistance = ptDistance; + } + } + + if ( minDistance > gSelectionDistance ) + { + // False. + mEditWeight = false; + + // Too Far Away. + return false; + } + + // True. + mEditWeight = true; + mEditWeightHandle = minNode; + + return true; +} + +void VPathEditor::updateWeight( const Gui3DMouseEvent &pEvent ) +{ + if ( !isEditingWeight() ) + { + // Woops! + return; + } + + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + Point3F nodePos = node->getWorldPosition(); + + // Fetch Node Transform. + MatrixF mat = node->getWorldTransform(); + + // Fetch the Normal. + const VectorF planeNormal = mat.getColumn3F( 0 ); + + // Construct Plane. + const PlaneF plane( nodePos, planeNormal ); + + Point3F iPt; + if ( plane.intersect( pEvent.pos, pEvent.vec, &iPt ) ) + { +/* + // Fetch Edit Vector. + VectorF tangentVect( mSelection.TangentHandle[mEditWeightHandle] - nodePos ); + tangentVect.normalize(); + + // Fetch Mouse Vector. + VectorF mouseVec( iPt - nodePos ); + F32 mouseDist = mouseVec.len(); + mouseVec.normalize(); + + // Find the Angles. + F32 tangentAngle = mAtan2( -tangentVect.z, tangentVect.x ); + F32 mouseAngle = mAtan2( -mouseVec.z, mouseVec.x ); + + // Determine Sign. + const S32 sign = ( planeNormal.y > 0.f ) ? -1.f : 1.f; + + // Delta Rotation.. + const QuatF deltaRotation( AngAxisF( planeNormal, sign * ( mouseAngle - tangentAngle ) ) ); + + // Calculate New Rotation. + QuatF newRotation; + newRotation.mul( nodePos, deltaRotation ); + + // Apply Rotation. + setNodeRotation( mSelection.Node, newRotation ); +*/ +/* + // Fetch Edit Vector. + VectorF handleVec( mSelection.TangentHandle[mEditWeightHandle] - nodePos ); + handleVec.normalize(); + + // Fetch Mouse Vector. + VectorF mouseVec( iPt - nodePos ); + mouseVec.normalize(); + + // Find the Angles. + F32 handleAngle = Utility::GetPitch( handleVec ); //mAtan2( -handleVec.z, handleVec.x ); + F32 mouseAngle = Utility::GetPitch( mouseVec ); //mAtan2( -mouseVec.z, mouseVec.x ); + + // Determine Sign. + const S32 sign = ( planeNormal.y > 0.f ) ? -1.f : 1.f; + + // Delta Rotation. + MatrixF rotMat; + AngAxisF::RotateY( sign * ( mouseAngle - handleAngle ), &rotMat ); + + // Rotate. + mat.mul( rotMat ); + + QuatF newRotation; + newRotation.set( mat ); + + // Apply Rotation. + setNodeRotation( mSelection.Node, newRotation ); +*/ + // Apply Weight. + setNodeWeight( mSelection.Node, ( iPt - nodePos ).len() ); + } +} + +//----------------------------------------------------------------------------- +// +// Path Editing Methods. +// +//----------------------------------------------------------------------------- + +void VPathEditor::setPathPosition( const Point3F &pPosition ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Update Position. + serverPath->setPosition( pPosition ); + clientPath->setPosition( pPosition ); + + // Update Selection. + updateSelection(); +} + +void VPathEditor::setPathRotation( const QuatF &pRotation ) +{ + // Determine the Matrix. + MatrixF mat; + pRotation.setMatrix( &mat ); + mat.setPosition( mSelection.Path->getPosition() ); + + // Update Transform. + setPathTransform( mat ); +} + +void VPathEditor::setPathTransform( const MatrixF &pTransform ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Update Transform. + serverPath->setTransform( pTransform ); + clientPath->setTransform( pTransform ); + + // Update Selection. + updateSelection(); +} + +void VPathEditor::setPathScale( const VectorF &pScale ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Fetch Current Scale. + VectorF scale = serverPath->getScale(); + scale.convolve( pScale ); + + // Update Scale. + serverPath->setScale( scale ); + clientPath->setScale( scale ); + + // Update Selection. + updateSelection(); +} + +//----------------------------------------------------------------------------- +// +// Node Editing Methods. +// +//----------------------------------------------------------------------------- + +bool VPathEditor::getPointOnPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + if ( pPath->getNodeCount() < 2 ) + { + // Start / End Points. + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + // Create Intersection Plane. + const PlaneF plane( pPath->getPosition(), VPath::gBezierUp ); + + // Intersection Point. + Point3F intersectionPoint; + if ( !plane.intersect( pEvent.pos, pEvent.vec, &intersectionPoint ) ) + { + // No Intersection. + return false; + } + + // I'th Node. + pNode = pPath->getNodeCount(); + // Set Identity. + pTransform.identity(); + // Set Position. + pTransform.setPosition( intersectionPoint ); + + // Return. + return true; + } + + switch ( pPath->mPathType ) + { + case VPath::k_PathLinear : + { + + return getPointOnLinearPath( pPath, pEvent, pNode, pTransform ); + + } break; + + case VPath::k_PathBezier : + { + + return getPointOnBezierPath( pPath, pEvent, pNode, pTransform ); + + } break; + } + + return false; +} + +bool VPathEditor::getPointOnLinearPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + // Start / End Points. + const Point3F pt0 = pEvent.pos; + const Point3F pt1 = pEvent.pos + pEvent.vec * gProjectDistance; + + S32 minNode = -1; + F32 minDistance = F32_MAX; + Point3F minPoint( 0.f, 0.f, 0.f ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Project to Screen. + Point3F srcNodeScreenPosition, dstNodeScreenPosition; + project( srcNode->getWorldPosition(), &srcNodeScreenPosition ); + project( dstNode->getWorldPosition(), &dstNodeScreenPosition ); + + // Skip? + if ( srcNodeScreenPosition.z > 1.f && dstNodeScreenPosition.z > 1.f ) + { + continue; + } + + Point3F ptOut0, ptOut1; + F32 ptOutDistance; + if ( !Utility::FindNearestDistanceBetweenLines( pt0, pt1, + srcNode->getWorldPosition(), dstNode->getWorldPosition(), + &ptOut0, &ptOut1, &ptOutDistance ) ) + { + continue; + } + + if ( ptOutDistance < minDistance ) + { + minDistance = ptOutDistance; + minPoint = ptOut1; + minNode = ( itr - pPath->mNodeList.begin() ); + } + } + + // Distance too Large? + if ( minDistance > 0.25f ) + { + // Invalid. + return false; + } + + // Setup. + pTransform.identity(); + pTransform.setPosition( minPoint ); + + // Store Node. + pNode = minNode; + + return true; +} + +bool VPathEditor::getPointOnBezierPath( VPath *pPath, const Gui3DMouseEvent &pEvent, S32 &pNode, MatrixF &pTransform ) +{ + S32 minNode = -1; + F32 minInterp = 0.f; + F32 minDistance = F32_MAX; + Point3F minPoint( 0.f, 0.f, 0.f ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Project to Screen. + Point3F srcNodeScreenPosition, dstNodeScreenPosition; + project( srcNode->getWorldPosition(), &srcNodeScreenPosition ); + project( dstNode->getWorldPosition(), &dstNodeScreenPosition ); + + // Skip? + if ( srcNodeScreenPosition.z > 1.f && dstNodeScreenPosition.z > 1.f ) + { + continue; + } + + // Positions. + const Point3F &pt0 = srcNode->getWorldPosition(); + const Point3F &pt3 = dstNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + srcNode->getWorldRotation().setMatrix( &mat0 ); + dstNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( VPath::gBezierAxis * srcNode->getWeight() ); + Point3F pt2( -VPath::gBezierAxis * dstNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + for ( F32 t = 0.f, it = 1.f; t <= 1.f; t += 0.1f, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F pos = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + + // Determine the Screen Position. + Point3F screenPos; + project( pos, &screenPos ); + // Behind? + if ( screenPos.z > 1.f ) + { + // Skip Point. + continue; + } + + // Determine the Distance. + F32 screenDistance = Point2F( screenPos.x - pEvent.mousePoint.x, screenPos.y - pEvent.mousePoint.y ).lenSquared(); + // Min Distance? + if ( screenDistance < minDistance ) + { + // Store. + minDistance = screenDistance; + minInterp = t; + minPoint = pos; + minNode = ( itr - pPath->mNodeList.begin() ); + } + } + } + + // Distance too Large? + if ( minDistance > 1000.f ) + { + // Invalid. + return false; + } + + // Fetch Orientation. + const VectorF &orientation = pPath->getPathOrientation( pPath->getNode( minNode ), + pPath->getNode( ( minNode + 1 ) % pPath->getNodeCount() ), + minInterp, true ); + + // Z-Axis. + VectorF zVec = -orientation; + zVec.normalize(); + + // X-Axis. + VectorF xVec = mCross( VPath::gBezierUp, zVec ); + xVec.normalize(); + + // Y-Axis. + VectorF yVec = mCross( zVec, xVec ); + yVec.normalize(); + + // Setup Object Transform. + pTransform.identity(); + pTransform.setColumn( 0, xVec ); + pTransform.setColumn( 1, -zVec ); + pTransform.setColumn( 2, yVec ); + // Set the Position. + pTransform.setPosition( minPoint ); + + // Store Node. + pNode = minNode; + + return true; +} + +void VPathEditor::addNode( const Gui3DMouseEvent &pEvent ) +{ + VPath *path = mSelection.Path; + if ( !path ) + { + // Woops! + return; + } + + // Min Index. + S32 nodeIndex = -1; + MatrixF nodeTransform( true ); + if ( !getPointOnPath( path, pEvent, nodeIndex, nodeTransform ) ) + { + // Can't Add. + return; + } + + // Invert Transform. + MatrixF pathTransform = mSelection.Path->getTransform(); + pathTransform.setPosition( Point3F::Zero ); + pathTransform.inverse(); + + Point3F nodePosition = ( nodeTransform.getPosition() - mSelection.Path->getPosition() ); + pathTransform.mulP( nodePosition ); + + // Node Rotation. + nodeTransform.mul( pathTransform ); + QuatF nodeRotation( nodeTransform ); + + // Node Weights. + F32 nodeWeight = 10.f; + + // Add New Node. + VPathNode *node = path->addNode( nodePosition, nodeRotation, nodeWeight, ++nodeIndex ); + + // Valid Node? + if ( !node ) + { + return; + } + + // Update Size. + path->updateContainer(); + + // Calculate Path. + path->calculatePath(); + + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor::addNode() - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorAddNodeAction *editAction = new VPathEditorAddNodeAction(); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = path; + editAction->mNodeIndex = nodeIndex; + + editAction->mNodePosition = nodePosition; + editAction->mNodeRotation = nodeRotation; + editAction->mNodeWeight = nodeWeight; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Set World Editor Dirty. + setWorldEditorDirty(); +} + +void VPathEditor::deleteNode( const S32 &pNodeIndex ) +{ + VPath *path = mSelection.Path; + if ( !path ) + { + // Woops! + return; + } + + // Fetch Node Properites. + VPathNode *node = path->getNode( pNodeIndex ); + const Point3F position = node->getLocalPosition(); + const QuatF rotation = node->getLocalRotation(); + const F32 weight = node->getWeight(); + + // Delete Node. + path->deleteNode( pNodeIndex ); + + // Update Path. + path->updateContainer(); + + // Calculate Path. + path->calculatePath(); + + // Selected Node? + const S32 _nodeIndex = pNodeIndex; + if ( pNodeIndex == mSelection.Node ) + { + // Update Selection. + updateSelection( mSelection.Path, -1 ); + } + + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor::deleteNode() - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorDeleteNodeAction *editAction = new VPathEditorDeleteNodeAction(); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = path; + editAction->mNodeIndex = _nodeIndex; + + editAction->mNodePosition = position; + editAction->mNodeRotation = rotation; + editAction->mNodeWeight = weight; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Set World Editor Dirty. + setWorldEditorDirty(); +} + +void VPathEditor::setNodePosition( const S32 &pNodeIndex, const Point3F &pPosition ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeLocalPosition( pNodeIndex ) == pPosition ) + { + return; + } + + // Set Position. + serverPath->setNodePosition( pNodeIndex, pPosition ); + clientPath->setNodePosition( pNodeIndex, pPosition ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodePosition", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeRotation( const S32 &pNodeIndex, const QuatF &pRotation ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeLocalRotation( pNodeIndex ) == pRotation ) + { + return; + } + + // Set Position. + serverPath->setNodeRotation( pNodeIndex, pRotation ); + clientPath->setNodeRotation( pNodeIndex, pRotation ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeRotation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeWeight( const S32 &pNodeIndex, const F32 &pWeight ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Change? + if ( serverPath->getNodeWeight( pNodeIndex ) == pWeight ) + { + return; + } + + // Set Weight. + serverPath->setNodeWeight( pNodeIndex, pWeight ); + clientPath->setNodeWeight( pNodeIndex, pWeight ); + + // Update Selection. + updateSelection(); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeWeight", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Set Orientation Mode. + serverPath->setNodeOrientationMode( pNodeIndex, pType ); + clientPath->setNodeOrientationMode( pNodeIndex, pType ); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeOrientation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::setNodeOrientationMode( const S32 &pNodeIndex, const VPathNode::eOrientationType &pType, const Point3F &pPoint ) +{ + // Fetch Paths. + VPath *serverPath = mSelection.Path; + VPath *clientPath = getClientPath( serverPath ); + + // Sanity! + if ( !serverPath || !clientPath ) + { + return; + } + + // Set Orientation Mode. + serverPath->setNodeOrientationMode( pNodeIndex, pType, pPoint ); + clientPath->setNodeOrientationMode( pNodeIndex, pType, pPoint ); + + // Dirty. + mIsDirty = true; + mNodeEdit.Dirty = true; + + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mSelection.Path->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", pNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mSelection.Node == pNodeIndex ) ); + + // Callback. + Con::executef( this, "onUpdateNodeOrientation", buffer[0], buffer[1], buffer[2] ); +} + +void VPathEditor::pushPathEdit( void ) +{ + // Clear Current Edit Dirty. + mPathEdit.Dirty = false; + + if ( mSelection.Path != NULL ) + { + // Store Node Details. + mPathEdit.Transform = mSelection.Path->getTransform(); + } +} + +void VPathEditor::popPathEdit( void ) +{ + // Did Edit? + if ( mPathEdit.Dirty && mSelection.Path != NULL ) + { + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorEditPathAction *editAction = new VPathEditorEditPathAction( "Edit Path" ); + + // Store Editor. + editAction->mEditor = this; + + // Store Path Details. + editAction->mPath = mSelection.Path; + editAction->mTransform = mPathEdit.Transform; + + // Add To Manager. + historyManager->addAction( editAction ); + + // Clear Dirty. + mPathEdit.Dirty = false; + + // Set World Editor Dirty. + setWorldEditorDirty(); + } +} + +void VPathEditor::pushNodeEdit( void ) +{ + // Clear Current Edit Dirty. + mNodeEdit.Dirty = false; + + if ( isValidSelection() ) + { + // Fetch Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Store Node Details. + mNodeEdit.Position = node->getLocalPosition(); + mNodeEdit.Rotation = node->getLocalRotation(); + mNodeEdit.Weight = node->getWeight(); + } +} + +void VPathEditor::popNodeEdit( void ) +{ + // Did Edit? + if ( mNodeEdit.Dirty && isValidSelection() ) + { + UndoManager *historyManager = NULL; + if ( !Sim::findObject( "EUndoManager", historyManager ) ) + { + Con::errorf( "VPathEditor - EUndoManager not found!" ); + return; + } + + // Create Undo Action. + VPathEditorEditNodeAction *editAction = new VPathEditorEditNodeAction( "Edit Node" ); + + // Store Editor. + editAction->mEditor = this; + + // Store Node Details. + editAction->mPath = mSelection.Path; + editAction->mNodeIndex = mSelection.Node; + + editAction->mNodePosition = mNodeEdit.Position; + editAction->mNodeRotation = mNodeEdit.Rotation; + editAction->mNodeWeight = mNodeEdit.Weight; + + editAction->mNodeOrientation = mSelection.Path->getNode( mSelection.Node )->getOrientationMode(); + + // Add To Manager. + historyManager->addAction( editAction ); + + // Clear Dirty. + mNodeEdit.Dirty = false; + + // Set World Editor Dirty. + setWorldEditorDirty(); + } +} + +void VPathEditor::setWorldEditorDirty( void ) +{ + WorldEditor *worldEditor; + if ( Sim::findObject( "EWorldEditor", worldEditor ) ) + { + worldEditor->setDirty(); + } +} + +//----------------------------------------------------------------------------- +// +// Render Methods. +// +//----------------------------------------------------------------------------- + +void VPathEditor::setStateBlock( void ) +{ + // Valid State Block? + if ( !mStateBlock ) + { + // Setup Definition. + GFXStateBlockDesc def; + def.blendDefined = true; + def.blendEnable = true; + def.blendSrc = GFXBlendSrcAlpha; + def.blendDest = GFXBlendInvSrcAlpha; + def.zDefined = true; + def.cullDefined = false; + + // Create State Block. + mStateBlock = GFX->createStateBlock( def ); + } + + // Set State Block. + GFX->setStateBlock( mStateBlock ); +} + +void VPathEditor::renderScene( const RectI &pUpdateRect ) +{ + // Setup State Block. + setStateBlock(); + + if ( isValidSelection() ) + { + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // Render Gizmo? + if ( mEditMode == k_Gizmo && mGizmoProfile->mode != ScaleMode ) + { + // Fetch Node Transform. + MatrixF mat= node->getWorldTransform(); + + // Move Gizmo. + mGizmo->set( mat, node->getWorldPosition(), Point3F( 1.0f, 1.0f, 1.0f ) ); + + // Render Gizmo. + mGizmo->renderGizmo( mLastCameraQuery.cameraMatrix ); + } + + // Render Handles? + if ( mSelection.Path->mPathType == VPath::k_PathBezier ) + { + // Fetch Tangent Handles. + const Point3F &pt0 = mSelection.TangentHandle[0]; + const Point3F &pt1 = mSelection.TangentHandle[1]; + + // State Block. + GFXStateBlockDesc desc; + desc.setZReadWrite( true, true ); + desc.fillMode = GFXFillSolid; + + // Set Color. + PrimBuild::color( gPathColorSel ); + + // Render Line. + PrimBuild::begin( GFXLineList, 2 ); + PrimBuild::vertex3fv( pt0 ); + PrimBuild::vertex3fv( pt1 ); + PrimBuild::end(); + + // Render Handles. + GFX->getDrawUtil()->drawSphere( desc, 0.1f, pt0, gPathColorSel ); + GFX->getDrawUtil()->drawSphere( desc, 0.1f, pt1, gPathColorSel ); + } + + // ToPoint Node? + if ( node->getOrientationMode().Type == VPathNode::k_OrientationToPoint ) + { + PrimBuild::color( gNodeLookAtPointColor ); + PrimBuild::begin( GFXLineStrip, 2 ); + + PrimBuild::vertex3fv( node->getWorldPosition() ); + PrimBuild::vertex3fv( node->getOrientationMode().Point ); + + PrimBuild::end(); + } + } + else if ( mSelection.Path && mEditMode == k_Gizmo ) + { + switch ( mGizmoProfile->mode ) + { + case MoveMode: + { + // Fetch Path Transform. + const MatrixF &mat = mSelection.Path->getTransform(); + + // Fetch the Path's Box Center. + const Point3F &pos = mSelection.Path->getWorldBox().getCenter(); + + // Move Gizmo. + mGizmo->set( mat, pos, Point3F( 1.0f, 1.0f, 1.0f ) ); + + // Render Gizmo. + mGizmo->renderGizmo( mLastCameraQuery.cameraMatrix ); + + } break; + } + } + + // Render Path Segments. + renderPaths( k_RenderSegments ); + + // Set Clip Rect. + GFX->setClipRect( pUpdateRect ); + + // Render Path Nodes. + renderPaths( k_RenderNodes ); + + if ( isValidSelection() ) + { + // Fetch Current Node. + VPathNode *node = mSelection.Path->getNode( mSelection.Node ); + + // ToPoint Node? + if ( node->getOrientationMode().Type == VPathNode::k_OrientationToPoint ) + { + // Project to Screen. + Point3F screenPosition; + project( node->getOrientationMode().Point, &screenPosition ); + if ( screenPosition.z <= 1.0f ) + { + // Determine the center & size of the node rectangle. + Point2I nodeCenter = Point2I( screenPosition.x, screenPosition.y ); + Point2I nodeHalfSize = Point2I( 8, 8 ); + // Determine Render Rectangle. + RectI nodeRect; + nodeRect.point = nodeCenter - nodeHalfSize; + nodeRect.extent = ( 2 * nodeHalfSize ); + + // Draw? + if ( getBounds().overlaps( nodeRect ) ) + { + // Render the Point. + GFX->getDrawUtil()->drawRectFill( nodeRect, gNodeLookAtPointColor ); + } + } + } + } +} + +void VPathEditor::renderPaths( const RenderType &pRenderType ) +{ + SimSet *objectSet = VPath::getServerSet(); + for ( SimSetIterator itr( objectSet ); *itr; ++itr ) + { + VPath *path = dynamic_cast( *itr ); + if ( path ) + { + // Render Path. + renderPath( pRenderType, path, ( path == mSelection.Path ) ? gPathColorSel : gPathColor ); + } + } +} + +void VPathEditor::renderPath( const RenderType &pRenderType, VPath *pPath, const ColorI &pColor ) +{ + if ( !pPath ) + { + // Sanity! + return; + } + + switch ( pRenderType ) + { + case k_RenderSegments : + { + switch ( pPath->mPathType ) + { + case VPath::k_PathLinear : + { + renderLinearPath( pPath, pColor ); + + } break; + + case VPath::k_PathBezier : + { + renderBezierPath( pPath, pColor ); + + } break; + } + + } break; + + case k_RenderNodes : + { + // Fetch Draw Util. + GFXDrawUtil *drawUtil = GFX->getDrawUtil(); + + // Fetch Bounds. + RectI bounds = getBounds(); + + const Point2I nodeMinHalfSize( 8, 8 ); + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Node. + VPathNode *node = ( *itr ); + + // Project to Screen. + Point3F screenPosition; + project( node->getWorldPosition(), &screenPosition ); + if ( screenPosition.z > 1.0f ) + { + continue; + } + + // Determine the node text information. + const char *nodeText = avar( "%d", ( itr - pPath->mNodeList.begin() ) ); + const Point2I nodeTextHalfSize = Point2I( 0.5f * (F32)getControlProfile()->mFont->getStrWidth( nodeText ), + 0.5f * (F32)getControlProfile()->mFont->getHeight() ); + + // Determine the center & size of the node rectangle. + Point2I nodeCenter = Point2I( screenPosition.x, screenPosition.y ); + Point2I nodeHalfSize = Point2I( nodeTextHalfSize.x + 3, nodeTextHalfSize.y + 3 ); + nodeHalfSize.setMax( nodeMinHalfSize ); + // Determine Render Rectangle. + RectI nodeRect; + nodeRect.point = nodeCenter - nodeHalfSize; + nodeRect.extent = ( 2 * nodeHalfSize ); + + // Draw? + if ( !bounds.overlaps( nodeRect ) ) + { + continue; + } + + // Render the Point. + drawUtil->drawRectFill( nodeRect, pColor ); + + // Draw the node index text. + drawUtil->setBitmapModulation( getControlProfile()->mFontColor ); + drawUtil->drawText( getControlProfile()->mFont, nodeCenter - nodeTextHalfSize, nodeText ); + } + + } break; + } +} + +void VPathEditor::renderLinearPath( VPath *pPath, const ColorI &pColor ) +{ + if ( pPath->mNodeList.size() < 2 ) + { + // No Lines. + return; + } + + PrimBuild::color( pColor ); + PrimBuild::begin( GFXLineStrip, ( pPath->mNodeList.size() + 1 ) ); + + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Apply Vertex. + PrimBuild::vertex3fv( ( *itr )->getWorldPosition() ); + } + + // Loop Back. + PrimBuild::vertex3fv( pPath->mNodeList.front()->getWorldPosition() ); + + PrimBuild::end(); +} + +void VPathEditor::renderBezierPath( VPath *pPath, const ColorI &pColor ) +{ + if ( pPath->mNodeList.size() < 2 ) + { + // No Lines. + return; + } + + PrimBuild::color( pColor ); + PrimBuild::begin( GFXLineStrip, U32( ( ( 1.01f / 0.01f ) + 1 ) * pPath->mNodeList.size() ) ); + + for ( VPathNodeIterator itr = pPath->mNodeList.begin(); itr != pPath->mNodeList.end(); itr++ ) + { + // Fetch Nodes. + VPathNode *srcNode = ( *itr ); + VPathNode *dstNode = ( itr == ( pPath->mNodeList.end() - 1 ) ) ? ( *( pPath->mNodeList.begin() ) ) : ( *( itr + 1 ) ); + + // Positions. + const Point3F &pt0 = srcNode->getWorldPosition(); + const Point3F &pt3 = dstNode->getWorldPosition(); + + // Fetch Node Rotation Matrices. + MatrixF mat0, mat1; + srcNode->getWorldRotation().setMatrix( &mat0 ); + dstNode->getWorldRotation().setMatrix( &mat1 ); + + // Determine Tangent Axis. + Point3F pt1( VPath::gBezierAxis * srcNode->getWeight() ); + Point3F pt2( -VPath::gBezierAxis * dstNode->getWeight() ); + + // Rotate Axis. + mat0.mulP( pt1 ); + mat1.mulP( pt2 ); + + // Offset Points. + pt1 += pt0; + pt2 += pt3; + + for ( F32 t = 0.f, it = 1.f; t <= 1.f; t += 0.01f, it = ( 1.f - t ) ) + { + // Calculate Position. + Point3F pos = ( pt0 * it * it * it ) + ( 3 * pt1 * it * it * t ) + ( 3 * pt2 * it * t * t ) + ( pt3 * t * t * t ); + // Apply Vertex. + PrimBuild::vertex3fv( pos ); + } + } + + PrimBuild::end(); +} + +//----------------------------------------------------------------------------- +// +// History Events +// +//----------------------------------------------------------------------------- + +void VPathEditor::VPathEditorEditPathAction::undo( void ) +{ + const MatrixF oldTransform = mTransform; + const MatrixF newTransform = mPath->getTransform(); + + // Apply Old Values. + mEditor->setPathTransform( oldTransform ); + + // The ol' Switcheroo. + mTransform = newTransform; + + // Update Selection. + mEditor->updateSelection(); + + if ( mPath == mEditor->mSelection.Path ) + { + // Arg Buffer. + char buffer[32]; + dSprintf( buffer, sizeof( buffer ), "%d", mPath->getId() ); + + // Callback. + Con::executef( mEditor, "onUpdatePath", buffer ); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorEditPathAction::redo( void ) +{ + // Undo. + undo(); +} + +void VPathEditor::VPathEditorEditNodeAction::undo( void ) +{ + // Fetch Properties. + const Point3F oldPosition = mNodePosition; + const QuatF oldRotation = mNodeRotation; + const F32 oldWeight = mNodeWeight; + const VPathNode::sOrientation oldOrientation = mNodeOrientation; + + VPathNode *node = mPath->getNode( mNodeIndex ); + const Point3F newPosition = node->getLocalPosition(); + const QuatF newRotation = node->getLocalRotation(); + const F32 newWeight = node->getWeight(); + const VPathNode::sOrientation newOrientation = node->getOrientationMode(); + + // Apply Old Values. + mPath->setNodePosition( mNodeIndex, oldPosition ); + mPath->setNodeRotation( mNodeIndex, oldRotation ); + mPath->setNodeWeight( mNodeIndex, oldWeight ); + + switch( oldOrientation.Type ) + { + case VPathNode::k_OrientationFree : + { + + // Orient Free. + mPath->setNodeOrientationMode( mNodeIndex, oldOrientation.Type ); + + } break; + + case VPathNode::k_OrientationToPoint : + { + + // Orient To Point. + mPath->setNodeOrientationMode( mNodeIndex, oldOrientation.Type, oldOrientation.Point ); + + } break; + } + + // The ol' Switcheroo. + mNodePosition = newPosition; + mNodeRotation = newRotation; + mNodeWeight = newWeight; + mNodeOrientation = newOrientation; + + // Update Selection. + mEditor->updateSelection(); + + if ( mPath == mEditor->mSelection.Path ) + { + // Arg Buffer. + char buffer[3][32]; + dSprintf( buffer[0], sizeof( buffer[0] ), "%d", mPath->getId() ); + dSprintf( buffer[1], sizeof( buffer[1] ), "%d", mNodeIndex ); + dSprintf( buffer[2], sizeof( buffer[2] ), "%d", ( mEditor->mSelection.Node == mNodeIndex ) ); + + // Callback. + Con::executef( mEditor, "onUpdateNode", buffer[0], buffer[1], buffer[2] ); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorEditNodeAction::redo( void ) +{ + // Undo. + undo(); +} + +void VPathEditor::VPathEditorAddNodeAction::undo( void ) +{ + // Selected Node? + if ( mNodeIndex == mEditor->mSelection.Node ) + { + // Update Selection. + mEditor->updateSelection( mEditor->mSelection.Path, -1 ); + } + + // Delete Node. + mPath->deleteNode( mNodeIndex ); + + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorAddNodeAction::redo( void ) +{ + // Add Node. + VPathNode *node = mPath->addNode( mNodePosition, mNodeRotation, mNodeWeight, mNodeIndex ); + + // Valid Node? + if ( node ) + { + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorDeleteNodeAction::undo( void ) +{ + // Add Node. + VPathNode *node = mPath->addNode( mNodePosition, mNodeRotation, mNodeWeight, mNodeIndex ); + + // Valid Node? + if ( node ) + { + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + } + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +void VPathEditor::VPathEditorDeleteNodeAction::redo( void ) +{ + // Delete Node. + mPath->deleteNode( mNodeIndex ); + + // Update Size. + mPath->updateContainer(); + + // Calculate Path. + mPath->calculatePath(); + + // Set World Editor Dirty. + mEditor->setWorldEditorDirty(); +} + +//----------------------------------------------------------------------------- +// +// Script Edit Methods +// +//----------------------------------------------------------------------------- + +DefineEngineMethod( VPathEditor, setNodePosition, void, (Point3F position), (Point3F::Zero), "( pPosition )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodePosition() - Invalid Node Selection." ); + return; + } + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodePosition( object->mSelection.Node, position ); + + // Create Undo Action. + object->popNodeEdit(); +} + +DefineEngineMethod( VPathEditor, setNodeRotation, void, (AngAxisF aa), (AngAxisF::AngAxisF()), "( pRotation )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeRotation() - Invalid Node Selection." ); + return; + } + + // Fetch Rotation. + QuatF rotation; + + // Set Rotation. + rotation.set( aa ); + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodeRotation( object->mSelection.Node, rotation ); + + // Create Undo Action. + object->popNodeEdit(); +} + +DefineEngineMethod( VPathEditor, setNodeWeight, void, (F32 weight), (1), "( pWeight )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeWeight() - Invalid Node Selection." ); + return; + } + + // Store. + object->pushNodeEdit(); + + // Apply Update. + object->setNodeWeight( object->mSelection.Node, weight); + + // Create Undo Action. + object->popNodeEdit(); +} + +DefineEngineMethod( VPathEditor, setNodeOrientationMode, void, (String orientationType, Point3F lookAtPoint), ("", Point3F::One), "( string pOrientationType, [vector pPoint] )" ) +{ + // Valid Selection? + if ( !object->isValidSelection() ) + { + Con::warnf( "VPathEditor::setNodeOrientationMode() - Invalid Node Selection." ); + return; + } + + // Store. + object->pushNodeEdit(); + + // Orient? + const VPathNode::eOrientationType type = VPathNode::getOrientationTypeEnum(orientationType); + + switch ( type ) + { + case VPathNode::k_OrientationFree : + { + + // Apply Mode. + object->setNodeOrientationMode( object->mSelection.Node, type ); + + } break; + + case VPathNode::k_OrientationToPoint: + { + // Apply Mode. + object->setNodeOrientationMode( object->mSelection.Node, type, lookAtPoint ); + } break; + } + + // Create Undo Action. + object->popNodeEdit(); +} + +//----------------------------------------------------------------------------- +// +// Utility +// +//----------------------------------------------------------------------------- + +bool Utility::FindNearestDistanceBetweenLines( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, Point3F *pOutA, Point3F *pOutB, F32 *pDist ) +{ + const Point3F pA1A0 = ( pA1 - pA0 ); + if ( pA1A0.isZero() ) + { + return false; + } + + const Point3F pB1B0 = ( pB1 - pB0 ); + if ( pB1B0.isZero() ) + { + return false; + } + + const Point3F pA0B0 = ( pA0 - pB0 ); + + const F32 &d1343 = pA0B0.x * pB1B0.x + pA0B0.y * pB1B0.y + pA0B0.z * pB1B0.z; + const F32 &d4321 = pB1B0.x * pA1A0.x + pB1B0.y * pA1A0.y + pB1B0.z * pA1A0.z; + const F32 &d1321 = pA0B0.x * pA1A0.x + pA0B0.y * pA1A0.y + pA0B0.z * pA1A0.z; + const F32 &d4343 = pB1B0.x * pB1B0.x + pB1B0.y * pB1B0.y + pB1B0.z * pB1B0.z; + const F32 &d2121 = pA1A0.x * pA1A0.x + pA1A0.y * pA1A0.y + pA1A0.z * pA1A0.z; + + const F32 &denom = d2121 * d4343 - d4321 * d4321; + if ( mIsZero( denom ) ) + { + return false; + } + + const F32 &mua = ( d1343 * d4321 - d1321 * d4343 ) / denom; + const F32 &mub = ( d1343 + d4321 * mua ) / d4343; + + *pOutA = pA0 + mua *pA1A0; + *pOutB = pB0 + mub *pB1B0; + + // Store Distance. + *pDist = ( ( *pOutA ) - ( *pOutB ) ).len(); + + return true; +} + +bool Utility::IntersectLineSegment( const Point3F &pA0, const Point3F &pA1, const Point3F &pB0, const Point3F &pB1, const bool pSnap, Point3F *pX ) +{ + // + // Finding the intersection with the following method: + // We have line a going from P1 to P2: + // Pa = P1 + ua( P2 - P1 ) + // and line b going from P3 to P4: + // Pb = P3 + ub( P4 - P3 ) + // + // Solving for Pa = Pb: + // x1 + ua( x2 - x1 ) = x3 + ub( x4 - x3 ) + // y1 + ua( y2 - y1 ) = y3 + ub( y4 - y3 ) + // + // Solving for ua and ub: + // ua = ( ( x4 - x3 )( y1 - y3 ) - ( y4 - y3 )( x1 - x3 ) ) / d + // ub = ( ( x2 - x1 )( y1 - y3 ) - ( y2 - y1 )( x1 - x3 ) ) / d + // denom = ( y4 - y3 )( x2 - x1 ) - ( x4 - x3 )( y2 - y1 ) + // + // x = x1 + ua( x2 - x1 ) + // y = y1 + ua( y2 - y1 ) + // + + const F32 d = ( ( pB1.y - pB0.y ) * ( pA1.x - pA0.x ) ) - ( ( pB1.x - pB0.x ) * ( pA1.y - pA0.y ) ); + + if ( d == 0.0f ) + { + // Lines are parallel + return false; + } + + // Find the point of intersection + const F32 uA = ( ( ( pB1.x - pB0.x ) * ( pA0.y - pB0.y ) ) - ( ( pB1.y - pB0.y ) * ( pA0.x - pB0.x ) ) ) / d; + const F32 uB = ( ( ( pA1.x - pA0.x ) * ( pA0.y - pB0.y ) ) - ( ( pA1.y - pA0.y ) * ( pA0.x - pB0.x ) ) ) / d; + + if ( !pSnap + && ( ( uA < 0.0f ) || ( uA > 1.0f ) + || ( uB < 0.0f ) || ( uB > 1.0f ) ) ) + { + return false; + } + + if ( pX ) + { + if ( uA < 0.0f ) + { + *pX = pA0; + } + else if ( uA > 1.f ) + { + *pX = pA1; + } + else + { + // The path intersects the segment + *pX = pA0 + uA * ( pA1 - pA0 ); + } + } + + return true; +} + +bool Utility::FindNearestPointOnLine( const Point3F &pSrcPosition, const Point3F &pA0, const Point3F &pA1, Point3F *pDstPosition ) +{ + const Point3F up( 0.0f, 0.0f, 1.0f ); + + Point3F dir = ( pA1 - pA0 ); + dir.normalize(); + + Point3F normal = mCross( dir, up ); + normal.normalize(); + + // Find the nearest intersection point between the point and the line + + const Point3F b0 = pSrcPosition + ( normal * 100000.0f ); + const Point3F b1 = pSrcPosition - ( normal * 100000.0f ); + + return IntersectLineSegment( pA0, pA1, b0, b1, true, pDstPosition ); +} + +F32 Utility::GetPitch( const VectorF &pVec ) +{ + F32 pitch; + if ( mFabs( pVec.x ) > mFabs( pVec.y ) ) + { + pitch = mAtan2( mFabs( pVec.z ), mFabs( pVec.x ) ); + } + else + { + pitch = mAtan2( mFabs( pVec.z ), mFabs( pVec.y ) ); + } + + if ( pVec.z < 0.f ) + { + pitch = -pitch; + } + + return pitch; +} + +F32 Utility::GetYaw( const VectorF &pVec ) +{ + F32 yaw = mAtan2( pVec.x, pVec.y ); + if ( yaw < 0.f ) + { + yaw += M_2PI_F; + } + + return yaw; +} diff --git a/Engine/source/Verve/VPath/VPathEditor.h b/Engine/source/Verve/VPath/VPathEditor.h new file mode 100644 index 000000000..c337edd0c --- /dev/null +++ b/Engine/source/Verve/VPath/VPathEditor.h @@ -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_ \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPathNode.cpp b/Engine/source/Verve/VPath/VPathNode.cpp new file mode 100644 index 000000000..d18794c4e --- /dev/null +++ b/Engine/source/Verve/VPath/VPathNode.cpp @@ -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 ); +} \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPathNode.h b/Engine/source/Verve/VPath/VPathNode.h new file mode 100644 index 000000000..dd829c5b5 --- /dev/null +++ b/Engine/source/Verve/VPath/VPathNode.h @@ -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_ \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPathObject.cpp b/Engine/source/Verve/VPath/VPathObject.cpp new file mode 100644 index 000000000..5d1116b78 --- /dev/null +++ b/Engine/source/Verve/VPath/VPathObject.cpp @@ -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( 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( 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( 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 ); +} \ No newline at end of file diff --git a/Engine/source/Verve/VPath/VPathObject.h b/Engine/source/Verve/VPath/VPathObject.h new file mode 100644 index 000000000..72153021d --- /dev/null +++ b/Engine/source/Verve/VPath/VPathObject.h @@ -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_ \ No newline at end of file diff --git a/Engine/source/Verve/VerveConfig.h b/Engine/source/Verve/VerveConfig.h new file mode 100644 index 000000000..deaf8f831 --- /dev/null +++ b/Engine/source/Verve/VerveConfig.h @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// 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_VERVECONFIG_H_ +#define _VT_VERVECONFIG_H_ + +//----------------------------------------------------------------------------- + +//#define VT_EDITOR + +//----------------------------------------------------------------------------- + +#endif // _VT_VERVECONFIG_H_ \ No newline at end of file diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index bf2f3b39f..a87e2662c 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -825,10 +825,10 @@ void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp) // Now re aquire all the resources we trashed earlier reacquireDefaultPoolResources(); //set last bound shaders - mD3DDeviceContext->PSSetShader(mLastPixShader, NULL, 0); - mD3DDeviceContext->VSSetShader(mLastVertShader, NULL, 0); + //mD3DDeviceContext->PSSetShader(mLastPixShader, NULL, 0); + //mD3DDeviceContext->VSSetShader(mLastVertShader, NULL, 0); // Mark everything dirty and flush to card, for sanity. - updateStates(true); + //updateStates(true); } void GFXD3D11Device::setupGenericShaders(GenericShaderType type) diff --git a/Templates/BaseGame/game/data/Verve/Verve.cs b/Templates/BaseGame/game/data/Verve/Verve.cs new file mode 100644 index 000000000..61b8b4ab6 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/Verve.cs @@ -0,0 +1,19 @@ +function Verve::create( %this ) +{ + exec("data/Verve/gui/verveCinematic.gui"); + + exec("data/Verve/scripts/server/verveCinematicController.cs"); + exec("data/Verve/scripts/server/verveCinematicTrigger.cs"); + exec("data/Verve/scripts/server/vervePathTutorialData.cs"); + + if(isObject(DatablockFilesList)) + { + DatablockFilesList.add( "data/Verve/scripts/datablocks/verve/VerveActorData.cs" ); + DatablockFilesList.add( "data/Verve/scripts/datablocks/verve/VervePathTutorialData.cs" ); + } +} + +function Verve::destroy( %this ) +{ + +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/Verve.module b/Templates/BaseGame/game/data/Verve/Verve.module new file mode 100644 index 000000000..00e86707c --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/Verve.module @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/BLACK.png b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/BLACK.png new file mode 100644 index 000000000..7ed2ea55a Binary files /dev/null and b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/BLACK.png differ diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/DemoRoomLrg.dae b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/DemoRoomLrg.dae new file mode 100644 index 000000000..a530ed565 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/DemoRoomLrg.dae @@ -0,0 +1,1258 @@ + + + + + + Torque 3D 2009 Interior Exporter + + + 8/09/2009 2:52:45 PM + 8/09/2009 2:52:45 PM + + + <subject /> + <keywords /> + <unit meter="1.000000" /> + <up_axis>Z_UP</up_axis> + </asset> + <library_images> + <image id="BLACK-Diffuse" name="BLACK-Diffuse"> + <init_from>file://BLACK.png</init_from> + </image> + <image id="FULL128X128G-Diffuse" name="FULL128X128G-Diffuse"> + <init_from>file://FULL128X128G.png</init_from> + </image> + <image id="PILLAR128X128G-Diffuse" name="PILLAR128X128G-Diffuse"> + <init_from>file://PILLAR128X128G.png</init_from> + </image> + <image id="FULL64X64G-Diffuse" name="FULL64X64G-Diffuse"> + <init_from>file://FULL64X64G.png</init_from> + </image> + </library_images> + <library_materials> + <material id="BLACK" name="BLACK"> + <instance_effect url="#BLACK-fx" /> + </material> + <material id="FULL128X128G" name="FULL128X128G"> + <instance_effect url="#FULL128X128G-fx" /> + </material> + <material id="PILLAR128X128G" name="PILLAR128X128G"> + <instance_effect url="#PILLAR128X128G-fx" /> + </material> + <material id="FULL64X64G" name="FULL64X64G"> + <instance_effect url="#FULL64X64G-fx" /> + </material> + </library_materials> + <library_effects> + <effect id="BLACK-fx" name="BLACK-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="BLACK-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="FULL128X128G-fx" name="FULL128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="FULL128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="PILLAR128X128G-fx" name="PILLAR128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="PILLAR128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="FULL64X64G-fx" name="FULL64X64G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="FULL64X64G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_geometries> + <geometry id="DemoRoomLrg_5c1b8cbb-lib" name="DemoRoomLrg_5c1b8cbbMesh"> + <mesh> + <source id="DemoRoomLrg_5c1b8cbb-Position"> + <float_array id="DemoRoomLrg_5c1b8cbb-Position-array" count="1014"> + -10.5000 10.5000 -0.5000 + -10.5000 10.5000 4.5000 + -10.5000 -10.5000 -0.5000 + -10.5000 -10.5000 4.5000 + -10.0000 10.5000 -0.5000 + -10.0000 10.5000 4.5000 + -10.0000 -10.5000 4.5000 + -10.0000 -10.5000 -0.5000 + -10.0000 10.0000 4.0000 + -10.0000 10.0000 -0.0000 + -10.0000 -10.0000 4.0000 + -10.0000 -10.0000 0.0000 + 10.0000 -10.5000 4.5000 + 10.0000 -10.5000 -0.5000 + 10.0000 -10.0000 4.5000 + -10.0000 -10.0000 4.5000 + -10.0000 -10.0000 -0.5000 + 10.0000 -10.0000 -0.5000 + 10.0000 -10.0000 0.0000 + 10.0000 -10.0000 4.0000 + 10.0000 10.0000 4.5000 + -10.0000 10.0000 4.5000 + 4.5000 -10.0000 4.0000 + 4.5000 10.0000 4.0000 + 10.0000 10.0000 4.0000 + 3.5000 4.5000 4.0000 + -3.5000 4.5000 4.0000 + 3.5000 3.5000 4.0000 + -3.5000 3.5000 4.0000 + 3.5000 -3.5000 4.0000 + -3.5000 -3.5000 4.0000 + 3.5000 -4.5000 4.0000 + -3.5000 -4.5000 4.0000 + -4.5000 10.0000 4.0000 + -4.5000 -10.0000 4.0000 + 4.5000 4.5000 4.0000 + -4.5000 4.5000 4.0000 + 4.5000 -3.5000 4.0000 + 4.5000 3.5000 4.0000 + -4.5000 -3.5000 4.0000 + -4.5000 3.5000 4.0000 + 4.5000 -4.5000 4.0000 + -4.5000 -4.5000 4.0000 + 10.0000 10.0000 -0.5000 + -10.0000 10.0000 -0.5000 + 4.5000 10.0000 0.0000 + 10.0000 10.0000 0.0000 + 4.5000 -10.0000 0.0000 + 3.5000 3.5000 0.0000 + -3.5000 3.5000 0.0000 + 3.5000 4.5000 0.0000 + -3.5000 4.5000 0.0000 + 3.5000 -4.5000 0.0000 + -3.5000 -4.5000 0.0000 + 3.5000 -3.5000 0.0000 + -3.5000 -3.5000 0.0000 + -4.5000 10.0000 0.0000 + -4.5000 -10.0000 0.0000 + 4.5000 4.5000 0.0000 + -4.5000 4.5000 0.0000 + 4.5000 3.5000 0.0000 + 4.5000 -3.5000 0.0000 + -4.5000 3.5000 0.0000 + -4.5000 -3.5000 0.0000 + 4.5000 -4.5000 0.0000 + -4.5000 -4.5000 0.0000 + 10.5000 10.5000 4.5000 + 10.5000 10.5000 -0.5000 + 10.5000 -10.0000 4.5000 + 10.5000 -10.5000 -0.5000 + 10.5000 -10.5000 4.5000 + 10.0000 10.5000 4.5000 + 10.5000 10.0000 4.5000 + 10.0000 10.5000 -0.5000 + -6.0000 10.5000 -0.5000 + -6.0000 10.5000 4.5000 + -6.0000 10.0000 4.5000 + -6.0000 10.0000 -0.5000 + -6.0000 10.0000 -0.0000 + -6.0000 10.0000 4.0000 + 6.0000 10.5000 -0.5000 + 6.0000 10.5000 4.5000 + 6.0000 10.0000 4.5000 + 6.0000 10.0000 -0.5000 + 6.0000 10.0000 0.0000 + 6.0000 10.0000 4.0000 + -2.0000 18.0000 0.0000 + 2.0000 18.0000 0.0000 + -2.0000 10.0000 0.0000 + 2.0000 10.0000 0.0000 + 2.0000 18.0000 -0.5000 + -2.0000 18.0000 -0.5000 + 2.0000 10.0000 -0.5000 + -2.0000 10.0000 -0.5000 + -4.5000 20.5000 -0.5000 + -4.5000 20.5000 4.5000 + -4.5000 10.5000 -0.5000 + -4.5000 10.5000 4.5000 + -4.0000 20.5000 -0.5000 + -4.0000 20.5000 4.5000 + -4.0000 10.0000 4.0000 + -4.0000 10.0000 -0.0000 + -4.5000 10.0000 4.5000 + -4.0000 10.0000 4.5000 + -4.0000 10.0000 -0.5000 + -4.5000 10.0000 -0.5000 + -4.0000 20.0000 4.0000 + -4.0000 20.0000 0.0000 + 4.0000 20.0000 -0.0000 + 4.0000 20.0000 4.0000 + 4.0000 10.0000 0.0000 + 4.0000 10.0000 4.0000 + 4.0000 20.5000 -0.5000 + 4.5000 20.5000 -0.5000 + 4.0000 20.5000 4.5000 + 4.5000 20.5000 4.5000 + 4.0000 10.0000 4.5000 + 4.5000 10.0000 4.5000 + 4.5000 10.0000 -0.5000 + 4.0000 10.0000 -0.5000 + 4.5000 10.5000 4.5000 + 4.5000 10.5000 -0.5000 + -2.0000 20.0000 0.0000 + -2.0000 20.0000 4.0000 + -2.0000 20.5000 -0.0000 + -2.0000 20.5000 4.0000 + -2.0000 20.0000 12.0000 + -2.0000 20.0000 15.9999 + -2.0000 20.5000 12.0000 + -2.0000 20.5000 15.9999 + -2.0000 20.5000 18.0000 + -2.0000 24.0000 18.0000 + -2.0000 20.5000 -2.0000 + -2.0000 24.0000 -2.0000 + -2.5000 20.5000 4.5000 + -2.5000 20.5000 11.5000 + -2.5000 20.0000 4.5000 + -2.5000 20.0000 11.5000 + -2.5000 20.0000 -2.5000 + -2.5000 20.5000 -2.5000 + -2.5000 20.0000 -0.5000 + -2.5000 20.5000 -0.5000 + -2.5000 20.5000 18.5000 + -2.5000 20.0000 18.5000 + -2.5000 20.5000 16.5000 + -2.5000 20.0000 16.5000 + -2.5000 24.5000 -2.5000 + -2.5000 24.5000 18.5000 + -2.0000 24.5000 18.5000 + -2.0000 24.5000 -2.5000 + -2.5000 20.0000 0.0000 + -2.5000 20.0000 4.0000 + -2.0000 20.0000 4.5000 + -2.0000 20.0000 11.5000 + -2.0000 20.0000 -2.5000 + -2.0000 20.0000 -0.5000 + -2.5000 20.0000 12.0000 + -2.5000 20.0000 15.9999 + -2.0000 20.0000 16.5000 + -2.0000 20.0000 18.5000 + 2.5000 20.0000 4.5000 + 2.5000 20.0000 11.5000 + 2.5000 20.5000 4.5000 + 2.5000 20.5000 11.5000 + 2.5000 20.0000 -2.5000 + 2.5000 20.0000 -0.5000 + 2.5000 20.5000 -2.5000 + 2.5000 20.5000 -0.5000 + 2.5000 20.0000 16.5000 + 2.5000 20.0000 18.5000 + 2.5000 20.5000 16.5000 + 2.5000 20.5000 18.5000 + 2.5000 24.5000 18.5000 + 2.5000 24.5000 -2.5000 + 2.0000 20.0000 4.0000 + 2.0000 20.0000 -0.0000 + 2.0000 20.5000 4.0000 + 2.0000 20.5000 -0.0000 + 2.0000 20.5000 15.9999 + 2.0000 20.0000 15.9999 + 2.0000 20.5000 12.0000 + 2.0000 20.0000 12.0000 + 2.0000 24.0000 18.0000 + 2.0000 20.5000 18.0000 + 2.0000 24.0000 -2.0000 + 2.0000 20.5000 -2.0000 + 2.0000 24.5000 18.5000 + 2.0000 24.5000 -2.5000 + 2.5000 20.0000 -0.0000 + 2.5000 20.0000 4.0000 + 2.0000 20.0000 4.5000 + 2.0000 20.0000 11.5000 + 2.0000 20.0000 -2.5000 + 2.0000 20.0000 -0.5000 + 2.5000 20.0000 12.0000 + 2.5000 20.0000 15.9999 + 2.0000 20.0000 16.5000 + 2.0000 20.0000 18.5000 + -4.0000 20.0000 4.5000 + -4.0000 20.0000 -0.5000 + 4.0000 20.0000 4.5000 + 4.0000 20.0000 -0.5000 + -2.0000 24.0000 18.5000 + 2.0000 24.0000 18.5000 + -2.0000 24.0000 -2.5000 + 2.0000 24.0000 -2.5000 + -2.0000 20.5000 -2.5000 + 2.0000 20.5000 -2.5000 + -2.0000 20.5000 18.5000 + 2.0000 20.5000 18.5000 + -4.0000 20.5000 11.5000 + -4.0000 20.5000 16.5000 + -4.0000 20.0000 12.0000 + -4.0000 20.0000 15.9999 + -4.0000 20.0000 16.5000 + -4.0000 20.0000 11.5000 + 4.0000 20.5000 11.5000 + 4.0000 20.5000 16.5000 + 4.0000 20.0000 12.0000 + 4.0000 20.0000 15.9999 + 4.0000 20.0000 16.5000 + 4.0000 20.0000 11.5000 + -2.0000 20.0000 18.4999 + 2.0000 20.0000 18.4999 + -2.0000 20.5000 18.4999 + 2.0000 20.5000 18.4999 + -4.0000 18.0000 0.0000 + -4.0000 18.0000 -0.5000 + 4.0000 18.0000 0.0000 + 4.0000 18.0000 -0.5000 + -2.0000 18.0000 4.5000 + 2.0000 18.0000 4.5000 + -2.0000 10.0000 4.5000 + 2.0000 10.0000 4.5000 + 2.0000 18.0000 4.0000 + -2.0000 18.0000 4.0000 + 2.0000 10.0000 4.0000 + -2.0000 10.0000 4.0000 + -4.0000 18.0000 4.5000 + -4.0000 18.0000 4.0000 + 4.0000 18.0000 4.5000 + 4.0000 18.0000 4.0000 + -2.0000 18.0000 12.0000 + 2.0000 18.0000 12.0000 + -2.0000 10.0000 12.0000 + 2.0000 10.0000 12.0000 + 2.0000 18.0000 11.5000 + -2.0000 18.0000 11.5000 + 2.0000 10.0000 11.5000 + -2.0000 10.0000 11.5000 + -4.5000 20.5000 11.5000 + -4.5000 20.5000 16.5000 + -4.5000 10.5000 11.5000 + -4.5000 10.5000 16.5000 + -4.0000 10.0000 15.9999 + -4.0000 10.0000 12.0000 + -4.5000 10.0000 15.9999 + -4.5000 10.0000 12.0000 + -4.5000 10.0000 16.5000 + -4.0000 10.0000 16.5000 + -4.0000 10.0000 11.5000 + -4.5000 10.0000 11.5000 + 4.0000 10.0000 12.0000 + 4.0000 10.0000 15.9999 + 4.5000 20.5000 11.5000 + 4.5000 20.5000 16.5000 + 4.5000 10.0000 15.9999 + 4.5000 10.0000 12.0000 + 4.0000 10.0000 16.5000 + 4.5000 10.0000 16.5000 + 4.5000 10.0000 11.5000 + 4.0000 10.0000 11.5000 + 4.5000 10.5000 16.5000 + 4.5000 10.5000 11.5000 + -4.0000 18.0000 12.0000 + -4.0000 18.0000 11.5000 + 4.0000 18.0000 12.0000 + 4.0000 18.0000 11.5000 + -2.0000 18.0000 16.5000 + 2.0000 18.0000 16.5000 + -2.0000 10.0000 16.5000 + 2.0000 10.0000 16.5000 + 2.0000 18.0000 16.0000 + -2.0000 18.0000 16.0000 + 2.0000 10.0000 16.0000 + -2.0000 10.0000 16.0000 + -4.0000 18.0000 16.5000 + -4.0000 18.0000 16.0000 + 4.0000 18.0000 16.5000 + 4.0000 18.0000 16.0000 + -10.5000 10.5000 11.5000 + -10.5000 10.5000 16.5000 + -10.5000 -10.5000 11.5000 + -10.5000 10.0000 16.5000 + -10.5000 -10.5000 16.5000 + -10.0000 10.5000 11.5000 + -10.0000 10.5000 16.5000 + -10.0000 -10.5000 11.5000 + -10.0000 -10.5000 16.5000 + -10.0000 10.0000 16.5000 + -10.5000 10.0000 11.5000 + -10.0000 10.0000 15.9999 + -10.0000 10.0000 12.0000 + -10.0000 -10.0000 15.9999 + -10.0000 -10.0000 12.0000 + 10.0000 -10.5000 16.5000 + 10.0000 -10.5000 11.5000 + 10.0000 -10.0000 16.5000 + -10.0000 -10.0000 16.5000 + 10.0000 -10.0000 11.5000 + -10.0000 -10.0000 11.5000 + 10.0000 -10.0000 12.0000 + 10.0000 -10.0000 15.9999 + 10.0000 10.0000 16.5000 + 10.0000 10.0000 16.0000 + 10.0000 10.0000 11.5000 + -10.0000 10.0000 11.5000 + 10.0000 10.0000 12.0000 + 10.5000 10.5000 16.5000 + 10.5000 10.5000 11.5000 + 10.5000 -10.5000 16.5000 + 10.5000 10.0000 11.5000 + 10.5000 -10.5000 11.5000 + 10.0000 10.5000 16.5000 + 10.5000 10.0000 16.5000 + 10.0000 10.5000 11.5000 + -6.0000 10.5000 11.5000 + -6.0000 10.5000 16.5000 + -6.0000 10.0000 16.5000 + -6.0000 10.0000 11.5000 + -6.0000 10.0000 12.0000 + -6.0000 10.0000 15.9999 + 6.0000 10.5000 11.5000 + 6.0000 10.5000 16.5000 + 6.0000 10.0000 16.5000 + 6.0000 10.0000 11.5000 + 6.0000 10.0000 12.0000 + 6.0000 10.0000 15.9999 + </float_array> + <technique_common> + <accessor source="#DemoRoomLrg_5c1b8cbb-Position-array" count="338" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="DemoRoomLrg_5c1b8cbb-Normal"> + <float_array id="DemoRoomLrg_5c1b8cbb-Normal-array" count="18"> + -1.0000 -0.0000 -0.0000 + -0.0000 1.0000 -0.0000 + -0.0000 -1.0000 -0.0000 + 0.0000 -0.0000 1.0000 + -0.0000 -0.0000 -1.0000 + 1.0000 -0.0000 0.0000 + </float_array> + <technique_common> + <accessor source="#DemoRoomLrg_5c1b8cbb-Normal-array" count="6" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="DemoRoomLrg_5c1b8cbb-UV0"> + <float_array id="DemoRoomLrg_5c1b8cbb-UV0-array" count="498"> + 0.0000 -0.0000 + 0.0000 9.0000 + 42.0000 -0.0000 + 42.0000 9.0000 + 41.0000 -0.0000 + 41.0000 9.0000 + 1.0000 9.0000 + 1.0000 -0.0000 + 0.0000 42.0000 + 1.0000 42.0000 + 41.0000 42.0000 + 42.0000 42.0000 + 3.0000 1.0000 + 3.0000 -0.0000 + -2.0000 1.0000 + -2.0000 0.0000 + 42.0000 1.0000 + 1.0000 1.0000 + 41.0000 1.0000 + 0.0000 1.0000 + 42.0000 41.0000 + 1.0000 41.0000 + -0.6250 -3.0000 + -2.0000 -3.0000 + -0.6250 2.0000 + -2.0000 2.0000 + -0.3750 0.6250 + 1.3750 0.6250 + -0.3750 0.3750 + 1.3750 0.3750 + -0.3750 -1.3750 + 1.3750 -1.3750 + -0.3750 -1.6250 + 1.3750 -1.6250 + 1.6250 2.0000 + 3.0000 2.0000 + 1.6250 -3.0000 + 3.0000 -3.0000 + -0.6250 0.6250 + 1.6250 0.6250 + -0.6250 -1.3750 + -0.6250 0.3750 + 1.6250 -1.3750 + 1.6250 0.3750 + -0.6250 -1.6250 + 1.6250 -1.6250 + 0.0000 41.0000 + 41.0000 41.0000 + 41.0000 8.0000 + 1.9524 8.0000 + 1.0000 8.0000 + 43.0500 42.0000 + 43.0500 41.0000 + 43.0500 0.0000 + -1.0500 0.0000 + -1.0500 9.0000 + 43.0500 9.0000 + -1.0500 42.0000 + -2.0030 -0.0000 + -2.0030 1.0000 + 2.8780 -0.0000 + 2.8780 1.0000 + 0.0000 -1.0000 + 0.2500 -1.0000 + 0.2500 0.0000 + -1.0000 -0.0000 + -1.0000 1.0000 + -1.0000 5.0000 + 0.0000 5.0000 + -1.0000 3.0000 + 0.0000 3.0000 + 0.0000 40.0000 + 24.0000 40.0000 + 24.0000 0.0000 + 40.0000 -0.0000 + 40.0000 9.0000 + -2.2500 2.0000 + -2.2500 0.0000 + 5.5000 1.0000 + 5.5000 0.0000 + -4.5000 -0.0000 + -4.5000 1.0000 + 2.2500 2.0000 + 2.2500 0.0000 + 2.0000 2.0000 + 2.0000 0.0000 + 32.0000 9.0000 + 32.0000 -1.0000 + 25.3333 9.0000 + 25.3333 -1.0000 + 5.0000 0.0000 + 5.0000 1.0000 + 5.1250 -0.0000 + 5.1250 1.0000 + 5.0000 3.0000 + 5.0000 4.0000 + 5.1250 3.0000 + 5.1250 4.0000 + 5.1250 4.5000 + 6.0000 4.5000 + 5.1250 -0.5000 + 6.0000 -0.5000 + 7.1111 0.3333 + 7.1111 0.6667 + 8.0000 0.3333 + 8.0000 0.6667 + 8.0000 -0.0000 + 7.1111 -0.0000 + 8.0000 0.0952 + 7.1111 0.0952 + 7.1111 1.0000 + 8.0000 1.0000 + 7.1111 0.9048 + 8.0000 0.9048 + -1.2500 0.0000 + -1.2500 2.0000 + -1.0000 2.0000 + -1.2500 2.2500 + -1.2500 5.7500 + -1.0000 2.2500 + -1.0000 5.7500 + -1.2500 -1.2500 + -1.2500 -0.2500 + -1.0000 -1.2500 + -1.0000 -0.2500 + -1.2500 6.0000 + -1.2500 8.0000 + -1.0000 6.0000 + -1.0000 8.0000 + -1.2500 8.2500 + -1.2500 9.2500 + -1.0000 8.2500 + -1.0000 9.2500 + 0.0000 8.0000 + 0.0000 0.3333 + 0.0000 0.6667 + 0.8889 0.3333 + 0.8889 0.6667 + 0.0000 0.0952 + 0.8889 -0.0000 + 0.8889 0.0952 + 0.0000 0.9048 + 0.8889 0.9048 + 0.8889 1.0000 + -5.0000 1.0000 + -5.0000 -0.0000 + -5.1250 1.0000 + -5.1250 -0.0000 + -5.1250 4.0000 + -5.0000 4.0000 + -5.1250 3.0000 + -5.0000 3.0000 + -6.0000 4.5000 + -5.1250 4.5000 + -6.0000 -0.5000 + -5.1250 -0.5000 + 1.0000 2.0000 + 1.2500 -0.0000 + 1.2500 2.0000 + 1.0000 2.2500 + 1.0000 5.7500 + 1.2500 2.2500 + 1.2500 5.7500 + 1.0000 -1.2500 + 1.0000 -0.2500 + 1.2500 -1.2500 + 1.2500 -0.2500 + 1.0000 6.0000 + 1.2500 6.0000 + 1.2500 8.0000 + 1.0000 8.2500 + 1.0000 9.2500 + 1.2500 8.2500 + 1.2500 9.2500 + 5.0000 10.0000 + -0.0000 10.0000 + 0.0000 4.5000 + 1.0000 4.5000 + 0.0000 -0.5000 + 1.0000 -0.5000 + 0.0000 5.1250 + 0.0000 6.0000 + 1.0000 5.1250 + -1.0000 -1.0000 + 1.0000 -1.0000 + 5.0000 8.0000 + -1.0000 9.7500 + -1.0000 10.0000 + 1.0000 9.7500 + 1.0000 10.0000 + 1.0000 2.3750 + 0.0000 2.3750 + 0.0000 0.6250 + 0.0000 9.3750 + 5.0000 0.6250 + 5.0000 9.3750 + -2.0000 6.0000 + -2.0000 8.0000 + 2.0000 6.0000 + 2.0000 8.0000 + -1.0000 9.0000 + 0.0000 2.0003 + 5.0000 2.0003 + -0.0011 9.0000 + 40.9989 9.0000 + -0.0011 -0.0000 + 40.9989 -0.0000 + 1.0002 42.0000 + 42.0001 42.0000 + 1.0002 41.0000 + 42.0001 41.0000 + -0.0011 41.0000 + -0.0011 42.0000 + 40.9989 41.0000 + 40.9989 42.0000 + -3.0000 2.0000 + -3.0000 -0.0000 + 40.9991 -0.0000 + -0.0008 -0.0000 + 40.9991 9.0000 + -0.0008 9.0000 + 0.9999 42.0000 + 41.9998 42.0000 + 0.9999 41.0000 + 41.9998 41.0000 + -0.0008 41.0000 + -0.0008 42.0000 + 40.9991 41.0000 + 40.9991 42.0000 + -2.0000 9.0000 + -2.0000 5.0000 + 0.0001 40.0000 + 0.0001 0.0000 + 2.0000 9.0000 + 1.0000 5.0000 + 2.0000 5.0000 + -2.0000 10.0000 + 2.0000 10.0000 + -4.0000 36.0000 + 4.0000 36.0000 + -4.0000 20.0000 + 4.0000 20.0000 + -8.0000 36.0000 + -8.0000 20.0000 + 8.0000 36.0000 + 8.0000 20.0000 + -8.0000 40.0000 + 8.0000 40.0000 + 40.0476 1.0000 + </float_array> + <technique_common> + <accessor source="#DemoRoomLrg_5c1b8cbb-UV0-array" count="249" stride="2"> + <param name="S" type="float" /> + <param name="T" type="float" /> + </accessor> + </technique_common> + </source> + <vertices id="DemoRoomLrg_5c1b8cbb-Vertex"> + <input semantic="POSITION" source="#DemoRoomLrg_5c1b8cbb-Position" /> + </vertices> + <triangles material="BLACK" count="253"> + <input semantic="VERTEX" offset="0" source="#DemoRoomLrg_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#DemoRoomLrg_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#DemoRoomLrg_5c1b8cbb-UV0" /> + <p> + 3 0 3 1 0 1 0 0 0 + 2 0 2 3 0 3 0 0 0 + 5 1 5 4 1 4 0 1 2 + 1 1 3 5 1 5 0 1 2 + 7 2 7 6 2 6 3 2 1 + 2 2 0 7 2 7 3 2 1 + 6 3 7 5 3 9 1 3 8 + 3 3 0 6 3 7 1 3 8 + 2 4 2 0 4 11 4 4 10 + 7 4 4 2 4 2 4 4 10 + 7 2 7 13 2 2 12 2 3 + 6 2 6 7 2 7 12 2 3 + 6 3 7 12 3 2 14 3 16 + 15 3 17 6 3 7 14 3 16 + 17 4 19 13 4 0 7 4 4 + 16 4 18 17 4 19 7 4 4 + 15 3 17 14 3 16 20 3 20 + 21 3 21 15 3 17 20 3 20 + 44 4 47 43 4 46 17 4 19 + 16 4 18 44 4 47 17 4 19 + 69 5 17 67 5 18 66 5 48 + 70 5 50 69 5 17 66 5 48 + 68 5 49 70 5 50 66 5 48 + 72 3 52 66 3 51 71 3 11 + 70 3 53 72 3 52 71 3 11 + 12 3 2 70 3 53 71 3 11 + 14 3 16 12 3 2 71 3 11 + 71 1 1 66 1 55 67 1 54 + 73 1 0 71 1 1 67 1 54 + 69 2 53 70 2 56 12 2 3 + 13 2 2 69 2 53 12 2 3 + 13 4 0 73 4 8 67 4 57 + 69 4 54 13 4 0 67 4 57 + 75 1 1 74 1 0 4 1 4 + 5 1 5 75 1 1 4 1 4 + 76 3 20 75 3 11 5 3 9 + 21 3 21 76 3 20 5 3 9 + 4 4 10 74 4 8 77 4 46 + 44 4 47 4 4 10 77 4 46 + 71 1 1 73 1 0 80 1 4 + 81 1 5 71 1 1 80 1 4 + 20 3 20 71 3 11 81 3 9 + 82 3 21 20 3 20 81 3 9 + 80 4 10 73 4 8 43 4 46 + 83 4 47 80 4 10 43 4 46 + 93 4 73 91 4 72 90 4 71 + 92 4 0 93 4 73 90 4 71 + 97 0 75 95 0 1 94 0 0 + 96 0 74 97 0 75 94 0 0 + 99 1 5 98 1 4 94 1 2 + 95 1 3 99 1 5 94 1 2 + 103 3 7 99 3 9 95 3 8 + 102 3 0 103 3 7 95 3 8 + 105 4 2 94 4 11 98 4 10 + 104 4 4 105 4 2 98 4 10 + 115 1 5 113 1 4 112 1 2 + 114 1 3 115 1 5 112 1 2 + 117 3 7 115 3 9 114 3 8 + 116 3 0 117 3 7 114 3 8 + 119 4 2 112 4 11 113 4 10 + 118 4 4 119 4 2 113 4 10 + 121 5 89 113 5 87 115 5 86 + 120 5 88 121 5 89 115 5 86 + 137 0 105 135 0 103 134 0 102 + 136 0 104 137 0 105 134 0 102 + 141 0 109 139 0 107 138 0 106 + 140 0 108 141 0 109 138 0 106 + 145 0 113 143 0 111 142 0 110 + 144 0 112 145 0 113 142 0 110 + 147 0 19 146 0 0 139 0 107 + 142 0 110 147 0 19 139 0 107 + 146 1 7 147 1 17 148 1 19 + 149 1 0 146 1 7 148 1 19 + 148 3 50 147 3 133 143 3 0 + 159 3 7 148 3 50 143 3 0 + 149 4 133 154 4 0 138 4 7 + 146 4 50 149 4 133 138 4 7 + 163 5 137 161 5 135 160 5 134 + 162 5 136 163 5 137 160 5 134 + 167 5 140 165 5 138 164 5 0 + 166 5 139 167 5 140 164 5 0 + 171 5 143 169 5 19 168 5 141 + 170 5 142 171 5 143 168 5 141 + 173 5 106 172 5 111 171 5 143 + 166 5 139 173 5 106 171 5 143 + 187 1 7 186 1 17 172 1 19 + 173 1 0 187 1 7 172 1 19 + 172 3 50 186 3 133 197 3 0 + 169 3 7 172 3 50 197 3 0 + 173 4 133 164 4 0 192 4 7 + 187 4 50 173 4 133 192 4 7 + 134 1 175 141 1 0 98 1 90 + 99 1 174 134 1 175 98 1 90 + 134 3 91 99 3 19 198 3 0 + 136 3 90 134 3 91 198 3 0 + 141 4 19 140 4 0 199 4 90 + 98 4 91 141 4 19 199 4 90 + 114 1 175 112 1 0 167 1 90 + 162 1 174 114 1 175 167 1 90 + 114 3 91 162 3 19 160 3 0 + 200 3 90 114 3 91 160 3 0 + 112 4 19 201 4 0 165 4 90 + 167 4 91 112 4 19 165 4 90 + 149 1 90 148 1 174 186 1 175 + 187 1 0 149 1 90 186 1 175 + 186 3 91 148 3 19 202 3 0 + 203 3 90 186 3 91 202 3 0 + 187 4 19 205 4 0 204 4 90 + 149 4 91 187 4 19 204 4 90 + 205 4 133 207 4 0 206 4 7 + 204 4 50 205 4 133 206 4 7 + 193 2 185 155 2 133 154 2 0 + 192 2 90 193 2 185 154 2 0 + 207 4 19 192 4 0 154 4 90 + 206 4 91 207 4 19 154 4 90 + 191 2 195 153 2 193 152 2 192 + 190 2 194 191 2 195 152 2 192 + 203 3 50 202 3 133 208 3 0 + 209 3 7 203 3 50 208 3 0 + 144 1 175 135 1 0 210 1 90 + 211 1 174 144 1 175 210 1 90 + 144 3 91 211 3 19 214 3 0 + 145 3 90 144 3 91 214 3 0 + 135 4 19 137 4 0 215 4 90 + 210 4 91 135 4 19 215 4 90 + 217 1 175 216 1 0 163 1 90 + 170 1 174 217 1 175 163 1 90 + 217 3 91 170 3 19 168 3 0 + 220 3 90 217 3 91 168 3 0 + 216 4 19 221 4 0 161 4 90 + 163 4 91 216 4 19 161 4 90 + 223 2 174 222 2 175 158 2 201 + 196 2 202 223 2 174 158 2 201 + 225 3 91 224 3 19 222 3 0 + 223 3 90 225 3 91 222 3 0 + 74 1 206 75 1 204 97 1 203 + 96 1 205 74 1 206 97 1 203 + 102 3 210 97 3 208 75 3 207 + 76 3 209 102 3 210 75 3 207 + 74 4 214 96 4 212 105 4 211 + 77 4 213 74 4 214 105 4 211 + 81 1 220 80 1 218 121 1 217 + 120 1 219 81 1 220 121 1 217 + 82 3 224 81 3 222 120 3 221 + 117 3 223 82 3 224 120 3 221 + 121 4 228 80 4 226 83 4 225 + 118 4 227 121 4 228 83 4 225 + 104 4 73 227 4 72 91 4 231 + 93 4 232 104 4 73 91 4 231 + 92 4 73 90 4 72 229 4 71 + 119 4 0 92 4 73 229 4 71 + 201 4 71 229 4 0 227 4 73 + 199 4 72 201 4 71 227 4 73 + 233 3 241 231 3 239 230 3 238 + 232 3 240 233 3 241 230 3 238 + 232 3 240 230 3 238 238 3 242 + 103 3 243 232 3 240 238 3 242 + 116 3 245 240 3 244 231 3 239 + 233 3 241 116 3 245 231 3 239 + 200 3 247 198 3 246 238 3 242 + 240 3 244 200 3 247 238 3 242 + 249 4 73 247 4 72 246 4 71 + 248 4 0 249 4 73 246 4 71 + 253 0 75 251 0 1 250 0 0 + 252 0 74 253 0 75 250 0 0 + 211 1 5 210 1 4 250 1 2 + 251 1 3 211 1 5 250 1 2 + 259 3 7 211 3 9 251 3 8 + 258 3 0 259 3 7 251 3 8 + 261 4 2 250 4 11 210 4 10 + 260 4 4 261 4 2 210 4 10 + 265 1 5 264 1 4 216 1 2 + 217 1 3 265 1 5 216 1 2 + 269 3 7 265 3 9 217 3 8 + 268 3 0 269 3 7 217 3 8 + 271 4 2 216 4 11 264 4 10 + 270 4 4 271 4 2 264 4 10 + 273 5 89 264 5 87 265 5 86 + 272 5 88 273 5 89 265 5 86 + 260 4 73 275 4 72 247 4 231 + 249 4 232 260 4 73 247 4 231 + 248 4 73 246 4 72 277 4 71 + 271 4 0 248 4 73 277 4 71 + 281 3 241 279 3 239 278 3 238 + 280 3 240 281 3 241 278 3 238 + 280 3 240 278 3 238 286 3 242 + 259 3 243 280 3 240 286 3 242 + 268 3 245 288 3 244 279 3 239 + 281 3 241 268 3 245 279 3 239 + 220 3 247 214 3 246 286 3 242 + 288 3 244 220 3 247 286 3 242 + 221 4 71 277 4 0 275 4 73 + 215 4 72 221 4 71 275 4 73 + 293 0 6 291 0 1 290 0 0 + 294 0 3 293 0 6 290 0 0 + 292 0 2 294 0 3 290 0 0 + 296 1 5 295 1 4 290 1 2 + 291 1 3 296 1 5 290 1 2 + 298 2 6 294 2 1 292 2 0 + 297 2 7 298 2 6 292 2 0 + 299 3 21 296 3 9 291 3 8 + 298 3 7 299 3 21 291 3 8 + 294 3 0 298 3 7 291 3 8 + 300 4 20 290 4 11 295 4 10 + 292 4 2 300 4 20 295 4 10 + 297 4 4 292 4 2 295 4 10 + 306 2 2 305 2 3 298 2 6 + 297 2 7 306 2 2 298 2 6 + 298 3 7 305 3 2 307 3 16 + 308 3 17 298 3 7 307 3 16 + 310 4 18 309 4 19 306 4 0 + 297 4 4 310 4 18 306 4 0 + 308 3 17 307 3 16 313 3 20 + 299 3 21 308 3 17 313 3 20 + 316 4 47 315 4 46 309 4 19 + 310 4 18 316 4 47 309 4 19 + 321 5 248 319 5 18 318 5 48 + 322 5 17 321 5 248 318 5 48 + 320 5 50 322 5 17 318 5 48 + 324 3 52 318 3 51 323 3 11 + 320 3 53 324 3 52 323 3 11 + 305 3 2 320 3 53 323 3 11 + 323 1 1 318 1 55 319 1 54 + 325 1 0 323 1 1 319 1 54 + 322 2 53 320 2 56 305 2 3 + 306 2 2 322 2 53 305 2 3 + 315 4 46 325 4 8 319 4 57 + 306 4 0 315 4 46 319 4 57 + 322 4 54 306 4 0 319 4 57 + 327 1 1 326 1 0 295 1 4 + 296 1 5 327 1 1 295 1 4 + 328 3 20 327 3 11 296 3 9 + 299 3 21 328 3 20 296 3 9 + 295 4 10 326 4 8 329 4 46 + 316 4 47 295 4 10 329 4 46 + 323 1 1 325 1 0 332 1 4 + 333 1 5 323 1 1 332 1 4 + 313 3 20 323 3 11 333 3 9 + 334 3 21 313 3 20 333 3 9 + 332 4 10 325 4 8 315 4 46 + 335 4 47 332 4 10 315 4 46 + 326 1 206 327 1 204 253 1 203 + 252 1 205 326 1 206 253 1 203 + 258 3 210 253 3 208 327 3 207 + 328 3 209 258 3 210 327 3 207 + 326 4 214 252 4 212 261 4 211 + 329 4 213 326 4 214 261 4 211 + 333 1 220 332 1 218 273 1 217 + 272 1 219 333 1 220 273 1 217 + 334 3 224 333 3 222 272 3 221 + 269 3 223 334 3 224 272 3 221 + 273 4 228 332 4 226 335 4 225 + 270 4 227 273 4 228 335 4 225 + </p> + </triangles> + <triangles material="FULL128X128G" count="88"> + <input semantic="VERTEX" offset="0" source="#DemoRoomLrg_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#DemoRoomLrg_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#DemoRoomLrg_5c1b8cbb-UV0" /> + <p> + 11 5 15 9 5 13 8 5 12 + 10 5 14 11 5 15 8 5 12 + 10 1 12 19 1 14 18 1 15 + 11 1 13 10 1 12 18 1 15 + 24 4 25 19 4 23 22 4 22 + 23 4 24 24 4 25 22 4 22 + 28 4 29 26 4 27 25 4 26 + 27 4 28 28 4 29 25 4 26 + 32 4 33 30 4 31 29 4 30 + 31 4 32 32 4 33 29 4 30 + 10 4 37 8 4 35 33 4 34 + 34 4 36 10 4 37 33 4 34 + 33 4 34 23 4 24 35 4 38 + 36 4 39 33 4 34 35 4 38 + 40 4 43 38 4 41 37 4 40 + 39 4 42 40 4 43 37 4 40 + 42 4 45 41 4 44 22 4 22 + 34 4 36 42 4 45 22 4 22 + 18 3 37 46 3 35 45 3 34 + 47 3 36 18 3 37 45 3 34 + 51 3 26 49 3 28 48 3 29 + 50 3 27 51 3 26 48 3 29 + 55 3 30 53 3 32 52 3 33 + 54 3 31 55 3 30 52 3 33 + 57 3 22 56 3 24 9 3 25 + 11 3 23 57 3 22 9 3 25 + 59 3 38 58 3 39 45 3 34 + 56 3 24 59 3 38 45 3 34 + 63 3 40 61 3 42 60 3 43 + 62 3 41 63 3 40 60 3 43 + 57 3 22 47 3 36 64 3 45 + 65 3 44 57 3 22 64 3 45 + 19 0 61 24 0 59 46 0 58 + 18 0 60 19 0 61 46 0 58 + 79 2 66 8 2 14 9 2 15 + 78 2 65 79 2 66 9 2 15 + 24 2 66 85 2 14 84 2 15 + 46 2 65 24 2 66 84 2 15 + 89 3 70 87 3 68 86 3 67 + 88 3 69 89 3 70 86 3 67 + 101 5 13 107 5 79 106 5 78 + 100 5 12 101 5 13 106 5 78 + 111 0 14 109 0 81 108 0 80 + 110 0 15 111 0 14 108 0 80 + 125 5 93 123 5 91 122 5 90 + 124 5 92 125 5 93 122 5 90 + 129 5 97 127 5 95 126 5 94 + 128 5 96 129 5 97 126 5 94 + 133 5 101 131 5 99 130 5 98 + 132 5 100 133 5 101 130 5 98 + 177 0 147 175 0 145 174 0 144 + 176 0 146 177 0 147 174 0 144 + 181 0 151 179 0 149 178 0 148 + 180 0 150 181 0 151 178 0 148 + 185 0 155 183 0 153 182 0 152 + 184 0 154 185 0 155 182 0 152 + 184 2 179 182 2 177 131 2 176 + 133 2 178 184 2 179 131 2 176 + 184 3 167 133 3 181 132 3 180 + 185 3 182 184 3 167 132 3 180 + 180 1 191 176 1 19 125 1 17 + 128 1 190 180 1 191 125 1 17 + 182 4 181 183 4 180 130 4 182 + 131 4 167 182 4 181 130 4 182 + 237 4 70 235 4 68 234 4 67 + 236 4 69 237 4 70 234 4 67 + 245 3 70 243 3 68 242 3 67 + 244 3 69 245 3 70 242 3 67 + 255 5 13 212 5 79 213 5 78 + 254 5 12 255 5 13 213 5 78 + 263 0 14 219 0 81 218 0 80 + 262 0 15 263 0 14 218 0 80 + 285 4 70 283 4 68 282 4 67 + 284 4 69 285 4 70 282 4 67 + 304 5 15 302 5 13 301 5 12 + 303 5 14 304 5 15 301 5 12 + 303 1 12 312 1 14 311 1 15 + 304 1 13 303 1 12 311 1 15 + 314 4 25 312 4 23 303 4 37 + 301 4 35 314 4 25 303 4 37 + 317 3 35 302 3 25 304 3 23 + 311 3 37 317 3 35 304 3 23 + 312 0 61 314 0 59 317 0 58 + 311 0 60 312 0 61 317 0 58 + 331 2 66 301 2 14 302 2 15 + 330 2 65 331 2 66 302 2 15 + 314 2 66 337 2 14 336 2 15 + 317 2 65 314 2 66 336 2 15 + </p> + </triangles> + <triangles material="PILLAR128X128G" count="32"> + <input semantic="VERTEX" offset="0" source="#DemoRoomLrg_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#DemoRoomLrg_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#DemoRoomLrg_5c1b8cbb-UV0" /> + <p> + 30 5 64 32 5 0 53 5 62 + 55 5 63 30 5 64 53 5 62 + 39 0 0 63 0 62 65 0 63 + 42 0 64 39 0 0 65 0 63 + 30 1 0 55 1 62 63 1 63 + 39 1 64 30 1 0 63 1 63 + 32 2 64 42 2 0 65 2 62 + 53 2 63 32 2 64 65 2 62 + 26 5 64 28 5 0 49 5 62 + 51 5 63 26 5 64 49 5 62 + 36 0 0 59 0 62 62 0 63 + 40 0 64 36 0 0 62 0 63 + 26 1 0 51 1 62 59 1 63 + 36 1 64 26 1 0 59 1 63 + 28 2 64 40 2 0 62 2 62 + 49 2 63 28 2 64 62 2 62 + 35 5 64 38 5 0 60 5 62 + 58 5 63 35 5 64 60 5 62 + 25 0 0 50 0 62 48 0 63 + 27 0 64 25 0 0 48 0 63 + 35 1 0 58 1 62 50 1 63 + 25 1 64 35 1 0 50 1 63 + 38 2 64 27 2 0 48 2 62 + 60 2 63 38 2 64 48 2 62 + 37 5 64 41 5 0 64 5 62 + 61 5 63 37 5 64 64 5 62 + 29 0 0 54 0 62 52 0 63 + 31 0 64 29 0 0 52 0 63 + 37 1 0 61 1 62 54 1 63 + 29 1 64 37 1 0 54 1 63 + 41 2 64 31 2 0 52 2 62 + 64 2 63 41 2 64 52 2 62 + </p> + </triangles> + <triangles material="FULL64X64G" count="80"> + <input semantic="VERTEX" offset="0" source="#DemoRoomLrg_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#DemoRoomLrg_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#DemoRoomLrg_5c1b8cbb-UV0" /> + <p> + 56 2 77 101 2 15 100 2 25 + 33 2 76 56 2 77 100 2 25 + 110 2 85 45 2 83 23 2 82 + 111 2 84 110 2 85 23 2 82 + 123 2 116 151 2 115 150 2 114 + 122 2 65 123 2 116 150 2 114 + 153 2 120 137 2 118 136 2 117 + 152 2 119 153 2 120 136 2 117 + 155 2 124 140 2 122 138 2 121 + 154 2 123 155 2 124 138 2 121 + 127 2 128 157 2 126 156 2 125 + 126 2 127 127 2 128 156 2 125 + 159 2 132 143 2 130 145 2 129 + 158 2 131 159 2 132 145 2 129 + 189 2 158 174 2 156 175 2 7 + 188 2 157 189 2 158 175 2 7 + 161 2 162 191 2 160 190 2 159 + 160 2 161 161 2 162 190 2 159 + 165 2 166 193 2 164 192 2 163 + 164 2 165 165 2 166 192 2 163 + 195 2 169 179 2 50 181 2 167 + 194 2 168 195 2 169 181 2 167 + 169 2 173 197 2 171 196 2 170 + 168 2 172 169 2 173 196 2 170 + 151 2 115 106 2 25 107 2 15 + 150 2 114 151 2 115 107 2 15 + 109 2 84 189 2 158 188 2 157 + 108 2 85 109 2 84 188 2 157 + 124 1 7 177 1 65 185 1 183 + 132 1 184 124 1 7 185 1 183 + 177 3 189 124 3 187 122 3 186 + 175 3 188 177 3 189 122 3 186 + 180 3 189 128 3 187 126 3 186 + 181 3 188 180 3 189 126 3 186 + 176 4 187 174 4 186 123 4 188 + 125 4 189 176 4 187 123 4 188 + 157 2 126 213 2 197 212 2 196 + 156 2 125 157 2 126 212 2 196 + 219 2 199 195 2 169 194 2 168 + 218 2 198 219 2 199 194 2 168 + 183 1 200 178 1 128 129 1 50 + 130 1 6 183 1 200 129 1 50 + 178 4 187 179 4 186 127 4 188 + 129 4 189 178 4 187 127 4 188 + 78 2 216 56 2 77 33 2 76 + 79 2 215 78 2 216 33 2 76 + 85 2 35 23 2 82 45 2 83 + 84 2 13 85 2 35 45 2 83 + 88 3 67 86 3 200 226 3 229 + 101 3 230 88 3 67 226 3 229 + 110 3 235 228 3 233 87 3 6 + 89 3 234 110 3 235 87 3 6 + 108 3 237 107 3 236 226 3 229 + 228 3 233 108 3 237 226 3 229 + 100 4 235 239 4 233 235 4 6 + 237 4 234 100 4 235 235 4 6 + 236 4 67 234 4 200 241 4 229 + 111 4 230 236 4 67 241 4 229 + 109 4 236 241 4 229 239 4 233 + 106 4 237 109 4 236 239 4 233 + 257 2 77 255 2 15 254 2 25 + 256 2 76 257 2 77 254 2 25 + 262 2 85 267 2 83 266 2 82 + 263 2 84 262 2 85 266 2 82 + 244 3 67 242 3 200 274 3 229 + 255 3 230 244 3 67 274 3 229 + 262 3 235 276 3 233 243 3 6 + 245 3 234 262 3 235 243 3 6 + 254 4 235 287 4 233 283 4 6 + 285 4 234 254 4 235 283 4 6 + 284 4 67 282 4 200 289 4 229 + 263 4 230 284 4 67 289 4 229 + 219 4 236 289 4 229 287 4 233 + 213 4 237 219 4 236 287 4 233 + 218 3 237 212 3 236 274 3 229 + 276 3 233 218 3 237 274 3 229 + 330 2 216 257 2 77 256 2 76 + 331 2 215 330 2 216 256 2 76 + 337 2 35 266 2 82 267 2 83 + 336 2 13 337 2 35 267 2 83 + </p> + </triangles> + </mesh> + </geometry> + </library_geometries> + <library_visual_scenes> + <visual_scene id="RootNode" name="RootNode"> + <node id="DemoRoomLrg_5c1b8cbb" name="DemoRoomLrg_5c1b8cbb"> + <instance_geometry url="#DemoRoomLrg_5c1b8cbb-lib"> + <bind_material> + <technique_common> + <instance_material symbol="BLACK" target="#BLACK" /> + <instance_material symbol="FULL128X128G" target="#FULL128X128G" /> + <instance_material symbol="PILLAR128X128G" target="#PILLAR128X128G" /> + <instance_material symbol="FULL64X64G" target="#FULL64X64G" /> + </technique_common> + </bind_material> + </instance_geometry> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#RootNode" /> + </scene> +</COLLADA> diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/Door.dae b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/Door.dae new file mode 100644 index 000000000..b930cea65 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/Door.dae @@ -0,0 +1,219 @@ +<?xml version="1.0" encoding="utf-8" ?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.0"> + <asset> + <contributor> + <author /> + <authoring_tool>Torque 3D 2009 Interior Exporter</authoring_tool> + <comments /> + </contributor> + <created>8/09/2009 2:52:45 PM</created> + <modified>8/09/2009 2:52:45 PM</modified> + <revision /> + <title /> + <subject /> + <keywords /> + <unit meter="1.000000" /> + <up_axis>Z_UP</up_axis> + </asset> + <library_images> + <image id="PILLAR128X128G-Diffuse" name="PILLAR128X128G-Diffuse"> + <init_from>file://PILLAR128X128G.png</init_from> + </image> + <image id="FULL128X128G-Diffuse" name="FULL128X128G-Diffuse"> + <init_from>file://FULL128X128G.png</init_from> + </image> + <image id="BLACK-Diffuse" name="BLACK-Diffuse"> + <init_from>file://BLACK.png</init_from> + </image> + </library_images> + <library_materials> + <material id="PILLAR128X128G" name="PILLAR128X128G"> + <instance_effect url="#PILLAR128X128G-fx" /> + </material> + <material id="FULL128X128G" name="FULL128X128G"> + <instance_effect url="#FULL128X128G-fx" /> + </material> + <material id="BLACK" name="BLACK"> + <instance_effect url="#BLACK-fx" /> + </material> + </library_materials> + <library_effects> + <effect id="PILLAR128X128G-fx" name="PILLAR128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="PILLAR128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="FULL128X128G-fx" name="FULL128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="FULL128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="BLACK-fx" name="BLACK-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="BLACK-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_geometries> + <geometry id="Door-lib" name="DoorMesh"> + <mesh> + <source id="Door-Position"> + <float_array id="Door-Position-array" count="24"> + 2.0000 -0.2500 -2.0000 + 2.0000 -0.2500 2.0000 + 2.0000 0.2500 -2.0000 + 2.0000 0.2500 2.0000 + -2.0000 -0.2500 -2.0000 + -2.0000 0.2500 -2.0000 + -2.0000 -0.2500 2.0000 + -2.0000 0.2500 2.0000 + </float_array> + <technique_common> + <accessor source="#Door-Position-array" count="8" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="Door-Normal"> + <float_array id="Door-Normal-array" count="18"> + 1.0000 -0.0000 -0.0000 + -1.0000 -0.0000 -0.0000 + -0.0000 1.0000 -0.0000 + -0.0000 -1.0000 -0.0000 + -0.0000 -0.0000 1.0000 + -0.0000 -0.0000 -1.0000 + </float_array> + <technique_common> + <accessor source="#Door-Normal-array" count="6" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="Door-UV0"> + <float_array id="Door-UV0-array" count="28"> + 5.7500 0.0000 + 5.7500 1.0000 + 6.0000 0.0000 + 6.0000 1.0000 + -5.7500 0.0000 + -6.0000 0.0000 + -5.7500 1.0000 + -6.0000 1.0000 + 1.0000 0.0000 + 0.0000 0.0000 + 1.0000 1.0000 + 0.0000 1.0000 + 8.0000 0.0000 + 8.0000 1.0000 + </float_array> + <technique_common> + <accessor source="#Door-UV0-array" count="14" stride="2"> + <param name="S" type="float" /> + <param name="T" type="float" /> + </accessor> + </technique_common> + </source> + <vertices id="Door-Vertex"> + <input semantic="POSITION" source="#Door-Position" /> + </vertices> + <triangles material="PILLAR128X128G" count="4"> + <input semantic="VERTEX" offset="0" source="#Door-Vertex" /> + <input semantic="NORMAL" offset="1" source="#Door-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#Door-UV0" /> + <p> + 3 0 3 1 0 1 0 0 0 + 2 0 2 3 0 3 0 0 0 + 7 1 7 5 1 5 4 1 4 + 6 1 6 7 1 7 4 1 4 + </p> + </triangles> + <triangles material="FULL128X128G" count="4"> + <input semantic="VERTEX" offset="0" source="#Door-Vertex" /> + <input semantic="NORMAL" offset="1" source="#Door-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#Door-UV0" /> + <p> + 3 2 11 2 2 9 5 2 8 + 7 2 10 3 2 11 5 2 8 + 1 3 10 6 3 11 4 3 9 + 0 3 8 1 3 10 4 3 9 + </p> + </triangles> + <triangles material="BLACK" count="4"> + <input semantic="VERTEX" offset="0" source="#Door-Vertex" /> + <input semantic="NORMAL" offset="1" source="#Door-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#Door-UV0" /> + <p> + 3 4 13 7 4 11 6 4 9 + 1 4 12 3 4 13 6 4 9 + 2 5 11 0 5 9 4 5 12 + 5 5 13 2 5 11 4 5 12 + </p> + </triangles> + </mesh> + </geometry> + </library_geometries> + <library_visual_scenes> + <visual_scene id="RootNode" name="RootNode"> + <node id="Door" name="Door"> + <instance_geometry url="#Door-lib"> + <bind_material> + <technique_common> + <instance_material symbol="PILLAR128X128G" target="#PILLAR128X128G" /> + <instance_material symbol="FULL128X128G" target="#FULL128X128G" /> + <instance_material symbol="BLACK" target="#BLACK" /> + </technique_common> + </bind_material> + </instance_geometry> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#RootNode" /> + </scene> +</COLLADA> diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/ElevatorPlatform.dae b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/ElevatorPlatform.dae new file mode 100644 index 000000000..2aaf2649f --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/ElevatorPlatform.dae @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="utf-8" ?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.0"> + <asset> + <contributor> + <author /> + <authoring_tool>Torque 3D 2009 Interior Exporter</authoring_tool> + <comments /> + </contributor> + <created>12/09/2009 9:50:04 AM</created> + <modified>12/09/2009 9:50:04 AM</modified> + <revision /> + <title /> + <subject /> + <keywords /> + <unit meter="1.000000" /> + <up_axis>Z_UP</up_axis> + </asset> + <library_images> + <image id="DemoRoomLrg_PILLAR128X128G-Diffuse" name="DemoRoomLrg_PILLAR128X128G-Diffuse"> + <init_from>file://PILLAR128X128G.png</init_from> + </image> + <image id="DemoRoomLrg_FULL128X128G-Diffuse" name="DemoRoomLrg_FULL128X128G-Diffuse"> + <init_from>file://FULL128X128G.png</init_from> + </image> + </library_images> + <library_materials> + <material id="DemoRoomLrg_PILLAR128X128G" name="DemoRoomLrg_PILLAR128X128G"> + <instance_effect url="#DemoRoomLrg_PILLAR128X128G-fx" /> + </material> + <material id="DemoRoomLrg_FULL128X128G" name="DemoRoomLrg_FULL128X128G"> + <instance_effect url="#DemoRoomLrg_FULL128X128G-fx" /> + </material> + </library_materials> + <library_effects> + <effect id="DemoRoomLrg_PILLAR128X128G-fx" name="DemoRoomLrg_PILLAR128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="DemoRoomLrg_PILLAR128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="DemoRoomLrg_FULL128X128G-fx" name="DemoRoomLrg_FULL128X128G-fx"> + <profile_COMMON> + <technique sid="standard"> + <phong> + <diffuse> + <texture texture="DemoRoomLrg_FULL128X128G-Diffuse" texcoord="CHANNEL0"> + <extra> + <technique profile="MAYA"> + <wrapU sid="wrapU0">TRUE</wrapU> + <wrapV sid="wrapV0">TRUE</wrapV> + <blend_mode>ADD</blend_mode> + </technique> + </extra> + </texture> + </diffuse> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_geometries> + <geometry id="ElevatorPlatform_5c1b8cbb-lib" name="ElevatorPlatform_5c1b8cbbMesh"> + <mesh> + <source id="ElevatorPlatform_5c1b8cbb-Position"> + <float_array id="ElevatorPlatform_5c1b8cbb-Position-array" count="24"> + 2.0000 -1.7500 -0.2500 + 2.0000 -1.7500 0.2500 + 2.0000 1.7500 -0.2500 + 2.0000 1.7500 0.2500 + -2.0000 -1.7500 -0.2500 + -2.0000 1.7500 -0.2500 + -2.0000 -1.7500 0.2500 + -2.0000 1.7500 0.2500 + </float_array> + <technique_common> + <accessor source="#ElevatorPlatform_5c1b8cbb-Position-array" count="8" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="ElevatorPlatform_5c1b8cbb-Normal"> + <float_array id="ElevatorPlatform_5c1b8cbb-Normal-array" count="18"> + 1.0000 -0.0000 -0.0000 + -1.0000 -0.0000 -0.0000 + -0.0000 1.0000 -0.0000 + -0.0000 -1.0000 -0.0000 + -0.0000 -0.0000 1.0000 + -0.0000 -0.0000 -1.0000 + </float_array> + <technique_common> + <accessor source="#ElevatorPlatform_5c1b8cbb-Normal-array" count="6" stride="3"> + <param name="X" type="float" /> + <param name="Y" type="float" /> + <param name="Z" type="float" /> + </accessor> + </technique_common> + </source> + <source id="ElevatorPlatform_5c1b8cbb-UV0"> + <float_array id="ElevatorPlatform_5c1b8cbb-UV0-array" count="16"> + 3.2500 -1.0000 + 3.0000 -1.0000 + 3.2500 0.0000 + 3.0000 0.0000 + 0.0000 -1.0000 + 0.0000 0.0000 + 1.0000 -1.0000 + 1.0000 0.0000 + </float_array> + <technique_common> + <accessor source="#ElevatorPlatform_5c1b8cbb-UV0-array" count="8" stride="2"> + <param name="S" type="float" /> + <param name="T" type="float" /> + </accessor> + </technique_common> + </source> + <vertices id="ElevatorPlatform_5c1b8cbb-Vertex"> + <input semantic="POSITION" source="#ElevatorPlatform_5c1b8cbb-Position" /> + </vertices> + <triangles material="DemoRoomLrg_PILLAR128X128G" count="8"> + <input semantic="VERTEX" offset="0" source="#ElevatorPlatform_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#ElevatorPlatform_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#ElevatorPlatform_5c1b8cbb-UV0" /> + <p> + 3 0 3 1 0 1 0 0 0 + 2 0 2 3 0 3 0 0 0 + 7 1 1 5 1 0 4 1 2 + 6 1 3 7 1 1 4 1 2 + 3 2 1 2 2 0 5 2 2 + 7 2 3 3 2 1 5 2 2 + 1 3 3 6 3 1 4 3 0 + 0 3 2 1 3 3 4 3 0 + </p> + </triangles> + <triangles material="DemoRoomLrg_FULL128X128G" count="4"> + <input semantic="VERTEX" offset="0" source="#ElevatorPlatform_5c1b8cbb-Vertex" /> + <input semantic="NORMAL" offset="1" source="#ElevatorPlatform_5c1b8cbb-Normal" /> + <input semantic="TEXCOORD" offset="2" set="0" source="#ElevatorPlatform_5c1b8cbb-UV0" /> + <p> + 3 4 7 7 4 5 6 4 4 + 1 4 6 3 4 7 6 4 4 + 2 5 5 0 5 4 4 5 6 + 5 5 7 2 5 5 4 5 6 + </p> + </triangles> + </mesh> + </geometry> + </library_geometries> + <library_visual_scenes> + <visual_scene id="RootNode" name="RootNode"> + <node id="ElevatorPlatform_5c1b8cbb" name="ElevatorPlatform_5c1b8cbb"> + <instance_geometry url="#ElevatorPlatform_5c1b8cbb-lib"> + <bind_material> + <technique_common> + <instance_material symbol="DemoRoomLrg_PILLAR128X128G" target="#DemoRoomLrg_PILLAR128X128G" /> + <instance_material symbol="DemoRoomLrg_FULL128X128G" target="#DemoRoomLrg_FULL128X128G" /> + </technique_common> + </bind_material> + </instance_geometry> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#RootNode" /> + </scene> +</COLLADA> diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL128X128G.png b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL128X128G.png new file mode 100644 index 000000000..58008eae0 Binary files /dev/null and b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL128X128G.png differ diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL64X64G.png b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL64X64G.png new file mode 100644 index 000000000..ac26d2b72 Binary files /dev/null and b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/FULL64X64G.png differ diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/PILLAR128X128G.png b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/PILLAR128X128G.png new file mode 100644 index 000000000..9e570122d Binary files /dev/null and b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/PILLAR128X128G.png differ diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/materials.cs b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/materials.cs new file mode 100644 index 000000000..c316237c6 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/art/shapes/VervePathTutorial/materials.cs @@ -0,0 +1,179 @@ +//--- Door.dae MATERIALS BEGIN --- +singleton Material(Door_PILLAR128X128G) +{ + mapTo = "PILLAR128X128G"; + + diffuseMap[0] = "PILLAR128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(Door_FULL128X128G) +{ + mapTo = "FULL128X128G"; + + diffuseMap[0] = "FULL128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(Door_BLACK) +{ + mapTo = "BLACK"; + + diffuseMap[0] = "BLACK"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +//--- Door.dae MATERIALS END --- + +//--- DemoRoomLrg.dae MATERIALS BEGIN --- +singleton Material(DemoRoomLrg_BLACK) +{ + mapTo = "BLACK"; + + diffuseMap[0] = "BLACK"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(DemoRoomLrg_FULL128X128G) +{ + mapTo = "FULL128X128G"; + + diffuseMap[0] = "FULL128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(DemoRoomLrg_PILLAR128X128G) +{ + mapTo = "PILLAR128X128G"; + + diffuseMap[0] = "PILLAR128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(DemoRoomLrg_FULL64X64G) +{ + mapTo = "FULL64X64G"; + + diffuseMap[0] = "FULL64X64G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +//--- DemoRoomLrg.dae MATERIALS END --- +//--- ElevatorPlatform.dae MATERIALS BEGIN --- +singleton Material(ElevatorPlatform_DemoRoomLrg_PILLAR128X128G) +{ + mapTo = "DemoRoomLrg_PILLAR128X128G"; + + diffuseMap[0] = "PILLAR128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +singleton Material(ElevatorPlatform_DemoRoomLrg_FULL128X128G) +{ + mapTo = "DemoRoomLrg_FULL128X128G"; + + diffuseMap[0] = "FULL128X128G"; + normalMap[0] = ""; + specularMap[0] = ""; + + diffuseColor[0] = "1 1 1 1"; + specular[0] = "1 1 1 1"; + specularPower[0] = 8; + pixelSpecular[0] = false; + emissive[0] = false; + + doubleSided = false; + translucent = false; + translucentBlendOp = "None"; +}; + +//--- ElevatorPlatform.dae MATERIALS END --- + diff --git a/Templates/BaseGame/game/data/Verve/art/shapes/actors/Soldier/soldier_rigged.dts b/Templates/BaseGame/game/data/Verve/art/shapes/actors/Soldier/soldier_rigged.dts new file mode 100644 index 000000000..8ca481f90 Binary files /dev/null and b/Templates/BaseGame/game/data/Verve/art/shapes/actors/Soldier/soldier_rigged.dts differ diff --git a/Templates/BaseGame/game/data/Verve/gui/VerveCinematic.gui b/Templates/BaseGame/game/data/Verve/gui/VerveCinematic.gui new file mode 100644 index 000000000..f71a3171c --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/gui/VerveCinematic.gui @@ -0,0 +1,43 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GameTSCtrl(VerveCinematicGui) { + canSaveDynamicFields = "1"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + helpTag = "0"; + noCursor = "1"; + + new VFadeControl( VFadeControlGui ) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/datablocks/datablockExec.cs b/Templates/BaseGame/game/data/Verve/scripts/datablocks/datablockExec.cs new file mode 100644 index 000000000..d85bb690d --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/datablocks/datablockExec.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// 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. +//----------------------------------------------------------------------------- + +// Load up all datablocks. This function is called when +// a server is constructed. + +// Do the sounds first -- later scripts/datablocks may need them +exec("./audioProfiles.cs"); + +// LightFlareData and LightAnimData(s) +exec("./lights.cs"); + +// Do the various effects next -- later scripts/datablocks may need them +exec("./particles.cs"); +exec("./environment.cs"); + +exec("./triggers.cs"); + +// Add a rigid example +exec("./rigidShape.cs"); + +exec("./health.cs"); + +// Load our supporting weapon datablocks, effects and such. They must be +// loaded before any weapon that uses them. +exec("./weapon.cs"); +exec("./weapons/grenadefx.cs"); +exec("./weapons/rocketfx.cs"); + +// Load the weapon datablocks +exec("./weapons/Lurker.cs"); +exec("./weapons/Ryder.cs"); +exec("./weapons/ProxMine.cs"); +exec("./weapons/Turret.cs"); + +exec("./teleporter.cs"); + +// Load the default player datablocks +exec("./player.cs"); + +// Load our other player datablocks +exec("./aiPlayer.cs"); + +// Load the vehicle datablocks +exec("./vehicles/cheetahCar.cs"); + +// Load Verve Data. +exec("./verve/VerveActorData.cs"); +exec("./verve/VervePathTutorialData.cs"); \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VerveActorData.cs b/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VerveActorData.cs new file mode 100644 index 000000000..e8bb3324b --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VerveActorData.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- + +function VHumanoidActorData::create( %dataBlock ) +{ + %actorObject = new VHumanoidActor() + { + dataBlock = %dataBlock; + }; + + return %actorObject; +} + +//----------------------------------------------------------------------------- + +datablock VHumanoidActorData( VSoldierActorData ) +{ + Category = "VActor"; + ShapeFile = "data/Verve/art/shapes/actors/Soldier/soldier_rigged.DAE"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VervePathTutorialData.cs b/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VervePathTutorialData.cs new file mode 100644 index 000000000..cd6c7ba23 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/datablocks/verve/VervePathTutorialData.cs @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- + +datablock StaticShapeData( VervePathTutorial_DoorData ) +{ + Category = "VerveTutorialData"; + shapeFile = "data/Verve/art/shapes/VervePathTutorial/Door.dae"; +}; + +datablock StaticShapeData( VervePathTutorial_ElevatorPlatformData ) +{ + Category = "VerveTutorialData"; + shapeFile = "data/Verve/art/shapes/VervePathTutorial/ElevatorPlatform.dae"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicController.cs b/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicController.cs new file mode 100644 index 000000000..0c5dae601 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicController.cs @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- + +$Verve::CinematicController = 0; + +//----------------------------------------------------------------------------- + +function Verve::GetCinematicController() +{ + // Valid Controller? + if ( !isObject( $Verve::CinematicController ) ) + { + $Verve::CinematicController = new VController() + { + Class = "VerveCinematicController"; + }; + } + + // Return Controller. + return $Verve::CinematicController; +} + +//----------------------------------------------------------------------------- + +// Verve::PlayCinematic( "sequences/BurgFlythrough.vsf" ); +function Verve::PlayCinematic( %sequenceFile ) +{ + if ( !isFile( %sequenceFile ) ) + { + error ( "Verve::PlayCinematic() - Invalid Sequence File." ); + return 0; + } + + // Fetch Controller. + %controller = Verve::GetCinematicController(); + + // Already Playing? + if ( %controller.isPlaying() ) + { + error ( "Verve::PlayCinematic() - Cinematic in Progress." ); + return 0; + } + + // Load the Sequence. + if ( !%controller.readFile( %sequenceFile ) ) + { + return 0; + } + + // Stop Input. + if ( isObject( moveMap ) ) + { + moveMap.pop(); + } + + // Store the Current Gui. + $Verve::StoredGui = Canvas.getContent(); + + // Valid GUI? + if ( !isObject( VerveCinematicGui ) ) + { + // Execute GUI Script. + exec( "art/gui/VerveCinematic.gui" ); + } + + // Set the Cinematic Gui. + Canvas.setContent( VerveCinematicGui ); + + // Clear First Person. + %clientCount = ClientGroup.getCount(); + for ( %i = 0; %i < %clientCount; %i++ ) + { + // Fetch Client. + %clientConnection = ClientGroup.getObject( %i ); + // Store Status. + %clientConnection.FirstPerson = %clientConnection.isFirstPerson(); + // Clear. + %clientConnection.setFirstPerson( false ); + } + + // Play the Sequence. + %controller.play(); + + // Return the Controller. + return %controller; +} + +//----------------------------------------------------------------------------- + +function VerveCinematicController::onStop( %this ) +{ + // Reset First Person Status. + %clientCount = ClientGroup.getCount(); + for ( %i = 0; %i < %clientCount; %i++ ) + { + // Fetch Client. + %clientConnection = ClientGroup.getObject( %i ); + // Reset. + %clientConnection.setFirstPerson( %clientConnection.FirstPerson ); + } + + // Reset the Canvas. + Canvas.setContent( $Verve::StoredGui ); + + // Resume Input. + if ( isObject( moveMap ) ) + { + moveMap.push(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicTrigger.cs b/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicTrigger.cs new file mode 100644 index 000000000..4cd6df9f1 --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/server/VerveCinematicTrigger.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- + +datablock TriggerData( VerveCinematicTrigger ) +{ + Field = "Value"; +}; + +//----------------------------------------------------------------------------- + +function VerveCinematicTrigger::onEnterTrigger( %this, %trigger, %object ) +{ + // Play Sequence. + Verve::PlayCinematic( %trigger.SequenceFile ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/scripts/server/VervePathTutorialData.cs b/Templates/BaseGame/game/data/Verve/scripts/server/VervePathTutorialData.cs new file mode 100644 index 000000000..264fec96f --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/scripts/server/VervePathTutorialData.cs @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// 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. +//----------------------------------------------------------------------------- + +datablock StaticShapeData( VervePathTutorial_DoorData ) +{ + Category = "VerveTutorialData"; + shapeFile = "art/shapes/VervePathTutorial/Door.dae"; +}; + +datablock StaticShapeData( VervePathTutorial_ElevatorPlatformData ) +{ + Category = "VerveTutorialData"; + shapeFile = "art/shapes/VervePathTutorial/ElevatorPlatform.dae"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup0_Open+Close.vsf b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup0_Open+Close.vsf new file mode 100644 index 000000000..d3305688d --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup0_Open+Close.vsf @@ -0,0 +1,85 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <Properties> + <Time>0</Time> + <Duration>1000</Duration> + <TimeScale>1</TimeScale> + <Loop>1</Loop> + <LoopBackwards>1</LoopBackwards> + <LoopCount>0</LoopCount> + <LoopDelay>500</LoopDelay> + <ResetOnCompletion>1</ResetOnCompletion> + </Properties> + <DataTable> + <DataItem Type="STATIC" Name="DoorGroup0_LeftPath" Value="DoorPath_Left" /> + <DataItem Type="STATIC" Name="DoorGroup0_Left" Value="DoorShape0_Left" /> + <DataItem Type="STATIC" Name="DoorGroup0_RightPath" Value="DoorPath_Right" /> + <DataItem Type="STATIC" Name="DoorGroup0_Right" Value="DoorShape0_Right" /> + </DataTable> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Enabled>1</Enabled> + <Label>DoorGroup0_Left</Label> + <Reference>DoorGroup0_Left</Reference> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionTrack</Label> + <Reference>DoorGroup0_LeftPath</Reference> + <OrientationMode>FREE</OrientationMode> + <OrientationData></OrientationData> + <Relative>0</Relative> + </Properties> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>0</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>1000</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + </VObject> + </VObject> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Enabled>1</Enabled> + <Label>DoorGroup0_Right</Label> + <Reference>DoorGroup0_Right</Reference> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionTrack</Label> + <Reference>DoorGroup0_RightPath</Reference> + <OrientationMode>FREE</OrientationMode> + <OrientationData></OrientationData> + <Relative>0</Relative> + </Properties> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>0</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>1000</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + </VObject> + </VObject> +</VerveControllerSequence> diff --git a/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup1_Open+Close.vsf b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup1_Open+Close.vsf new file mode 100644 index 000000000..a1e0e4d6c --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/DoorGroup1_Open+Close.vsf @@ -0,0 +1,87 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <Properties> + <Time>0</Time> + <Duration>1000</Duration> + <TimeScale>1</TimeScale> + <Loop>1</Loop> + <LoopBackwards>1</LoopBackwards> + <LoopDelay>500</LoopDelay> + <ResetOnCompletion>1</ResetOnCompletion> + <name>VerveEditorController</name> + <parentGroup>RootGroup</parentGroup> + <canSaveDynamicFields>1</canSaveDynamicFields> + </Properties> + <DataTable> + <DataItem Type="STATIC" Name="DoorGroup1_Right" Value="DoorShape1_Right" /> + <DataItem Type="STATIC" Name="DoorGroup1_Left" Value="DoorShape1_Left" /> + <DataItem Type="STATIC" Name="DoorGroup1_RightPath" Value="DoorPath_Right" /> + <DataItem Type="STATIC" Name="DoorGroup1_LeftPath" Value="DoorPath_Left" /> + </DataTable> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Enabled>1</Enabled> + <Label>DoorGroup1_Left</Label> + <Reference>DoorGroup1_Left</Reference> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionTrack</Label> + <Reference>DoorGroup1_LeftPath</Reference> + <OrientationMode>FREE</OrientationMode> + <OrientationData></OrientationData> + <Relative>1</Relative> + </Properties> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>0</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>1000</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + </VObject> + </VObject> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Enabled>1</Enabled> + <Label>DoorGroup1_Right</Label> + <Reference>DoorGroup1_Right</Reference> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionTrack</Label> + <Reference>DoorGroup1_RightPath</Reference> + <OrientationMode>FREE</OrientationMode> + <OrientationData></OrientationData> + <Relative>1</Relative> + </Properties> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>0</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>1000</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + </VObject> + </VObject> +</VerveControllerSequence> diff --git a/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/ElevatorPlatform_Up+Down.vsf b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/ElevatorPlatform_Up+Down.vsf new file mode 100644 index 000000000..33a0e9dfc --- /dev/null +++ b/Templates/BaseGame/game/data/Verve/sequences/VervePathTutorial/ElevatorPlatform_Up+Down.vsf @@ -0,0 +1,53 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <Properties> + <Time>0</Time> + <Duration>5000</Duration> + <TimeScale>1</TimeScale> + <Loop>0</Loop> + <LoopBackwards>0</LoopBackwards> + <LoopCount>-1</LoopCount> + <LoopDelay>0</LoopDelay> + <ResetOnCompletion>0</ResetOnCompletion> + <name>VerveEditorController</name> + <parentGroup>RootGroup</parentGroup> + <canSaveDynamicFields>1</canSaveDynamicFields> + </Properties> + <DataTable> + <DataItem Type="STATIC" Name="ElevatorPlatformGroup" Value="ElevatorPlatformShape" /> + <DataItem Type="STATIC" Name="ElevatorPlatformGroupPath" Value="ElevatorPlatformPath" /> + </DataTable> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Enabled>1</Enabled> + <Label>ElevatorPlatformGroup</Label> + <Reference>ElevatorPlatformGroup</Reference> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionTrack</Label> + <Reference>ElevatorPlatformGroupPath</Reference> + <OrientationMode>FREE</OrientationMode> + <OrientationData></OrientationData> + <Relative>0</Relative> + </Properties> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>0</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + <VObject Type="VMotionEvent"> + <Properties> + <Enabled>1</Enabled> + <Label>MotionEvent</Label> + <TriggerTime>5000</TriggerTime> + <Duration>0</Duration> + </Properties> + </VObject> + </VObject> + </VObject> +</VerveControllerSequence> diff --git a/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_P.hlsl b/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_P.hlsl new file mode 100644 index 000000000..4780388ec --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_P.hlsl @@ -0,0 +1,94 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Base Texture +// Diffuse Color +// Deferred Shading: Empty Specular +// Deferred Shading: Mat Info Flags +// Eye Space Depth (Out) +// Visibility +// GBuffer Conditioner +// Deferred Material + +struct ConnectData +{ + float4 vpos : SV_Position; + float2 texCoord : TEXCOORD0; + float4 wsEyeVec : TEXCOORD1; + float3 gbNormal : TEXCOORD2; +}; + + +struct Fragout +{ + float4 col : SV_Target0; + float4 col1 : SV_Target1; + float4 col2 : SV_Target2; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform SamplerState diffuseMap : register(S0), + uniform Texture2D diffuseMapTex : register(T0), + uniform float4 diffuseMaterialColor : register(C0), + uniform float matInfoFlags : register(C1), + uniform float3 vEye : register(C3), + uniform float4 oneOverFarplane : register(C4), + uniform float visibility : register(C2) +) +{ + Fragout OUT; + + // Vert Position + + // Base Texture +float4 diffuseColor = diffuseMapTex.Sample(diffuseMap, IN.texCoord); + OUT.col1 = diffuseColor; + + // Diffuse Color + OUT.col1 *= diffuseMaterialColor; + + // Deferred Shading: Empty Specular + OUT.col2.g = 1.0; + OUT.col2.ba = 0.0; + + // Deferred Shading: Mat Info Flags + OUT.col2.r = matInfoFlags; + + // Eye Space Depth (Out) +#ifndef CUBE_SHADOW_MAP + float eyeSpaceDepth = dot(vEye, (IN.wsEyeVec.xyz / IN.wsEyeVec.w)); +#else + float eyeSpaceDepth = length( IN.wsEyeVec.xyz / IN.wsEyeVec.w ) * oneOverFarplane.x; +#endif + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // GBuffer Conditioner + float4 normal_depth = float4(normalize(IN.gbNormal), eyeSpaceDepth); + + // output buffer format: GFXFormatR16G16B16A16F + // g-buffer conditioner: float4(normal.X, normal.Y, depth Hi, depth Lo) + float4 _gbConditionedOutput = float4(sqrt(half(2.0/(1.0 - normal_depth.y))) * half2(normal_depth.xz), 0.0, normal_depth.a); + + // Encode depth into hi/lo + float2 _tempDepth = frac(normal_depth.a * float2(1.0, 65535.0)); + _gbConditionedOutput.zw = _tempDepth.xy - _tempDepth.yy * float2(1.0/65535.0, 0.0); + + OUT.col = _gbConditionedOutput; + + // Deferred Material + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_V.hlsl b/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_V.hlsl new file mode 100644 index 000000000..a323a9608 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/76d48535f69be600_V.hlsl @@ -0,0 +1,74 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Base Texture +// Diffuse Color +// Deferred Shading: Empty Specular +// Deferred Shading: Mat Info Flags +// Eye Space Depth (Out) +// Visibility +// GBuffer Conditioner +// Deferred Material + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float2 out_texCoord : TEXCOORD0; + float4 wsEyeVec : TEXCOORD1; + float3 gbNormal : TEXCOORD2; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4), + uniform float3 eyePosWorld : register(C12), + uniform float4x4 worldViewOnly : register(C8) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Base Texture + OUT.out_texCoord = (float2)IN.texCoord; + + // Diffuse Color + + // Deferred Shading: Empty Specular + + // Deferred Shading: Mat Info Flags + + // Eye Space Depth (Out) + float3 depthPos = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; + OUT.wsEyeVec = float4( depthPos.xyz - eyePosWorld, 1 ); + + // Visibility + + // GBuffer Conditioner + OUT.gbNormal = mul(worldViewOnly, float4( normalize(IN.normal), 0.0 ) ).xyz; + + // Deferred Material + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_P.hlsl b/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_P.hlsl new file mode 100644 index 000000000..2c0e0ccda --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_P.hlsl @@ -0,0 +1,52 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Eye Space Depth (Out) +// Visibility + +struct ConnectData +{ + float4 vpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float3 vEye : register(C1), + uniform float4 oneOverFarplane : register(C2), + uniform float visibility : register(C0) +) +{ + Fragout OUT; + + // Vert Position + + // Eye Space Depth (Out) +#ifndef CUBE_SHADOW_MAP + float eyeSpaceDepth = dot(vEye, (IN.wsEyeVec.xyz / IN.wsEyeVec.w)); +#else + float eyeSpaceDepth = length( IN.wsEyeVec.xyz / IN.wsEyeVec.w ) * oneOverFarplane.x; +#endif + OUT.col = float4(eyeSpaceDepth.rrr,1); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_V.hlsl b/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_V.hlsl new file mode 100644 index 000000000..f7db2ba1f --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/7a74ac0558b62462_V.hlsl @@ -0,0 +1,51 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Eye Space Depth (Out) +// Visibility + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4), + uniform float3 eyePosWorld : register(C8) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Eye Space Depth (Out) + float3 depthPos = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; + OUT.wsEyeVec = float4( depthPos.xyz - eyePosWorld, 1 ); + + // Visibility + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl new file mode 100644 index 000000000..560f6c23d --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl @@ -0,0 +1,77 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Deferred RT Lighting +// Visibility +// HDR Output + +struct ConnectData +{ + float4 vpos : SV_Position; + float4 screenspacePos : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float4 diffuseMaterialColor : register(C0), + uniform float4 rtParamslightInfoBuffer : register(C2), + uniform SamplerState lightInfoBuffer : register(S0), + uniform Texture2D lightInfoBufferTex : register(T0), + uniform float visibility : register(C1) +) +{ + Fragout OUT; + + // Vert Position + + // Diffuse Color + OUT.col = diffuseMaterialColor; + + // Deferred RT Lighting + float2 uvScene = IN.screenspacePos.xy / IN.screenspacePos.w; + uvScene = ( uvScene + 1.0 ) / 2.0; + uvScene.y = 1.0 - uvScene.y; + uvScene = ( uvScene * rtParamslightInfoBuffer.zw ) + rtParamslightInfoBuffer.xy; + float3 d_lightcolor; + float d_NL_Att; + float d_specular; + lightinfoUncondition(lightInfoBufferTex.Sample(lightInfoBuffer, uvScene), d_lightcolor, d_NL_Att, d_specular); + OUT.col *= float4(d_lightcolor, 1.0); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // HDR Output + OUT.col = hdrEncode( OUT.col ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl new file mode 100644 index 000000000..be8a848ef --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl @@ -0,0 +1,67 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Deferred RT Lighting +// Visibility +// HDR Output + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; + float2 texCoord2 : TEXCOORD1; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float4 screenspacePos : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Diffuse Color + + // Deferred RT Lighting + OUT.screenspacePos = OUT.hpos; + + // Visibility + + // HDR Output + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_P.hlsl b/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_P.hlsl new file mode 100644 index 000000000..2b0cb5f0e --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_P.hlsl @@ -0,0 +1,54 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// skybox +// Diffuse Color +// Reflect Cube +// HDR Output + +struct ConnectData +{ + float4 vpos : SV_Position; + float3 reflectVec : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float4 diffuseMaterialColor : register(C0), + uniform SamplerState cubeMap : register(S0), + uniform TextureCube cubeMapTex : register(T0) +) +{ + Fragout OUT; + + // Vert Position + + // skybox + + // Diffuse Color + OUT.col = diffuseMaterialColor; + + // Reflect Cube + OUT.col *= cubeMapTex.Sample( cubeMap, IN.reflectVec ); + + // HDR Output + OUT.col = hdrEncode( OUT.col ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_V.hlsl b/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_V.hlsl new file mode 100644 index 000000000..f4e6f087d --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/a1a7a101cca9ce72_V.hlsl @@ -0,0 +1,58 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// skybox +// Diffuse Color +// Reflect Cube +// HDR Output + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float3 reflectVec : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4), + uniform float3 eyePosWorld : register(C8) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // skybox + + // Diffuse Color + + // Reflect Cube + float3 cubeVertPos = mul(objTrans, float4(IN.position,1)).xyz; + float3 cubeNormal = ( mul( (objTrans), float4(IN.normal, 0) ) ).xyz; + cubeNormal = bool(length(cubeNormal)) ? normalize(cubeNormal) : cubeNormal; + float3 eyeToVert = cubeVertPos - eyePosWorld; + OUT.reflectVec = reflect(eyeToVert, cubeNormal); + + // HDR Output + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h b/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h new file mode 100644 index 000000000..065cea6dc --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Condition Method +//------------------------------------------------------------------------------ +inline float4 autogenCondition_bde4cbab(in float3 lightColor, in float NL_att, in float specular, in float4 bufferSample) +{ + float4 rgbLightInfoOut = float4(lightColor, 0) * NL_att + float4(bufferSample.rgb, specular); + + return rgbLightInfoOut; +} + + +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +//------------------------------------------------------------------------------ +// Autogenerated 'GBuffer Conditioner' Condition Method +//------------------------------------------------------------------------------ +inline float4 autogenCondition_55070f7a(in float4 unconditionedOutput) +{ + // g-buffer conditioner: float4(normal.X, normal.Y, depth Hi, depth Lo) + float4 _gbConditionedOutput = float4(sqrt(half(2.0/(1.0 - unconditionedOutput.y))) * half2(unconditionedOutput.xz), 0.0, unconditionedOutput.a); + + // Encode depth into hi/lo + float2 _tempDepth = frac(unconditionedOutput.a * float2(1.0, 65535.0)); + _gbConditionedOutput.zw = _tempDepth.xy - _tempDepth.yy * float2(1.0/65535.0, 0.0); + + + return _gbConditionedOutput; +} + + +//------------------------------------------------------------------------------ +// Autogenerated 'GBuffer Conditioner' Uncondition Method +//------------------------------------------------------------------------------ +inline float4 autogenUncondition_55070f7a(SamplerState deferredSamplerVar, Texture2D deferredTexVar, float2 screenUVVar) +{ + // Sampler g-buffer + float4 bufferSample = deferredTexVar.SampleLevel(deferredSamplerVar, screenUVVar,0); + // g-buffer unconditioner: float4(normal.X, normal.Y, depth Hi, depth Lo) + float2 _inpXY = bufferSample.xy; + float _xySQ = dot(_inpXY, _inpXY); + float4 _gbUnconditionedInput = float4( sqrt(half(1.0 - (_xySQ / 4.0))) * _inpXY, -1.0 + (_xySQ / 2.0), bufferSample.a).xzyw; + + // Decode depth + _gbUnconditionedInput.w = dot( bufferSample.zw, float2(1.0, 1.0/65535.0)); + + return _gbUnconditionedInput; +} + + diff --git a/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_P.hlsl b/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_P.hlsl new file mode 100644 index 000000000..e935e60ba --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_P.hlsl @@ -0,0 +1,80 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Base Texture +// Deferred RT Lighting +// Visibility +// HDR Output + +struct ConnectData +{ + float4 vpos : SV_Position; + float2 texCoord : TEXCOORD0; + float4 screenspacePos : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform SamplerState diffuseMap : register(S0), + uniform Texture2D diffuseMapTex : register(T0), + uniform float4 rtParamslightInfoBuffer : register(C1), + uniform SamplerState lightInfoBuffer : register(S1), + uniform Texture2D lightInfoBufferTex : register(T1), + uniform float visibility : register(C0) +) +{ + Fragout OUT; + + // Vert Position + + // Base Texture +float4 diffuseColor = diffuseMapTex.Sample(diffuseMap, IN.texCoord); + OUT.col = diffuseColor; + + // Deferred RT Lighting + float2 uvScene = IN.screenspacePos.xy / IN.screenspacePos.w; + uvScene = ( uvScene + 1.0 ) / 2.0; + uvScene.y = 1.0 - uvScene.y; + uvScene = ( uvScene * rtParamslightInfoBuffer.zw ) + rtParamslightInfoBuffer.xy; + float3 d_lightcolor; + float d_NL_Att; + float d_specular; + lightinfoUncondition(lightInfoBufferTex.Sample(lightInfoBuffer, uvScene), d_lightcolor, d_NL_Att, d_specular); + OUT.col *= float4(d_lightcolor, 1.0); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // HDR Output + OUT.col = hdrEncode( OUT.col ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_V.hlsl b/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_V.hlsl new file mode 100644 index 000000000..3d55cf201 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/b524839793fade4e_V.hlsl @@ -0,0 +1,57 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Base Texture +// Deferred RT Lighting +// Visibility +// HDR Output + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float2 out_texCoord : TEXCOORD0; + float4 screenspacePos : TEXCOORD1; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Base Texture + OUT.out_texCoord = (float2)IN.texCoord; + + // Deferred RT Lighting + OUT.screenspacePos = OUT.hpos; + + // Visibility + + // HDR Output + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_P.hlsl b/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_P.hlsl new file mode 100644 index 000000000..e85bd696f --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_P.hlsl @@ -0,0 +1,87 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Deferred Shading: Empty Specular +// Deferred Shading: Mat Info Flags +// Eye Space Depth (Out) +// Visibility +// GBuffer Conditioner +// Deferred Material + +struct ConnectData +{ + float4 vpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; + float3 gbNormal : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : SV_Target0; + float4 col1 : SV_Target1; + float4 col2 : SV_Target2; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float4 diffuseMaterialColor : register(C0), + uniform float matInfoFlags : register(C1), + uniform float3 vEye : register(C3), + uniform float4 oneOverFarplane : register(C4), + uniform float visibility : register(C2) +) +{ + Fragout OUT; + + // Vert Position + + // Diffuse Color + OUT.col1 = float4(1.0,1.0,1.0,1.0); + OUT.col1 = diffuseMaterialColor; + + // Deferred Shading: Empty Specular + OUT.col2.g = 1.0; + OUT.col2.ba = 0.0; + + // Deferred Shading: Mat Info Flags + OUT.col2.r = matInfoFlags; + + // Eye Space Depth (Out) +#ifndef CUBE_SHADOW_MAP + float eyeSpaceDepth = dot(vEye, (IN.wsEyeVec.xyz / IN.wsEyeVec.w)); +#else + float eyeSpaceDepth = length( IN.wsEyeVec.xyz / IN.wsEyeVec.w ) * oneOverFarplane.x; +#endif + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // GBuffer Conditioner + float4 normal_depth = float4(normalize(IN.gbNormal), eyeSpaceDepth); + + // output buffer format: GFXFormatR16G16B16A16F + // g-buffer conditioner: float4(normal.X, normal.Y, depth Hi, depth Lo) + float4 _gbConditionedOutput = float4(sqrt(half(2.0/(1.0 - normal_depth.y))) * half2(normal_depth.xz), 0.0, normal_depth.a); + + // Encode depth into hi/lo + float2 _tempDepth = frac(normal_depth.a * float2(1.0, 65535.0)); + _gbConditionedOutput.zw = _tempDepth.xy - _tempDepth.yy * float2(1.0/65535.0, 0.0); + + OUT.col = _gbConditionedOutput; + + // Deferred Material + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_V.hlsl b/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_V.hlsl new file mode 100644 index 000000000..e27e33019 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/c5e4ec9bb49846a9_V.hlsl @@ -0,0 +1,70 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Deferred Shading: Empty Specular +// Deferred Shading: Mat Info Flags +// Eye Space Depth (Out) +// Visibility +// GBuffer Conditioner +// Deferred Material + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; + float2 texCoord2 : TEXCOORD1; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; + float3 gbNormal : TEXCOORD1; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4), + uniform float3 eyePosWorld : register(C12), + uniform float4x4 worldViewOnly : register(C8) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Diffuse Color + + // Deferred Shading: Empty Specular + + // Deferred Shading: Mat Info Flags + + // Eye Space Depth (Out) + float3 depthPos = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; + OUT.wsEyeVec = float4( depthPos.xyz - eyePosWorld, 1 ); + + // Visibility + + // GBuffer Conditioner + OUT.gbNormal = mul(worldViewOnly, float4( normalize(IN.normal), 0.0 ) ).xyz; + + // Deferred Material + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/c74b275969540357_P.hlsl b/Templates/BaseGame/game/data/shaderCache/c74b275969540357_P.hlsl new file mode 100644 index 000000000..3933a59ca --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/c74b275969540357_P.hlsl @@ -0,0 +1,47 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Paraboloid Vert Transform +// Visibility +// Depth (Out) + +struct ConnectData +{ + float4 vpos : SV_Position; + float2 posXY : TEXCOORD0; + float depth : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float visibility : register(C0) +) +{ + Fragout OUT; + + // Paraboloid Vert Transform + clip( 1.0 - abs(IN.posXY.x) ); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // Depth (Out) + OUT.col = float4( IN.depth, 0, 0, 1 ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/c74b275969540357_V.hlsl b/Templates/BaseGame/game/data/shaderCache/c74b275969540357_V.hlsl new file mode 100644 index 000000000..be4cd1c15 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/c74b275969540357_V.hlsl @@ -0,0 +1,61 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Paraboloid Vert Transform +// Visibility +// Depth (Out) + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float2 posXY : TEXCOORD0; + float depth : TEXCOORD1; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float2 atlasScale : register(C4), + uniform float4x4 worldViewOnly : register(C0), + uniform float4 lightParams : register(C5), + uniform float2 atlasXOffset : register(C6) +) +{ + ConnectData OUT; + + // Paraboloid Vert Transform + OUT.hpos = mul(worldViewOnly, float4(IN.position.xyz,1)).xzyw; + float L = length(OUT.hpos.xyz); + OUT.hpos /= L; + OUT.hpos.z = OUT.hpos.z + 1.0; + OUT.hpos.xy /= OUT.hpos.z; + OUT.hpos.z = L / lightParams.x; + OUT.hpos.w = 1.0; + OUT.posXY = OUT.hpos.xy; + OUT.hpos.xy *= atlasScale.xy; + OUT.hpos.xy += atlasXOffset; + + // Visibility + + // Depth (Out) + OUT.depth = OUT.hpos.z / OUT.hpos.w; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_P.hlsl b/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_P.hlsl new file mode 100644 index 000000000..2c0e0ccda --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_P.hlsl @@ -0,0 +1,52 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Eye Space Depth (Out) +// Visibility + +struct ConnectData +{ + float4 vpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float3 vEye : register(C1), + uniform float4 oneOverFarplane : register(C2), + uniform float visibility : register(C0) +) +{ + Fragout OUT; + + // Vert Position + + // Eye Space Depth (Out) +#ifndef CUBE_SHADOW_MAP + float eyeSpaceDepth = dot(vEye, (IN.wsEyeVec.xyz / IN.wsEyeVec.w)); +#else + float eyeSpaceDepth = length( IN.wsEyeVec.xyz / IN.wsEyeVec.w ) * oneOverFarplane.x; +#endif + OUT.col = float4(eyeSpaceDepth.rrr,1); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_V.hlsl b/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_V.hlsl new file mode 100644 index 000000000..f7db2ba1f --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/d653a08573e79020_V.hlsl @@ -0,0 +1,51 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Eye Space Depth (Out) +// Visibility + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float4 wsEyeVec : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4), + uniform float3 eyePosWorld : register(C8) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Eye Space Depth (Out) + float3 depthPos = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; + OUT.wsEyeVec = float4( depthPos.xyz - eyePosWorld, 1 ); + + // Visibility + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_P.hlsl b/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_P.hlsl new file mode 100644 index 000000000..bc61ae75d --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_P.hlsl @@ -0,0 +1,69 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Diffuse Vertex Color +// Visibility +// Fog +// HDR Output +// Forward Shaded Material +// Translucent + +struct ConnectData +{ + float4 vpos : SV_Position; + float4 vertColor : COLOR; + float3 wsPosition : TEXCOORD0; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float4 diffuseMaterialColor : register(C0), + uniform float visibility : register(C1), + uniform float4 fogColor : register(C2), + uniform float3 eyePosWorld : register(C3), + uniform float3 fogData : register(C4) +) +{ + Fragout OUT; + + // Vert Position + + // Diffuse Color + OUT.col = diffuseMaterialColor; + + // Diffuse Vertex Color + OUT.col *= IN.vertColor; + + // Visibility + OUT.col.a *= visibility; + + // Fog + float fogAmount = saturate( computeSceneFog( eyePosWorld, IN.wsPosition, fogData.r, fogData.g, fogData.b ) ); + OUT.col.rgb = lerp( fogColor.rgb, OUT.col.rgb, fogAmount ); + + // HDR Output + OUT.col = hdrEncode( OUT.col ); + + // Forward Shaded Material + + // Translucent + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_V.hlsl b/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_V.hlsl new file mode 100644 index 000000000..b3f3e673f --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/efef832dc37c8755_V.hlsl @@ -0,0 +1,63 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Diffuse Color +// Diffuse Vertex Color +// Visibility +// Fog +// HDR Output +// Forward Shaded Material +// Translucent + +struct VertData +{ + float3 position : POSITION; + float4 diffuse : COLOR; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float4 vertColor : COLOR; + float3 outWsPosition : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Diffuse Color + + // Diffuse Vertex Color + OUT.vertColor = IN.diffuse; + + // Visibility + + // Fog + OUT.outWsPosition = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; + + // HDR Output + + // Forward Shaded Material + + // Translucent + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_P.hlsl b/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_P.hlsl new file mode 100644 index 000000000..d549fabd2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_P.hlsl @@ -0,0 +1,52 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Paraboloid Vert Transform +// Visibility +// Depth (Out) +// Single Pass Paraboloid + +struct ConnectData +{ + float4 vpos : SV_Position; + float isBack : TEXCOORD0; + float2 posXY : TEXCOORD1; + float depth : TEXCOORD2; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform float visibility : register(C0) +) +{ + Fragout OUT; + + // Paraboloid Vert Transform + clip( abs( IN.isBack ) - 0.999 ); + clip( 1.0 - abs(IN.posXY.x) ); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // Depth (Out) + OUT.col = float4( IN.depth, 0, 0, 1 ); + + // Single Pass Paraboloid + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_V.hlsl b/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_V.hlsl new file mode 100644 index 000000000..847482580 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/f04ad263e891c04c_V.hlsl @@ -0,0 +1,67 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Paraboloid Vert Transform +// Visibility +// Depth (Out) +// Single Pass Paraboloid + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float isBack : TEXCOORD0; + float2 posXY : TEXCOORD1; + float depth : TEXCOORD2; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float2 atlasScale : register(C4), + uniform float4x4 worldViewOnly : register(C0), + uniform float4 lightParams : register(C5) +) +{ + ConnectData OUT; + + // Paraboloid Vert Transform + OUT.hpos = mul(worldViewOnly, float4(IN.position.xyz,1)).xzyw; + float L = length(OUT.hpos.xyz); + bool isBack = OUT.hpos.z < 0.0; + OUT.isBack = isBack ? -1.0 : 1.0; + if ( isBack ) OUT.hpos.z = -OUT.hpos.z; + OUT.hpos /= L; + OUT.hpos.z = OUT.hpos.z + 1.0; + OUT.hpos.xy /= OUT.hpos.z; + OUT.hpos.z = L / lightParams.x; + OUT.hpos.w = 1.0; + OUT.posXY = OUT.hpos.xy; + OUT.hpos.xy *= atlasScale.xy; + OUT.hpos.x += isBack ? 0.5 : -0.5; + + // Visibility + + // Depth (Out) + OUT.depth = OUT.hpos.z / OUT.hpos.w; + + // Single Pass Paraboloid + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_P.hlsl b/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_P.hlsl new file mode 100644 index 000000000..e10b01aa1 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_P.hlsl @@ -0,0 +1,84 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Detail +// Diffuse Color +// Deferred RT Lighting +// Visibility +// HDR Output + +struct ConnectData +{ + float4 vpos : SV_Position; + float2 detCoord : TEXCOORD0; + float4 screenspacePos : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : SV_Target0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN, + uniform SamplerState detailMap : register(S0), + uniform Texture2D detailMapTex : register(T0), + uniform float4 diffuseMaterialColor : register(C0), + uniform float4 rtParamslightInfoBuffer : register(C2), + uniform SamplerState lightInfoBuffer : register(S1), + uniform Texture2D lightInfoBufferTex : register(T1), + uniform float visibility : register(C1) +) +{ + Fragout OUT; + + // Vert Position + + // Detail + OUT.col = ( detailMapTex.Sample(detailMap, IN.detCoord) * 2.0 ) - 1.0; + + // Diffuse Color + OUT.col = diffuseMaterialColor; + + // Deferred RT Lighting + float2 uvScene = IN.screenspacePos.xy / IN.screenspacePos.w; + uvScene = ( uvScene + 1.0 ) / 2.0; + uvScene.y = 1.0 - uvScene.y; + uvScene = ( uvScene * rtParamslightInfoBuffer.zw ) + rtParamslightInfoBuffer.xy; + float3 d_lightcolor; + float d_NL_Att; + float d_specular; + lightinfoUncondition(lightInfoBufferTex.Sample(lightInfoBuffer, uvScene), d_lightcolor, d_NL_Att, d_specular); + OUT.col *= float4(d_lightcolor, 1.0); + + // Visibility + fizzle( IN.vpos.xy, visibility ); + + // HDR Output + OUT.col = hdrEncode( OUT.col ); + + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_V.hlsl b/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_V.hlsl new file mode 100644 index 000000000..ae63bd6d3 --- /dev/null +++ b/Templates/BaseGame/game/data/shaderCache/fd1301c841a0c80b_V.hlsl @@ -0,0 +1,73 @@ +//***************************************************************************** +// Torque -- HLSL procedural shader +//***************************************************************************** + +// Dependencies: +#include "core/rendering/shaders/lighting.hlsl" +//------------------------------------------------------------------------------ +// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method +//------------------------------------------------------------------------------ +inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) +{ + lightColor = bufferSample.rgb; + NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); + specular = bufferSample.a; +} + + +#include "core/rendering/shaders/torque.hlsl" + +// Features: +// Vert Position +// Detail +// Diffuse Color +// Deferred RT Lighting +// Visibility +// HDR Output + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float3 B : BINORMAL; + float2 texCoord : TEXCOORD0; + float2 texCoord2 : TEXCOORD1; +}; + + +struct ConnectData +{ + float4 hpos : SV_Position; + float2 detCoord : TEXCOORD0; + float4 screenspacePos : TEXCOORD1; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0), + uniform float2 detailScale : register(C4) +) +{ + ConnectData OUT; + + // Vert Position + OUT.hpos = mul(modelview, float4(IN.position.xyz,1)); + + // Detail + OUT.detCoord = IN.texCoord * detailScale; + + // Diffuse Color + + // Deferred RT Lighting + OUT.screenspacePos = OUT.hpos; + + // Visibility + + // HDR Output + + return OUT; +} diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_d.png b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_d.png new file mode 100644 index 000000000..aa5a1ead5 Binary files /dev/null and b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_d.png differ diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_h.png b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_h.png new file mode 100644 index 000000000..0636c3e14 Binary files /dev/null and b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_h.png differ diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_n.png b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_n.png new file mode 100644 index 000000000..1422b1db2 Binary files /dev/null and b/Templates/BaseGame/game/tools/VPathEditor/GUI/Images/btn_Palette_n.png differ diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/Profiles.cs b/Templates/BaseGame/game/tools/VPathEditor/GUI/Profiles.cs new file mode 100644 index 000000000..ae99719c6 --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/GUI/Profiles.cs @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VPathEditorProfile ) +{ + CanKeyFocus = true; + + FontType = "Arial Bold"; + FontColor = "0 0 0"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditor.gui b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditor.gui new file mode 100644 index 000000000..9deb0e197 --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditor.gui @@ -0,0 +1,434 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new VPathEditor(EVPathEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VPathEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "1"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + + new GuiWindowCollapseCtrl(VPathEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "Path Editor"; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(VPathTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "1"; + internalNamesOnly = "0"; + }; + }; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "193 4"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "VPathTreeView.DeleteSelectedPaths();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete Selected Path"; + hovertime = "1000"; + internalName = "deleteSelection"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "core/art/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "176 3"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "VPathTreeView.CreatePath();"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Create New Path"; + hovertime = "1000"; + internalName = "CreateSelection"; + canSaveDynamicFields = "0"; + }; + }; + new GuiWindowCollapseCtrl(VPathEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(VPathEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorPlugin );"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 127"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "EVPathEditor.setNodePosition( $ThisControl.getValue() );"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "EVPathEditor.setNodeRotation( $ThisControl.getValue() );"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Weight"; + }; + new GuiTextEditCtrl(){ + internalName = "weight"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "EVPathEditor.setNodeWeight( $ThisControl.getValue() );"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 84"; + Extent = "46 18"; + text = "Orientation"; + }; + new GuiPopUpMenuCtrl(EPathEditorNodeOrientationMode){ + internalName = "weight"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 84"; + Extent = "141 18"; + text = ""; + Command = "OnOrientationChanged();"; + }; + new GuiTextCtrl(){ + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 105"; + Extent = "46 18"; + text = "Lookat Pt"; + }; + new GuiTextEditCtrl(EPathEditorNodeOrientationData){ + internalName = "weight"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 105"; + Extent = "141 18"; + text = ""; + AltCommand = "OnOrientationChanged();"; + }; + }; + new GuiContainer(){ // Path Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Path Properties"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 150"; + Extent = "223 315"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(VPathInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "179 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(VPathFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function EPathEditorNodeOrientationMode::onWake( %this ) +{ + if ( %this.size() == 0 ) + { + %this.add( "FREE", 0 ); + %this.add( "TOPOINT", 1 ); + } +} + +function OnOrientationChanged() +{ + %mode = EPathEditorNodeOrientationMode.getText(); + %data = EPathEditorNodeOrientationData.getText(); + EVPathEditor.setNodeOrientationMode( %mode, %data ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorPalette.gui b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorPalette.gui new file mode 100644 index 000000000..94f8102dc --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorPalette.gui @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +%paletteId = new GuiControl(VPathEditorPalette) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EVPathEditorSelectButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Select Path / Node (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EVPathEditorMoveButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EVPathEditorRotateButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Rotate Point (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EVPathEditorScaleButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EVPathEditorAddNodeButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Add Node (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EVPathEditorDeleteNodeButton) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Delete Node (6)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; + +//----------------------------------------------------------------------------- + +function EVPathEditorSelectButton::onClick( %this ) +{ + EVPathEditor.EditMode = "Gizmo"; + GlobalGizmoProfile.Mode = "Select"; +} + +function EVPathEditorMoveButton::onClick( %this ) +{ + EVPathEditor.EditMode = "Gizmo"; + GlobalGizmoProfile.Mode = "Move"; +} + +function EVPathEditorRotateButton::onClick( %this ) +{ + EVPathEditor.EditMode = "Gizmo"; + GlobalGizmoProfile.Mode = "Rotate"; +} + +function EVPathEditorScaleButton::onClick( %this ) +{ + EVPathEditor.EditMode = "Gizmo"; + GlobalGizmoProfile.Mode = "Scale"; +} + +function EVPathEditorAddNodeButton::onClick( %this ) +{ + EVPathEditor.EditMode = "AddNode"; +} + +function EVPathEditorDeleteNodeButton::onClick( %this ) +{ + EVPathEditor.EditMode = "DeleteNode"; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorToolbar.gui b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorToolbar.gui new file mode 100644 index 000000000..76fa8aff7 --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/GUI/VPathEditorToolbar.gui @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +%guiContent = new GuiControl(VPathEditorToolbar) +{ + canSaveDynamicFields = "0"; + internalName = "VPathEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiTextCtrl() + { + internalName = "ToolbarLabel"; + profile = "GuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "2 7"; + extent = "77 16"; + minExtent = "8 8"; + visible = "1"; + text = " VPath Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiPopUpMenuCtrl(VPathEditorToolbarPathTypeMenu) + { + canSaveDynamicFields = "0"; + internalName = "PathTypeMenu"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "85 7"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; +}; diff --git a/Templates/BaseGame/game/tools/VPathEditor/Scripts/Editor.cs b/Templates/BaseGame/game/tools/VPathEditor/Scripts/Editor.cs new file mode 100644 index 000000000..c940eddcc --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/Scripts/Editor.cs @@ -0,0 +1,228 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function EVPathEditor::onDeleteKey( %this ) +{ + %editPath = EVPathEditor.getSelectedPath(); + %editNode = EVPathEditor.getSelectedNode(); + if ( isObject( %editPath ) && %editNode != -1 ) + { + // Delete the Node. + %this.deleteSelection(); + } + else + { + // Clear Selection. + %this.clearSelection(); + + // Delete the Path. + MEDeleteUndoAction::submit( %editPath ); + } +} + +function EVPathEditor::onUpdateSelection( %this, %editPath, %editNode ) +{ + // Clear World Editor Selection. + EWorldEditor.clearSelection(); + + %clearNode = true; + if ( isObject( %editPath ) ) + { + // Reset Type. + VPathEditorToolbarPathTypeMenu.setText( %editPath.PathType ); + + // Set World Editor Selection. + EWorldEditor.selectObject( %editPath ); + + // Inspect. + VPathInspector.inspect( %editPath ); + + // Update the Node Inspector. + if ( %editNode != -1 ) + { + // Valid Node. + %clearNode = false; + + VPathEditorOptionsWindow-->position.setActive( true ); + VPathEditorOptionsWindow-->position.setValue( %editPath.getNodeLocalPosition( %editNode ) ); + + VPathEditorOptionsWindow-->rotation.setActive( true ); + VPathEditorOptionsWindow-->rotation.setValue( %editPath.getNodeLocalRotation( %editNode ) ); + + VPathEditorOptionsWindow-->weight.setActive( true ); + VPathEditorOptionsWindow-->weight.setValue( %editPath.getNodeWeight( %editNode ) ); + + %orientationMode = %editPath.getNodeOrientationMode( %editNode ); + %orientationType = EPathEditorNodeOrientationMode.findText( strupr( getField( %orientationMode, 0 ) ) ); + %orientationData = getField( %orientationMode, 1 ); + + EPathEditorNodeOrientationMode.setSelected( %orientationType, false ); + EPathEditorNodeOrientationData.Text = %orientationData; + } + } + + // Invalid Node? + if ( %clearNode ) + { + VPathEditorOptionsWindow-->position.setActive( false ); + VPathEditorOptionsWindow-->position.setValue( "" ); + + VPathEditorOptionsWindow-->rotation.setActive( true ); + VPathEditorOptionsWindow-->rotation.setValue( "" ); + + VPathEditorOptionsWindow-->weight.setActive( true ); + VPathEditorOptionsWindow-->weight.setValue( "" ); + } +} + +function VPathEditorToolbarPathTypeMenu::onSelect( %this ) +{ + %editPath = EVPathEditor.getSelectedPath(); + if ( isObject( %editPath ) ) + { + // Apply Type. + %editPath.PathType = %this.getText(); + } +} + +function VPathTreeView::onInspect( %this, %object ) +{ + // VPath? + if ( !%object.isMemberOfClass( "VPath" ) ) + { + return; + } + + // Select Object. + EVPathEditor.setSelection( %object ); +} + +function VPathTreeView::DeleteSelectedPaths( %this ) +{ + // Clear the Selection. + EVPathEditor.clearSelection(); + + // Iterate over Selection. + %selectionList = %this.getSelectedItemList(); + %selectionCount = getWordCount( %selectionList ); + for ( %i = 0; %i < %selectionCount; %i++ ) + { + // Fetch Index. + %itemIndex = getWord( %selectionList, %i ); + + // Fetch Object. + %itemObject = %this.getItemValue( %itemIndex ); + + // Skip Non-Path Objects. + if ( !%itemObject.isMemberOfClass( "VPath" ) ) + { + continue; + } + + // Delete the Object. + MEDeleteUndoAction::submit( %itemObject ); + } + + // Clear the Selection. + %this.clearSelection(); + EVPathEditor.clearSelection(); + + // Build the Tree. + %this.open( GetServerPathSet(), true ); +} + +function VPathTreeView::CreatePath( %this ) +{ + // Create Path Object. + EWCreatorWindow.createObject( "ObjectBuilderGui.buildObject( \"VPath\" );" ); +} + +//----------------------------------------------------------------------------- +// +// Node Editing +// +//----------------------------------------------------------------------------- + +function EVPathEditor::onUpdateNode( %this, %editPath, %editNode, %selected ) +{ + if ( %selected ) + { + %this.onUpdateNodePosition( %editPath, %editNode, %selected ); + %this.onUpdateNodeRotation( %editPath, %editNode, %selected ); + %this.onUpdateNodeWeight( %editPath, %editNode, %selected ); + %this.onUpdateNodeOrientation( %editPath, %editNode, %selected ); + } +} + +function EVPathEditor::onUpdateNodePosition( %this, %editPath, %editNode, %selected ) +{ + if ( %selected ) + { + VPathEditorOptionsWindow-->position.setValue( %editPath.getNodeLocalPosition( %editNode ) ); + } +} + +function EVPathEditor::onUpdateNodeRotation( %this, %editPath, %editNode, %selected ) +{ + if ( %selected ) + { + VPathEditorOptionsWindow-->rotation.setValue( %editPath.getNodeLocalRotation( %editNode ) ); + } +} + +function EVPathEditor::onUpdateNodeWeight( %this, %editPath, %editNode, %selected ) +{ + if ( %selected ) + { + VPathEditorOptionsWindow-->weight.setValue( %editPath.getNodeWeight( %editNode ) ); + } +} + +function EVPathEditor::onUpdateNodeOrientation( %this, %editPath, %editNode, %selected ) +{ + if ( %selected ) + { + %orientationMode = %editPath.getNodeOrientationMode( %editNode ); + %orientationType = EPathEditorNodeOrientationMode.findText( strupr( getField( %orientationMode, 0 ) ) ); + %orientationData = getField( %orientationMode, 1 ); + + // Change? + if ( EPathEditorNodeOrientationMode.getSelected() != %orientationType ) + { + // Update. + EPathEditorNodeOrientationMode.setSelected( %orientationType ); + } + + // Change? + if ( EPathEditorNodeOrientationData.getText() !$= %orientationData ) + { + // Update. + EPathEditorNodeOrientationData.setText( %orientationData ); + } + } +} + +//----------------------------------------------------------------------------- +// +// Inspector +// +//----------------------------------------------------------------------------- + +function VPathInspector::inspect( %this, %obj ) +{ + VPathFieldInfoControl.setText( "" ); + Parent::inspect( %this, %obj ); +} + +function VPathInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function VPathInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + VPathFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VPathEditor/Scripts/Plugin.cs b/Templates/BaseGame/game/tools/VPathEditor/Scripts/Plugin.cs new file mode 100644 index 000000000..8af3a167a --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/Scripts/Plugin.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VPathEditorPlugin ) +{ + SuperClass = "EditorPlugin"; +}; + +//----------------------------------------------------------------------------- + +function VPathEditorPlugin::onWorldEditorStartup( %this ) +{ + //---------------------------------------------------------------------- + // + // Editor Init + // + //---------------------------------------------------------------------- + + EditorGui.add( EVPathEditor ); + EVPathEditor.setVisible( false ); + + %this.EditorMap = new ActionMap(); + %this.EditorMap.bindCmd( keyboard, "backspace", "EVPathEditor.onDeleteKey();", "" ); + %this.EditorMap.bindCmd( keyboard, "delete", "EVPathEditor.onDeleteKey();", "" ); + %this.EditorMap.bindCmd( keyboard, "1", "EVPathEditorSelectButton.performClick();", "" ); + %this.EditorMap.bindCmd( keyboard, "2", "EVPathEditorMoveButton.performClick();", "" ); + %this.EditorMap.bindCmd( keyboard, "3", "EVPathEditorRotateButton.performClick();", "" ); + %this.EditorMap.bindCmd( keyboard, "4", "EVPathEditorScaleButton.performClick();", "" ); + + //---------------------------------------------------------------------- + // + // Editor Toggles + // + //---------------------------------------------------------------------- + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Path Editor", "", VPathEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Path Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "VPathEditorPlugin", "VPathEditorPalette", expandFilename( "tools/VPathEditor/GUI/Images/btn_Palette" ), %tooltip ); + + // Find and Store the Button. + %this.ToolbarButton = ToolsToolbarArray.findObjectByInternalName( "VPathEditorPalette", false ); + + // Extend Width. + %extent = EWToolsToolbar.getExtent(); + EWToolsToolbar.setExtent( ( getWord( %extent, 0 ) + 33 ) SPC getWord( %extent, 1 ) ); + + //---------------------------------------------------------------------- + // + // Initialise Toolbar + // + //---------------------------------------------------------------------- + + if ( !isObject( VPathEditorToolbar ) ) + { + exec( "~/VPathEditor/GUI/VPathEditorToolbar.gui" ); + } + + // Add Toolbar. + EditorGuiToolbar.add( VPathEditorToolbar ); + + // Populate Type Menu. + VPathEditorToolbarPathTypeMenu.clear(); + VPathEditorToolbarPathTypeMenu.add( "BEZIER", 0 ); + VPathEditorToolbarPathTypeMenu.add( "LINEAR", 1 ); + VPathEditorToolbarPathTypeMenu.setFirstSelected(); + + //---------------------------------------------------------------------- + // + // Initialise Editor Palette + // + //---------------------------------------------------------------------- + + if ( !isObject( VPathEditorPalette ) ) + { + exec( "~/VPathEditor/GUI/VPathEditorPalette.gui" ); + } + + // Use Existing Group Number + 1. + %groupNum = ToolsPaletteArray.getObject( ToolsPaletteArray.getCount() - 1 ).GroupNum + 1; + + %paletteGroup = VPathEditorPalette; + while ( VPathEditorPalette.getCount() > 0 ) + { + // Fetch Button. + %paletteButton = %paletteGroup.getObject( 0 ); + + // Setup. + %paletteButton.Visible = false; + %paletteButton.GroupNum = %groupNum; + %paletteButton.PaletteName = VPathEditorPalette; + + // Add To Palette Array. + ToolsPaletteArray.addGuiControl( %paletteButton ); + } + + //---------------------------------------------------------------------- + // + // Initialise Library + // + //---------------------------------------------------------------------- + + EWCreatorWindow.registerMissionObject( "VPath", "VPath", "", "Level" ); +} + +//EditorGui.setEditor(\"VPathEditorPlugin\"); +function VPathEditorPlugin::onActivated( %this ) +{ + if ( !isObject( EVPathEditor ) ) + { + return; + } + + // Display Editor. + EVPathEditor.setVisible( true ); + EVPathEditor.makeFirstResponder( true ); + EditorGui.bringToFront( EVPathEditor ); + VPathEditorToolbar.setVisible( true ); + VPathTreeView.open( GetServerPathSet(), true ); + + // Sync Gizmo. + %this.syncGizmo(); + + // Enable Map. + %this.EditorMap.push(); + + // Valid Selection? + if ( EWorldEditor.getSelectionSize() ) + { + %selection = EWorldEditor.getSelectedObject( 0 ); + if ( isObject( %selection ) && %selection.isMemberOfClass( "VPath" ) ) + { + // Select Object. + EVPathEditor.setSelection( %selection ); + } + } + + // Parent Call. + Parent::onActivated( %this ); +} + +function VPathEditorPlugin::onDeactivated( %this ) +{ + // Hide Editor. + EVPathEditor.setVisible( false ); + VPathEditorToolbar.setVisible( false ); + + // Disable Map. + %this.EditorMap.pop(); + + // Parent Call. + Parent::onDeactivated( %this ); +} + +function VPathEditorPlugin::isDirty( %this ) +{ + return EVPathEditor.isDirty; +} + +function VPathEditorPlugin::clearDirty( %this ) +{ + EVPathEditor.isDirty = false; +} + +function VPathEditorPlugin::syncGizmo( %this ) +{ + switch$( GlobalGizmoProfile.Mode ) + { + case "None" : EVPathEditorSelectButton.performClick(); + case "Move" : EVPathEditorMoveButton.performClick(); + case "Rotate" : EVPathEditorRotateButton.performClick(); + case "Scale" : EVPathEditorScaleButton.performClick(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VPathEditor/main.cs b/Templates/BaseGame/game/tools/VPathEditor/main.cs new file mode 100644 index 000000000..91b13ea47 --- /dev/null +++ b/Templates/BaseGame/game/tools/VPathEditor/main.cs @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function InitializeVPathEditor() +{ + // Gui. + exec( "./GUI/Profiles.cs" ); + exec( "./GUI/VPathEditor.gui" ); + + // Scripts. + exec( "./Scripts/Plugin.cs" ); + exec( "./Scripts/Editor.cs" ); +} + +function DestroyVPathEditor() +{ + // Void. +} diff --git a/Templates/BaseGame/game/tools/VerveEditor/DefaultPrefs.cs b/Templates/BaseGame/game/tools/VerveEditor/DefaultPrefs.cs new file mode 100644 index 000000000..f9a28fd04 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/DefaultPrefs.cs @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Recent Files +// +//----------------------------------------------------------------------------- + +$Pref::VerveEditor::RecentFileSize = 10; + +//----------------------------------------------------------------------------- +// +// Event Snap +// +//----------------------------------------------------------------------------- + +$Pref::VerveEditor::Event::SnapToTime = true; +$Pref::VerveEditor::Event::SnapToTimeThreshold = 100; +$Pref::VerveEditor::Event::SnapToSiblings = true; +$Pref::VerveEditor::Event::SnapToSiblingThreshold = 100; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Buttons.psd b/Templates/BaseGame/game/tools/VerveEditor/GUI/Buttons.psd new file mode 100644 index 000000000..1f5aaab69 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Buttons.psd differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/GuiProfiles.cs b/Templates/BaseGame/game/tools/VerveEditor/GUI/GuiProfiles.cs new file mode 100644 index 000000000..079bdaa68 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/GUI/GuiProfiles.cs @@ -0,0 +1,213 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VEditorDefaultProfile ) +{ + opaque = true; + fillColor = "70 70 70"; + fillColorHL = "90 90 90"; + fillColorNA = "70 70 70"; + + border = 1; + borderColor = "120 120 120"; + borderColorHL = "100 100 100"; + borderColorNA = "240 240 240"; + + fontType = "Arial"; + fontSize = 12; + fontCharset = ANSI; + + fontColor = "255 255 255"; + fontColorHL = "255 255 255"; + fontColorNA = "255 255 255"; + fontColorSEL = "255 255 255"; +}; + +singleton GuiControlProfile( VEditorTestProfile ) +{ + opaque = true; + fillColor = "255 255 0"; + fillColorHL = "255 255 0"; + fillColorNA = "255 255 0"; +}; + +singleton GuiControlProfile( VEditorNoFillProfile : VEditorDefaultProfile ) +{ + opaque = false; +}; + +singleton GuiControlProfile( VEditorNoBorderProfile : VEditorDefaultProfile ) +{ + border = false; +}; + +singleton GuiControlProfile( VEditorTransparentProfile : VEditorDefaultProfile ) +{ + opaque = false; + border = false; +}; + +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VEditorTextProfile : VEditorDefaultProfile ) +{ + border = false; + opaque = false; + + fontType = "Arial Bold"; +}; + +singleton GuiControlProfile( VEditorTextEditProfile : VEditorDefaultProfile ) +{ + fillColor = "70 70 70"; + fillColorHL = "90 90 90"; + fillColorSEL = "0 0 0"; + fillColorNA = "70 70 70"; + + fontColor = "255 255 255"; + fontColorHL = "0 0 0"; + fontColorSEL = "128 128 128"; + fontColorNA = "128 128 128"; + + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + justify = "left"; + tab = true; + canKeyFocus = true; +}; + +singleton GuiControlProfile( VEditorPopupMenuProfile : GuiPopUpMenuProfile ) +{ + FillColorHL = "90 90 90"; + FillColorSEL = "0 0 0"; + + FontColorHL = "255 255 255"; +}; + +singleton GuiControlProfile ( VEditorBitmapButtonProfile : VEditorDefaultProfile ) +{ + justify = "center"; + + hasBitmapArray = true; + bitmap = "./Images/Button"; +}; + +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VEditorGroupHeaderProfile : VEditorDefaultProfile ) +{ + CanKeyFocus = true; + TextOffset = "23 0"; + + fontColor = "70 70 70"; +}; + +singleton GuiControlProfile( VEditorGroupHeaderErrorProfile : VEditorGroupHeaderProfile ) +{ + fontColor = "255 70 70"; +}; + +singleton GuiControlProfile( VEditorGroupTrackProfile : VEditorTransparentProfile ) +{ + CanKeyFocus = true; +}; + +singleton GuiControlProfile( VEditorTrackProfile : VEditorDefaultProfile ) +{ + CanKeyFocus = true; + TextOffset = "33 0"; + + opaque = true; + fillColor = "255 255 255 15"; + fillColorHL = "151 166 191 60"; + + borderColor = "100 100 100"; +}; + +singleton GuiControlProfile( VEditorTrackErrorProfile : VEditorTrackProfile ) +{ + fontColor = "255 70 70"; +}; + +singleton GuiControlProfile( VEditorEventProfile : VEditorDefaultProfile ) +{ + CanKeyFocus = true; + Justify = "left"; + TextOffset = "6 1"; + + fillColor = "81 81 81"; + fillColorHL = "102 102 102"; + + borderColor = "255 255 255"; + borderColorHL = "255 255 255"; + borderColorNA = "100 100 100"; +}; + +singleton GuiControlProfile( VEditorTimeLineProfile : VEditorDefaultProfile ) +{ + CanKeyFocus = true; + + opaque = false; + fillColorHL = "255 255 255 15"; + + border = false; + borderColor = "100 100 100"; +}; + +singleton GuiControlProfile( VEditorPropertyProfile : VEditorDefaultProfile ) +{ + fillColor = "102 102 102"; +}; + +//----------------------------------------------------------------------------- + +singleton GuiControlProfile ( VEditorScrollProfile : VEditorDefaultProfile ) +{ + opaque = false; + border = false; + + hasBitmapArray = true; + bitmap = "./Images/ScrollBar"; +}; + +singleton GuiControlProfile ( VEditorCheckBoxProfile : GuiCheckBoxProfile ) +{ + // Void. +}; + +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VEditorPropertyRolloutProfile : GuiRolloutProfile ) +{ + border = 0; + hasBitmapArray = true; + bitmap = "./Images/PropertyRollout"; + + fontType = "Arial"; + fontSize = 12; + fontCharset = ANSI; + + fontColor = "255 255 255"; + fontColorHL = "255 255 255"; + fontColorNA = "255 255 255"; + fontColorSEL = "255 255 255"; +}; + +singleton GuiControlProfile( VEditorPropertyLabelProfile : VEditorTextProfile ) +{ + border = "1"; + justify = "center"; +}; + +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( VEditorPreferenceLabelProfile : GuiTextProfile ) +{ + opaque = true; + fillColor = "242 241 240"; + fillColorHL = "242 241 240"; + fillColorNA = "242 241 240"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Button.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Button.png new file mode 100644 index 000000000..fc420ad8a Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Button.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground.png new file mode 100644 index 000000000..12c703b9d Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_h.png new file mode 100644 index 000000000..8b55fa7ed Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_i.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_i.png new file mode 100644 index 000000000..5f23f7ca6 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/GroupBackground_i.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/PropertyRollout.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/PropertyRollout.png new file mode 100644 index 000000000..2ab71d1c6 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/PropertyRollout.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar.png new file mode 100644 index 000000000..dc2318343 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar_.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar_.png new file mode 100644 index 000000000..287ce57eb Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/ScrollBar_.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Spacer.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Spacer.png new file mode 100644 index 000000000..bb2d24be1 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/Spacer.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent.png new file mode 100644 index 000000000..7be6afbe8 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_d.png new file mode 100644 index 000000000..b8e9f8df3 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_h.png new file mode 100644 index 000000000..b4b96029f Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddEvent_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup.png new file mode 100644 index 000000000..27ae0e21d Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_d.png new file mode 100644 index 000000000..8877ceaa6 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_h.png new file mode 100644 index 000000000..887080475 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddGroup_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL.png new file mode 100644 index 000000000..f2c5a0179 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_d.png new file mode 100644 index 000000000..6df64c5c8 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_h.png new file mode 100644 index 000000000..d1302ed4a Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddL_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR.png new file mode 100644 index 000000000..a69233788 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_d.png new file mode 100644 index 000000000..392d196dc Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_h.png new file mode 100644 index 000000000..b5d80a246 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddR_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml.png new file mode 100644 index 000000000..fc32ee544 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_d.png new file mode 100644 index 000000000..adfe16658 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_h.png new file mode 100644 index 000000000..119f5df6d Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddSml_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack.png new file mode 100644 index 000000000..4428e8ebc Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_d.png new file mode 100644 index 000000000..3ef7d2a0f Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_h.png new file mode 100644 index 000000000..1b32c0259 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_AddTrack_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete.png new file mode 100644 index 000000000..a7a01eb50 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml.png new file mode 100644 index 000000000..63b67b3a1 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_d.png new file mode 100644 index 000000000..0cf78be02 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_h.png new file mode 100644 index 000000000..ef35233d2 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_DeleteSml_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_d.png new file mode 100644 index 000000000..1b5aa8b09 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_h.png new file mode 100644 index 000000000..17721dc23 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Delete_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward.png new file mode 100644 index 000000000..c14fc173c Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_d.png new file mode 100644 index 000000000..f01742727 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_h.png new file mode 100644 index 000000000..24f3234de Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Forward_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_d.png new file mode 100644 index 000000000..298764c09 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_h.png new file mode 100644 index 000000000..7d7975f32 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_n.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_n.png new file mode 100644 index 000000000..881d92250 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Palette_n.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause.png new file mode 100644 index 000000000..b0d7a9dc1 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_d.png new file mode 100644 index 000000000..62c5aeed3 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_h.png new file mode 100644 index 000000000..7e510a997 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Pause_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play.png new file mode 100644 index 000000000..9163fa726 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_d.png new file mode 100644 index 000000000..5df9830f0 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_h.png new file mode 100644 index 000000000..f24a859de Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Play_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind.png new file mode 100644 index 000000000..dbf50891e Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_d.png new file mode 100644 index 000000000..dc73431ea Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_h.png new file mode 100644 index 000000000..0cd671ccb Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_Rewind_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB.png new file mode 100644 index 000000000..fb3ad2a6a Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_d.png new file mode 100644 index 000000000..e1b0036c6 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_h.png new file mode 100644 index 000000000..94fbfebcf Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepB_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF.png new file mode 100644 index 000000000..78a33a0cc Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_d.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_d.png new file mode 100644 index 000000000..d4ca592b6 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_d.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_h.png b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_h.png new file mode 100644 index 000000000..35749528d Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/Images/btn_StepF_h.png differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/PropertyContainer.psd b/Templates/BaseGame/game/tools/VerveEditor/GUI/PropertyContainer.psd new file mode 100644 index 000000000..6bc1aab40 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/PropertyContainer.psd differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditor.gui b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditor.gui new file mode 100644 index 000000000..a5259e821 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditor.gui @@ -0,0 +1,764 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VerveEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "728 714"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "VEditorDefaultProfile"; + hovertime = "1000"; + + new VEditorScrollControl(VerveEditorGroupScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "right"; + VertSizing = "height"; + Position = "1 1"; + Extent = "212 663"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOff"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiScriptNotifyCtrl(VerveEditorGroupNotify) { + onChildAdded = "0"; + onChildRemoved = "0"; + onChildResized = "0"; + onParentResized = "1"; + onResize = "1"; + onLoseFirstResponder = "0"; + onGainFirstResponder = "0"; + canSaveDynamicFields = "0"; + class = "VerveEditorScrollNotifyV"; + className = "VerveEditorScrollNotifyV"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "212 1"; + MinExtent = "210 1"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new VEditorButton() { + class = "VerveEditorTimeLineBackground"; + canSaveDynamicFields = "1"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "212 1"; + MinExtent = "210 1"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + Context = "1"; + }; + new GuiStackControl(VerveEditorGroupStack) { + class = "VerveEditorStack"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "212 1"; + MinExtent = "210 1"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new VEditorScrollControl(VerveEditorTrackScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "210 1"; + Extent = "516 663"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiScriptNotifyCtrl(VerveEditorTrackNotify) { + onChildAdded = "0"; + onChildRemoved = "0"; + onChildResized = "0"; + onParentResized = "1"; + onResize = "1"; + onLoseFirstResponder = "0"; + onGainFirstResponder = "0"; + canSaveDynamicFields = "0"; + class = "VerveEditorScrollNotify"; + className = "VerveEditorScrollNotify"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "516 32"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new VTimeLineControl(VerveEditorTrackTimeLine) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTimeLineProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1100 32"; + MinExtent = "1100 32"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + IsController = "0"; + Controller = "VerveEditorController"; + Zoom = "0"; + + new VEditorButton() { + class = "VerveEditorTimeLineBackground"; + canSaveDynamicFields = "1"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "516 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + Context = "0"; + }; + new GuiStackControl(VerveEditorTrackStack) { + class = "VerveEditorStack"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "516 32"; + MinExtent = "8 32"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + }; + new VEditorScrollControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "1 661"; + Extent = "212 56"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOff"; + constantThumbHeight = "0"; + childMargin = "1 1"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "208 36"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(VerveEditorAddGroupButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + class = "VEditorAddGroupButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 3"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Add New Group"; + command = "$ThisControl.DisplayContextMenu();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_AddGroup"; + }; + new GuiBitmapButtonCtrl(VerveEditorAddTrackButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + class = "VEditorAddTrackButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "36 3"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Add New Track"; + command = "$ThisControl.DisplayContextMenu();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_AddTrack"; + }; + new GuiBitmapButtonCtrl(VerveEditorAddEventButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "69 3"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Add New Event"; + command = "VerveEditor::AddEvent();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_AddEvent"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorBitmapButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "175 3"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Delete Selected Object(s)"; + command = "VerveEditor::DeleteSelection();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_Delete"; + }; + }; + }; + new VEditorScrollControl(VerveEditorTimeScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "210 661"; + Extent = "516 56"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiScriptNotifyCtrl(VerveEditorTimeNotify) { + onChildAdded = "0"; + onChildRemoved = "0"; + onChildResized = "0"; + onParentResized = "1"; + onResize = "1"; + onLoseFirstResponder = "0"; + onGainFirstResponder = "0"; + canSaveDynamicFields = "0"; + class = "VerveEditorScrollNotifyH"; + className = "VerveEditorScrollNotifyH"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "516 41"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new VTimeLineControl(VerveEditorTimeLine) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTimeLineProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1100 41"; + MinExtent = "1100 41"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + IsController = "1"; + Controller = "VerveEditorController"; + Zoom = "0"; + }; + }; + }; + }; + new VEditorScrollControl(VerveEditorPropertyScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "left"; + VertSizing = "height"; + Position = "723 1"; + Extent = "300 766"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + childMargin = "3 3"; + + new GuiStackControl(VerveEditorPropertyStack) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "3 3"; + Extent = "279 256"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + new VEditorScrollControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "1 713"; + Extent = "212 54"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOff"; + constantThumbHeight = "0"; + childMargin = "1 1"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "208 36"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + }; + new VEditorScrollControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "210 713"; + Extent = "516 54"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + constantThumbHeight = "0"; + childMargin = "1 1"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "2 2"; + Extent = "500 50"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + Position = "114 10"; + Extent = "258 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorBitmapButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "50 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Jump Backwards"; + command = "VerveEditor::Rewind();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_Rewind"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "52 0"; + Extent = "50 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Step Backwards 1 Frame"; + command = "VerveEditor::StepB();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_StepB"; + }; + new GuiBitmapButtonCtrl(VerveEditorPlayButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "104 0"; + Extent = "50 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Play / Pause"; + command = "VerveEditor::TogglePlay( $ThisControl );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_Play"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "156 0"; + Extent = "50 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Step Forward 1 Frame"; + command = "VerveEditor::StepF();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_StepF"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorBitmapButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "208 0"; + Extent = "50 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Jump Forward"; + command = "VerveEditor::Forward();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_Forward"; + }; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 10"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Insert Time (Front)"; + command = "VerveEditor::InsertTimeFront();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_AddL"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "VEditorTransparentProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "460 10"; + Extent = "30 30"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + tooltip = "Insert Time (Back)"; + command = "VerveEditor::InsertTimeBack();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "./Images/btn_AddR"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorGroupBuilder.gui b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorGroupBuilder.gui new file mode 100644 index 000000000..c1cf41dc7 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorGroupBuilder.gui @@ -0,0 +1,434 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VerveEditorGroupBuilderGUI) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl(VerveEditorGroupBuilderWindow) { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Create Group"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "268 181"; + Extent = "280 178"; + MinExtent = "256 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Label:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "14 30"; + Extent = "84 16"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(VerveEditorGroupBuilderNameField) { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "79 29"; + Extent = "191 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "0"; + Profile = "GuiGroupBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "7 55"; + Extent = "267 70"; + MinExtent = "1 1"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl(VerveEditorGroupBuilderFieldStack) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "3 3"; + Extent = "261 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "261 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Scene Object:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "center"; + position = "4 1"; + Extent = "100 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "VEditorPopupMenuProfile"; + HorizSizing = "left"; + VertSizing = "center"; + position = "104 1"; + Extent = "156 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + internalName = "SceneObjectList"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "66 139"; + Extent = "96 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VerveEditorGroupBuilderGUI._Build( VerveEditorGroupBuilderNameField.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "174 139"; + Extent = "96 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VerveEditorGroupBuilderGUI.Close();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function VerveEditorGroupBuilderGUI::Build( %this, %groupType, %callbackMethod ) +{ + if ( %callbackMethod $= "" ) + { + return; + } + + // Store Info. + %this.GroupType = %groupType; + %this.CallbackMethod = %callbackMethod; + + // Clear Text. + VerveEditorGroupBuilderNameField.setText( "" ); + + // Clear Stack. + VerveEditorGroupBuilderFieldStack.clear(); + + // Populate the Field Stack. + eval( %groupType @ "::PopulateBuildStack( 0, " @ VerveEditorGroupBuilderFieldStack @ ");" ); + + // Display. + if($Verve::UseSeparateWindow) + VerveEditorWindow.pushDialog( %this ); + else + Canvas.pushDialog( %this ); + + + // Resize Everything. + %container = VerveEditorGroupBuilderFieldStack.getParent(); + %stackExtent = VerveEditorGroupBuilderFieldStack.getExtent(); + %stackPosition = VerveEditorGroupBuilderFieldStack.getPosition(); + %containerExtent = %container.getExtent(); + %containerHeight = ( VerveEditorGroupBuilderFieldStack.getCount() > 0 ) ? getWord( %stackExtent, 1 ) + 2 * getWord( %stackPosition, 1 ) : 1; + %containerHeightDelta = %containerHeight - getWord( %containerExtent, 1 ); + %container.setExtent( getWord( %containerExtent, 0 ), %containerHeight ); + + %windowExtent = VerveEditorGroupBuilderWindow.getExtent(); + VerveEditorGroupBuilderWindow.setExtent( getWord( %windowExtent, 0 ), getWord( %windowExtent, 1 ) + %containerHeightDelta ); +} + +function VerveEditorGroupBuilderGUI::Close( %this ) +{ + if($Verve::UseSeparateWindow) + VerveEditorWindow.popDialog( %this ); + else + Canvas.popDialog( %this ); +} + +function VerveEditorGroupBuilderGUI::_Build( %this, %groupLabel ) +{ + if ( %groupLabel $= "" ) + { + messageBox( "Warning", "You must provide a Valid Group Label.", "Ok" ); + return; + } + + if ( %this.CallbackMethod $= "" ) + { + // Close Dialog. + if($Verve::UseSeparateWindow) + VerveEditorWindow.popDialog( %this ); + else + Canvas.popDialog( %this ); + return; + } + + // Eval Method. + eval( %this.CallbackMethod @ "(" @ %this.GroupType @ "," @ %groupLabel @ ");" ); + + // Clear. + %this.CallbackMethod = ""; + + // Close Dialog. + if($Verve::UseSeparateWindow) + VerveEditorWindow.popDialog( %this ); + else + Canvas.popDialog( %this ); +} + +//----------------------------------------------------------------------------- + +function VerveEditorGroupBuilderFieldStack::CreateObjectList( %this, %objectType, %internalName, %label ) +{ + %container = new GuiControl() + { + Profile = "GuiTransparentProfile"; + + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "261 20"; + }; + + %label = new GuiTextCtrl() + { + Profile = "GuiTextProfile"; + + HorizSizing = "right"; + VertSizing = "center"; + Position = "4 1"; + Extent = "100 18"; + + Text = %label; + }; + %container.add( %label ); + + %listObject = new GuiPopUpMenuCtrl() + { + Class = "VerveEditorGroupBuilderObjectList"; + Profile = "VEditorPopupMenuProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = "104 1"; + Extent = "156 18"; + + InternalName = %internalName; + }; + %container.add( %listObject ); + + // Create NULL Entry. + %listObject.add( "", 0 ); + + // Populate List. + %listObject.CheckGroup( MissionGroup, %objectType ); + + // Sort the List. + %listObject.sort(); + + %this.add( %container ); + + return %listObject; +} + +function VerveEditorGroupBuilderObjectList::CheckGroup( %this, %group, %objectType ) +{ + // Populate List. + %groupSize = %group.getCount(); + for ( %i = 0; %i < %groupSize; %i++ ) + { + %groupObject = %group.getObject( %i ); + if ( %groupObject.getName() $= "" ) + { + continue; + } + + if ( %groupObject.isMemberOfClass( %objectType ) ) + { + %this.add( %groupObject.getName(), %this.size() ); + } + else if ( %groupObject.isMemberOfClass( "SimSet" ) ) + { + %this.CheckGroup( %groupObject, %objectType ); + } + } +} + +function VerveEditorGroupBuilderFieldStack::CreateCheckbox( %this, %internalName, %label ) +{ + %container = new GuiControl() + { + Profile = "GuiTransparentProfile"; + + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "261 20"; + }; + + %label = new GuiTextCtrl() + { + Profile = "GuiTextProfile"; + + HorizSizing = "right"; + VertSizing = "center"; + Position = "4 1"; + Extent = "100 18"; + + Text = %label; + }; + %container.add( %label ); + + %checkBox = new GuiCheckBoxCtrl() + { + Profile = "GuiCheckboxProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = "104 1"; + Extent = "156 18"; + + InternalName = %internalName; + + Text = ""; + }; + %container.add( %checkBox ); + + %this.add( %container ); + + return %checkBox; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorImportPathNodes.gui b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorImportPathNodes.gui new file mode 100644 index 000000000..6ec7b430c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorImportPathNodes.gui @@ -0,0 +1,133 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VerveEditorImportPathNodesGUI) { + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Import Path Nodes"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "268 181"; + Extent = "280 98"; + MinExtent = "256 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Speed:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "14 30"; + Extent = "84 16"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(VerveEditorImportPathNodesSpeed) { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "79 29"; + Extent = "191 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "66 62"; + Extent = "96 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VMotionTrack::_ImportPathNodes( VerveEditorImportPathNodesSpeed.getText() );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "174 62"; + Extent = "96 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VerveEditorWindow.popDialog( VerveEditorImportPathNodesGUI );"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorPreferences.gui b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorPreferences.gui new file mode 100644 index 000000000..31579a5fb --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/GUI/VerveEditorPreferences.gui @@ -0,0 +1,367 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VerveEditorPreferenceGui) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "392 253"; + Extent = "240 262"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 24 4 4"; + Padding = "4 24 4 4"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "VerveEditor::CloseEditorPreferences();"; + EdgeSnap = "1"; + canCollapse = "0"; + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + text = "Verve Editor - Preferences"; + + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 93"; + Extent = "220 125"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiBitmapBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 10"; + Extent = "221 116"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + class = "VerveEditorPreferenceLabel"; + Profile = "VEditorPreferenceLabelProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 2"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Event Snap "; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "30 50"; + Extent = "110 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Threshold:"; + maxLength = "1024"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "6 30"; + Extent = "128 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$Pref::VerveEditor::Event::SnapToTime"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = " Snap to Time"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 50"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$Pref::VerveEditor::Event::SnapToTimeThreshold"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "6 80"; + Extent = "128 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$Pref::VerveEditor::Event::SnapToSiblings"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = " Snap to Siblings"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "30 100"; + Extent = "110 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Threshold:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 100"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$Pref::VerveEditor::Event::SnapToSiblingThreshold"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 30"; + Extent = "220 53"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiBitmapBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 10"; + Extent = "221 44"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + class = "VerveEditorPreferenceLabel"; + Profile = "VEditorPreferenceLabelProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 2"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Recent Files "; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "6 30"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$Pref::VerveEditor::RecentFileSize"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 30"; + Extent = "158 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "items shown in Window Menu"; + maxLength = "1024"; + }; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 228"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "VerveEditor::CloseEditorPreferences();"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function VerveEditorPreferenceLabel::onWake( %this ) +{ + %this.setActive( false ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_AddSml.psd b/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_AddSml.psd new file mode 100644 index 000000000..20ce53d2e Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_AddSml.psd differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_Palette.psd b/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_Palette.psd new file mode 100644 index 000000000..52b4a1f32 Binary files /dev/null and b/Templates/BaseGame/game/tools/VerveEditor/GUI/btn_Palette.psd differ diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VController.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VController.cs new file mode 100644 index 000000000..99e8cc04c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VController.cs @@ -0,0 +1,362 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VControllerPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + + Group[0] = "VController"; + Field[0, 0] = "Duration"; + Field[0, 1] = "TimeScale"; + + Field[0, 2] = "SPACER 6"; + + Field[0, 3] = "Loop"; + Field[0, 4] = "LoopBackwards"; + Field[0, 5] = "LoopCount"; + Field[0, 6] = "LoopDelay"; + + Field[0, 7] = "SPACER 6"; + + Field[0, 8] = "ResetOnCompletion"; +}; + +//----------------------------------------------------------------------------- + +function VerveEditor::TogglePlay() +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + // No Controller. + return; + } + + if ( !$VerveEditor::Controller.isPlaying() ) + { + // Play. + VerveEditor::Play(); + } + else + { + // Pause. + VerveEditor::Pause(); + } +} + +function VerveEditor::Play() +{ + // Start Playing. + $VerveEditor::Controller.play(); +} + +function VerveEditor::Pause() +{ + // Stop but do not Reset. + $VerveEditor::Controller.stop( false ); +} + +function VerveEditor::StepF() +{ + // Determine the time to step towards. + %time = mClamp( $VerveEditor::Controller.Time + ( 32 * $VerveEditor::Controller.TimeScale ), 0.0, $VerveEditor::Controller.Duration ); + // Reset. + $VerveEditor::Controller.reset( %time ); +} + +function VerveEditor::StepB() +{ + // Switch TimeScale. + $VerveEditor::Controller.TimeScale *= -1.0; + // Step. + VerveEditor::StepF(); + // Switch Back TimeScale. + $VerveEditor::Controller.TimeScale *= -1.0; +} + +function VerveEditor::Rewind() +{ + if ( $VerveEditor::Controller.TimeScale > 0 ) + { + // Front. + $VerveEditor::Controller.reset( 0 ); + } + else + { + // Back. + $VerveEditor::Controller.reset( $VerveEditor::Controller.Duration ); + } +} + +function VerveEditor::Forward() +{ + if ( $VerveEditor::Controller.TimeScale < 0 ) + { + // Front. + $VerveEditor::Controller.reset( 0 ); + } + else + { + // Back. + $VerveEditor::Controller.reset( $VerveEditor::Controller.Duration ); + } +} + +function VerveEditor::InsertTimeFront() +{ + %time = 0; + %length = 1000; + + VerveEditor::InsertTime( %time, %length ); +} + +function VerveEditor::InsertTimeBack() +{ + %time = $VerveEditor::Controller.Duration; + %length = 1000; + + VerveEditor::InsertTime( %time, %length ); +} + +function VerveEditor::InsertTime( %time, %length ) +{ + if ( %length <= 0 ) + { + return; + } + + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + // Increase Duration. + $VerveEditor::Controller.setFieldValue( "Duration", $VerveEditor::Controller.Duration + %length ); + + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %trackSet = %groupSet.getObject( %i ); + %trackCount = %trackSet.getCount(); + for ( %j = 0; %j < %trackCount; %j++ ) + { + %eventSet = %trackSet.getObject( %j ); + %eventCount = %eventSet.getCount(); + for ( %k = 0; %k < %eventCount; %k++ ) + { + %eventSet.getObject( %k ).InsertTime( %time, %length ); + } + } + } + + if ( %time < $VerveEditor::Controller.Time ) + { + // Update Time. + $VerveEditor::Controller.setFieldValue( "Time", $VerveEditor::Controller.Time + %length ); + } + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); +} + +function VerveEditor::DeleteTime( %time, %length ) +{ + if ( %length <= 0 ) + { + return; + } + + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %trackSet = %groupSet.getObject( %i ); + %trackCount = %trackSet.getCount(); + for ( %j = 0; %j < %trackCount; %j++ ) + { + %eventSet = %trackSet.getObject( %j ); + %eventCount = %eventSet.getCount(); + for ( %k = 0; %k < %eventCount; %k++ ) + { + %eventObject = %eventSet.getObject( %k ); + if ( %eventObject.DeleteTime( %time, %length ) ) + { + // Delete. + %eventObject.delete(); + + // Backstep. + %k -= 1; + %eventCount -= 1; + } + } + } + } + + // Decrease Duration. + $VerveEditor::Controller.setFieldValue( "Duration", $VerveEditor::Controller.Duration - %length ); + + if ( $VerveEditor::Controller.Time > %time && $VerveEditor::Controller.Time < ( %time + %length ) ) + { + // Clamp. + $VerveEditor::Controller.setFieldValue( "Time", %time ); + } + else if ( $VerveEditor::Controller.Time >= ( %time + %length ) ) + { + // Push Back. + $VerveEditor::Controller.setFieldValue( "Time", $VerveEditor::Controller.Time - %length ); + } + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + // Refresh Editor. + VerveEditor::Refresh(); +} + +function VEvent::InsertTime( %this, %time, %length ) +{ + %triggerTime = %this.getFieldValue( "TriggerTime" ); + %triggerDuration = %this.getFieldValue( "Duration" ); + + if ( %time <= %triggerTime ) + { + %this.setFieldValue( "TriggerTime", %triggerTime + %length ); + } + else if ( %time > %triggerTime && %time < %triggerTime + %triggerDuration ) + { + %this.setFieldValue( "Duration", %triggerDuration + %length ); + } +} + +function VEvent::DeleteTime( %this, %time, %length ) +{ + %triggerTime = %this.getFieldValue( "TriggerTime" ); + %triggerDuration = %this.getFieldValue( "Duration" ); + + if ( %triggerTime >= %time && %triggerTime <= ( %time + %length ) ) + { + %tail = ( %triggerTime + %triggerDuration ) - ( %time + %length ); + if ( %tail > 0 ) + { + // Trim Duration. + %this.setFieldValue( "TriggerTime", %time ); + %this.setFieldValue( "Duration", %tail ); + } + else + { + // Delete This Event. + return true; + } + } + else if ( %triggerTime > %time ) + { + // Shuffle Back. + %this.setFieldValue( "TriggerTime", %triggerTime - %length ); + } + else if ( %triggerTime < %time && ( %triggerTime + %triggerDuration ) > %time ) + { + // Trim Duration. + %this.setFieldValue( "Duration", ( %triggerTime + %triggerDuration ) - %time ); + } + + // No Delete. + return false; +} + +//------------------------------------------------------------------------ + +function VerveEditorController::CanPaste( %this, %targetObject ) +{ + if ( !isObject( %targetObject ) ) + { + // Nope! + return false; + } + + if ( !%this.CanAdd( %targetObject.getClassName() ) ) + { + // Nope! + return false; + } + + return %targetObject.isMemberOfClass( "VGroup" ); +} + +function VerveEditorController::CanAdd( %this, %targetClass ) +{ + if ( !isWordInList( %targetClass, $VerveEditor::UniqueGroupList ) ) + { + // Not a Unique Group. + return true; + } + + %groupCount = %this.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %groupObject = %this.getObject( %i ); + if ( %groupObject.isMemberOfClass( %targetClass ) ) + { + // Invalid. + return false; + } + } + + // All Good. + return true; +} + +function VerveEditorController::onPlay( %this ) +{ + // Update Play Button. + VerveEditorPlayButton.setBitmap( "tools/VerveEditor/GUI/Images/btn_Pause" ); + + // Start Update Event. + VerveEditorTimeLine.ControllerUpdate(); +} + +function VerveEditorController::onPause( %this ) +{ + // Update Play Button. + VerveEditorPlayButton.setBitmap( "tools/VerveEditor/GUI/Images/btn_Play" ); + + // Stop Update Event. + VerveEditorTimeLine.StopUpdate(); +} + +function VerveEditorController::onStop( %this ) +{ + // Update Play Button. + VerveEditorPlayButton.setBitmap( "tools/VerveEditor/GUI/Images/btn_Play" ); + + // Stop Update Event. + VerveEditorTimeLine.StopUpdate(); +} + +function VerveEditorController::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + if ( !VerveEditorHistoryManager.Locked ) + { + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryChangeProperty"; + SuperClass = "VerveEditorHistoryObject"; + + ActionName = "Change Property (" @ %fieldName @ ")"; + + // Store References. + Object = %this; + FieldName = %fieldName; + OldValue = %oldValue; + NewValue = %newValue; + }; + } + + switch$ ( %fieldName ) + { + case "Duration" : VerveEditor::UpdateDuration(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VControllerProperties.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VControllerProperties.cs new file mode 100644 index 000000000..b3bd39d5c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/VControllerProperties.cs @@ -0,0 +1,217 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VControllerPropertyList::CreateInspectorGroup( %this, %targetStack ) +{ + %baseGroup = Parent::CreateInspectorGroup( %this, %targetStack ); + if ( %baseGroup.getClassName() !$= "ScriptGroup" ) + { + // Temp Store. + %temp = %baseGroup; + + // Create SimSet. + %baseGroup = new SimSet(); + + // Add Original Control. + %baseGroup.add( %temp ); + } + + // Create Data Table Group. + %groupRollout = %targetStack.CreatePropertyRollout( "VController DataTable" ); + %propertyStack = %groupRollout.Stack; + + // Reference. + %propertyStack.InternalName = "DataTableStack"; + + // Store. + %baseGroup.add( %groupRollout ); + + // Return. + return %baseGroup; +} + +function VControllerPropertyList::InspectObject( %this, %object ) +{ + if ( !%object.isMemberOfClass( "VController" ) ) + { + // Invalid Object. + return; + } + + // Default Inspect. + Parent::InspectObject( %this, %object ); + + // Update Data Table. + %dataTableStack = %this.ControlCache.findObjectByInternalName( "DataTableStack", true ); + if ( !isObject( %dataTableStack ) ) + { + // Invalid Table. + return; + } + + // Clear Stack. + while ( %dataTableStack.getCount() > 1 ) + { + // Delete Object. + %dataTableStack.getObject( 1 ).delete(); + } + + %dataFieldCount = %object.getDataFieldCount(); + for ( %i = 0; %i < %dataFieldCount; %i++ ) + { + // Add To List. + %dataFieldList = trim( %dataFieldList SPC %object.getDataFieldName( %i ) ); + } + + // Sort Word List. + %dataFieldList = sortWordList( %dataFieldList ); + + for ( %i = 0; %i < %dataFieldCount; %i++ ) + { + // Fetch Field Name. + %dataFieldName = getWord( %dataFieldList, %i ); + + // Create Field. + VerveEditor::CreateField( %dataTableStack, %dataFieldName, "Data" ); + } + + // Create Add Field. + VerveEditor::CreateAddDataField( %dataTableStack ); + + // Update. + %dataTableStack.InspectObject( %object ); +} + +function VController::DisplayContextMenu( %this, %x, %y ) +{ + %contextMenu = $VerveEditor::VController::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VControllerContextMenu"; + Position = 0; + + Item[0] = "Add Group" TAB ""; + + Item[1] = "" TAB ""; + + Item[2] = "Cu&t" TAB "" TAB ""; + Item[3] = "&Copy" TAB "" TAB ""; + Item[4] = "&Paste" TAB "" TAB "VerveEditor::Paste();"; + + Item[5] = "" TAB ""; + + Item[6] = "&Delete" TAB "" TAB ""; + + PasteIndex = 4; + }; + %contextMenu.Init(); + + // Disable Cut, Copy & Delete. + %contextMenu.enableItem( 2, false ); + %contextMenu.enableItem( 3, false ); + %contextMenu.enableItem( 6, false ); + + // Cache. + $VerveEditor::VController::ContextMenu = %contextMenu; + } + + // Remove Add Menu. + %contextMenu.removeItem( %contextMenu.AddIndex ); + + // Insert Menu. + %contextMenu.insertSubMenu( %contextMenu.AddIndex, getField( %contextMenu.Item[0], 0 ), %this.GetAddGroupMenu() ); + + // Enable/Disable Pasting. + %contextMenu.enableItem( %contextMenu.PasteIndex, VerveEditor::CanPaste() ); + + if ( %x $= "" || %y $= "" ) + { + %position = %this.getGlobalPosition(); + %extent = %this.getExtent(); + + %x = getWord( %position, 0 ) + getWord( %extent, 0 ); + %y = getWord( %position, 1 ); + } + + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); +} + +function VController::GetAddGroupMenu( %this ) +{ + %contextMenu = $VerveEditor::VController::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %customTemplateMenu = new PopupMenu() + { + Class = "VerveCustomTemplateMenu"; + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VGroupAddGroupMenu"; + Position = 0; + }; + %customTemplateMenu.Init(); + + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VGroupAddGroupMenu"; + Position = 0; + + Item[0] = "Add Camera Group" TAB "" TAB "VerveEditor::AddGroup(\"VCameraGroup\");"; + Item[1] = "Add Director Group" TAB "" TAB "VerveEditor::AddGroup(\"VDirectorGroup\");"; + Item[2] = "Add Light Object Group" TAB "" TAB "VerveEditor::AddGroup(\"VLightObjectGroup\");"; + Item[3] = "Add Particle Effect Group" TAB "" TAB "VerveEditor::AddGroup(\"VParticleEffectGroup\");"; + Item[4] = "Add Scene Object Group" TAB "" TAB "VerveEditor::AddGroup(\"VSceneObjectGroup\");"; + Item[5] = "Add Spawn Sphere Group" TAB "" TAB "VerveEditor::AddGroup(\"VSpawnSphereGroup\");"; + + Item[6] = "" TAB ""; + + Item[7] = "Add Custom Group" TAB %customTemplateMenu; + + DirectorIndex = 1; + CustomIndex = 7; + CustomMenu = %customTemplateMenu; + }; + %contextMenu.Init(); + + // Refresh Menu. + %customTemplateMenu = %contextMenu.CustomMenu; + if ( %customTemplateMenu.getItemCount() == 0 ) + { + // Remove Item. + %contextMenu.removeItem( %contextMenu.CustomIndex ); + + // Add Dummy. + %contextMenu.insertItem( %contextMenu.CustomIndex, getField( %contextMenu.Item[%contextMenu.CustomIndex], 0 ) ); + + // Disable Custom Menu. + %contextMenu.enableItem( %contextMenu.CustomIndex, false ); + } + + // Cache. + $VerveEditor::VController::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable / Disable Director Group. + %contextMenu.enableItem( %contextMenu.DirectorIndex, %this.CanAdd( "VDirectorGroup" ) ); + + // Return Menu. + return %contextMenu; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/main.cs new file mode 100644 index 000000000..7410f038c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Controller/main.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitControllerScripts() +{ + // Core. + exec( "./VController.cs" ); + exec( "./VControllerProperties.cs" ); + + // Custom. + // Exec Custom Controller Scripts. +} +VerveEditor::InitControllerScripts(); diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorControls.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorControls.cs new file mode 100644 index 000000000..499133eed --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorControls.cs @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::DeleteControls() +{ + while ( VerveEditorGroupStack.getCount() > 0 ) + { + VerveEditorGroupStack.getObject( 0 ).delete(); + } + + while ( VerveEditorTrackStack.getCount() > 0 ) + { + VerveEditorTrackStack.getObject( 0 ).delete(); + } +} + +function VerveEditorStack::FindControl( %this, %object ) +{ + %trackCount = %this.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %track = %this.getObject( %i ); + if ( %track.Proxy.getId() == %object.getId() ) + { + return %track; + } + } + + return -1; +} + +function VerveEditorStack::FindControlIndex( %this, %object ) +{ + %trackCount = %this.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %track = %this.getObject( %i ); + if ( %track.Proxy.getId() == %object.getId() ) + { + return %i; + } + } + + return -1; +} + +//------------------------------------------------------------------------- + +function VerveEditorTimeLine::onLoseFirstResponder( %this ) +{ + // Clear Selection. + %this.setSelection( false ); + + // Force OnSelectionUpdate. + %this.onSelectionUpdate(); +} + +function VerveEditorTimeLine::StopUpdate( %this ) +{ + // Cancel Event. + cancel( $VerveEditor::Controller::TickEvent ); +} + +function VerveEditorTimeLine::ControllerUpdate( %this ) +{ + // Cancel Event. + cancel( $VerveEditor::Controller::TickEvent ); + + %scrollParent = %this.getParentOfType( "VEditorScrollControl" ); + if ( !isObject( %scrollParent ) ) + { + // Woops! + return; + } + + // Fetch Point. + %point = %this.toPoint( $VerveEditor::Controller.Time ); + + // Fetch Scroll Point. + %scrollPoint = %scrollParent.getScrollPositionX(); + %scrollWidth = getWord( %scrollParent.getExtent(), 0 ) - 19; + + if ( ( %point < %scrollPoint ) || ( %point > ( %scrollPoint + %scrollWidth ) ) ) + { + // Scroll To View Time. + %scrollParent.setScrollPosition( %point - %scrollWidth * 0.50, 0 ); + } + + // Schedule Next Event. + $VerveEditor::Controller::TickEvent = %this.schedule( 100, "ControllerUpdate" ); +} + +function VerveEditorTimeLine::onSelectionUpdate( %this ) +{ + // Fetch Selection. + %selectionString = %this.getSelection(); + + %selectionActive = getWord( %selectionString, 0 ); + if ( !%selectionActive ) + { + // Clear Selection. + VerveEditorTrackTimeLine.setSelection( false ); + } + else + { + if ( !getWord( VerveEditorTrackTimeLine.getSelection(), 0 ) ) + { + // Clear Editor Selection. + VerveEditor::ClearSelection(); + } + + // Set Selection. + VerveEditorTrackTimeLine.setSelection( true, getWord( %selectionString, 1 ), getWord( %selectionString, 2 ) ); + } +} + +function VerveEditorTimeLine::onSelectionRightClick( %this, %point, %modifiers, %clickCount ) +{ + %this.DisplayContextMenu( getWord( %point, 0 ), getWord( %point, 1 ) ); +} + +function VerveEditorTimeLine::DisplayContextMenu( %this, %x, %y ) +{ + %contextMenu = $VerveEditor::VTimeLine::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VTimeLineMenu"; + Position = 0; + + Item[0] = "Insert Time Before" TAB "" TAB "VerveEditorTimeLine.InsertTimeBefore();"; + Item[1] = "Insert Time After" TAB "" TAB "VerveEditorTimeLine.InsertTimeAfter();"; + + Item[2] = "" TAB ""; + + Item[3] = "Delete Time" TAB "" TAB "VerveEditorTimeLine.DeleteTime();"; + + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VTimeLine::ContextMenu = %contextMenu; + } + + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); + +} + +function VerveEditorTimeLine::InsertTimeBefore( %this ) +{ + // Fetch Selection. + %selectionString = %this.getSelection(); + %selectionActive = getWord( %selectionString, 0 ); + if ( !%selectionActive ) + { + // Woops! + return; + } + + // Determine Position. + %selectionPosition = getWord( %selectionString, 1 ); + + // Insert Time. + VerveEditor::InsertTime( %selectionPosition, getWord( %selectionString, 2 ) ); +} + +function VerveEditorTimeLine::InsertTimeAfter( %this ) +{ + // Fetch Selection. + %selectionString = %this.getSelection(); + %selectionActive = getWord( %selectionString, 0 ); + if ( !%selectionActive ) + { + // Woops! + return; + } + + // Determine Position. + %selectionPosition = getWord( %selectionString, 1 ) + getWord( %selectionString, 2 ); + + // Insert Time. + VerveEditor::InsertTime( %selectionPosition, getWord( %selectionString, 2 ) ); +} + +function VerveEditorTimeLine::DeleteTime( %this ) +{ + // Fetch Selection. + %selectionString = %this.getSelection(); + %selectionActive = getWord( %selectionString, 0 ); + if ( !%selectionActive ) + { + // Woops! + return; + } + + // Determine Position. + %selectionPosition = getWord( %selectionString, 1 ); + + // Delete Time. + VerveEditor::DeleteTime( %selectionPosition, getWord( %selectionString, 2 ) ); + + // Clear Selection. + %this.setSelection( false ); + + // Force OnSelectionUpdate. + %this.onSelectionUpdate(); +} + +//------------------------------------------------------------------------- + +function VerveEditorTimeLineBackground::onMouseUp( %this, %point, %modifiers, %clickCount ) +{ + // Clear Selection. + VerveEditor::ClearSelection(); +} + +function VerveEditorTimeLineBackground::onRightMouseUp( %this, %point, %modifiers, %clickCount ) +{ + // Clear Selection. + VerveEditor::ClearSelection(); + + if ( !%this.Context ) + { + // Return. + return; + } + + // Display Context Menu. + $VerveEditor::Controller.schedule( 32, "DisplayContextMenu", getWord( %point, 0 ), getWord( %point, 1 ) ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorHistory.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorHistory.cs new file mode 100644 index 000000000..80866fcb8 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorHistory.cs @@ -0,0 +1,265 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +$VerveEditor::HistoryManager = new UndoManager( VerveEditorHistoryManager ); +$VerveEditor::UndoCount = 0; +$VerveEditor::RedoCount = 0; + +//----------------------------------------------------------------------------- + +function VerveEditor::IsDirty() +{ + if ( !isObject( VerveEditorHistoryManager ) ) + { + // Woops! + return false; + } + + return !( ( VerveEditorHistoryManager.getUndoCount() == $VerveEditor::UndoCount ) + && ( VerveEditorHistoryManager.getRedoCount() == $VerveEditor::RedoCount ) ); +} + +function VerveEditor::ClearDirty() +{ + // Reset. + $VerveEditor::UndoCount = VerveEditorHistoryManager.getUndoCount(); + $VerveEditor::RedoCount = VerveEditorHistoryManager.getRedoCount(); +} + +function VerveEditor::ClearHistory() +{ + // Clear History. + VerveEditorHistoryManager.clearAll(); + + // Clear Dirty. + VerveEditor::ClearDirty(); +} + +function VerveEditor::CanUndo() +{ + return ( VerveEditorHistoryManager.getUndoCount() > 0 ); +} + +function VerveEditor::Undo() +{ + VerveEditorHistoryManager.Undo(); + + // Refresh. + VerveEditor::Refresh(); +} + +function VerveEditor::CanRedo() +{ + return ( VerveEditorHistoryManager.getRedoCount() > 0 ); +} + +function VerveEditor::Redo() +{ + VerveEditorHistoryManager.Redo(); + + // Refresh. + VerveEditor::Refresh(); +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryObject::onAdd( %this ) +{ + %historyManager = VerveEditorHistoryManager; + if ( %historyManager.Locked ) + { + // Delete. + %this.schedule( 0, delete ); + return; + } + + if ( isObject( %historyManager.HistoryGroup ) ) + { + // Add To Group. + %historyManager.HistoryGroup.Group.add( %this ); + return; + } + + // Add To Manager. + %this.addToManager( %historyManager ); + + // Update Window. + VerveEditorWindow.UpdateWindowTitle(); +} + +//------------------------------------------------------------------------- + +function VerveEditor::ToggleHistoryGroup() +{ + %historyManager = VerveEditorHistoryManager; + if ( isObject( %historyManager.HistoryGroup ) ) + { + // Clear. + %historyManager.HistoryGroup = 0; + + // Update Window. + VerveEditorWindow.UpdateWindowTitle(); + + return; + } + + if ( VerveEditorHistoryManager.Locked ) + { + // Locked. + return; + } + + %historyManager.HistoryGroup = new UndoScriptAction() + { + Class = "VerveEditorHistoryGroup"; + + ActionName = "History Group"; + + // Store Object References. + Group = new SimGroup(); + }; + + // Add To Manager. + %historyManager.HistoryGroup.addToManager( %historyManager ); +} + +function VerveEditorHistoryGroup::onRemove( %this ) +{ + if ( isObject( %this.Group ) ) + { + // Delete Group. + %this.Group.delete(); + } +} + +function VerveEditorHistoryGroup::Undo( %this ) +{ + // Undo In Reverse Order. + + %undoCount = %this.Group.getCount(); + for ( %i = ( %undoCount - 1 ); %i >= 0; %i-- ) + { + %this.Group.getObject( %i ).Undo(); + } +} + +function VerveEditorHistoryGroup::Redo( %this ) +{ + %undoCount = %this.Group.getCount(); + for ( %i = 0; %i < %undoCount; %i++ ) + { + %this.Group.getObject( %i ).Redo(); + } +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryCreateObject::Undo( %this ) +{ + // Undo Delete. + %parentObject = %this.Parent; + %object = %this.Object; + + // Detach Object. + %parentObject.removeObject( %object ); +} + +function VerveEditorHistoryCreateObject::Redo( %this ) +{ + // Redo Delete. + %parentObject = %this.Parent; + %object = %this.Object; + + // Attach Object. + %parentObject.addObject( %object ); +} + +function VerveEditorHistoryCreateObject::onRemove( %this ) +{ + /* + if ( !isObject( %this.Object.getParent() ) || %this.Object.getParent().getId() != %this.Parent.getId() ) + { + SimObject::Delete( %this.Object ); + } + */ +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryDeleteObject::Undo( %this ) +{ + // Undo Delete. + %parentObject = %this.Parent; + %object = %this.Object; + + // Attach Object. + %parentObject.addObject( %object ); +} + +function VerveEditorHistoryDeleteObject::Redo( %this ) +{ + // Redo Delete. + %parentObject = %this.Parent; + %object = %this.Object; + + // Detach Object. + %parentObject.removeObject( %object ); +} + +function VerveEditorHistoryDeleteObject::onRemove( %this ) +{ + /* + if ( !isObject( %this.Object.getParent() ) || %this.Object.getParent().getId() != %this.Parent.getId() ) + { + SimObject::Delete( %this.Object ); + } + */ +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryChangeProperty::Undo( %this ) +{ + // Undo Change. + %object = %this.Object; + %fieldName = %this.FieldName; + %oldValue = %this.OldValue; + + // Lock History. + VerveEditorHistoryManager.Locked = true; + + // Attach Object. + %object.setFieldValue( %fieldName, %oldValue, false ); + + // Unlock History. + VerveEditorHistoryManager.Locked = false; +} + +function VerveEditorHistoryChangeProperty::Redo( %this ) +{ + // Redo Change. + %object = %this.Object; + %fieldName = %this.FieldName; + %newValue = %this.NewValue; + + // Lock History. + VerveEditorHistoryManager.Locked = true; + + // Attach Object. + %object.setFieldValue( %fieldName, %newValue, false ); + + // Unlock History. + VerveEditorHistoryManager.Locked = false; +} + +function VerveEditorHistoryManager::Lock( %this ) +{ + %this.Locked = true; +} + +function VerveEditorHistoryManager::UnLock( %this ) +{ + %this.Locked = false; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorMenu.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorMenu.cs new file mode 100644 index 000000000..20bcfe3a3 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorMenu.cs @@ -0,0 +1,261 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveWindowMenu::Clear( %this ) +{ + while ( %this.getItemCount() > 0 ) + { + %this.removeItem( 0 ); + } +} + +function VerveWindowMenu::Init( %this ) +{ + // Clear Items. + %this.Clear(); + + %i = 0; + while ( %this.Item[%i] !$= "" ) + { + %itemString = %this.Item[%i]; + %itemLabel = getField( %itemString, 0 ); + %itemAccel = getField( %itemString, 1 ); + %itemMethod = getField( %itemString, 2 ); + %itemMap = getField( %itemString, 3 ); + + if ( !isObject( %itemMap ) ) + { + %itemMap = VerveEditorMap; + } + + if ( isObject( %itemAccel ) ) + { + %this.insertSubMenu( %i, %itemLabel, %itemAccel ); + } + else + { + // Insert Item. + %this.insertItem( %i, %itemLabel, %itemAccel ); + + if ( !%this.IsPopup && %itemAccel !$= "" && isObject( %itemMap ) ) + { + // Label Hack... + switch$( %itemAccel ) + { + case "DEL" : %itemAccel = "DELETE"; + case "ESC" : %itemAccel = "ESCAPE"; + } + + // Perform Keybind. + %itemMap.bindCmd( "keyboard", strreplace( %itemAccel, "+", " " ), %itemMethod, "" ); + } + } + + %i++; + } +} + +function VerveWindowMenu::onSelectItem( %this, %id, %text ) +{ + %command = getField( %this.item[%id], 2 ); + if ( %command !$= "" ) + { + eval( %command ); + return true; + } + + return false; +} + +//------------------------------------------------------------------------- + +function VerveEditorWindow::onCreateMenu( %this ) +{ + // Store Menu Bars. + if ( !isObject( %this.MenuSet ) ) + { + %this.MenuSet = new SimSet(); + } + + // CMD Key. + %cmdKey = $platform $= "macos" ? "Cmd" : "Ctrl"; + + //--------------------------------------------------------------------- + // + // File Menu + // + //--------------------------------------------------------------------- + + %recentSequenceMenu = new PopupMenu() + { + Class = "VerveRecentFileMenu"; + SuperClass = "VerveWindowMenu"; + + Label = "Recent Files"; + Position = 0; + + Item[0] = "None"; + }; + + %fileMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + Label = "&File"; + Position = 0; + + Item[0] = "&New" TAB %cmdKey @ "+N" TAB "VerveEditor::NewFile();"; + Item[1] = "&Open" TAB %cmdKey @ "+O" TAB "VerveEditor::LoadFile();"; + Item[2] = "" TAB ""; + Item[3] = "&Save" TAB %cmdKey @ "+S" TAB "VerveEditor::SaveFile();"; + Item[4] = "Save &As" TAB %cmdKey @ "-Shift+S" TAB "VerveEditor::SaveFile( true );"; + Item[5] = "" TAB ""; + Item[6] = "Recent Files" TAB %recentSequenceMenu; + }; + %this.MenuSet.add( %fileMenu ); + + if ( $platform !$= "macos" ) + { + %fileMenu.Item[7] = "" TAB ""; + %fileMenu.Item[8] = "&Close" TAB %cmdKey @ "+F4" TAB "ToggleVerveEditor( true );"; + } + + //--------------------------------------------------------------------- + // + // Edit Menu + // + //--------------------------------------------------------------------- + + %editMenu = new PopupMenu() + { + Class = "VerveWindowEditMenu"; + SuperClass = "VerveWindowMenu"; + + Label = "&Edit"; + Position = 1; + + Item[0] = "&Undo" TAB %cmdKey @ "+Z" TAB "VerveEditor::Undo();"; + Item[1] = "&Redo" TAB %cmdKey @ "+Y" TAB "VerveEditor::Redo();"; + Item[2] = "" TAB ""; + Item[3] = "Cu&t" TAB %cmdKey @ "+X" TAB "VerveEditor::CutSelection();" TAB VerveEditorEditMap; + Item[4] = "&Copy" TAB %cmdKey @ "+C" TAB "VerveEditor::CopySelection();" TAB VerveEditorEditMap; + Item[5] = "&Paste" TAB %cmdKey @ "+V" TAB "VerveEditor::Paste();" TAB VerveEditorEditMap; + + Item[6] = "" TAB ""; + Item[7] = "&Delete" TAB "Del" TAB "VerveEditor::DeleteSelection();" TAB VerveEditorEditMap; + + Item[8] = "" TAB ""; + Item[9] = "&Clear Selection" TAB "Esc" TAB "VerveEditor::ClearSelection();"; + + Item[10] = "" TAB ""; + Item[11] = "&Preferences" TAB %cmdKey @ "+P" TAB "VerveEditor::LaunchEditorPreferences();"; + }; + %this.MenuSet.add( %editMenu ); + + // Init Popups. + %fileMenu.Init(); + %editMenu.Init(); + + // Attach. + %fileMenu.attachToMenuBar( %this, %fileMenu.Position, %fileMenu.Label ); + %editMenu.attachToMenuBar( %this, %editMenu.Position, %editMenu.Label ); +} + +function VerveEditorWindow::ClearMenu( %this ) +{ + if ( isObject( %this.MenuSet ) ) + { + while( %this.MenuSet.getCount() > 0 ) + { + // Fetch Object. + %menuObject = %this.MenuSet.getObject( 0 ); + + // Detach. + %menuObject.removeFromMenuBar(); + + // Delete. + %menuObject.delete(); + } + } +} + +function VerveEditorWindow::onDestroyMenu( %this ) +{ + // Clear the Menu. + %this.ClearMenu(); + + // Delete the Menu Set. + if ( isObject( %this.MenuSet ) ) + { + %this.MenuSet.delete(); + } +} + +function VerveRecentFileMenu::onMenuSelect( %this ) +{ + %this.Refresh(); +} + +function VerveRecentFileMenu::onSelectItem( %this, %index, %text ) +{ + // Load the File. + VerveEditor::LoadFile( $Pref::VerveEditor::RecentFile[ %index ] ); + + return false; +} + +function VerveRecentFileMenu::Refresh( %this ) +{ + // Clear The List. + %this.Clear(); + + // Populate Menu. + if ( $Pref::VerveEditor::RecentFileSize == 0 || $Pref::VerveEditor::RecentFile[0] $= "" ) + { + // Insert Default Item. + %this.insertItem( 0, %this.Item[0], "" ); + + // Disable. + %this.enableItem( 0, false ); + } + else + { + for ( %i = 0; %i < $Pref::VerveEditor::RecentFileSize; %i++ ) + { + // Valid? + if ( $Pref::VerveEditor::RecentFile[%i] $= "" ) + { + // Nope! + break; + } + + // Insert Item. + %this.insertItem( %i, makeRelativePath( $Pref::VerveEditor::RecentFile[%i], $VerveEditor::FilePath ), "" ); + } + } +} + +function VerveWindowEditMenu::onMenuSelect( %this ) +{ + %this.Refresh(); +} + +function VerveWindowEditMenu::Refresh( %this ) +{ + // Undo & Redo. + %this.enableItem( 0, VerveEditor::CanUndo() ); + %this.enableItem( 1, VerveEditor::CanRedo() ); + + // Cut, Copy & Paste. + %this.enableItem( 3, VerveEditor::CanCopy() ); + %this.enableItem( 4, VerveEditor::CanCopy() ); + %this.enableItem( 5, VerveEditor::CanPaste() ); + + // Delete. + %this.enableItem( 7, VerveEditor::CanCopy() ); + + // Clear Selection. + %this.enableItem( 9, VerveEditor::CanCopy() ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorPreferences.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorPreferences.cs new file mode 100644 index 000000000..923c89c5b --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorPreferences.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::LaunchEditorPreferences() +{ + if ( !isObject( VerveEditorPreferenceGui ) ) + { + // Load the GUI. + exec ( "~/VerveEditor/GUI/VerveEditorPreferences.gui" ); + } + + // Awake? + if ( VerveEditorPreferenceGui.isAwake() ) + { + // Sanity!. + return; + } + + // Launch. + VerveEditorWindow.pushDialog( VerveEditorPreferenceGui ); +} + +function VerveEditor::CloseEditorPreferences() +{ + // Close. + VerveEditorWindow.popDialog( VerveEditorPreferenceGui ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorWindow.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorWindow.cs new file mode 100644 index 000000000..22baa8e95 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/EditorWindow.cs @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +$VerveEditor::MapStore = new SimSet(); + +//----------------------------------------------------------------------------- + +function VerveEditorWindow::Open() +{ + if ( isObject( VerveEditorWindow ) ) + { + return; + } + + // Create the Controller. + VerveEditor::CreateController(); + + // Create ActionMap. + %actionMap = new ActionMap( VerveEditorMap ); + %actionMap.pop(); + + // Create Edit ActionMap. + %editActionMap = new ActionMap( VerveEditorEditMap ); + %editActionMap.pop(); + + // Create Window. + if($Verve::UseSeparateWindow) + { + %editorWindow = new VEditorWindow( VerveEditorWindow ); + + // Init Window? + if ( $Pref::VerveEditor::WindowSize $= "" ) + { + // Default Window Size. + %editorWindow.setVideoMode( 800, 253, false ); + } + else + { + // Last Known Window Size. + %editorWindow.setVideoMode( getWord( $Pref::VerveEditor::WindowSize, 0 ), + getWord( $Pref::VerveEditor::WindowSize, 1 ), + false ); + } + + return %editorWindow; + } + else + { + %editorWindow = new guiWindowCtrl(VerveEditorWindow) + { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + return %editorWindow; + } +} + +function VerveEditorWindow::UpdateWindowTitle( %this ) +{ + %fileName = fileName( $VerveEditor::Controller.FileName ); + if ( %fileName $= "" ) + { + %fileName = "Untitled.vsf"; + } + + if ( VerveEditor::IsDirty() ) + { + // Signify Unsaved Work. + %fileName = %fileName @ "*"; + } + + // Set Title. + %this.setWindowTitle( %fileName SPC "- Verve" ); +} + +function VerveEditorWindow::onGainFocus( %this ) +{ + if($Verve::UseSeparateWindow) + return; + + %activeSet = ActiveActionMapSet; + while ( %activeSet.getCount() > 0 ) + { + // Get Object. + %activeMap = %activeSet.getObject( 0 ); + + // Pop It. + %activeMap.pop(); + + if ( %activeMap != GlobalActionMap.getId() ) + { + // Store It. + $VerveEditor::MapStore.add( %activeMap ); + } + } + + // Give Our Commands Preference. + GlobalActionMap.pop(); + VerveEditorMap.push(); + VerveEditorEditMap.push(); + GlobalActionMap.push(); + + // Reset Cursor. + %this.resetCursor(); +} + +function VerveEditorWindow::onLoseFocus( %this ) +{ + %activeSet = $VerveEditor::MapStore; + // Active Set? + if ( isObject( %activeSet ) ) + { + while ( %activeSet.getCount() > 0 ) + { + // Get Object. + %activeMap = %activeSet.getObject( 0 ); + + // Push It. + %activeMap.push(); + + // Remove It. + $VerveEditor::MapStore.remove( %activeMap ); + } + } + + // Valid Map? + if ( isObject( VerveEditorMap ) ) + { + VerveEditorMap.pop(); + } + + // Valid Map? + if ( isObject( VerveEditorEditMap ) ) + { + VerveEditorEditMap.pop(); + } +} + +function VerveEditorWindow::onRemove( %this ) +{ + // Save? + // Note: This crashes the game! + // At this stage, if the editor is dirty a save prompt should have + // been made already... Lets hope! + //VerveEditor::SavePrompt(); + + // Clear Inspector. + VerveEditorPropertyStack.ClearStack(); + + if ( isObject( VerveEditorMap ) ) + { + VerveEditorMap.delete(); + } + + if ( isObject( VerveEditorEditMap ) ) + { + VerveEditorEditMap.delete(); + } + + // Clear the Menu. + %this.ClearMenu(); + + // Force Reset. + %this.onLoseFocus(); + + // Store the Window Extents on Shutdown. + $Pref::VerveEditor::WindowSize = getWords( %this.getVideoMode(), 0, 1 ); + + // Playing? + if ( $VerveEditor::Controller.isPlaying() ) + { + // Stop, but do not reset. + $VerveEditor::Controller.stop( false ); + } + + // Clear the Current Sequence. + $VerveEditor::Controller.clear(); + // Clear the File Name. + $VerveEditor::Controller.FileName = ""; + + /* + // Delete the Controller. + VerveEditor::DeleteController(); + */ + + if ( isFile( $VerveEditor::TemplateVClipboard ) ) + { + // Clear Clipboard. + fileDelete( $VerveEditor::TemplateVClipboard ); + } + + // World Editor Initialised? + if ( isObject( VerveEditorPlugin.ToolbarButton ) ) + { + // Toggle Off the Plugin Button. + VerveEditorPlugin.ToolbarButton.setStateOn( false ); + } +} + +function VerveEditorWindow::onWindowClose( %this ) +{ + if ( !VerveEditor::SavePromptCancel() ) + { + // Don't Close. + return; + } + + // Delete Window. + %this.schedule( 0, delete ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VCameraShakeEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VCameraShakeEvent.cs new file mode 100644 index 000000000..d61b241aa --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VCameraShakeEvent.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VCameraShakeEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventDPropertyList"; + + Group[0] = "VCameraShakeEvent"; + Field[0, 0] = "Falloff"; + Field[0, 1] = "Amplitude"; + Field[0, 2] = "Frequency"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VDirectorEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VDirectorEvent.cs new file mode 100644 index 000000000..6eb5bf331 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VDirectorEvent.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VDirectorEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VDirectorEvent"; + Field[0, 0] = "Label"; + Field[0, 1] = "Target"; + Type[0, 1] = "VCameraGroupEnum"; +}; + +//----------------------------------------------------------------------------- + +function VDirectorEvent::onRemove( %this ) +{ + // Schedule Update. + %this.getParent().schedule( 0, "update" ); +} + +function VDirectorEvent::Refresh( %this, %trackContainer ) +{ + // Create Control. + %eventButton = Parent::Refresh( %this, %trackContainer ); + + // Reference Label. + %eventButton.LabelField = "EventLabel"; + + // Add Field Notify. + %this.AddFieldNotify( "EventLabel", %eventButton ); + + // Update Label. + %this.UpdateLabel(); +} + +function VDirectorEvent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + // Parent Callback. + Parent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ); + + // Fetch Parent. + %parent = %this.getParent(); + if ( !isObject( %parent ) ) + { + return; + } + + switch$( %fieldName ) + { + case "TriggerTime" : %parent.Update(); + + case "Duration" : %parent.Update(); + + case "Target" : %this.UpdateLabel(); + + case "Label" : %this.UpdateLabel(); + } +} + +function VDirectorEvent::UpdateLabel( %this ) +{ + // Valid Target Camera? + %targetLabel = %this.Target; + if ( %targetLabel $= "" ) + { + %targetLabel = "Invalid Target"; + } + + // Valid Scene Label? + if ( %this.Label !$= "" ) + { + %eventLabel = %this.Label @ ": " @ %targetLabel; + } + else + { + %eventLabel = %targetLabel; + } + + // Set Value. + %this.setFieldValue( "EventLabel", %eventLabel ); +} + +function VDirectorEvent::getSnapTime( %this, %targetTime ) +{ + // Don't Snap to Other Events. + + if ( $VerveEditor::Event::SnapTime > 0 ) + { + // Snap. + return mRound( %targetTime, $VerveEditor::Event::SnapTime ); + } + + // No Snap! + return %targetTime; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VEvent.cs new file mode 100644 index 000000000..57ec6ce85 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VEvent.cs @@ -0,0 +1,314 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + //Parent = "VObjectPropertyList"; + + Group[0] = "VEvent"; + Field[0, 0] = "TriggerTime"; +}; + +new ScriptObject( VEventDPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + //Parent = "VObjectPropertyList"; + + Group[0] = "VEvent"; + Field[0, 0] = "TriggerTime"; + Field[0, 1] = "Duration"; +}; + +//----------------------------------------------------------------------------- + +function VEvent::CanCopy( %this, %targetObject ) +{ + return false; +} + +function VEvent::CanPaste( %this, %targetObject ) +{ + return false; +} + +function VEvent::Refresh( %this, %trackContainer ) +{ + // Store Container Reference. + %this.TrackContainer = %trackContainer; + + // Create Control. + return VerveEditor::CreateEventControl( %this ); +} + +//------------------------------------------------------------------------- + +function VerveEditor::CreateEventControl( %object ) +{ + %eventButton = new VEditorButton() + { + SuperClass = "VEditorSelectable"; + Class = "VEditorSelectableEvent"; + Profile = "VEditorEventProfile"; + + HorizSizing = "right"; + VertSizing = "center"; + Position = "0 2"; + Extent = "5 22"; + MinExtent = "1 22"; + + ButtonType = "ToggleButton"; + GroupNum = "-1"; + + // No Text. + Text = ""; + + // Draggable. + IsDraggable = "1"; + }; + %object.TrackContainer.add( %eventButton ); + + // Reference Proxy. + %eventButton.Proxy = %object; + + // Reference Control. + %object.Control = %eventButton; + + // Field Notify. + %object.AddFieldNotify( "TriggerTime", %eventButton ); + %object.AddFieldNotify( "Duration", %eventButton ); + + return %eventButton; +} + +function VEditorSelectableEvent::onMouseDown( %this, %point, %modifiers, %clickCount ) +{ + // Fetch Global Position. + %globalPosition = %this.getGlobalPosition(); + + // Get Local Points. + %x = getWord( %point, 0 ) - getWord( %globalPosition, 0 ); + %y = getWord( %point, 1 ) - getWord( %globalPosition, 1 ); + + // Store Mouse Down Point. + %this.MouseDown = %x SPC %y; + + // Reset. + %this.Proxy.DragModify = false; +} + +function VEditorSelectableEvent::onMouseDragged( %this, %point, %modifiers, %clickCount ) +{ + if ( !%this.Proxy.DragModify ) + { + // Store Original Time. + %this.Proxy.DragTime = %this.Proxy.TriggerTime; + + // Set Selection. + VerveEditor::SetSelection( %this ); + } + + // Fetch Track. + %trackControl = %this.Proxy.getParent().Control.SiblingControl; + + // Mouse Position. + %mousePosition = getWord( %point, 0 ) - getWord( %trackControl.getGlobalPosition(), 0 ) - getWord( %this.MouseDown, 0 ); + + // Fetch Time. + %time = mClamp( VerveEditorTimeLine.toTime( %mousePosition ), 0, $VerveEditor::Controller.Duration ); + + // Apply. + %this.Proxy.SnapToTime( %time, true ); +} + +function VEditorSelectableEvent::onMouseUp( %this, %point, %modifiers, %clickCount ) +{ + Parent::onMouseUp( %this, %point, %modifiers, %clickCount ); + + if ( %this.Proxy.DragModify ) + { + // Store New Time. + %newTime = %this.Proxy.TriggerTime; + + // Reset Value. + %this.Proxy.TriggerTime = %this.Proxy.DragTime; + + // Set Value. + %this.Proxy.setFieldValue( "TriggerTime", %newTime ); + + // Clear Modify. + %this.Proxy.DragModify = false; + } +} + +function VEvent::getSnapTime( %this, %targetTime ) +{ + if ( $Pref::VerveEditor::Event::SnapToSiblings && $Pref::VerveEditor::Event::SnapToSiblingThreshold > 0 ) + { + // Iterate Over Sibling Events. + %trackObject = %this.getParent(); + %eventCount = %trackObject.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + %eventObject = %trackObject.getObject( %i ); + if ( %eventObject.getId() == %this.getId() ) + { + continue; + } + + // Snap Back -> Front. + %snapTime = %eventObject.TriggerTime - %this.Duration; + if ( mAbs( %targetTime - %snapTime ) < $Pref::VerveEditor::Event::SnapToSiblingThreshold / 2 ) + { + // Snap. + return %snapTime; + } + +/* + // Overlaping? + if ( ( %this.TriggerTime + %this.Duration ) > %eventObject.TriggerTime ) + { + // Snap. + return %snapTime; + } +*/ + + // Snap Front -> Back + %snapTime = %eventObject.TriggerTime + %eventObject.Duration; + if ( mAbs( %targetTime - %snapTime ) < $Pref::VerveEditor::Event::SnapToSiblingThreshold / 2 ) + { + // Snap. + return %snapTime; + } + +/* + // Overlaping? + if ( %this.TriggerTime < ( %eventObject.TriggerTime + %eventObject.Duration ) ) + { + // Snap. + return %snapTime; + } +*/ + } + } + + if ( $Pref::VerveEditor::Event::SnapToTime && $Pref::VerveEditor::Event::SnapToTimeThreshold > 0 ) + { + // Snap. + return mRound( %targetTime, $Pref::VerveEditor::Event::SnapToTimeThreshold ); + } + + // No Snap! + return %targetTime; +} + +function VEvent::SnapToTime( %this, %targetTime, %dragged ) +{ + // Fetch Duration. + %duration = %this.Duration; + + // Nasty Hack. + if ( %this.isMemberOfClass( "VDirectorEvent" ) + || %this.isMemberOfClass( "VShapeAnimationEvent" ) ) + { + // Clear Duration. + %duration = 0; + } + + // Snap. + %targetTime = %this.getSnapTime( %targetTime ); + + if ( %dragged ) + { + if ( %targetTime != %this.TriggerTime ) + { + // Flag Modified. + %this.DragModify = true; + } + + // Lock History. + VerveEditorHistoryManager.Locked = true; + + // Set Time. + %this.setFieldValue( "TriggerTime", %targetTime ); + + // UnLock History. + VerveEditorHistoryManager.Locked = false; + } + else + { + // Set Time. + %this.setFieldValue( "TriggerTime", %targetTime ); + } +} + +function VEditorSelectableEvent::Update( %this, %fieldName, %fieldValue ) +{ + if ( %this.LabelField !$= "" && %this.LabelField $= %fieldName ) + { + // Apply Text. + %this.Text = %fieldValue; + + // Return. + return; + } + + %eventTime = %this.Proxy.getFieldValue( "TriggerTime" ); + %eventDuration = %this.Proxy.getFieldValue( "Duration" ); + switch$ ( %fieldName ) + { + case "TriggerTime" : %eventTime = %fieldValue; + + case "Duration" : %eventDuration = %fieldValue; + } + + // Update Position + %controlPositionX = VerveEditorTimeLine.toPoint( %eventTime ); + %controlPositionX += ( %eventDuration == 0 ) ? ( -2 ) : 0; + + // Update Extent. + %controlExtentX = ( %eventDuration == 0 ) ? 5 : ( VerveEditorTimeLine.toPoint( %eventTime + %eventDuration ) - %controlPositionX ); + + %this.setPosition( %controlPositionX, getWord( %this.getPosition(), 1 ) ); + %this.setExtent( %controlExtentX, getWord( %this.getExtent(), 1 ) ); +} + +function VEvent::DisplayContextMenu( %this, %x, %y ) +{ + %contextMenu = $VerveEditor::VEvent::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VEventContextMenu"; + Position = 0; + + Item[0] = "Cu&t" TAB "" TAB "VerveEditor::CutSelection();"; + Item[1] = "&Copy" TAB "" TAB "VerveEditor::CopySelection( true );"; + + Item[2] = "" TAB ""; + + Item[3] = "&Delete" TAB "" TAB "VerveEditor::DeleteSelection();"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VEvent::ContextMenu = %contextMenu; + } + + // Enable/Disable Cut & Copy. + %contextMenu.enableItem( 0, VerveEditor::CanCopy() ); + %contextMenu.enableItem( 1, VerveEditor::CanCopy() ); + + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); +} diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VFadeEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VFadeEvent.cs new file mode 100644 index 000000000..b612e90d5 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VFadeEvent.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VFadeEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventDPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VFadeEvent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + // Parent Callback. + Parent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ); + + // Fetch Parent. + %parent = %this.getParent(); + if ( !isObject( %parent ) ) + { + return; + } + + switch$( %fieldName ) + { + case "TriggerTime" : %parent.Update(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectAnimationEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectAnimationEvent.cs new file mode 100644 index 000000000..bead9a877 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectAnimationEvent.cs @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VLightObjectAnimationEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventDPropertyList"; + + Group[0] = "VLightObjectAnimationEvent"; + Field[0, 0] = "AnimationData"; + Type[0, 0] = "VLightAnimationDataEnum"; +}; + +//----------------------------------------------------------------------------- + +function VLightObjectAnimationEvent::Refresh( %this, %trackContainer ) +{ + // Create Control. + %eventButton = Parent::Refresh( %this, %trackContainer ); + + // Reference Label. + %eventButton.LabelField = "AnimationData"; + + // Add Field Notify. + %this.AddFieldNotify( "AnimationData", %eventButton ); + + // Return Button. + return %eventButton; +} + +function VLightObjectAnimationEvent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + // Parent Callback. + Parent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ); + + // Fetch Parent. + %parent = %this.getParent(); + if ( !isObject( %parent ) ) + { + return; + } + + switch$( %fieldName ) + { + case "AnimationData" : %parent.Update(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectToggleEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectToggleEvent.cs new file mode 100644 index 000000000..ddb7d8a18 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VLightObjectToggleEvent.cs @@ -0,0 +1,14 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VLightObjectToggleEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VLightObjectToggleEvent"; + Field[0, 0] = "Action"; + Type[0, 0] = "ToggleEnum"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VMotionEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VMotionEvent.cs new file mode 100644 index 000000000..75680cf04 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VMotionEvent.cs @@ -0,0 +1,183 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VMotionEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VMotionEvent::CreatePathNode( %this, %transform ) +{ + // Fetch Track & Group. + %track = %this.getParent(); + %group = %track.getParent(); + + // Fetch Object References. + %object = %group.getSceneObject(); + %path = %track.getPath(); + + // Fetch Index. + %nodeIndex = %this.getIndex(); + + // Create New Node. + %path.addNode( %transform, 10, %nodeIndex ); + + // Update Transform. + %object.setTransform( %transform ); + + if ( !VerveEditorHistoryManager.Locked ) + { + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryCreateMotionEvent"; + SuperClass = "VerveEditorHistoryCreateObject"; + + ActionName = "Create Object"; + + // Store Object References. + Parent = %track; + Object = %this; + + // Store Node Information. + PathObject = %path; + NodeIndex = %nodeIndex; + NodeTransform = %path.getNodeWorldTransform( %nodeIndex ); + NodeWeight = %path.getNodeWeight( %nodeIndex ); + }; + + // Force OnAdd. + VerveEditorHistoryObject::onAdd( %historyObject ); + } + + // Reset the Controller. + $VerveEditor::Controller.reset( $VerveEditor::Controller.Time ); +} + +function VMotionEvent::Delete( %this ) +{ + // Fetch Parent. + %parentObject = %this.getParent(); + %rootObject = %this.getRoot(); + if ( !%parentObject || ( %rootObject.getId() != $VerveEditor::Controller.getId() ) ) + { + // Not Editing, Delete. + Parent::delete( %this ); + return; + } + + if ( !VerveEditorHistoryManager.Locked ) + { + %path = %parentObject.getPath(); + %nodeIndex = %this.getIndex(); + + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryDeleteMotionEvent"; + SuperClass = "VerveEditorHistoryDeleteObject"; + + ActionName = "Delete Object"; + + // Store Object References. + Parent = %parentObject; + Object = %this; + + // Store Node Information. + PathObject = %path; + NodeIndex = %nodeIndex; + NodeTransform = %path.getNodeWorldTransform( %nodeIndex ); + NodeWeight = %path.getNodeWeight( %nodeIndex ); + }; + + // Force OnAdd. + VerveEditorHistoryObject::onAdd( %historyObject ); + } + + // Detach Object. + %parentObject.removeObject( %this ); +} + +function VMotionEvent::OnRemove( %this ) +{ + // Fetch Path. + %path = %this.getParent().getPath(); + if ( !isObject( %path ) ) + { + return; + } + + // Delete Node. + %path.deleteNode( %this.getIndex() ); +} + +function VMotionEvent::OnSelect( %this ) +{ + // Fetch Path. + %path = %this.getParent().getPath(); + if ( !isObject( EVPathEditor ) || !isObject( %path ) ) + { + // No Editor. + return; + } + + // Update Selection. + EVPathEditor.setSelection( %path, %this.getIndex() ); +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryCreateMotionEvent::Undo( %this ) +{ + // Delete Node. + %this.PathObject.DeleteNode( %this.NodeIndex ); + + // Dirty. + EVPathEditor.isDirty = true; + + // Regular Undo. + Parent::Undo( %this ); +} + +function VerveEditorHistoryCreateMotionEvent::Redo( %this ) +{ + // Create Node. + %this.PathObject.AddNode( %this.NodeTransform, %this.NodeWeight, %this.NodeIndex ); + + // Dirty. + EVPathEditor.isDirty = true; + + // Regular Redo. + Parent::Redo( %this ); +} + +//------------------------------------------------------------------------- + +function VerveEditorHistoryDeleteMotionEvent::Undo( %this ) +{ + // Create Node. + %this.PathObject.AddNode( %this.NodeTransform, %this.NodeWeight, %this.NodeIndex ); + + // Dirty. + EVPathEditor.isDirty = true; + + // Regular Undo. + Parent::Undo( %this ); +} + +function VerveEditorHistoryDeleteMotionEvent::Redo( %this ) +{ + // Delete Node. + %this.PathObject.DeleteNode( %this.NodeIndex ); + + // Dirty. + EVPathEditor.isDirty = true; + + // Regular Redo. + Parent::Redo( %this ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VParticleEffectToggleEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VParticleEffectToggleEvent.cs new file mode 100644 index 000000000..c95f7c30d --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VParticleEffectToggleEvent.cs @@ -0,0 +1,14 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VParticleEffectToggleEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VParticleEffectToggleEvent"; + Field[0, 0] = "Action"; + Type[0, 0] = "ToggleEnum"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VPostEffectToggleEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VPostEffectToggleEvent.cs new file mode 100644 index 000000000..f803cc2b8 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VPostEffectToggleEvent.cs @@ -0,0 +1,14 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VPostEffectToggleEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VPostEffectToggleEvent"; + Field[0, 0] = "Action"; + Type[0, 0] = "ToggleEnum"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSceneJumpEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSceneJumpEvent.cs new file mode 100644 index 000000000..089bfa3bb --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSceneJumpEvent.cs @@ -0,0 +1,14 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSceneJumpEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VSceneJumpEvent"; + Field[0, 0] = "Target"; + Type[0, 0] = "VSceneEnum"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VScriptEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VScriptEvent.cs new file mode 100644 index 000000000..e7c4472ba --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VScriptEvent.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VScriptEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VScriptEvent"; + Field[0, 0] = "CommandType"; + Type[0, 0] = "VCommandEnum"; + Field[0, 1] = "Command"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VShapeAnimationEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VShapeAnimationEvent.cs new file mode 100644 index 000000000..dc0e3b52d --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VShapeAnimationEvent.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VShapeAnimationEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventDPropertyList"; + + Group[0] = "VShapeAnimationEvent"; + Field[0, 0] = "AnimationData"; + Type[0, 0] = "VShapeAnimationEnum"; + Field[0, 1] = "AutoDuration"; +}; + +//----------------------------------------------------------------------------- + +function VShapeAnimationEvent::Refresh( %this, %trackContainer ) +{ + // Create Control. + %eventButton = Parent::Refresh( %this, %trackContainer ); + + // Reference Label. + %eventButton.LabelField = "AnimationData"; + + // Add Field Notify. + %this.AddFieldNotify( "AnimationData", %eventButton ); + %this.AddFieldNotify( "AutoDuration", %eventButton ); + + // Return Button. + return %eventButton; +} + +function VShapeAnimationEvent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + // Parent Callback. + Parent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ); + + // Fetch Parent. + %parent = %this.getParent(); + if ( !isObject( %parent ) ) + { + return; + } + + switch$( %fieldName ) + { + case "AnimationData" : %parent.Update(); + + case "AutoDuration" : %parent.Update(); + + case "TriggerTime" : %parent.Update(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSlowMoEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSlowMoEvent.cs new file mode 100644 index 000000000..9385f02e1 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSlowMoEvent.cs @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSlowMoEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventDPropertyList"; + + Group[0] = "VSlowMoEvent"; + Field[0, 0] = "TimeScale"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSoundEffectEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSoundEffectEvent.cs new file mode 100644 index 000000000..6ceecfc14 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSoundEffectEvent.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSoundEffectEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; + + Group[0] = "VSoundEffectEvent"; + Field[0, 0] = "SoundEffect"; + Type[0, 0] = "VSFXProfileEnum"; +}; + +//----------------------------------------------------------------------------- + +function VSoundEffectEvent::Refresh( %this, %trackContainer ) +{ + // Create Control. + %eventButton = Parent::Refresh( %this, %trackContainer ); + + // Reference Label. + %eventButton.LabelField = "SoundEffect"; + + // Add Field Notify. + %this.AddFieldNotify( "SoundEffect", %eventButton ); + + // Return Button. + return %eventButton; +} + +function VSoundEffectEvent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + switch$ ( %fieldName ) + { + case "SoundEffect" : %this.NotifyFieldChange( "Duration", 0 ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSpawnSphereSpawnTargetEvent.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSpawnSphereSpawnTargetEvent.cs new file mode 100644 index 000000000..6262bb23d --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/VSpawnSphereSpawnTargetEvent.cs @@ -0,0 +1,10 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSpawnSphereSpawnTargetEventPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VEventPropertyList"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/main.cs new file mode 100644 index 000000000..a456a5e38 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Events/main.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitEventScripts() +{ + // Core. + exec( "./VEvent.cs" ); + + // Built-In. + exec( "./VCameraShakeEvent.cs" ); + exec( "./VDirectorEvent.cs" ); + exec( "./VFadeEvent.cs" ); + exec( "./VLightObjectAnimationEvent.cs" ); + exec( "./VLightObjectToggleEvent.cs" ); + exec( "./VMotionEvent.cs" ); + exec( "./VParticleEffectToggleEvent.cs" ); + exec( "./VPostEffectToggleEvent.cs" ); + exec( "./VSceneJumpEvent.cs" ); + exec( "./VScriptEvent.cs" ); + exec( "./VShapeAnimationEvent.cs" ); + exec( "./VSlowMoEvent.cs" ); + exec( "./VSoundEffectEvent.cs" ); + exec( "./VSpawnSphereSpawnTargetEvent.cs" ); + + // Custom. + // Exec Custom Event Scripts. +} +VerveEditor::InitEventScripts(); diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VCameraGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VCameraGroup.cs new file mode 100644 index 000000000..164d3d306 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VCameraGroup.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VCameraGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VSceneObjectGroupPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VCameraGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VCameraGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Animation Track" TAB "" TAB "VerveEditor::AddTrack( \"VShapeAnimationTrack\" );"; + Item[1] = "Add Camera Shake Track" TAB "" TAB "VerveEditor::AddTrack( \"VCameraShakeTrack\" );"; + Item[2] = "Add Motion Track" TAB "" TAB "VerveEditor::AddTrack( \"VMotionTrack\" );"; + Item[3] = "Add Post Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VPostEffectToggleTrack\" );"; + Item[4] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[5] = "Add Sound Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VSoundEffectTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VShapeAnimationTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VCameraShakeTrack" ) ); + %contextMenu.enableItem( 2, %this.CanAdd( "VMotionTrack" ) ); + %contextMenu.enableItem( 3, %this.CanAdd( "VPostEffectToggleTrack" ) ); + %contextMenu.enableItem( 4, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 5, %this.CanAdd( "VSoundEffectTrack" ) ); + + // Return Menu. + return %contextMenu; +} + +function VCameraGroup::isValid( %this ) +{ + // Valid? + return VTorque::isCameraObject( %this.getSceneObject() ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VDirectorGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VDirectorGroup.cs new file mode 100644 index 000000000..9360f22d0 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VDirectorGroup.cs @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VDirectorGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VGroupPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VDirectorGroup::PopulateBuildStack( %this, %stack ) +{ + Parent::PopulateBuildStack( %this, %stack ); + + // Create Director Track Checkbox. + %directorTrackCheckBox = %stack.CreateCheckbox( "DirectorTrackToggle", "Add Director Track:" ); + %directorTrackCheckBox.setStateOn( true ); +} + +function VDirectorGroup::ResolveBuildStack( %this, %stack ) +{ + Parent::ResolveBuildStack( %this, %stack, %groupObject ); + + // Find the Track Toggle. + %directorTrackCheckBox = %stack.findObjectByInternalName( "DirectorTrackToggle", true ); + if ( isObject( %directorTrackCheckBox ) && %directorTrackCheckBox.getValue() == true ) + { + // Create the Director Track. + %directorTrackCheckBox = VerveEditor::AddTrack( "VDirectorTrack", %this, false ); + } +} + +//----------------------------------------------------------------------------- + +function VDirectorGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Director Track" TAB "" TAB "VerveEditor::AddTrack( \"VDirectorTrack\" );"; + Item[1] = "Add Fade Track" TAB "" TAB "VerveEditor::AddTrack( \"VFadeTrack\" );"; + Item[2] = "Add Scene Jump Track" TAB "" TAB "VerveEditor::AddTrack( \"VSceneJumpTrack\" );"; + Item[3] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[4] = "Add Slow Mo Track" TAB "" TAB "VerveEditor::AddTrack( \"VSlowMoTrack\" );"; + Item[5] = "Add Sound Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VSoundEffectTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VDirectorTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VFadeTrack" ) ); + %contextMenu.enableItem( 2, %this.CanAdd( "VSceneJumpTrack" ) ); + %contextMenu.enableItem( 3, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 4, %this.CanAdd( "VSlowMoTrack" ) ); + %contextMenu.enableItem( 5, %this.CanAdd( "VSoundEffectTrack" ) ); + + // Return Menu. + return %contextMenu; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VGroup.cs new file mode 100644 index 000000000..554f583c3 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VGroup.cs @@ -0,0 +1,360 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VGroup::OnAdd( %this ) +{ + %ourClass = %this.getClassName(); + if ( isWordInList( %ourClass, $VerveEditor::UniqueGroupList ) ) + { + %controller = $VerveEditor::Controller; + %groupCount = %controller.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %groupObject = %controller.getObject( %i ); + if ( %groupObject.getId() == %this.getId() ) + { + // Skip. + continue; + } + + if ( %groupObject.isMemberOfClass( %ourClass ) ) + { + // Alert Message. + messageBox( "Verve Editor", "You cannot have more than one \"" @ %ourClass @ "\" in your sequence.", "Ok", "Warning" ); + + // Invalid. + return false; + } + } + } + + // Regular Add. + return Parent::OnAdd( %this ); +} + +function VGroup::OnAttach( %this ) +{ + // Add Event Notify. + VerveEditor::AddEventNotify( %this, "VGroupObjectUpdate", "OnGroupObjectUpdate" ); +} + +function VGroup::OnDetach( %this ) +{ + // Remove Event Notify. + VerveEditor::RemoveEventNotify( %this, "VGroupObjectUpdate" ); +} + +function VGroup::CanPaste( %this, %targetObject ) +{ + if ( !isObject( %targetObject ) ) + { + // Nope! + return false; + } + + if ( !%this.CanAdd( %targetObject.getClassName() ) ) + { + // Nope! + return false; + } + + return %targetObject.isMemberOfClass( "VTrack" ); +} + +function VGroup::CanAdd( %this, %targetClass ) +{ + if ( isWordInList( %targetClass, $VerveEditor::NonUniqueTrackList ) ) + { + // Non-Unique Class. + return true; + } + + // All Tracks are Unique. + %trackCount = %this.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %trackObject = %this.getObject( %i ); + if ( %trackObject.isMemberOfClass( %targetClass ) ) + { + // Invalid. + return false; + } + } + + // All Good. + return true; +} + +function VGroup::isValid( %this ) +{ + // Yup. + return true; +} + +function VGroup::Refresh( %this ) +{ + // Create Control. + %groupControl = VerveEditor::CreateGroupControl( %this ); + + // Update Validity. + %this.OnGroupObjectUpdate(); + + %trackCount = %this.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %this.getObject( %i ).Refresh(); + } + + // Return Control. + return %groupControl; +} + +function VGroup::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + // Parent Callback. + Parent::OnFieldChange( %this, %fieldName, %oldValue, %newValue ); + + switch$ ( %fieldName ) + { + case "Reference" : + + if ( $VerveEditor::InspectorObject.getId() == %this.getId() ) + { + // Post Event. + VerveEditor::PostEvent( "VGroupObjectUpdate", %this ); + } + } +} + +function VGroup::OnGroupObjectUpdate( %this, %refObject ) +{ + if ( !isObject( %this.Control ) ) + { + return; + } + + // Update Validity. + if ( %this.isValid() ) + { + // Valid. + %this.Control.setProfile( "VEditorGroupHeaderProfile" ); + } + else + { + // Invalid. + %this.Control.setProfile( "VEditorGroupHeaderErrorProfile" ); + } +} + +//----------------------------------------------------------------------------- + +function VGroup::PopulateBuildStack( %this, %stack ) +{ + // Void. +} + +function VGroup::ResolveBuildStack( %this, %stack ) +{ + // Void. +} + +//----------------------------------------------------------------------------- + +function VGroup::DisplayContextMenu( %this, %x, %y ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VGroupContextMenu"; + Position = 0; + + Item[0] = "Add Track" TAB ""; + + Item[1] = "" TAB ""; + + Item[2] = "Cu&t" TAB "" TAB "VerveEditor::CutSelection();"; + Item[3] = "&Copy" TAB "" TAB "VerveEditor::CopySelection();"; + Item[4] = "&Paste" TAB "" TAB "VerveEditor::Paste();"; + + Item[5] = "" TAB ""; + + Item[6] = "&Delete" TAB "" TAB "VerveEditor::DeleteSelection();"; + + AddIndex = 0; + PasteIndex = 4; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu = %contextMenu; + } + + // Remove Add Menu. + %contextMenu.removeItem( %contextMenu.AddIndex ); + + // Available Tracks Menu. + %groupMenu = 0; + if ( %this.isMethod( "GetAddTrackMenu" ) ) + { + %groupMenu = %this.GetAddTrackMenu(); + } + + if ( isObject( %groupMenu ) ) + { + // Insert Menu. + %contextMenu.insertSubMenu( %contextMenu.AddIndex, getField( %contextMenu.Item[0], 0 ), %groupMenu ); + + // Enable. + %contextMenu.enableItem( %contextMenu.AddIndex, true ); + } + else + { + // Add Dummy. + %contextMenu.insertItem( %contextMenu.AddIndex, getField( %contextMenu.Item[0], 0 ) ); + + // Disable. + %contextMenu.enableItem( %contextMenu.AddIndex, false ); + } + + // Enable/Disable Pasting. + %contextMenu.enableItem( %contextMenu.PasteIndex, VerveEditor::CanPaste() ); + + // Display. + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); +} + +function VGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Track" TAB "" TAB "VerveEditor::AddTrack( \"VTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VTrack" ) ); + + // Return Menu. + return %contextMenu; +} + +//----------------------------------------------------------------------------- + +function VerveEditor::CreateGroupControl( %object ) +{ + %groupWidth = getWord( VerveEditorGroupStack.getExtent(), 0 ); + %groupHeight = 26; + %trackWidth = getWord( VerveEditorTrackStack.getExtent(), 0 ); + %trackHeight = %groupHeight; + + %groupContainer = new VEditorButton() + { + SuperClass = "VEditorSelectable"; + Class = "VEditorSelectableGroup"; + Profile = "VEditorGroupHeaderProfile"; + + Bitmap = "~/VerveEditor/GUI/Images/GroupBackground"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %groupWidth SPC %groupHeight; + + ButtonType = "ToggleButton"; + GroupNum = "-1"; + + IsContainer = "1"; + }; + VerveEditorGroupStack.add( %groupContainer ); + + %groupCheckbox = new GuiCheckBoxCtrl() + { + Class = "VEditorBoolPropertyField"; + InternalName = "Enabled"; + Profile = "VEditorCheckBoxProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 0"; + Extent = "14" SPC %groupHeight; + + Object = %object; + FieldName = "Enabled"; + Command = "$ThisControl.ApplyValue();"; + + Text = ""; + }; + %groupContainer.add( %groupCheckbox ); + + %trackContainer = new VEditorButton() + { + SuperClass = "VEditorSelectable"; + Class = "VEditorSelectableGroup"; + Profile = "VEditorGroupTrackProfile"; + + Bitmap = "~/VerveEditor/GUI/Images/GroupBackground"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %trackWidth SPC %trackHeight; + + ButtonType = "ToggleButton"; + GroupNum = "-1"; + + IsContainer = "1"; + }; + VerveEditorTrackStack.add( %trackContainer ); + + // Field Notify. + %object.AddFieldNotify( "Label", %groupContainer ); + %object.AddFieldNotify( "Enabled", %groupCheckbox ); + + // Reference Siblings. + %trackContainer.SiblingControl = %groupContainer; + %groupContainer.SiblingControl = %trackContainer; + + // Reference Proxy. + %groupContainer.Proxy = %object; + %trackContainer.Proxy = %object; + + // Reference Control. + %object.Control = %groupContainer; + + return %trackContainer; +} + +function VEditorSelectableGroup::Update( %this, %fieldName, %fieldValue ) +{ + %this.setText( %fieldValue ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VLightObjectGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VLightObjectGroup.cs new file mode 100644 index 000000000..0a674a33c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VLightObjectGroup.cs @@ -0,0 +1,120 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VLightObjectGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VSceneObjectGroupPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VLightObjectGroup::PopulateBuildStack( %this, %stack ) +{ + // Ignore Parent Fields. + //Parent::PopulateBuildStack( %this, %stack ); + + // Object Reference. + %lightObjectList = %stack.CreateObjectList( VTorque::getLightObjectClass(), "LightObjectList", "Light Object:" ); + + if ( VTorque::GetSelectedCount() ) + { + %selection = VTorque::GetSelectedObject(); + if ( %selection.getName() !$= "" && VTorque::isLightObject( %selection ) ) + { + // Select Object. + %lightObjectList.setText( %selection.getName() ); + } + } + + // Create Toggle Track Checkbox. + %toggleTrackCheckBox = %stack.CreateCheckbox( "ToggleTrackToggle", "Add Toggle Track:" ); + %toggleTrackCheckBox.setStateOn( true ); +} + +function VLightObjectGroup::ResolveBuildStack( %this, %stack ) +{ + // Ignore Parent Fields. + //Parent::ResolveBuildStack( %this, %stack, %groupObject ); + + // Fetch the Controller. + %controller = %this.getRoot(); + + // Find the Particle Effect List. + %lightObjectList = %stack.findObjectByInternalName( "LightObjectList", true ); + if ( isObject( %lightObjectList ) ) + { + // Fetch Selected Object. + %lightObject = %lightObjectList.getText(); + + // Data Field Name. + %dataFieldName = strreplace( %this.Label, " ", "_" ); + + // Create a New Data Field. + %controller.addDataField( "STATIC", %dataFieldName ); + + if ( %lightObject !$= "" ) + { + // Set the Field Value. + %controller.setFieldValue( %dataFieldName, %lightObject ); + } + + // Reference the Data Field. + %this.Reference = %dataFieldName; + } + + // Find the Track Toggle. + %toggleTrackCheckBox = %stack.findObjectByInternalName( "ToggleTrackToggle", true ); + if ( %toggleTrackCheckBox.getValue() ) + { + // Create the Toggle Track. + %toggleTrackCheckBox = VerveEditor::AddTrack( "VLightObjectToggleTrack", %this, false ); + } +} + +//----------------------------------------------------------------------------- + +function VLightObjectGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VLightObjectGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Animation Track" TAB "" TAB "VerveEditor::AddTrack( \"VLightObjectAnimationTrack\" );"; + Item[1] = "Add Motion Track" TAB "" TAB "VerveEditor::AddTrack( \"VMotionTrack\" );"; + Item[2] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[3] = "Add Sound Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VSoundEffectTrack\" );"; + Item[4] = "Add Toggle Track" TAB "" TAB "VerveEditor::AddTrack( \"VLightObjectToggleTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VLightObjectAnimationTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VMotionTrack" ) ); + %contextMenu.enableItem( 2, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 3, %this.CanAdd( "VSoundEffectTrack" ) ); + %contextMenu.enableItem( 4, %this.CanAdd( "VLightObjectToggleTrack" ) ); + + // Return Menu. + return %contextMenu; +} + +function VLightObjectGroup::isValid( %this ) +{ + // Valid? + return VTorque::isLightObject( %this.getSceneObject() ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VParticleEffectGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VParticleEffectGroup.cs new file mode 100644 index 000000000..f30cca71e --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VParticleEffectGroup.cs @@ -0,0 +1,118 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VParticleEffectGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VSceneObjectGroupPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VParticleEffectGroup::PopulateBuildStack( %this, %stack ) +{ + // Ignore Parent Fields. + //Parent::PopulateBuildStack( %this, %stack ); + + // Object Reference. + %particleEffectList = %stack.CreateObjectList( VTorque::getParticleEffectClass(), "ParticleEffectList", "Particle Effect:" ); + + if ( VTorque::GetSelectedCount() ) + { + %selection = VTorque::GetSelectedObject(); + if ( %selection.getName() !$= "" && VTorque::isParticleEffect( %selection ) ) + { + // Select Object. + %particleEffectList.setText( %selection.getName() ); + } + } + + // Create Toggle Track Checkbox. + %toggleTrackCheckBox = %stack.CreateCheckbox( "ToggleTrackToggle", "Add Toggle Track:" ); + %toggleTrackCheckBox.setStateOn( true ); +} + +function VParticleEffectGroup::ResolveBuildStack( %this, %stack ) +{ + // Ignore Parent Fields. + //Parent::ResolveBuildStack( %this, %stack, %groupObject ); + + // Fetch the Controller. + %controller = %this.getRoot(); + + // Find the Particle Effect List. + %particleEffectList = %stack.findObjectByInternalName( "ParticleEffectList", true ); + if ( isObject( %particleEffectList ) ) + { + // Fetch Selected Object. + %particlEffect = %particleEffectList.getText(); + + // Data Field Name. + %dataFieldName = strreplace( %this.Label, " ", "_" ); + + // Create a New Data Field. + %controller.addDataField( "STATIC", %dataFieldName ); + + if ( %particlEffect !$= "" ) + { + // Set the Field Value. + %controller.setFieldValue( %dataFieldName, %particlEffect ); + } + + // Reference the Data Field. + %this.Reference = %dataFieldName; + } + + // Find the Track Toggle. + %toggleTrackCheckBox = %stack.findObjectByInternalName( "ToggleTrackToggle", true ); + if ( %toggleTrackCheckBox.getValue() ) + { + // Create the Toggle Track. + %toggleTrackCheckBox = VerveEditor::AddTrack( "VParticleEffectToggleTrack", %this, false ); + } +} + +//----------------------------------------------------------------------------- + +function VParticleEffectGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VParticleEffectGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Motion Track" TAB "" TAB "VerveEditor::AddTrack( \"VMotionTrack\" );"; + Item[1] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[2] = "Add Sound Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VSoundEffectTrack\" );"; + Item[3] = "Add Toggle Track" TAB "" TAB "VerveEditor::AddTrack( \"VParticleEffectToggleTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VMotionTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 2, %this.CanAdd( "VSoundEffectTrack" ) ); + %contextMenu.enableItem( 3, %this.CanAdd( "VParticleEffectToggleTrack" ) ); + + // Return Menu. + return %contextMenu; +} + +function VParticleEffectGroup::isValid( %this ) +{ + // Valid? + return VTorque::isParticleEffect( %this.getSceneObject() ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSceneObjectGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSceneObjectGroup.cs new file mode 100644 index 000000000..7483ea209 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSceneObjectGroup.cs @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSceneObjectGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VGroupPropertyList"; + + Group[0] = "VGroup"; + Field[0, 0] = "Reference"; + Type[0, 0] = "VControllerDataEnum"; +}; + +//----------------------------------------------------------------------------- + +function VSceneObjectGroup::OnSelect( %this ) +{ + if ( !%this.isValid() ) + { + // Invalid Object. + return; + } + + // Update Selection. + VTorque::SetSelectedObject( %this.getSceneObject() ); +} + +function VSceneObjectGroup::isValid( %this ) +{ + // Valid? + return VTorque::isSceneObject( %this.getSceneObject() ); +} + +//----------------------------------------------------------------------------- + +function VSceneObjectGroup::PopulateBuildStack( %this, %stack ) +{ + Parent::PopulateBuildStack( %this, %stack ); + + // Object Reference. + %sceneObjectList = %stack.CreateObjectList( "SceneObject", "SceneObjectList", "Scene Object:" ); + + if ( VTorque::GetSelectedCount() ) + { + %selection = VTorque::GetSelectedObject(); + if ( %selection.getName() !$= "" && %selection.isMemberOfClass( "SceneObject" ) ) + { + // Select Object. + %sceneObjectList.setText( %selection.getName() ); + } + } + + // Create Motion Track Checkbox. + %motionTrackCheckBox = %stack.CreateCheckbox( "MotionTrackToggle", "Add Motion Track:" ); + %motionTrackCheckBox.setStateOn( true ); + + // Object Reference. + %pathObjectList = %stack.CreateObjectList( "VPath", "PathObjectList", "Path Object:" ); +} + +function VSceneObjectGroup::ResolveBuildStack( %this, %stack ) +{ + Parent::ResolveBuildStack( %this, %stack, %groupObject ); + + // Fetch the Controller. + %controller = %this.getRoot(); + + // Find the Scene Object List. + %sceneObjectList = %stack.findObjectByInternalName( "SceneObjectList", true ); + if ( isObject( %sceneObjectList ) ) + { + // Fetch Selected Object. + %sceneObject = %sceneObjectList.getText(); + + // Data Field Name. + %dataFieldName = strreplace( %this.Label, " ", "_" ); + + // Create a New Data Field. + %controller.addDataField( "STATIC", %dataFieldName ); + + if ( %sceneObject !$= "" ) + { + // Set the Field Value. + %controller.setFieldValue( %dataFieldName, %sceneObject ); + } + + // Reference the Data Field. + %this.Reference = %dataFieldName; + } + + // Find the Path Toggle. + %motionTrackCheckBox = %stack.findObjectByInternalName( "MotionTrackToggle", true ); + if ( %motionTrackCheckBox.getValue() ) + { + // Create the Motion Track. + %motionTrack = VerveEditor::AddTrack( "VMotionTrack", %this, false ); + + %pathObjectList = %stack.findObjectByInternalName( "PathObjectList", true ); + if ( isObject( %pathObjectList ) ) + { + // Fetch Selected Object. + %pathObject = %pathObjectList.getText(); + + // Data Field Name. + %dataFieldName = strreplace( %this.Label @ "Path", " ", "_" ); + + // Create a New Data Field. + %controller.addDataField( "STATIC", %dataFieldName ); + + if ( %pathObject !$= "" ) + { + // Set the Field Value. + %controller.setFieldValue( %dataFieldName, %pathObject ); + } + + // Reference the Data Field. + %motionTrack.Reference = %dataFieldName; + } + } +} + +//----------------------------------------------------------------------------- + +function VSceneObjectGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VSceneObjectGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Animation Track" TAB "" TAB "VerveEditor::AddTrack( \"VShapeAnimationTrack\" );"; + Item[1] = "Add Motion Track" TAB "" TAB "VerveEditor::AddTrack( \"VMotionTrack\" );"; + Item[2] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[3] = "Add Sound Effect Track" TAB "" TAB "VerveEditor::AddTrack( \"VSoundEffectTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VShapeAnimationTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VMotionTrack" ) ); + %contextMenu.enableItem( 2, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 3, %this.CanAdd( "VSoundEffectTrack" ) ); + + // Return Menu. + return %contextMenu; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSpawnSphereGroup.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSpawnSphereGroup.cs new file mode 100644 index 000000000..cd2913ad9 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/VSpawnSphereGroup.cs @@ -0,0 +1,100 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSpawnSphereGroupPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VSceneObjectGroupPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VSceneObjectGroup::PopulateBuildStack( %this, %stack ) +{ + VGroup::PopulateBuildStack( %this, %stack ); + + // Object Reference. + %sceneObjectList = %stack.CreateObjectList( "SceneObject", "SceneObjectList", "Scene Object:" ); + + if ( VTorque::GetSelectedCount() ) + { + %selection = VTorque::GetSelectedObject(); + if ( %selection.getName() !$= "" && %selection.isMemberOfClass( "SceneObject" ) ) + { + // Select Object. + %sceneObjectList.setText( %selection.getName() ); + } + } +} + +function VSceneObjectGroup::ResolveBuildStack( %this, %stack ) +{ + VGroup::ResolveBuildStack( %this, %stack, %groupObject ); + + // Fetch the Controller. + %controller = %this.getRoot(); + + // Find the Scene Object List. + %sceneObjectList = %stack.findObjectByInternalName( "SceneObjectList", true ); + if ( isObject( %sceneObjectList ) ) + { + // Fetch Selected Object. + %sceneObject = %sceneObjectList.getText(); + + // Data Field Name. + %dataFieldName = strreplace( %this.Label, " ", "_" ); + + // Create a New Data Field. + %controller.addDataField( "STATIC", %dataFieldName ); + + if ( %sceneObject !$= "" ) + { + // Set the Field Value. + %controller.setFieldValue( %dataFieldName, %sceneObject ); + } + + // Reference the Data Field. + %this.Reference = %dataFieldName; + } +} + +//----------------------------------------------------------------------------- + +function VSpawnSphereGroup::GetAddTrackMenu( %this ) +{ + %contextMenu = $VerveEditor::VGroup::ContextMenu[%this.getClassName()]; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VSpawnSphereGroupAddTrackMenu"; + Position = 0; + + Item[0] = "Add Script Event Track" TAB "" TAB "VerveEditor::AddTrack( \"VScriptEventTrack\" );"; + Item[1] = "Add Spawn Target Track" TAB "" TAB "VerveEditor::AddTrack( \"VSpawnSphereSpawnTargetTrack\" );"; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VGroup::ContextMenu[%this.getClassName()] = %contextMenu; + } + + // Enable/Disable Adding Tracks. + %contextMenu.enableItem( 0, %this.CanAdd( "VScriptEventTrack" ) ); + %contextMenu.enableItem( 1, %this.CanAdd( "VSpawnSphereSpawnTargetTrack" ) ); + + // Return Menu. + return %contextMenu; +} + +function VSpawnSphereGroup::isValid( %this ) +{ + // Valid? + return VTorque::isSpawnSphereObject( %this.getSceneObject() ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/main.cs new file mode 100644 index 000000000..e8cac3c10 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Groups/main.cs @@ -0,0 +1,25 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitGroupScripts() +{ + // Core. + exec( "./VGroup.cs" ); + + // Built In. + exec( "./VCameraGroup.cs" ); + exec( "./VDirectorGroup.cs" ); + exec( "./VLightObjectGroup.cs" ); + exec( "./VParticleEffectGroup.cs" ); + exec( "./VSceneObjectGroup.cs" ); + exec( "./VSpawnSphereGroup.cs" ); + + // Custom. + // Exec Custom Group Scripts. + + // Unique Group List. + $VerveEditor::UniqueGroupList = "VDirectorGroup"; +} +VerveEditor::InitGroupScripts(); diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Controls.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Controls.cs new file mode 100644 index 000000000..b2b64f858 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Controls.cs @@ -0,0 +1,163 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditorPropertyStack::ClearStack( %this ) +{ + while ( %this.getCount() > 0 ) + { + // Remove Object. + %this.remove( %this.getObject( 0 ) ); + } +} + +function VerveEditorPropertyStack::CreatePropertyRollout( %this, %groupLabel ) +{ + %groupWidth = getWord( %this.getExtent(), 0 ); + %groupHeight = 32; + + %propertyRollout = new GuiRolloutCtrl() + { + Class = "VEditorPropertyRollout"; + Profile = "VEditorPropertyRolloutProfile"; + + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %groupWidth SPC 18; + + Caption = %groupLabel; + }; + + %propertyStack = new GuiStackControl() + { + Class = "VEditorPropertyStack"; + Profile = "GuiTransparentProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %groupWidth SPC %groupHeight; + + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + }; + %propertyRollout.add( %propertyStack ); + + // Add Spacer. + VerveEditor::CreateSpacer( %propertyStack, 4 ); + + // Reference Stack. + %propertyRollout.Stack = %propertyStack; + + return %propertyRollout; +} + +function VEditorPropertyRollout::InspectObject( %this, %object ) +{ + %this.Stack.InspectObject( %object ); +} + +function VEditorPropertyStack::InspectObject( %this, %object ) +{ + %fieldCount = %this.getCount(); + for ( %i = 1; %i < %fieldCount; %i++ ) + { + %fieldContainer = %this.getObject( %i ); + %fieldControl = %fieldContainer.findObjectByInternalName( "FieldControl" ); + if ( !isObject( %fieldControl ) ) + { + // Nothing to Update. + continue; + } + + // Store Object. + %fieldControl.Object = %object; + + // Get Values. + %fieldName = %fieldControl.FieldName; + %fieldValue = %object.getFieldValue( %fieldName ); + + // Update Control? + if ( %fieldControl.isMethod( "Update" ) ) + { + // Update. + %fieldControl.Update( %fieldName, %fieldValue ); + } + } +} + +function VerveEditor::CreateField( %targetStack, %fieldName, %fieldType ) +{ + %fieldWidth = getWord( %targetStack.getExtent(), 0 ); + %fieldHeight = 20; + + %fieldContainer = new GuiControl() + { + Profile = "VEditorTransparentProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %fieldWidth SPC %fieldHeight; + }; + %targetStack.add( %fieldContainer ); + + %fieldLabel = new GuiTextCtrl() + { + Profile = "VEditorTextProfile"; + + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 2"; + Extent = %fieldWidth SPC 18; + + Text = %fieldName; + MaxLength = "1024"; + }; + %fieldContainer.add( %fieldLabel ); + + if ( isMethod( "VerveEditor", "Create" @ %fieldType @ "Field" ) ) + { + // Create the Input Control. + eval( "%fieldInput = VerveEditor::Create" @ %fieldType @ "Field( %fieldContainer, %fieldName );" ); + } + else + { + // Default To String Control. + %fieldInput = VerveEditor::CreateStringField( %fieldContainer, %fieldName ); + } + + return %fieldContainer; +} + +function VEditorPropertyField::ApplyValue( %this, %fieldName, %fieldValue ) +{ + // Apply Value. + %this.Object.setFieldValue( %fieldName, %fieldValue ); + + // Update Control. + %this.Update( %fieldName, %this.Object.getFieldValue( %fieldName ) ); +} + +function VerveEditor::CreateSpacer( %targetStack, %spacerHeight ) +{ + %fieldWidth = getWord( %targetStack.getExtent(), 0 ); + %fieldHeight = %spacerHeight; + + %fieldContainer = new GuiControl() + { + Profile = "VEditorTransparentProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %fieldWidth SPC %fieldHeight; + }; + %targetStack.add( %fieldContainer ); + + return %fieldContainer; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/CutCopyPaste.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/CutCopyPaste.cs new file mode 100644 index 000000000..c88fdbf21 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/CutCopyPaste.cs @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CanCut() +{ + return VerveEditor::CanCopy(); +} + +function VerveEditor::CutSelection() +{ + if ( !isObject( $VerveEditor::Controller ) || !VerveEditor::HasSelection() ) + { + return; + } + + %targetObject = $VerveEditor::InspectorObject; + if ( isObject( %targetObject ) ) + { + // Write To File. + %targetObject.writeFile( $VerveEditor::TemplateVClipboard ); + + // Store Object Type. + $VerveEditor::TemplateVClipboardObject = %targetObject; + + // Delete Object. + %targetObject.Delete(); + + // Refresh Editor. + VerveEditor::Refresh(); + } +} + +function VerveEditor::CanCopy() +{ + if ( VerveEditor::HasSelection() ) + { + if ( $VerveEditor::InspectorObject == $VerveEditor::Controller ) + { + return false; + } + } + + if ( $VerveEditor::InspectorObject.isMethod( "CanCopy" ) ) + { + if ( !$VerveEditor::InspectorObject.CanCopy() ) + { + return false; + } + } + + return ActiveActionMapSet.isMember( VerveEditorEditMap ); +} + +function VerveEditor::CopySelection() +{ + if ( !isObject( $VerveEditor::Controller ) || !VerveEditor::CanCopy() ) + { + return; + } + + %targetObject = $VerveEditor::InspectorObject; + if ( isObject( %targetObject ) ) + { + // Write To File. + %targetObject.writeFile( $VerveEditor::TemplateVClipboard ); + + // Reference Object. + $VerveEditor::TemplateVClipboardObject = %targetObject; + } +} + +function VerveEditor::CanPaste() +{ + if ( !VerveEditor::HasSelection() || !isFile( $VerveEditor::TemplateVClipboard ) ) + { + return false; + } + + return $VerveEditor::InspectorObject.CanPaste( $VerveEditor::TemplateVClipboardObject ); +} + +function VerveEditor::Paste() +{ + if ( !isObject( $VerveEditor::Controller ) || !VerveEditor::CanPaste() ) + { + return; + } + + if ( $VerveEditor::InspectorObject.getId() == $VerveEditor::Controller.getId() ) + { + // Special Paste. + VerveEditor::AddTemplateGroup( $VerveEditor::TemplateVClipboard ); + + return; + } + + if ( isObject( $VerveEditor::InspectorObject ) ) + { + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + // Read From File. + $VerveEditor::InspectorObject.readFile( $VerveEditor::TemplateVClipboard ); + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + // Refresh Editor. + VerveEditor::Refresh(); + } +} + +function VerveEditor::DeleteSelection() +{ + if ( !isObject( $VerveEditor::Controller ) || !VerveEditor::HasSelection() ) + { + return; + } + + %selectionSet = $VerveEditor::SelectionSet; + while ( %selectionSet.getCount() > 0 ) + { + %selection = %selectionSet.getObject( 0 ); + + if ( isObject( %selection.SiblingControl ) ) + { + // Delete Sibling Control. + %selection.SiblingControl.delete(); + } + + if ( isObject( %selection.Proxy ) ) + { + // Do Callback? + if ( %selection.Proxy.isMethod( "onRemove" ) ) + { + // Quick Callback. + %selection.Proxy.onRemove(); + } + + // Delete Reference Object. + %selection.Proxy.delete(); + } + + // Delete Control. + %selection.delete(); + } + + // Refresh. + VerveEditor::Refresh(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/EventNotify.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/EventNotify.cs new file mode 100644 index 000000000..fdfb5276e --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/EventNotify.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::GetEventManager() +{ + if ( !isObject( $VerveEditor::EventManager ) ) + { + $VerveEditor::EventManager = new EventManager() + { + Queue = "ProjectEventManager"; + }; + } + + return $VerveEditor::EventManager; +} + +function VerveEditor::RegisterEvent( %eventName ) +{ + if ( !VerveEditor::GetEventManager().isRegisteredEvent( %eventName ) ) + { + // Register Event. + VerveEditor::GetEventManager().RegisterEvent( %eventName ); + } +} + +function VerveEditor::AddEventNotify( %object, %eventName, %callback ) +{ + if ( isObject( $VerveEditor::EventManager ) ) + { + // Subscribe To Event. + $VerveEditor::EventManager.SubScribe( %object, %eventName, %callback ); + } +} + +function VerveEditor::RemoveEventNotify( %object, %eventName ) +{ + if ( isObject( $VerveEditor::EventManager ) ) + { + // Remove Event. + $VerveEditor::EventManager.Remove( %object, %eventName ); + } +} + +function VerveEditor::PostEvent( %eventName, %refObject ) +{ + if ( isObject( $VerveEditor::EventManager ) ) + { + // Notify Event. + $VerveEditor::EventManager.PostEvent( %eventName, %refObject ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Factory.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Factory.cs new file mode 100644 index 000000000..d96b10330 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Factory.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::AddGroup( %groupType ) +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + // No Controller. + return; + } + + if ( %groupType $= "" ) + { + // Default. + %groupType = "VGroup"; + } + + /* + // Add Template Group. + VerveEditor::AddTemplateGroup( $VerveEditor::TemplateFolder @ "/" @ %groupType @ ".vsf" ); + */ + + // Get the Name of the Target Group. + VerveEditorGroupBuilderGUI.Build( %groupType, "VerveEditor::_AddGroup" ); +} + +function VerveEditor::_AddGroup( %groupType, %groupLabel ) +{ + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + // Create the Group. + %groupObject = new ( %groupType )(); + + // Add to Group. + $VerveEditor::Controller.addObject( %groupObject ); + + // Apply the Label. + %groupObject.setLabelUnique( %groupLabel ); + + // Callback. + if ( !%groupObject.OnAdd() ) + { + // Remove Object. + $VerveEditor::Controller.removeObject( %groupObject ); + + // Delete Object. + %groupObject.delete(); + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + return; + } + + // Resolve the Field Stack. + %groupObject.ResolveBuildStack( VerveEditorGroupBuilderFieldStack ); + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + // Refresh Editor. + VerveEditor::Refresh(); + + // Set Selection. + VerveEditor::SetSelection( %groupObject.Control ); +} + +function VerveEditor::AddTemplateGroup( %templateFile ) +{ + if ( !isObject( $VerveEditor::Controller ) || !isFile( %templateFile ) ) + { + // No Controller. + return; + } + + // Fetch Current Count. + %groupCount = $VerveEditor::Controller.getCount(); + + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + // Load Template. + $VerveEditor::Controller.readTemplate( %templateFile ); + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + %newCount = $VerveEditor::Controller.getCount(); + if ( %groupCount != %newCount ) + { + if ( %newCount > %groupCount ) + { + // Select New Object. + %selectedObject = $VerveEditor::Controller.getObject( %newCount - 1 ); + } + + // Refresh Editor. + VerveEditor::Refresh(); + + if ( isObject( %selectedObject ) ) + { + // Set Selection. + VerveEditor::SetSelection( %selectedObject.Control ); + } + } +} + +function VerveEditor::AddTrack( %trackType, %targetGroup, %refresh ) +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + // No Controller. + return; + } + + if ( !isObject( %targetGroup ) ) + { + if ( !isObject( $VerveEditor::InspectorObject ) ) + { + // No Controller or Selection. + return; + } + + // Use Current Selection. + %targetGroup = $VerveEditor::InspectorObject; + } + + if ( !%targetGroup.isMemberOfClass( "VGroup" ) ) + { + // Invalid Target. + return; + } + + if ( %trackType $= "" ) + { + // Default. + %trackType = "VTrack"; + } + + // Create Track. + %trackObject = new ( %trackType )(); + + // Add to Group. + %targetGroup.addObject( %trackObject ); + + // Refresh Label. + %trackObject.setLabelUnique( %trackObject.Label ); + + // Callback. + if ( !%trackObject.OnAdd() ) + { + // Remove Object. + %targetGroup.removeObject( %trackObject ); + + // Delete Object. + %trackObject.delete(); + + // Return. + return 0; + } + + if ( %refresh $= "" || %refresh == true ) + { + // Refresh. + VerveEditor::Refresh(); + + // Select New Object. + VerveEditor::SetSelection( %trackObject.Control ); + } + + // Return Track. + return %trackObject; +} + +function VerveEditor::AddEvent( %targetTrack, %targetTime, %refresh ) +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + // No Controller. + return; + } + + if ( !isObject( %targetTrack ) ) + { + if ( !isObject( $VerveEditor::InspectorObject ) ) + { + // No Controller or Selection. + return; + } + + // Use Current Selection. + %targetTrack = $VerveEditor::InspectorObject; + } + + if ( !%targetTrack.isMemberOfClass( "VTrack" ) ) + { + // Invalid Target. + return; + } + + // Create Event. + %eventObject = %targetTrack.CreateEvent(); + if ( !isObject( %eventObject ) ) + { + // Return. + return; + } + + // Add to Track. + %targetTrack.addObject( %eventObject ); + + if ( %targetTime $= "" ) + { + // User Controller Time. + %targetTime = $VerveEditor::Controller.Time; + } + + // Apply Time. + %eventObject.SnapToTime( %targetTime, true ); + + // Callback. + if ( !%eventObject.OnAdd() ) + { + // Remove Object. + %targetTrack.removeObject( %eventObject ); + + // Delete Object. + %eventObject.delete(); + + // Return. + return 0; + } + + if ( %refresh $= "" || %refresh == true ) + { + // Refresh. + VerveEditor::Refresh(); + + // Select Existing Track. + VerveEditor::SetSelection( %targetTrack.Control ); + } + + // Return Event. + return %eventObject; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FactoryControls.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FactoryControls.cs new file mode 100644 index 000000000..4a6893494 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FactoryControls.cs @@ -0,0 +1,115 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +$VerveEditor::TemplateFolder = getMainDotCsDir() @ "/" @ expandFileName( "tools/VerveEditor/Templates" ); +$VerveEditor::TemplateCustomFolder = $VerveEditor::TemplateFolder @ "/Custom"; +$VerveEditor::TemplateVClipboard = $VerveEditor::TemplateFolder @ "/VClipboard.vsf"; +$VerveEditor::TemplateVClipboardObject = ""; + +//----------------------------------------------------------------------------- + +function VerveCustomTemplateMenu::Init( %this ) +{ + %fieldCount = 0; + %fileSpec = $VerveEditor::TemplateCustomFolder @ "/*.vsf"; + for ( %file = findFirstFile( %fileSpec ); %file !$= ""; %file = findNextFile( %fileSpec ) ) + { + // Create Item. + %this.Item[%fieldCount] = "Add" SPC fileBase( %file ) TAB "" TAB "VerveEditor::AddTemplateGroup(\"" @ %file @ "\");"; + + // Increment. + %fieldCount += 1; + } + + // Sort By File Name. + for ( %j = 0; %j < %fieldCount; %j++ ) + { + for ( %i = %fieldCount - 1; %i > %j; %i-- ) + { + %itemA = getField( %this.Item[%i - 0], 0 ); + %itemB = getField( %this.Item[%i - 1], 0 ); + + if ( strcmp( strlwr( %itemA ), strlwr( %itemB ) ) < 0 ) + { + // Swap. + %itemTmp = %this.Item[%i]; + %this.Item[%i - 0] = %this.Item[%i - 1]; + %this.Item[%i - 1] = %itemTmp; + } + } + } + + // Parent Init. + Parent::Init( %this ); +} + +function VEditorAddGroupButton::DisplayContextMenu( %this, %x, %y ) +{ + // Use Current Controller. + %targetController = $VerveEditor::Controller; + + // Get Context Menu. + %contextMenu = %targetController.GetAddGroupMenu(); + if ( !isObject( %contextMenu ) ) + { + return; + } + + if ( %x $= "" || %y $= "" ) + { + %position = %this.getGlobalPosition(); + %extent = %this.getExtent(); + + %x = getWord( %position, 0 ) + getWord( %extent, 0 ); + %y = getWord( %position, 1 ); + } + + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); +} + +function VEditorAddTrackButton::DisplayContextMenu( %this, %x, %y ) +{ + if ( !isObject( $VerveEditor::InspectorObject ) ) + { + // No Controller or Selection. + return; + } + + // Use Current Selection. + %targetGroup = $VerveEditor::InspectorObject; + + if ( !%targetGroup.isMemberOfClass( "VGroup" ) ) + { + // Invalid Target. + return; + } + + // Get Context Menu. + %contextMenu = %targetGroup.GetAddTrackMenu(); + if ( !isObject( %contextMenu ) ) + { + return; + } + + if ( %x $= "" || %y $= "" ) + { + %position = %this.getGlobalPosition(); + %extent = %this.getExtent(); + + %x = getWord( %position, 0 ) + getWord( %extent, 0 ); + %y = getWord( %position, 1 ); + } + + // Display. + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FieldNotify.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FieldNotify.cs new file mode 100644 index 000000000..5e87678ec --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/FieldNotify.cs @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::AddInspectorFieldNotify( %fieldName, %refObject ) +{ + if ( !isObject( $VerveEditor::InspectorFieldNotifySet ) ) + { + $VerveEditor::InspectorFieldNotifySet = new SimSet(); + } + + %inspectorSet = $VerveEditor::InspectorFieldNotifySet; + if ( isObject( %refObject ) && !%inspectorSet.isMember( %refObject ) ) + { + // Add The Object. + %inspectorSet.add( %refObject ); + } + + // Add Field Reference. + %refObject.InspectorFieldNotifyList = rtrim( %fieldName SPC %refObject.InspectorFieldNotifyList ); +} + +function VObject::AddFieldNotify( %this, %fieldName, %refObject ) +{ + if ( isObject( %refObject ) ) + { + // Store. + %this.FieldNotify[%fieldName] = trim( %this.FieldNotify[%fieldName] SPC %refObject ); + + // Update. + %refObject.Update( %fieldName, %this.getFieldValue( %fieldName ) ); + } +} + +function VObject::setFieldValue( %this, %fieldName, %fieldValue ) +{ + // Fetch Old Value. + %oldValue = %this.getFieldValue( %fieldName ); + + if ( stricmp( %oldValue , %fieldValue ) == 0 ) + { + // No Update. + return; + } + + // Update Value. + Parent::setFieldValue( %this, %fieldName, %fieldValue ); + + // Notify Change. + %this.NotifyFieldChange( %fieldName, %oldValue ); +} + +function VObject::NotifyFieldChange( %this, %fieldName, %oldValue ) +{ + // Get Field Value. + %newValue = %this.getFieldValue( %fieldName ); + + %controlList = %this.FieldNotify[%fieldName]; + %controlCount = getWordCount( %controlList ); + for ( %i = 0; %i < %controlCount; %i++ ) + { + // Fetch the Control. + %control = getWord( %controlList, %i ); + + if ( !isObject( %control ) ) + { + // Remove Deleted Controls. + %controlList = removeWord( %controlList, %i ); + %controlCount -= 1; + + %i -= 1; + continue; + } + + // Update. + %control.Update( %fieldName, %newValue ); + } + + // Updated List? + %this.FieldNotify[%fieldName] = %controlList; + + // Update Inspector Fields? + if ( isObject( $VerveEditor::InspectorObject ) && $VerveEditor::InspectorObject.getId() == %this.getId() ) + { + %refObjectSet = $VerveEditor::InspectorFieldNotifySet; + %refObjectCount = %refObjectSet.getCount(); + for ( %i = 0; %i < %controlCount; %i++ ) + { + // Fetch the Object. + %refObject = %refObjectSet.getObject( %i ); + if ( !isWordInList( %fieldName, %refObject.InspectorFieldNotifyList ) ) + { + // Skip. + continue; + } + + if ( %refObject.isMethod( "Update" ) ) + { + // Update. + %refObject.Update( %fieldName, %newValue ); + } + } + } + + // Update Object? + if ( %this.isMethod( "onFieldChange" ) ) + { + // Notify. + %this.onFieldChange( %fieldName, %oldValue, %newValue ); + } +} + +function VController::setFieldValue( %this, %fieldName, %fieldValue ) +{ + // Fetch Old Value. + %oldValue = %this.getFieldValue( %fieldName ); + + if ( stricmp( %oldValue , %fieldValue ) == 0 ) + { + // No Update. + return; + } + + // Update Value. + Parent::setFieldValue( %this, %fieldName, %fieldValue ); + + // Notify Change. + %this.NotifyFieldChange( %fieldName, %oldValue ); +} + +function VController::NotifyFieldChange( %this, %fieldName, %oldValue ) +{ + // Use Default Callback. + VObject::NotifyFieldChange( %this, %fieldName, %oldValue ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeBool.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeBool.cs new file mode 100644 index 000000000..d3fd3e04b --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeBool.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateBoolField( %fieldContainer, %fieldName ) +{ + %fieldWidth = getWord( %fieldContainer.getExtent(), 0 ); + + %fieldInput = new GuiCheckBoxCtrl() + { + Class = "VEditorBoolPropertyField"; + InternalName = "FieldControl"; + Profile = "VEditorCheckBoxProfile"; + + HorizSizing = "width"; + VertSizing = "center"; + Position = %fieldWidth - 156 SPC 0; + Extent = "150 18"; + + Text = ""; + + Command = "$ThisControl.ApplyValue();"; + + // Store Field Properties. + FieldName = %fieldName; + }; + %fieldContainer.add( %fieldInput ); + + // Field Notify. + VerveEditor::AddInspectorFieldNotify( %fieldName, %fieldInput ); + + return %fieldInput; +} + +function VEditorBoolPropertyField::ApplyValue( %this ) +{ + VEditorPropertyField::ApplyValue( %this, %this.FieldName, %this.getValue() ); +} + +function VEditorBoolPropertyField::Update( %this, %fieldName, %fieldValue ) +{ + if ( %this.getValue() !$= %fieldValue ) + { + %this.setValue( %fieldValue ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeData.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeData.cs new file mode 100644 index 000000000..93fe911fc --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeData.cs @@ -0,0 +1,336 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateDataField( %fieldContainer, %fieldName ) +{ + %fieldWidth = getWord( %fieldContainer.getExtent(), 0 ); + + %fieldType = new GuiPopUpMenuCtrl() + { + Class = "VEditorDataTypePropertyField"; + Profile = "VEditorPopupMenuProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 72 SPC 0; + Extent = 44 SPC 18; + + Command = "$ThisControl.ApplyValue();"; + + // Store Field Properties. + FieldName = %fieldName; + }; + %fieldContainer.add( %fieldType ); + + %fieldInput = new GuiTextEditCtrl() + { + Class = "VEditorDataPropertyField"; + SuperClass = "VEditorStringPropertyField"; + InternalName = "FieldControl"; + Profile = "VEditorTextEditProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 156 SPC 0; + Extent = 80 SPC 18; + + AltCommand = "$ThisControl.ApplyValue();"; + Validate = "$ThisControl.ApplyValue();"; + + // Store Field Properties. + FieldName = %fieldName; + FieldType = %fieldType; + }; + %fieldContainer.add( %fieldInput ); + + %fieldButton = new GuiBitmapButtonCtrl() + { + Class = "VEditorDataPropertyButton"; + InternalName = "FieldButton"; + Profile = "VEditorBitmapButtonProfile"; + + HorizSizing = "left"; + VertSizing = "bottom"; + Position = %fieldWidth - 24 SPC 0; + Extent = "18 18"; + + Bitmap = "tools/VerveEditor/GUI/Images/btn_DeleteSml"; + + Command = %fieldInput @ ".Remove();"; + }; + %fieldContainer.add( %fieldButton ); + + // Apply Enum Content. + %fieldType.add( "EXP", 0 ); + %fieldType.add( "STA", 1 ); + %fieldType.add( "VAR", 2 ); + + return %fieldInput; +} + +function VEditorDataPropertyField::Update( %this, %fieldName, %fieldValue ) +{ + // Fetch Object. + %controller = $VerveEditor::Controller; + if ( !isObject( %controller ) ) + { + // No Object! + return; + } + + if ( %fieldName $= "" ) + { + return; + } + + Parent::Update( %this, %fieldName, %fieldValue ); + + // Update Type. + %fieldType = %controller.getDataFieldType( %fieldName ); + switch$( %fieldType ) + { + case "EXPRESSION" : %fieldType = "EXP"; + case "STATIC" : %fieldType = "STA"; + case "VARIABLE" : %fieldType = "VAR"; + } + + // Apply. + %this.FieldType.setText( %fieldType ); +} + +function VEditorDataPropertyField::ApplyValue( %this ) +{ + // Fetch Object. + %controller = $VerveEditor::Controller; + if ( !isObject( %controller ) ) + { + // No Object! + return; + } + + // Update? + %update = stricmp( %controller.getFieldValue( %this.FieldName ), %this.getText() ); + + // Parent Update. + Parent::ApplyValue( %this ); + + if ( %update ) + { + // Post Event. + VerveEditor::PostEvent( "VGroupObjectUpdate", %controller ); + } +} + +function VEditorDataTypePropertyField::ApplyValue( %this ) +{ + // Fetch Object. + %controller = $VerveEditor::Controller; + if ( !isObject( %controller ) ) + { + // No Object! + return; + } + + // Update Type. + %fieldType = %this.getText(); + switch$( %fieldType ) + { + case "EXP" : %fieldType = "EXPRESSION"; + case "STA" : %fieldType = "STATIC"; + case "VAR" : %fieldType = "VARIABLE"; + } + + if ( %controller.getDataFieldType( %this.FieldName ) !$= %fieldType ) + { + // Apply. + %controller.addDataField( %fieldType, %this.FieldName ); + + // Post Event. + VerveEditor::PostEvent( "VGroupObjectUpdate", %controller ); + } +} + +//------------------------------------------------------------------------- + +function VEditorDataPropertyField::Insert( %fieldType, %fieldName, %fieldValue ) +{ + %controller = $VerveEditor::Controller; + if ( !isObject( %controller ) ) + { + // No Object! + return; + } + + if ( %fieldName $= "" ) + { + // Invalid Field Name. + return; + } + + switch$( %fieldType ) + { + case "EXP" : %fieldType = "EXPRESSION"; + case "STA" : %fieldType = "STATIC"; + case "VAR" : %fieldType = "VARIABLE"; + } + + // Add Data Field. + %controller.addDataField( %fieldType, strReplace( %fieldName, " ", "" ) ); + + // Apply Value. + %controller.setFieldValue( %fieldName, %fieldValue ); + + // Refresh Inspection. + schedule( 0, 0, "VerveEditor::OnSelectionUpdate" ); +} + +function VEditorDataPropertyField::Remove( %this ) +{ + %controller = $VerveEditor::Controller; + if ( !isObject( %controller ) ) + { + // No Object! + return; + } + + // Clear Data. + %controller.removeDataField( %this.FieldName ); + + // Refresh Inspection. + schedule( 0, 0, "VerveEditor::OnSelectionUpdate" ); +} + +//------------------------------------------------------------------------- + +function VerveEditor::CreateAddDataField( %targetStack ) +{ + %fieldWidth = getWord( %targetStack.getExtent(), 0 ); + %fieldHeight = 18; + + %fieldContainer = new GuiControl() + { + Profile = "VEditorTransparentProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %fieldWidth SPC %fieldHeight; + }; + %targetStack.add( %fieldContainer ); + + %fieldName = new GuiTextEditCtrl() + { + Class = "VEditorAddDataNameField"; + InternalName = "FieldControl"; + Profile = "VEditorTextEditProfile"; + + HorizSizing = "right"; + VertSizing = "center"; + Position = "6 0"; + Extent = "106" SPC 18; + + Text = "FieldName"; + }; + %fieldContainer.add( %fieldName ); + + %fieldValue = new GuiTextEditCtrl() + { + Class = "VEditorAddDataValueField"; + InternalName = "FieldValue"; + Profile = "VEditorTextEditProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 156 SPC 0; + Extent = 80 SPC 18; + + Text = "FieldValue"; + }; + %fieldContainer.add( %fieldValue ); + + %fieldType = new GuiPopUpMenuCtrl() + { + Class = "VEditorDataTypePropertyField"; + InternalName = "FieldType"; + Profile = "VEditorPopupMenuProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 72 SPC 0; + Extent = 44 SPC 18; + }; + %fieldContainer.add( %fieldType ); + + %fieldButton = new GuiBitmapButtonCtrl() + { + Class = "VEditorDataPropertyButton"; + InternalName = "FieldButton"; + Profile = "VEditorBitmapButtonProfile"; + + HorizSizing = "left"; + VertSizing = "bottom"; + Position = %fieldWidth - 24 SPC 0; + Extent = "18 18"; + + Bitmap = "tools/VerveEditor/GUI/Images/btn_AddSml"; + + Command = "VEditorDataPropertyField::Insert(" @ %fieldType @ ".getText(), " @ %fieldName @ ".getText(), " @ %fieldValue @ ".getText() );"; + }; + %fieldContainer.add( %fieldButton ); + + // Apply Enum Content. + %fieldType.add( "EXP", 0 ); + %fieldType.add( "STA", 1 ); + %fieldType.add( "VAR", 2 ); + + // Set Default. + %fieldType.setFirstSelected(); + + return %fieldContainer; +} + +function VEditorAddDataNameField::onGainFirstResponder( %this ) +{ + VEditorStringPropertyField::onGainFirstResponder( %this ); + + if ( %this.getText() $= "FieldName" ) + { + // Clear. + %this.setText( "" ); + } +} + +function VEditorAddDataNameField::onLoseFirstResponder( %this ) +{ + VEditorStringPropertyField::onLoseFirstResponder( %this ); + + if ( %this.getText() $= "" ) + { + // Clear. + %this.setText( "FieldName" ); + } +} + +function VEditorAddDataValueField::onGainFirstResponder( %this ) +{ + VEditorStringPropertyField::onGainFirstResponder( %this ); + + if ( %this.getText() $= "FieldValue" ) + { + // Clear. + %this.setText( "" ); + } +} + +function VEditorAddDataValueField::onLoseFirstResponder( %this ) +{ + VEditorStringPropertyField::onLoseFirstResponder( %this ); + + if ( %this.getText() $= "" ) + { + // Clear. + %this.setText( "FieldValue" ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeEnum.cs new file mode 100644 index 000000000..e83224d08 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeEnum.cs @@ -0,0 +1,94 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateEnumField( %fieldContainer, %fieldName, %class ) +{ + %fieldWidth = getWord( %fieldContainer.getExtent(), 0 ); + + %fieldInput = new GuiPopupMenuCtrl() + { + Class = %class; + SuperClass = "VEditorEnumPropertyField"; + InternalName = "FieldControl"; + Profile = "VEditorPopupMenuProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 156 SPC 0; + Extent = "150 18"; + + Command = "$ThisControl.ApplyValue();"; + + // Store Field Properties. + FieldName = %fieldName; + }; + %fieldContainer.add( %fieldInput ); + + // Field Notify. + VerveEditor::AddInspectorFieldNotify( %fieldName, %fieldInput ); + + return %fieldInput; +} + +function VEditorEnumPropertyField::ApplyValue( %this ) +{ + // Apply Value. + VEditorPropertyField::ApplyValue( %this, %this.FieldName, %this.getText() ); +} + +function VEditorEnumPropertyField::Update( %this, %fieldName, %fieldValue ) +{ + if ( %this.getText() !$= %fieldValue ) + { + // Apply Text. + %this.setText( %fieldValue ); + } +} + +function VEditorEnumPropertyField::PopulateFromDatablockGroup( %this, %className ) +{ + // Clear List. + %this.clear(); + + // Iterate Over Datablocks. + %dataSet = DataBlockGroup; + %dataCount = %dataSet.getCount(); + for ( %i = 0; %i < %dataCount; %i++ ) + { + // Fetch Item. + %dataObject = %dataSet.getObject( %i ); + if ( %dataObject.isMemberOfClass( %className ) ) + { + // Add Item. + %this.add( %dataObject.getName(), %i ); + } + } + + // Sort. + %this.sort(); +} + +function VEditorEnumPropertyField::PopulateFromRootGroup( %this, %className ) +{ + // Clear List. + %this.clear(); + + // Iterate Over RootGroup. + %dataSet = RootGroup; + %dataCount = %dataSet.getCount(); + for ( %i = 0; %i < %dataCount; %i++ ) + { + // Fetch Item. + %dataObject = %dataSet.getObject( %i ); + if ( %dataObject.isMemberOfClass( %className ) ) + { + // Add Item. + %this.add( %dataObject.getName(), %i ); + } + } + + // Sort. + %this.sort(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeString.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeString.cs new file mode 100644 index 000000000..17dc2d6f0 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeString.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateStringField( %fieldContainer, %fieldName ) +{ + %fieldWidth = getWord( %fieldContainer.getExtent(), 0 ); + + %fieldInput = new GuiTextEditCtrl() + { + Class = "VEditorStringPropertyField"; + InternalName = "FieldControl"; + Profile = "VEditorTextEditProfile"; + + HorizSizing = "left"; + VertSizing = "center"; + Position = %fieldWidth - 156 SPC 0; + Extent = "150 18"; + + AltCommand = "$ThisControl.ApplyValue();"; + Validate = "$ThisControl.ApplyValue();"; + + // Store Field Properties. + FieldName = %fieldName; + }; + %fieldContainer.add( %fieldInput ); + + // Field Notify. + VerveEditor::AddInspectorFieldNotify( %fieldName, %fieldInput ); + + return %fieldInput; +} + +function VEditorStringPropertyField::ApplyValue( %this ) +{ + VEditorPropertyField::ApplyValue( %this, %this.FieldName, %this.getText() ); +} + +function VEditorStringPropertyField::Update( %this, %fieldName, %fieldValue ) +{ + if ( %this.getText() !$= %fieldValue ) + { + %this.setText( %fieldValue ); + } +} + +function VEditorStringPropertyField::onGainFirstResponder( %this ) +{ + // Disable Cut, Copy & Paste. + VerveEditorEditMap.pop(); +} + +function VEditorStringPropertyField::onLoseFirstResponder( %this ) +{ + // Enable Cut, Copy & Paste. + VerveEditorEditMap.push(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeToggleEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeToggleEnum.cs new file mode 100644 index 000000000..1235cbaf1 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeToggleEnum.cs @@ -0,0 +1,16 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateToggleEnumField( %fieldContainer, %fieldName, %class ) +{ + // Create Enum Menu. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName ); + + // Populate Menu. + %fieldInput.add( "On", 0 ); + %fieldInput.add( "Off", 1 ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCameraGroupEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCameraGroupEnum.cs new file mode 100644 index 000000000..6c8cfae85 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCameraGroupEnum.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVCameraGroupEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + return VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVCameraGroupEnumPropertyField" ); +} + +function VEditorVCameraGroupEnumPropertyField::OnWake( %this ) +{ + // Clear List. + %this.clear(); + + // Iterate Over Groups. + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %group = %groupSet.getObject( %i ); + if ( %group.isMemberOfClass( "VCameraGroup" ) ) + { + // Add Item. + %this.add( %group.Label, %i ); + } + } + + // Sort. + %this.sort(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCommandEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCommandEnum.cs new file mode 100644 index 000000000..7b0a902ac --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVCommandEnum.cs @@ -0,0 +1,16 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVCommandEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVCommandEnumPropertyField" ); + + // Populate Menu. + %fieldInput.add( "EXPRESSION", 0 ); + %fieldInput.add( "METHOD", 1 ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVControllerDataEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVControllerDataEnum.cs new file mode 100644 index 000000000..1e2d68c27 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVControllerDataEnum.cs @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVControllerDataEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + return VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVControllerDataEnumPropertyField" ); +} + +function VEditorVControllerDataEnumPropertyField::OnWake( %this, %eventName ) +{ + // Clear List. + %this.clear(); + + // Iterate Over Data Items. + %dataObject = $VerveEditor::Controller; + %dataFieldCount = %dataObject.getDataFieldCount(); + for ( %i = 0; %i < %dataFieldCount; %i++ ) + { + // Add Field Name. + %this.add( %dataObject.getDataFieldName( %i ), %i ); + } + + // Sort. + %this.sort(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVGroupEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVGroupEnum.cs new file mode 100644 index 000000000..810bd08c0 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVGroupEnum.cs @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVGroupEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + return VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVGroupEnumPropertyField" ); +} + +function VEditorVGroupEnumPropertyField::OnWake( %this ) +{ + // Clear List. + %this.clear(); + + // Iterate Over Groups. + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + // Add Item. + %this.add( %groupSet.getObject( %i ).Label, %i ); + } + + // Sort. + %this.sort(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVLightAnimationDataEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVLightAnimationDataEnum.cs new file mode 100644 index 000000000..6b390ebfb --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVLightAnimationDataEnum.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVLightAnimationDataEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum List. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName ); + + // Populate Enum. + %fieldInput.PopulateFromDatablockGroup( "LightAnimData" ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPathOrientationModeEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPathOrientationModeEnum.cs new file mode 100644 index 000000000..a9f85353c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPathOrientationModeEnum.cs @@ -0,0 +1,19 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVPathOrientationModeEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVPathOrientationModeEnumPropertyField" ); + + // Populate Menu. + %fieldInput.add( "FREE", 0 ); + %fieldInput.add( "INTERPOLATE", 1 ); + %fieldInput.add( "TOOBJECT", 2 ); + %fieldInput.add( "TOPATH", 3 ); + %fieldInput.add( "TOPOINT", 4 ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPostEffectEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPostEffectEnum.cs new file mode 100644 index 000000000..60f951257 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVPostEffectEnum.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVPostEffectEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum List. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName ); + + // Populate Enum. + %fieldInput.PopulateFromRootGroup( "PostEffect" ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSFXProfileEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSFXProfileEnum.cs new file mode 100644 index 000000000..ecbd1fcdb --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSFXProfileEnum.cs @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVSFXProfileEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum List. + %fieldInput = VerveEditor::CreateEnumField( %fieldContainer, %fieldName ); + + // Populate Enum. + %fieldInput.PopulateFromDatablockGroup( "SFXProfile" ); + + return %fieldInput; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSceneEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSceneEnum.cs new file mode 100644 index 000000000..d7102e376 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVSceneEnum.cs @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVSceneEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + return VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVSceneEnumPropertyField" ); +} + +function VEditorVSceneEnumPropertyField::OnWake( %this ) +{ + // Clear List. + %this.clear(); + + // Iterate Over Groups. + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + %groupObject = %groupSet.getObject( %i ); + if ( %groupObject.isMemberOfClass( "VDirectorGroup" ) ) + { + break; + } + + // Clear. + %groupObject = 0; + } + + if ( !isObject( %groupObject ) ) + { + return; + } + + %trackSet = %groupObject; + %trackCount = %trackSet.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %trackObject = %trackSet.getObject( %i ); + if ( %trackObject.isMemberOfClass( "VDirectorTrack" ) ) + { + break; + } + + // Clear. + %trackObject = 0; + } + + if ( !isObject( %groupObject ) ) + { + return; + } + + %eventSet = %trackObject; + %eventCount = %eventSet.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + %eventObject = %eventSet.getObject( %i ); + if ( %eventObject.Label !$= "" && %this.findText( %eventObject.Label ) == -1 ) + { + %this.add( %eventObject.Label, %this.Size() ); + } + } + + // Sort. + %this.sort(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVShapeAnimationEnum.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVShapeAnimationEnum.cs new file mode 100644 index 000000000..eb3c320a9 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/TypeVShapeAnimationEnum.cs @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::CreateVShapeAnimationEnumField( %fieldContainer, %fieldName ) +{ + // Create Enum Menu. + return VerveEditor::CreateEnumField( %fieldContainer, %fieldName, "VEditorVShapeAnimationEnumPropertyField" ); +} + +function VEditorVShapeAnimationEnumPropertyField::OnWake( %this ) +{ + // Clear List. + %this.clear(); + + // Valid Target? + if ( !$VerveEditor::InspectorObject.isMethod( "getSceneObject" ) ) + { + return; + } + + // Fetch Scene Object. + %objectReference = $VerveEditor::InspectorObject.getSceneObject(); + + // Valid Object? + if ( !isObject( %objectReference ) || !%objectReference.isMemberOfClass( "ShapeBase" ) ) + { + return; + } + + // Find the Constructor for this Shape. + %objectConstructor = %this.FindConstructor( %objectReference ); + if ( !isObject( %objectConstructor ) ) + { + // Invalid Shape Constructor. + return; + } + + // Iterate Over Sequences. + %sequenceCount = %objectConstructor.getSequenceCount(); + for ( %i = 0; %i < %sequenceCount; %i++ ) + { + %sequenceName = %objectConstructor.getSequenceName( %i ); + if ( %this.FindText( %sequenceName ) == -1 ) + { + // Add Item. + %this.add( %sequenceName, %this.Size() ); + } + } + + // Sort. + %this.sort(); +} + +function VEditorVShapeAnimationEnumPropertyField::FindConstructor( %this, %objectReference ) +{ + %datablock = %objectReference.getDataBlock(); + if ( !isObject( %datablock ) ) + { + return 0; + } + + // Fetch the Shape File. + %shapeFile = %datablock.shapeFile; + + %count = TSShapeConstructorGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = TSShapeConstructorGroup.getObject(%i); + if ( %obj.baseShape $= %shapeFile ) + { + return %obj; + } + } + + return 0; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/main.cs new file mode 100644 index 000000000..d85bac4b2 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Fields/main.cs @@ -0,0 +1,25 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitInspectorFieldScripts() +{ + exec( "./TypeBool.cs" ); + exec( "./TypeData.cs" ); + exec( "./TypeEnum.cs" ); + exec( "./TypeString.cs" ); + + exec( "./TypeVCameraGroupEnum.cs" ); + exec( "./TypeVCommandEnum.cs" ); + exec( "./TypeVControllerDataEnum.cs" ); + exec( "./TypeVGroupEnum.cs" ); + exec( "./TypeVLightAnimationDataEnum.cs" ); + exec( "./TypeVPathOrientationModeEnum.cs" ); + exec( "./TypeVPostEffectEnum.cs" ); + exec( "./TypeVSceneEnum.cs" ); + exec( "./TypeVSFXProfileEnum.cs" ); + exec( "./TypeVShapeAnimationEnum.cs" ); + exec( "./TypeToggleEnum.cs" ); +} +VerveEditor::InitInspectorFieldScripts(); \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Lists.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Lists.cs new file mode 100644 index 000000000..23869e2ef --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Lists.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VEditorPropertyList::onAdd( %this ) +{ + if ( !VEditorObjectPropertySet.isMember( %this ) ) + { + // Add Reference List. + VEditorObjectPropertySet.add( %this ); + } +} + +function VEditorPropertyList::onRemove( %this ) +{ + if ( isObject( %this.ControlCache ) ) + { + if ( %this.ControlCache.getClassName() !$= "SimSet" ) + { + // Clear Set. + while ( %this.ControlCache.getCount() > 0 ) + { + // Delete Control. + %this.ControlCache.getObject( 0 ).delete(); + } + } + + // Delete Cache. + %this.ControlCache.delete(); + } +} + +new ScriptGroup( VEditorObjectPropertySet ) +{ + //------------------------------------------------------------------------- + // + // VObject + // + //------------------------------------------------------------------------- + + new ScriptObject( VObjectPropertyList ) + { + SuperClass = "VEditorPropertyList"; + + Group[0] = "VObject"; + Field[0, 0] = "Label"; + Field[0, 1] = "Enabled"; + }; +}; diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Properties.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Properties.cs new file mode 100644 index 000000000..de715b50a --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Properties.cs @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VEditorPropertyList::CreateInspector( %this ) +{ + // Target Stack. + %targetStack = VerveEditorPropertyStack; + + // Clear Stack. + %targetStack.ClearStack(); + + %propertyList = %this; + while ( isObject( %propertyList ) ) + { + if ( !isObject( %propertyList.ControlCache ) ) + { + // Create and Store Cache. + %propertyList.ControlCache = %propertyList.CreateInspectorGroup( %targetStack ); + } + + if ( %propertyList.ControlCache.getClassName() !$= "SimSet" ) + { + // Single Control. + %targetStack.add( %propertyList.ControlCache ); + } + else + { + // Multiple Controls. + %controlSet = %propertyList.ControlCache; + %controlCount = %controlSet.getCount(); + for ( %i = 0; %i < %controlCount; %i++ ) + { + %targetStack.add( %controlSet.getObject( %i ) ); + } + } + + // Get the Parent. + %propertyList = %propertyList.Parent; + } +} + +function VEditorPropertyList::CreateInspectorGroup( %this, %targetStack ) +{ + %controlSet = new SimSet(); + + %i = 0; + while ( %this.Group[%i] !$= "" ) + { + %groupName = %this.Group[%i]; + %groupRollout = %targetStack.CreatePropertyRollout( %groupName ); + %propertyStack = %groupRollout.Stack; + + %j = 0; + while ( %this.Field[%i, %j] !$= "" ) + { + %fieldName = %this.Field[%i, %j]; + %fieldType = %this.Type[%i, %j]; + + if ( %fieldType $= "" ) + { + // Use ConsoleObject Field Type. + %fieldType = $VerveEditor::InspectorObject.getFieldType( %fieldName ); + %fieldType = getSubStr( %fieldType, 4, strlen( %fieldType ) - 4 ); + } + + if ( getWordCount( %fieldName ) == 1 ) + { + VerveEditor::CreateField( %propertyStack, %fieldName, %fieldType ); + } + else + { + %fieldType = getWord( %fieldName, 0 ); + switch$ ( %fieldType ) + { + case "SPACER" : VerveEditor::CreateSpacer( %propertyStack, getWord( %fieldName, 1 ) ); + } + } + + // Next Field. + %j++; + } + + // Store. + %controlSet.add( %groupRollout ); + + // Next Group. + %i++; + } + + %controlCount = %controlSet.getCount(); + if ( %controlCount == 1 ) + { + %control = %controlSet.getObject( 0 ); + %controlSet.delete(); + + return %control; + } + + return %controlSet; +} + +function VEditorPropertyList::InspectObject( %this, %object ) +{ + if ( %this.InspectorLocked ) + { + return; + } + + // Prevent Infinite Loops. + %this.InspectorLocked = true; + + %propertyList = %this; + while ( isObject( %propertyList ) ) + { + if ( !isObject( %propertyList.ControlCache ) ) + { + continue; + } + + if ( %propertyList.ControlCache.getClassName() !$= "SimSet" ) + { + // Single Control. + %targetStack = %propertyList.ControlCache.InspectObject( %object ); + } + else + { + // Multiple Controls. + %controlSet = %propertyList.ControlCache; + %controlCount = %controlSet.getCount(); + for ( %i = 0; %i < %controlCount; %i++ ) + { + %controlSet.getObject( %i ).InspectObject( %object ); + } + } + + // Get the Parent. + %propertyList = %propertyList.Parent; + } + + // All Done. + %this.InspectorLocked = false; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Selection.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Selection.cs new file mode 100644 index 000000000..1034044a2 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/Selection.cs @@ -0,0 +1,224 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +$VerveEditor::InspectorObject = 0; +$VerveEditor::SelectionSet = new SimSet(); + +//----------------------------------------------------------------------------- + +function VerveEditor::HasSelection() +{ + return ( isObject( $VerveEditor::InspectorObject ) || $VerveEditor::SelectionSet.getCount() > 0 ); +} + +//------------------------------------------------------------------------- + +function VerveEditor::OnSelectionUpdate() +{ + // Clear Inspector. + VerveEditorPropertyStack.ClearStack(); + + %selectionSet = $VerveEditor::SelectionSet; + %selectionCount = %selectionSet.getCount(); + if ( %selectionCount == 1 ) + { + // Fetch Object. + %selection = %selectionSet.getObject( 0 ); + + // Highlight + %selection.setStateOn( true ); + if ( isObject( %selection.SiblingControl ) ) + { + %selection.SiblingControl.setStateOn( true ); + } + + if ( isObject( %selection.Proxy ) ) + { + // Change Selection. + %selection = %selection.Proxy; + } + + if ( isObject( %selection ) ) + { + // Inspector Property List. + %selectionList = %selection.getClassName() @ "PropertyList"; + if ( isObject( %selectionList ) ) + { + // Inspect Object. + VerveEditor::InspectObject( %selection, %selectionList ); + } + + // Callback? + if ( %selection.isMethod( "onSelect" ) ) + { + %selection.onSelect(); + } + } + } + else + { + %selection = $VerveEditor::InspectorObject; + if ( isObject( %selection ) ) + { + // Callback? + if ( %selection.isMethod( "onDeselect" ) ) + { + %selection.onDeselect(); + } + } + + // Clear Inspector Object. + $VerveEditor::InspectorObject = 0; + + if ( %selectionCount == 0 ) + { + // Inspect Controller. + VerveEditor::InspectObject( $VerveEditor::Controller, VControllerPropertyList ); + } + } +} + +function VerveEditor::InspectObject( %object, %propertyList ) +{ + // Reference Inspected Object. + $VerveEditor::InspectorObject = %object; + + // Create Lists. + %propertyList.CreateInspector(); + + // Update Fields. + %propertyList.InspectObject( %object ); +} + +function VEditorSelectable::OnMouseEnter( %this, %position, %modifiers, %clickCount ) +{ + if ( isObject( %this.SiblingControl ) ) + { + %this.SiblingControl.setStateOn( true ); + } +} + +function VEditorSelectable::OnMouseLeave( %this, %position, %modifiers, %clickCount ) +{ + if ( isObject( %this.SiblingControl ) ) + { + %this.SiblingControl.setStateOn( %this.getState() ); + } +} + +function VEditorSelectable::OnRightMouseUp( %this, %position, %modifiers, %clickCount ) +{ + // Set Selection. + VerveEditor::SetSelection( %this ); + + // Repaint. + VerveEditorWindow.Repaint(); + + if ( %this.Proxy.isMethod( "DisplayContextMenu" ) ) + { + // Display Context Menu. + %this.Proxy.schedule( 32, "DisplayContextMenu", getWord( %position, 0 ), getWord( %position, 1 ) ); + } +} + +function VEditorSelectable::OnMouseUp( %this, %position, %modifiers, %clickCount ) +{ + switch ( %modifiers ) + { + case 0 : VerveEditor::SetSelection( %this ); + + case 4 : VerveEditor::ToggleSelection( %this ); + } +} + +function VEditorSelectable::OnAddSelection( %this ) +{ + %this.setStateOn( true ); + + if ( isObject( %this.SiblingControl ) ) + { + %this.SiblingControl.setStateOn( true ); + } + + // Set First Responder. + %this.setFirstResponder(); +} + +function VEditorSelectable::OnRemoveSelection( %this ) +{ + %this.setStateOn( false ); + + if ( isObject( %this.SiblingControl ) ) + { + %this.SiblingControl.setStateOn( false ); + } +} + +//------------------------------------------------------------------------- + +function VerveEditor::SetSelection( %object ) +{ + VerveEditor::ClearSelection(); + + VerveEditor::AddSelection( %object ); +} + +function VerveEditor::ClearSelection() +{ + $VerveEditor::Selection::SurpressCallback = true; + while ( $VerveEditor::SelectionSet.getCount() > 0 ) + { + VerveEditor::RemoveSelection( $VerveEditor::SelectionSet.getObject( 0 ) ); + } + + if ( $VerveEditor::Selection::SurpressCallback ) + { + VerveEditor::OnSelectionUpdate(); + } + + $VerveEditor::Selection::SurpressCallback = false; +} + +function VerveEditor::AddSelection( %object ) +{ + $VerveEditor::SelectionSet.add( %object ); + + if ( %object.isMethod( "OnAddSelection" ) ) + { + %object.OnAddSelection(); + } + + if ( !$VerveEditor::Selection::SurpressCallback ) + { + VerveEditor::OnSelectionUpdate(); + } +} + +function VerveEditor::RemoveSelection( %object ) +{ + $VerveEditor::SelectionSet.remove( %object ); + + if ( %object.isMethod( "OnRemoveSelection" ) ) + { + %object.OnRemoveSelection(); + } + + if ( !$VerveEditor::Selection::SurpressCallback ) + { + VerveEditor::OnSelectionUpdate(); + } +} + +function VerveEditor::ToggleSelection( %object ) +{ + if ( !$VerveEditor::SelectionSet.isMember( %object ) ) + { + VerveEditor::AddSelection( %object ); + } + else + { + VerveEditor::RemoveSelection( %object ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/main.cs new file mode 100644 index 000000000..f8a840d02 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Inspector/main.cs @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitInspectorScripts() +{ + exec( "./Controls.cs" ); + exec( "./CutCopyPaste.cs" ); + exec( "./EventNotify.cs" ); + exec( "./Factory.cs" ); + exec( "./FactoryControls.cs" ); + exec( "./FieldNotify.cs" ); + exec( "./Lists.cs" ); + exec( "./Properties.cs" ); + exec( "./Selection.cs" ); + + exec( "./Fields/main.cs" ); +} +VerveEditor::InitInspectorScripts(); \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Persistence.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Persistence.cs new file mode 100644 index 000000000..7064061d6 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Persistence.cs @@ -0,0 +1,232 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +$VerveEditor::FilePath = "sequences"; +$VerveEditor::FileSpec = "Verve Sequence Files (*.vsf)|*.vsf|All Files (*.*)|*.*|"; + +//----------------------------------------------------------------------------- + +function VerveEditor::GetFileTarget( %type ) +{ + %filePath = $VerveEditor::FilePath; + if ( strlen( $Pref::VerveEditor::FilePath ) > 0 ) + { + %filePath = $Pref::VerveEditor::FilePath; + } + + %fileDialog = new ( %type @ "FileDialog" )() + { + Filters = $VerveEditor::FileSpec; + DefaultPath = %filePath; + ChangePath = false; + MustExist = true; + }; + + // Record the file name + %filename = ""; + if ( %fileDialog.Execute() ) + { + %filename = %fileDialog.FileName; + + // Store the preference + $Pref::VerveEditor::FilePath = makeRelativePath( filePath( %filename ), getMainDotCsDir() ); + } + + // Delete the dialog + %fileDialog.delete(); + + // Return the filename + return %filename; +} + +function VerveEditor::NewFile() +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + return; + } + + // Save? + if ( !VerveEditor::SavePrompt() ) + { + return; + } + + // Clear Sequence Lists. + $VerveEditor::Controller.clear(); + + // Clear File. + $VerveEditor::Controller.FileName = ""; + + // Reset Properties. + $VerveEditor::Controller.Time = 0; + $VerveEditor::Controller.Duration = 5000; + $VerveEditor::Controller.TimeScale = 1.0; + + // Clear Editor History. + VerveEditor::ClearHistory(); + + // Refresh Editor. + VerveEditor::Refresh(); +} + +function VerveEditor::LoadFile( %fileName ) +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + return; + } + + // Save? + if ( !VerveEditor::SavePrompt() ) + { + return; + } + + if ( %fileName $= "" ) + { + %fileName = VerveEditor::GetFileTarget( "Open" ); + } + + // Clear File. + $VerveEditor::Controller.FileName = ""; + + if ( $VerveEditor::Controller.readFile( %fileName ) ) + { + // Pause. + VerveEditor::Pause(); + + // Store the File. + $VerveEditor::Controller.FileName = %fileName; + + // Update File History. + VerveEditor::UpdateFileHistory( %fileName ); + + // Clear Editor History. + VerveEditor::ClearHistory(); + + // Refresh Editor. + VerveEditor::Refresh(); + + return true; + } + + // Argh! + // Attempting to load a file which results in failure means the existing + // sequence is messed up, ouch! Do something better than creating a new + // sequence... + VerveEditor::NewFile(); + + return false; +} + +function VerveEditor::SaveFile( %forceSaveAs ) +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + return false; + } + + %fileName = $VerveEditor::Controller.FileName; + if ( %forceSaveAs || %fileName $= "" ) + { + %fileName = VerveEditor::GetFileTarget( "Save" ); + if ( %fileName $= "" ) + { + // No Save. + return false; + } + } + + if ( fileExt( fileName( %fileName ) ) $= "" ) + { + // Add Extension. + %fileName = %fileName @ ".vsf"; + } + + // Write. + $VerveEditor::Controller.writeFile( %fileName ); + + // Store the File. + $VerveEditor::Controller.FileName = %fileName; + + // Update File History. + VerveEditor::UpdateFileHistory( %fileName ); + + // Clear Dirty. + VerveEditor::ClearDirty(); + + // Update Window Title. + VerveEditorWindow.UpdateWindowTitle(); + + // Valid Save. + return true; +} + +function VerveEditor::SavePrompt() +{ + if ( !VerveEditor::IsDirty() ) + { + return true; + } + + %result = messageBox( "Verve Editor", "Save Changes to your sequence?", "SaveDontSave", "Warning" ); + if ( %result $= $MROk ) + { + // Save. + return VerveEditor::SaveFile(); + } + + return true; +} + +function VerveEditor::SavePromptCancel() +{ + if ( !VerveEditor::IsDirty() ) + { + return true; + } + + %result = messageBox( "Verve Editor", "Save Changes to your sequence?", "SaveDontSaveCancel", "Warning" ); + if ( %result $= $MRCancel ) + { + return false; + } + + if ( %result $= $MROk ) + { + // Save. + return VerveEditor::SaveFile(); + } + + return true; +} + +function VerveEditor::UpdateFileHistory( %filePath ) +{ + // Make Relative. + %fileLabel = makeRelativePath( %filePath, getMainDotCsDir() ); + + // Select an Index. + %initIndex = $Pref::VerveEditor::RecentFileSize; + for ( %i = 0; %i < %initIndex; %i++ ) + { + %prefFile = $Pref::VerveEditor::RecentFile[%i]; + if ( %prefFile $= %fileLabel ) + { + %initIndex = %i; + break; + } + } + + // Push Others Down. + for ( %i = %initIndex; %i > 0; %i-- ) + { + $Pref::VerveEditor::RecentFile[%i] = $Pref::VerveEditor::RecentFile[%i - 1]; + } + + // Push to the Front. + $Pref::VerveEditor::RecentFile[0] = %fileLabel; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Plugin.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Plugin.cs new file mode 100644 index 000000000..df7c4efcc --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Plugin.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +// Verve Editor +new ScriptObject( VerveEditorPlugin ) +{ + SuperClass = "EditorPlugin"; +}; + +//----------------------------------------------------------------------------- + +function VerveEditorPlugin::onWorldEditorStartup( %this ) +{ + //---------------------------------------------------------------------- + // + // Editor Toggles + // + //---------------------------------------------------------------------- + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Verve Editor", "", VerveEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Verve Editor (" @ %accel @ ")"; + + // Add ourselves to the ToolsToolbar + EditorGui.addToToolsToolbar( "VerveEditorPlugin", "VerveEditorPluginPalette", expandFilename( "tools/VerveEditor/GUI/Images/btn_Palette" ), %tooltip ); + + // Find and Store the Button. + %this.ToolbarButton = ToolsToolbarArray.findObjectByInternalName( "VerveEditorPluginPalette", false ); + %this.ToolbarButton.ButtonType = "ToggleButton"; + + // Extend Width. + %extent = EWToolsToolbar.getExtent(); + EWToolsToolbar.setExtent( ( getWord( %extent, 0 ) + 33 ) SPC getWord( %extent, 1 ) ); +} + +function VerveEditorPlugin::setEditorFunction( %this ) +{ + if ( %this.ToolbarButton.getValue() ) + { + // Launch Editor. + VerveEditor::LaunchEditor(); + } + else + { + VerveEditorWindow.onWindowClose(); + } + + // Maintain Last Editor. + return false; +} + +function VerveEditorPlugin::onDeactivated( %this ) +{ + // Unchecked Box? + if ( %this.ToolbarButton.getValue() ) + { + return; + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/ScrollNotify.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/ScrollNotify.cs new file mode 100644 index 000000000..11a522256 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/ScrollNotify.cs @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VEditorScrollControl::onScroll( %this ) +{ + %notifyObj = %this.getObject( 0 ); + if ( %notifyObj.isMethod( "onScroll" ) ) + { + %notifyObj.onScroll(); + } +} + +function VerveEditorScrollNotify::onWake( %this ) +{ + VerveEditorScrollNotifyV::onWake( %this ); + VerveEditorScrollNotifyH::onWake( %this ); +} + +function VerveEditorScrollNotify::onScroll( %this ) +{ + %this.onResize(); +} + +function VerveEditorScrollNotify::onResize( %this ) +{ + VerveEditorScrollNotifyV::onResize( %this ); + VerveEditorScrollNotifyH::onResize( %this ); +} + +function VerveEditorScrollNotify::onParentResized( %this ) +{ + %this.schedule( 32, "updateSize" ); +} + +function VerveEditorScrollNotify::updateSize( %this ) +{ + VerveEditorScrollNotifyH::updateSize( %this ); + VerveEditorScrollNotifyV::updateSize( %this ); +} + +//------------------------------------------------------------------------- + +function VerveEditorScrollNotifyV::onWake( %this ) +{ + if ( !isObject( $VerveEditor::ScrollNotifyVSet ) ) + { + $VerveEditor::ScrollNotifyVSet = new SimSet(); + } + + $VerveEditor::ScrollNotifyVSet.add( %this ); +} + +function VerveEditorScrollNotifyV::onScroll( %this ) +{ + %this.onResize(); +} + +function VerveEditorScrollNotifyV::onResize( %this ) +{ + if ( !isObject( $VerveEditor::ScrollNotifyVSet ) ) + { + // Not Awake Yet! + return; + } + + %scrollPosition = %this.getParent().getScrollPositionY(); + if ( !%this.SurpressUpdate ) + { + %refSet = $VerveEditor::ScrollNotifyVSet; + %refCount = %refSet.getCount(); + for ( %i = 0; %i < %refCount; %i++ ) + { + %refObject = %refSet.getObject( %i ).getParent(); + %refObject.SurpressUpdate = true; + %refObject.setScrollPosition( %refObject.getScrollPositionX(), %scrollPosition ); + %refObject.SurpressUpdate = false; + } + } +} + +function VerveEditorScrollNotifyV::onParentResized( %this ) +{ + %this.schedule( 32, "updateSize" ); +} + +function VerveEditorScrollNotifyV::updateSize( %this ) +{ + %minX = getWord( %this.getObject( 0 ).MinExtent, 0 ); + %minY = getWord( %this.getParent().getExtent(), 1 ) - 3; + %this.MinExtent = %minX SPC %minY; + + %newX = getWord( %this.getExtent(), 0 ); + %newY = getWord( VerveEditorTrackStack.getExtent(), 1 ); + %this.setExtent( %newX, %newY ); + + // The onResize callback isn't called if all we did was move around + %this.onResize(); +} + +//------------------------------------------------------------------------- + +function VerveEditorScrollNotifyH::onWake( %this ) +{ + if ( !isObject( $VerveEditor::ScrollNotifyHSet ) ) + { + $VerveEditor::ScrollNotifyHSet = new SimSet(); + } + + $VerveEditor::ScrollNotifyHSet.add( %this ); +} + +function VerveEditorScrollNotifyH::onScroll( %this ) +{ + %this.onResize(); +} + +function VerveEditorScrollNotifyH::onResize( %this ) +{ + if ( !isObject( $VerveEditor::ScrollNotifyHSet ) ) + { + // Not Awake Yet! + return; + } + + %scrollPosition = %this.getParent().getScrollPositionX(); + if ( !%this.SurpressUpdate ) + { + %refSet = $VerveEditor::ScrollNotifyHSet; + %refCount = %refSet.getCount(); + for ( %i = 0; %i < %refCount; %i++ ) + { + %refObject = %refSet.getObject( %i ).getParent(); + %refObject.SurpressUpdate = true; + %refObject.setScrollPosition( %scrollPosition, %refObject.getScrollPositionY() ); + %refObject.SurpressUpdate = false; + } + } +} + +function VerveEditorScrollNotifyH::onParentResized( %this ) +{ + %this.schedule( 32, "updateSize" ); +} + +function VerveEditorScrollNotifyH::updateSize( %this ) +{ + %this.MinExtent = %this.getObject( 0 ).MinExtent; + %this.setExtent( getWord( %this.getParent().getExtent(), 0 ) - 19, getWord( %this.getExtent(), 1 ) ); + + // The onResize callback isn't called if all we did was move around + %this.onResize(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VCameraShakeTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VCameraShakeTrack.cs new file mode 100644 index 000000000..c524d8421 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VCameraShakeTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VCameraShakeTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VCameraShakeTrack::CreateEvent( %this ) +{ + // Create Event. + return new VCameraShakeEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VDirectorTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VDirectorTrack.cs new file mode 100644 index 000000000..7bc197391 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VDirectorTrack.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VDirectorTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VDirectorTrack::Refresh( %this ) +{ + // Create Control. + %trackControl = Parent::Refresh( %this ); + + // Add Field Notify. + VObject::AddFieldNotify( $VerveEditor::Controller, "Duration", %this ); + + // Return Control. + return %trackControl; +} + +function VDirectorTrack::CreateEvent( %this ) +{ + // Create Event. + return new VDirectorEvent(); +} + +//------------------------------------------------------------------------- + +function VDirectorTrack::Update( %this ) +{ + // Root Update. + %this.UpdateTrack(); + + %trackControl = %this.Control.SiblingControl; + if ( !isObject( %trackControl ) ) + { + return; + } + + // Update GUI Elements. + %eventCount = %trackControl.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + // Get Control. + %eventControl = %trackControl.getObject( %i ); + + // Update. + %eventControl.Update(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VFadeTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VFadeTrack.cs new file mode 100644 index 000000000..54424180f --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VFadeTrack.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VFadeTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VFadeTrack::CreateEvent( %this ) +{ + // Create Event. + return new VFadeEvent(); +} + +function VFadeTrack::Refresh( %this ) +{ + // Create Control. + %trackControl = Parent::Refresh( %this ); + + // Update Labels. + %this.Update(); + + // Return Track. + return %trackControl; +} + +function VFadeTrack::Update( %this ) +{ + %eventCount = %this.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + %eventObject = %this.getObject( %i ); + %eventButton = %eventObject.Control; + + // Set The Label. + %eventButton.Text = ( ( %i % 2 ) == 0 ) ? "Fade In" : "Fade Out"; + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectAnimationTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectAnimationTrack.cs new file mode 100644 index 000000000..58b1e784a --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectAnimationTrack.cs @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VLightObjectAnimationTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; + + Group[0] = "Animation Track"; + Field[0, 0] = "AnimationData"; + Type[0, 0] = "VLightAnimationDataEnum"; +}; + +//----------------------------------------------------------------------------- + +function VLightObjectAnimationTrack::CreateEvent( %this ) +{ + // Create Event. + return new VLightObjectAnimationEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectToggleTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectToggleTrack.cs new file mode 100644 index 000000000..cde9e0c24 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VLightObjectToggleTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VLightObjectToggleTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VLightObjectToggleTrack::CreateEvent( %this ) +{ + // Create Event. + return new VLightObjectToggleEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VMotionTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VMotionTrack.cs new file mode 100644 index 000000000..2341988e9 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VMotionTrack.cs @@ -0,0 +1,264 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VMotionTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; + + Group[0] = "VMotionTrack"; + Field[0, 0] = "Reference"; + Type[0, 0] = "VControllerDataEnum"; + Field[0, 1] = "OrientationMode"; + Type[0, 1] = "VPathOrientationModeEnum"; + Field[0, 2] = "OrientationData"; + Field[0, 3] = "Relative"; +}; + +//----------------------------------------------------------------------------- + +function VMotionTrack::CreateEvent( %this, %canCreateNode ) +{ + if ( %canCreateNode $= "" ) %canCreateNode = true; + + // Fetch Object References. + %object = %this.getParent().getSceneObject(); + %path = %this.getPath(); + + if ( isObject( %object ) && isObject( %path ) ) + { + // Create Event. + %event = new VMotionEvent(); + + // Create a Node? + %createNode = ( %this.getCount() >= %path.getNodeCount() ); + if ( !%canCreateNode || !%createNode ) + { + // Return Event. + return %event; + } + + // Use Transform. + %transform = %object.getTransform(); + + // Object Attached? + if ( %path.isObjectAttached( %object ) ) + { + // Get Offset. + %positionOffset = %path.getPathObjectOffset( %object ); + + // Determine Real Position. + %newPosition = VectorSub( %object.getPosition(), %positionOffset ); + + // Set Transform. + %transform = %newPosition SPC getWords( %transform, 3 ); + } + else if ( %this.Relative && %path.getNodeCount() > 0 ) + { + // Fetch Node Position. + %nodePosition = %path.getNodeWorldPosition( 0 ); + + // Set Position. + %object.setTransform( %nodePosition SPC getWords( %transform, 3 ) ); + } + + // Create New Node. + %event.schedule( 32, "CreatePathNode", %transform ); + + // Return Event. + return %event; + } + + // No Object. + return 0; +} + +function VMotionTrack::OnSelect( %this ) +{ + // Fetch Path. + %path = %this.getPath(); + if ( !isObject( EVPathEditor ) || !isObject( %path ) ) + { + // No Editor. + return; + } + + // Update Selection. + EVPathEditor.setSelection( %path ); +} + +//----------------------------------------------------------------------------- + +function VMotionTrack::GetContextMenu( %this ) +{ + %contextMenu = $VerveEditor::VMotionTrack::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VTrackContextMenu"; + Position = 0; + + Item[0] = "&Add Event" TAB "" TAB "VEditorSelectableTrack::AddEvent();"; + + Item[1] = "" TAB ""; + + Item[2] = "&Import Path Nodes" TAB "" TAB "VMotionTrack::ImportPathNodes();"; + + Item[3] = "" TAB ""; + + Item[4] = "Cu&t" TAB "" TAB "VerveEditor::CutSelection();"; + Item[5] = "&Copy" TAB "" TAB "VerveEditor::CopySelection();"; + Item[6] = "&Paste" TAB "" TAB "VEditorSelectableTrack::PasteEvent();"; + + Item[7] = "" TAB ""; + + Item[8] = "&Delete" TAB "" TAB "VerveEditor::DeleteSelection();"; + + AddIndex = 0; + PasteIndex = 4; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VMotionTrack::ContextMenu = %contextMenu; + } + + // Return Menu. + return %contextMenu; +} + +function VMotionTrack::ImportPathNodes() +{ + if ( !VerveEditor::HasSelection() ) + { + // Invalid Selection. + return; + } + + %trackObject = $VerveEditor::InspectorObject; + if ( !%trackObject.isMemberOfClass( "VMotionTrack" ) ) + { + // Invalid Selection. + return; + } + + // Load the Import Options Dialog. + if($Verve::UseSeparateWindow) + VerveEditorWindow.pushDialog( VerveEditorImportPathNodesGUI ); + else + Canvas.pushDialog( VerveEditorImportPathNodesGUI ); +} + +function VMotionTrack::_ImportPathNodes( %speed ) +{ + // Awake? + if ( VerveEditorImportPathNodesGUI.isAwake() ) + { + // Close the GUI. + if($Verve::UseSeparateWindow) + VerveEditorWindow.popDialog( VerveEditorImportPathNodesGUI ); + else + Canvas.popDialog( VerveEditorImportPathNodesGUI ); + } + + if ( !VerveEditor::HasSelection() ) + { + // Invalid Selection. + return; + } + + %trackObject = $VerveEditor::InspectorObject; + if ( !%trackObject.isMemberOfClass( "VMotionTrack" ) ) + { + // Invalid Selection. + return; + } + + // Fetch the Controller. + %controller = %trackObject.getRoot(); + + // Group History Actions. + VerveEditor::ToggleHistoryGroup(); + + // Clear the Track. + while( %trackObject.getCount() > 0 ) + { + // Fetch Object. + %event = %trackObject.getObject( 0 ); + + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryDeleteObject"; + SuperClass = "VerveEditorHistoryObject"; + + ActionName = "Delete Object"; + + // Store Object References. + Parent = %trackObject; + Object = %event; + }; + + // Detach Object. + %trackObject.removeObject( %event ); + } + + // Fetch the Path. + %pathObject = %trackObject.getPath(); + + // New Duration. + %controllerDuration = 0; + // Last Event Time. + %lastEventTime = 0; + // Fetch the Node Count. + %nodeCount = %pathObject.getNodeCount(); + for ( %i = 0; %i < ( %nodeCount + %controller.Loop ); %i++ ) + { + // Create a new Event. + %newEvent = %trackObject.CreateEvent( false ); + + if ( %i > 0 ) + { + // Fetch the Node Length. + %nodeLength = %pathObject.getNodeLength( %i - 1 ); + // Determine the Trigger Time. + %triggerInterval = 1000 * ( %nodeLength / %speed ); + + // Determine the Trigger Time. + %lastEventTime = ( %lastEventTime + %triggerInterval ); + + // Update Duration. + %controllerDuration = %lastEventTime; + // Set the Event's Trigger Time. + %newEvent.TriggerTime = %lastEventTime; + } + + if ( %i < %nodeCount ) + { + // Add the Event. + %trackObject.addObject( %newEvent ); + } + + // Do Event Callback. + %newEvent.OnAdd(); + } + + // Set the Controller Duration. + %controller.setFieldValue( "Duration", %controllerDuration ); + + // Finish Up. + VerveEditor::ToggleHistoryGroup(); + + // Refresh the Editor. + VerveEditor::Refresh(); + + // Set Selection. + VerveEditor::SetSelection( %trackObject.Control ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VParticleEffectToggleTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VParticleEffectToggleTrack.cs new file mode 100644 index 000000000..9e0bc894a --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VParticleEffectToggleTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VParticleEffectToggleTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VParticleEffectToggleTrack::CreateEvent( %this ) +{ + // Create Event. + return new VParticleEffectToggleEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VPostEffectToggleTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VPostEffectToggleTrack.cs new file mode 100644 index 000000000..3d3618c65 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VPostEffectToggleTrack.cs @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VPostEffectToggleTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; + + Group[0] = "VPostEffectToggleTrack"; + Field[0, 0] = "PostEffect"; + Type[0, 0] = "VPostEffectEnum"; +}; + +//----------------------------------------------------------------------------- + +function VPostEffectToggleTrack::CreateEvent( %this ) +{ + // Create Event. + return new VPostEffectToggleEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSceneJumpTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSceneJumpTrack.cs new file mode 100644 index 000000000..59e5dd645 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSceneJumpTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSceneJumpTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VSceneJumpTrack::CreateEvent( %this ) +{ + // Create Event. + return new VSceneJumpEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VScriptEventTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VScriptEventTrack.cs new file mode 100644 index 000000000..eb891dcbf --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VScriptEventTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VScriptEventTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VScriptEventTrack::CreateEvent( %this ) +{ + // Create Event. + return new VScriptEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VShapeAnimationTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VShapeAnimationTrack.cs new file mode 100644 index 000000000..13ea7a0c8 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VShapeAnimationTrack.cs @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VShapeAnimationTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; + + Group[0] = "VShapeAnimationTrack"; + Field[0, 0] = "ThreadIndex"; +}; + +//----------------------------------------------------------------------------- + +function VShapeAnimationTrack::Refresh( %this ) +{ + // Create Control. + %trackControl = Parent::Refresh( %this ); + + // Add Field Notify. + VObject::AddFieldNotify( $VerveEditor::Controller, "Duration", %this ); + + // Object Reference Notify. + VObject::AddFieldNotify( %this.getParent(), "Reference", %this ); + + // Return Control. + return %trackControl; +} + +function VShapeAnimationTrack::CreateEvent( %this ) +{ + // Create Event. + return new VShapeAnimationEvent(); +} + +//------------------------------------------------------------------------- + +function VShapeAnimationTrack::Update( %this ) +{ + // Root Update. + %this.UpdateTrack(); + + %trackControl = %this.Control.SiblingControl; + if ( !isObject( %trackControl ) ) + { + return; + } + + // Update GUI Elements. + %eventCount = %trackControl.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + // Get Control. + %eventControl = %trackControl.getObject( %i ); + + // Update. + %eventControl.Update(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSlowMoTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSlowMoTrack.cs new file mode 100644 index 000000000..4afc92d6b --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSlowMoTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSlowMoTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VSlowMoTrack::CreateEvent( %this ) +{ + // Create Event. + return new VSlowMoEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSoundEffectTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSoundEffectTrack.cs new file mode 100644 index 000000000..ede0ef05c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSoundEffectTrack.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSoundEffectTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VSoundEffectTrack::CreateEvent( %this ) +{ + // Create Event. + return new VSoundEffectEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSpawnSphereSpawnTargetTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSpawnSphereSpawnTargetTrack.cs new file mode 100644 index 000000000..40ee01009 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VSpawnSphereSpawnTargetTrack.cs @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VSpawnSphereSpawnTargetTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; + + Group[0] = "Spawn Target Track"; + Field[0, 0] = "DespawnOnLoop"; + Field[0, 1] = "DespawnOnStop"; +}; + +//----------------------------------------------------------------------------- + +function VSpawnSphereSpawnTargetTrack::CreateEvent( %this ) +{ + // Create Event. + return new VSpawnSphereSpawnTargetEvent(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VTrack.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VTrack.cs new file mode 100644 index 000000000..a3cfb240c --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/VTrack.cs @@ -0,0 +1,266 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +new ScriptObject( VTrackPropertyList ) +{ + SuperClass = "VEditorPropertyList"; + Parent = "VObjectPropertyList"; +}; + +//----------------------------------------------------------------------------- + +function VTrack::OnAdd( %this ) +{ + %ourClass = %this.getClassName(); + if ( !isWordInList( %ourClass, $VerveEditor::NonUniqueTrackList ) ) + { + %group = %this.getParent(); + %trackCount = %group.getCount(); + for ( %i = 0; %i < %trackCount; %i++ ) + { + %trackObject = %group.getObject( %i ); + if ( %trackObject.getId() == %this.getId() ) + { + // Skip. + continue; + } + + if ( %trackObject.isMemberOfClass( %ourClass ) ) + { + // Alert Message. + messageBox( "Verve Editor", "You cannot have more than one \"" @ %ourClass @ "\" in a group.", "Ok", "Warning" ); + + // Invalid. + return false; + } + } + } + + // Regular Add. + return Parent::OnAdd( %this ); +} + +function VTrack::CanPaste( %this, %targetObject ) +{ + if ( !isObject( %targetObject ) ) + { + // Nope! + return false; + } + + return %targetObject.isMemberOfClass( "VEvent" ); +} + +function VTrack::Refresh( %this ) +{ + // Create Control. + %trackControl = VerveEditor::CreateTrackControl( %this ); + + %eventCount = %this.getCount(); + for ( %i = 0; %i < %eventCount; %i++ ) + { + %this.getObject( %i ).Refresh( %trackControl ); + } + + // Return Control. + return %trackControl; +} + +function VTrack::CreateEvent( %this ) +{ + // Create Event. + return new VEvent(); +} + +//------------------------------------------------------------------------- + +function VerveEditor::CreateTrackControl( %object ) +{ + %groupWidth = getWord( VerveEditorGroupStack.getExtent(), 0 ); + %groupHeight = 26; + %trackWidth = getWord( VerveEditorTrackStack.getExtent(), 0 ); + %trackHeight = %groupHeight; + + %groupContainer = new VEditorButton() + { + SuperClass = "VEditorSelectable"; + Class = "VEditorSelectableTrack"; + Profile = "VEditorTrackProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %groupWidth SPC %groupHeight; + + ButtonType = "ToggleButton"; + GroupNum = "-1"; + + IsContainer = "1"; + }; + VerveEditorGroupStack.add( %groupContainer ); + + %groupCheckbox = new GuiCheckBoxCtrl() + { + Class = "VEditorBoolPropertyField"; + InternalName = "Enabled"; + Profile = "VEditorCheckBoxProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 0"; + Extent = "14" SPC %trackHeight; + + Object = %object; + FieldName = "Enabled"; + Command = "$ThisControl.ApplyValue();"; + + Text = ""; + }; + %groupContainer.add( %groupCheckbox ); + + %trackContainer = new VEditorButton() + { + SuperClass = "VEditorSelectable"; + Class = "VEditorSelectableTrack"; + Profile = "VEditorTrackProfile"; + + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %trackWidth SPC %trackHeight; + + ButtonType = "ToggleButton"; + GroupNum = "-1"; + + IsContainer = "1"; + }; + VerveEditorTrackStack.add( %trackContainer ); + + // Field Notify. + %object.AddFieldNotify( "Label", %groupContainer ); + %object.AddFieldNotify( "Enabled", %groupCheckbox ); + + // Reference Siblings. + %trackContainer.SiblingControl = %groupContainer; + %groupContainer.SiblingControl = %trackContainer; + + // Reference Proxy. + %groupContainer.Proxy = %object; + %trackContainer.Proxy = %object; + + // Reference Control. + %object.Control = %groupContainer; + + return %trackContainer; +} + +function VEditorSelectableTrack::Update( %this, %fieldName, %fieldValue ) +{ + %this.setText( %fieldValue ); +} + +function VTrack::GetContextMenu( %this ) +{ + %contextMenu = $VerveEditor::VTrack::ContextMenu; + if ( !isObject( %contextMenu ) ) + { + %contextMenu = new PopupMenu() + { + SuperClass = "VerveWindowMenu"; + + IsPopup = true; + + Label = "VTrackContextMenu"; + Position = 0; + + Item[0] = "&Add Event" TAB "" TAB "VEditorSelectableTrack::AddEvent();"; + + Item[1] = "" TAB ""; + + Item[2] = "Cu&t" TAB "" TAB "VerveEditor::CutSelection();"; + Item[3] = "&Copy" TAB "" TAB "VerveEditor::CopySelection();"; + Item[4] = "&Paste" TAB "" TAB "VEditorSelectableTrack::PasteEvent();"; + + Item[5] = "" TAB ""; + + Item[6] = "&Delete" TAB "" TAB "VerveEditor::DeleteSelection();"; + + AddIndex = 0; + PasteIndex = 4; + }; + %contextMenu.Init(); + + // Cache. + $VerveEditor::VTrack::ContextMenu = %contextMenu; + } + + // Return Menu. + return %contextMenu; +} + +function VTrack::DisplayContextMenu( %this, %x, %y ) +{ + // Fetch the Context Menu. + %contextMenu = %this.GetContextMenu(); + + // Fetch Track Control. + %trackControl = %this.Control.SiblingControl; + + // Enable If Track Stack Member. + %enableAdd = VerveEditorTrackStack.isMember( %trackControl ); + + if ( %enableAdd ) + { + // Time. + %time = VerveEditorTimeLine.toTime( %x - getWord( %trackControl.getGlobalPosition(), 0 ) ); + if ( %time < 0 || %time > $VerveEditor::Controller.Duration ) + { + // Disable. + %enableAdd = false; + } + + // Store Time. + %this.MouseTime = %time; + } + + // Enable/Disable Adding Events. + %contextMenu.enableItem( %contextMenu.AddIndex , %enableAdd ); + + // Enable/Disable Pasting. + %contextMenu.enableItem( %contextMenu.PasteIndex, %enableAdd & VerveEditor::CanPaste() ); + + // Display. + if($Verve::UseSeparateWindow) + %contextMenu.showPopup( VerveEditorWindow, %x, %y ); + else + %contextMenu.showPopup( Canvas, %x, %y ); +} + +function VEditorSelectableTrack::AddEvent() +{ + if ( !VerveEditor::HasSelection() ) + { + // Invalid Selection. + return; + } + + %trackObject = $VerveEditor::InspectorObject; + if ( !%trackObject.isMemberOfClass( "VTrack" ) ) + { + // Invalid Selection. + return; + } + + // Create Event. + VerveEditor::AddEvent( %trackObject, %trackObject.MouseTime ); + + // Clear. + %trackObject.MouseTime = ""; +} + +function VEditorSelectableTrack::PasteEvent() +{ + // Void. +} diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/main.cs new file mode 100644 index 000000000..7460e1364 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Tracks/main.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VerveEditor::InitTrackScripts() +{ + // Core. + exec( "./VTrack.cs" ); + + // Built-In. + exec( "./VCameraShakeTrack.cs" ); + exec( "./VDirectorTrack.cs" ); + exec( "./VFadeTrack.cs" ); + exec( "./VLightObjectAnimationTrack.cs" ); + exec( "./VLightObjectToggleTrack.cs" ); + exec( "./VMotionTrack.cs" ); + exec( "./VParticleEffectToggleTrack.cs" ); + exec( "./VPostEffectToggleTrack.cs" ); + exec( "./VSceneJumpTrack.cs" ); + exec( "./VScriptEventTrack.cs" ); + exec( "./VShapeAnimationTrack.cs" ); + exec( "./VSlowMoTrack.cs" ); + exec( "./VSoundEffectTrack.cs" ); + exec( "./VSpawnSphereSpawnTargetTrack.cs" ); + + // Custom. + // Exec Custom Track Scripts. + + // Non-Unique Group List. + $VerveEditor::NonUniqueTrackList = "VTrack VPostEffectToggleTrack VSoundEffectTrack"; +} +VerveEditor::InitTrackScripts(); diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/Utility.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Utility.cs new file mode 100644 index 000000000..4a63d6484 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/Utility.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Class +// +//----------------------------------------------------------------------------- + +function SimObject::isMemberOfClassList( %this, %typeList ) +{ + %typeCount = getWordCount( %typeList ); + for ( %i = 0; %i < %typeCount; %i++ ) + { + if ( %this.isMemberOfClass( getWord( %typeList, %i ) ) ) + { + return true; + } + } + + return false; +} + +//----------------------------------------------------------------------------- +// +// GUI +// +//----------------------------------------------------------------------------- + +function GuiControl::getParentOfType( %this, %className ) +{ + %parent = %this.getParent(); + while ( isObject( %parent ) ) + { + if ( %parent.isMemberOfClass( %className ) ) + { + return %parent; + } + + %parent = %parent.getParent(); + } + + return 0; +} + +//----------------------------------------------------------------------------- +// +// MATH +// +//----------------------------------------------------------------------------- + +function mRound( %number, %delta ) +{ + return ( mFloor( %number / %delta + 0.5 ) * %delta ); +} + +//----------------------------------------------------------------------------- +// +// STRING +// +//----------------------------------------------------------------------------- + +function isWordInList( %word, %list ) +{ + %wordCount = getWordCount( %list ); + for ( %i = 0; %i < %wordCount; %i++ ) + { + if ( getWord( %list, %i ) $= %word ) + { + return true; + } + } + + return false; +} + +function sortWordList( %list ) +{ + %wordCount = getWordCount( %list ); + for ( %j = 0; %j < %wordCount; %j++ ) + { + for ( %i = %wordCount - 1; %i > %j; %i-- ) + { + %wordA = getWord( %list, %i - 0 ); + %wordB = getWord( %list, %i - 1 ); + + // Compare and swap if needed + if ( strcmp( strlwr( %wordA ), strlwr( %wordB ) ) < 0 ) + { + %list = setWord( %list, %i - 1, %wordA ); + %list = setWord( %list, %i - 0, %wordB ); + } + } + } + + return %list; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Scripts/VObject.cs b/Templates/BaseGame/game/tools/VerveEditor/Scripts/VObject.cs new file mode 100644 index 000000000..689b0a478 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Scripts/VObject.cs @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function VObject::OnAdd( %this ) +{ + // Fetch Parent. + %parentObject = %this.getParent(); + %rootObject = %this.getRoot(); + if ( !%parentObject || ( %rootObject.getId() != $VerveEditor::Controller.getId() ) ) + { + return true; + } + + if ( !VerveEditorHistoryManager.Locked ) + { + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryCreateObject"; + SuperClass = "VerveEditorHistoryObject"; + + ActionName = "Create Object"; + + // Store Object References. + Parent = %parentObject; + Object = %this; + }; + } + + // Valid. + return true; +} + +function VObject::OnRemove( %this ) +{ + // Void. +} + +function VObject::Delete( %this ) +{ + // Fetch Parent. + %parentObject = %this.getParent(); + %rootObject = %this.getRoot(); + if ( !%parentObject || ( %rootObject.getId() != $VerveEditor::Controller.getId() ) ) + { + // Callback. + %this.OnRemove(); + + // Not Editing, Delete. + Parent::delete( %this ); + return; + } + + if ( !VerveEditorHistoryManager.Locked ) + { + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryDeleteObject"; + SuperClass = "VerveEditorHistoryObject"; + + ActionName = "Delete Object"; + + // Store Object References. + Parent = %parentObject; + Object = %this; + }; + } + + // Callback. + %this.OnRemove(); + + // Detach Object. + %parentObject.removeObject( %this ); +} + +function VObject::OnFieldChange( %this, %fieldName, %oldValue, %newValue ) +{ + if ( !VerveEditorHistoryManager.Locked ) + { + // Add History Item. + %historyObject = new UndoScriptAction() + { + Class = "VerveEditorHistoryChangeProperty"; + SuperClass = "VerveEditorHistoryObject"; + + ActionName = "Change Property (" @ %fieldName @ ")"; + + // Store References. + Object = %this; + FieldName = %fieldName; + OldValue = %oldValue; + NewValue = %newValue; + }; + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VCameraGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VCameraGroup.vsf new file mode 100644 index 000000000..f39e0da62 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VCameraGroup.vsf @@ -0,0 +1,17 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VCameraGroup"> + <Properties> + <Label>CameraGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Label>MotionTrack</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + </VObject> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VDirectorGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VDirectorGroup.vsf new file mode 100644 index 000000000..cecc7f685 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VDirectorGroup.vsf @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VDirectorGroup"> + <Properties> + <Label>DirectorGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + <VObject Type="VDirectorTrack"> + <Properties> + <Label>DirectorTrack</Label> + <Enabled>1</Enabled> + </Properties> + </VObject> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VGroup.vsf new file mode 100644 index 000000000..320de6a88 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VGroup.vsf @@ -0,0 +1,10 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VGroup"> + <Properties> + <Label>EmptyGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VLightObjectGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VLightObjectGroup.vsf new file mode 100644 index 000000000..009b73919 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VLightObjectGroup.vsf @@ -0,0 +1,17 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VLightObjectGroup"> + <Properties> + <Label>LightObjectGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + <VObject Type="VLightObjectToggleTrack"> + <Properties> + <Label>ToggleTrack</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + </VObject> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VParticleEffectGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VParticleEffectGroup.vsf new file mode 100644 index 000000000..f199f8ddc --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VParticleEffectGroup.vsf @@ -0,0 +1,17 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VParticleEffectGroup"> + <Properties> + <Label>ParticleEffectGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + <VObject Type="VParticleEffectToggleTrack"> + <Properties> + <Label>ToggleTrack</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + </VObject> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Templates/VSceneObjectGroup.vsf b/Templates/BaseGame/game/tools/VerveEditor/Templates/VSceneObjectGroup.vsf new file mode 100644 index 000000000..2010c3eef --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Templates/VSceneObjectGroup.vsf @@ -0,0 +1,17 @@ +<?xml version="1.0" ?> +<VerveControllerSequence Version="0.0.0a"> + <VObject Type="VSceneObjectGroup"> + <Properties> + <Label>SceneObjectGroup</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + <VObject Type="VMotionTrack"> + <Properties> + <Label>MotionTrack</Label> + <Enabled>1</Enabled> + <Reference /> + </Properties> + </VObject> + </VObject> +</VerveControllerSequence> \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Torque/ObjectClasses.cs b/Templates/BaseGame/game/tools/VerveEditor/Torque/ObjectClasses.cs new file mode 100644 index 000000000..58bd02bba --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Torque/ObjectClasses.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Torque3D +// +//----------------------------------------------------------------------------- + +function VTorque::isSceneObject( %object ) +{ + return ( isObject( %object ) && %object.isMemberOfClass( "SceneObject" ) ); +} + +function VTorque::isCameraObject( %object ) +{ + return ( isObject( %object ) && %object.isMemberOfClass( "GameBase" ) ); +} + +function VTorque::getLightObjectClass() +{ + return "LightBase"; +} + +function VTorque::isLightObject( %object ) +{ + return ( isObject( %object ) && %object.isMemberOfClass( "LightBase" ) ); +} + +function VTorque::isSpawnSphereObject( %object ) +{ + return ( isObject( %object ) && %object.isMemberOfClass( "SpawnSphere" ) ); +} + +function VTorque::getParticleEffectClass() +{ + return "ParticleEmitterNode"; +} + +function VTorque::isParticleEffect( %object ) +{ + return ( isObject( %object ) && %object.isMemberOfClass( "ParticleEmitterNode" ) ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Torque/Selection.cs b/Templates/BaseGame/game/tools/VerveEditor/Torque/Selection.cs new file mode 100644 index 000000000..1bd934e58 --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Torque/Selection.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Torque3D +// +//----------------------------------------------------------------------------- + +function VTorque::GetSelectedCount() +{ + if ( !isObject( EWorldEditor ) ) + { + // Null. + return 0; + } + + // Return Count. + return EWorldEditor.getSelectionSize(); +} + +function VTorque::GetSelectedObject( %index ) +{ + if ( !isObject( EWorldEditor ) ) + { + // Null. + return 0; + } + + // Init Index. + if ( %index $= "" ) + { + %index = 0; + } + + // Return Object. + return EWorldEditor.getSelectedObject( %index ); +} + +function VTorque::SetSelectedObject( %object ) +{ + if ( !isObject( EWorldEditor ) ) + { + return; + } + + EWorldEditor.selectObject( %object ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/VerveEditor/Torque/main.cs b/Templates/BaseGame/game/tools/VerveEditor/Torque/main.cs new file mode 100644 index 000000000..468707b4b --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/Torque/main.cs @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Torque3D +// +//----------------------------------------------------------------------------- + +function VerveEditor::InitTorqueScripts() +{ + // Core. + exec( "./ObjectClasses.cs" ); + exec( "./Selection.cs" ); +} +VerveEditor::InitTorqueScripts(); diff --git a/Templates/BaseGame/game/tools/VerveEditor/main.cs b/Templates/BaseGame/game/tools/VerveEditor/main.cs new file mode 100644 index 000000000..6fcc802db --- /dev/null +++ b/Templates/BaseGame/game/tools/VerveEditor/main.cs @@ -0,0 +1,234 @@ +//----------------------------------------------------------------------------- +// Verve +// Copyright (C) - Violent Tulip +//----------------------------------------------------------------------------- + +function InitializeVerveEditor() +{ + $Verve::UseSeparateWindow = false; + + // Preferences. + exec( "./DefaultPrefs.cs" ); + + // GUI. + exec( "./GUI/GuiProfiles.cs" ); + exec( "./GUI/VerveEditorGroupBuilder.gui" ); + exec( "./GUI/VerveEditorImportPathNodes.gui" ); + + // Scripts. + exec( "./Scripts/Plugin.cs" ); + exec( "./Scripts/Utility.cs" ); + + exec( "./Scripts/EditorControls.cs" ); + exec( "./Scripts/EditorHistory.cs" ); + exec( "./Scripts/EditorMenu.cs" ); + exec( "./Scripts/EditorPreferences.cs" ); + exec( "./Scripts/EditorWindow.cs" ); + exec( "./Scripts/Persistence.cs" ); + exec( "./Scripts/ScrollNotify.cs" ); + exec( "./Scripts/VObject.cs" ); + + exec( "./Scripts/Inspector/main.cs" ); + + exec( "./Scripts/Controller/main.cs" ); + exec( "./Scripts/Groups/main.cs" ); + exec( "./Scripts/Tracks/main.cs" ); + exec( "./Scripts/Events/main.cs" ); + + exec( "./Torque/main.cs" ); + + // Register Events. + VerveEditor::RegisterEvent( "VGroupObjectUpdate" ); +} + +function DestroyVerveEditor() +{ + // Ensure the Editor has Shutdown. + if ( isObject( VerveEditorWindow ) ) + { + // Prompt for Save. + VerveEditor::SavePrompt(); + + // Reset. + VerveEditor::Reset(); + + // Delete the Window. + VerveEditorWindow.delete(); + } +} + +function ToggleVerveEditor( %value ) +{ + if ( %value && $Verve::UseSeparateWindow ) + { + if ( !isObject( VerveEditorWindow ) ) + { + VerveEditor::LaunchEditor(); + } + else + { + VerveEditorWindow.onWindowClose(); + } + } +} + +function VerveEditor::LaunchEditor() +{ + // Launch Window. + %mainScreen = VerveEditorWindow::Open(); + + if ( !isObject( VerveEditorGui ) ) + { + // Load the GUI. + exec ( "./GUI/VerveEditor.gui" ); + } + + // Apply GUI. + if($Verve::UseSeparateWindow) + %mainScreen.setContent( VerveEditorGUI ); + else + { + %mainScreen.add(VerveEditorGUI); + VerveEditorGUI.position.y = VerveEditorGUI.Position.y + 20; + EditorGUI.add(%mainScreen); + } + + // Clear History. + VerveEditor::ClearHistory(); + + // Update Window Title. + if($Verve::UseSeparateWindow) + VerveEditorWindow.UpdateWindowTitle(); + + // Update Selection. + VerveEditor::OnSelectionUpdate(); + + // Update Sizes. + VerveEditor::UpdateSizes(); +} + +function VerveEditor::ResetController() +{ + // Delete. + VerveEditor::DeleteController(); + // Create. + return VerveEditor::CreateController(); +} + +function VerveEditor::DeleteController() +{ + // Current Controller? + if ( isObject( $VerveEditor::Controller ) ) + { + // Stop but do not Reset. + $VerveEditor::Controller.stop( false ); + // Delete the Controller. + $VerveEditor::Controller.delete(); + // Deleted? + return !isObject( $VerveEditor::Controller ); + } + + // No Deletion. + return false; +} + +function VerveEditor::CreateController() +{ + // Current Controller? + if ( !isObject( VerveEditorController ) ) + { + // Create Controller. + $VerveEditor::Controller = new VController( VerveEditorController ); + } + + // Return ID. + return $VerveEditor::Controller; +} + +function VerveEditor::Refresh() +{ + if ( !isObject( $VerveEditor::Controller ) ) + { + return; + } + + // Clear Selection. + VerveEditor::ClearSelection(); + + // Delete Existing Controls. + VerveEditor::DeleteControls(); + + // Sort Groups & Tracks. + $VerveEditor::Controller.sortGroups(); + $VerveEditor::Controller.sortTracks(); + + %groupSet = $VerveEditor::Controller; + %groupCount = %groupSet.getCount(); + for ( %i = 0; %i < %groupCount; %i++ ) + { + // Update Controls. + %groupSet.getObject( %i ).Refresh(); + } + + // Update Window Title. + VerveEditorWindow.UpdateWindowTitle(); + + // Update Duration. + VerveEditor::UpdateDuration(); + + // Update Sizes. + VerveEditor::UpdateSizes(); + + // Update Selection. + VerveEditor::OnSelectionUpdate(); +} + +function VerveEditor::UpdateSizes() +{ + VerveEditorGroupNotify.UpdateSize(); + VerveEditorTrackNotify.UpdateSize(); + VerveEditorTimeNotify.UpdateSize(); +} + +function VerveEditor::UpdateDuration( %duration ) +{ + if ( %duration !$= "" ) + { + // Update Duration. + $VerveEditor::Controller.setFieldValue( "Duration", %duration ); + } + + // Update Duration. + VerveEditorTimeLine.updateDuration(); + VerveEditorTrackTimeLine.updateDuration(); + + // Update Sizes. + VerveEditorGroupNotify.UpdateSize(); + VerveEditorTrackNotify.UpdateSize(); + VerveEditorTimeNotify.UpdateSize(); +} + +package VerveEditorSaveIntercept +{ + function EditorSaveMission() + { + // Reset. + VerveEditor::Reset(); + + // Perform the Save. + Parent::EditorSaveMission(); + } +}; + +function VerveEditor::Reset() +{ + // Valid Controller? + if ( isObject( $VerveEditor::Controller ) ) + { + // Reset. + $VerveEditor::Controller.Reset(); + + // Stop. + $VerveEditor::Controller.Stop(); + } +} \ No newline at end of file diff --git a/Templates/Full/game/art/datablocks/datablockExec.cs b/Templates/Full/game/art/datablocks/datablockExec.cs index 0c66f7df7..f1b874159 100644 --- a/Templates/Full/game/art/datablocks/datablockExec.cs +++ b/Templates/Full/game/art/datablocks/datablockExec.cs @@ -64,4 +64,11 @@ exec("./aiPlayer.cs"); exec("./vehicles/cheetahCar.cs"); // Physics objects -exec("./physics.cs"); \ No newline at end of file +exec("./physics.cs"); + +if(isFile("./verve/VerveActorData.cs")) +{ + // Load Verve Data. + exec("./verve/VerveActorData.cs"); + exec("./verve/VervePathTutorialData.cs"); +} \ No newline at end of file diff --git a/Templates/Full/game/core/art/grids/512_black.png b/Templates/Full/game/core/art/grids/512_black.png deleted file mode 100644 index 5e57c16c2..000000000 Binary files a/Templates/Full/game/core/art/grids/512_black.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_blue.png b/Templates/Full/game/core/art/grids/512_blue.png deleted file mode 100644 index 2511284dd..000000000 Binary files a/Templates/Full/game/core/art/grids/512_blue.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_forestgreen.png b/Templates/Full/game/core/art/grids/512_forestgreen.png deleted file mode 100644 index c5f2cd2fd..000000000 Binary files a/Templates/Full/game/core/art/grids/512_forestgreen.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_forestgreen_lines.png b/Templates/Full/game/core/art/grids/512_forestgreen_lines.png deleted file mode 100644 index 5f6f1a105..000000000 Binary files a/Templates/Full/game/core/art/grids/512_forestgreen_lines.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_green.png b/Templates/Full/game/core/art/grids/512_green.png deleted file mode 100644 index d2cbde68e..000000000 Binary files a/Templates/Full/game/core/art/grids/512_green.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_grey.png b/Templates/Full/game/core/art/grids/512_grey.png deleted file mode 100644 index c4b574c76..000000000 Binary files a/Templates/Full/game/core/art/grids/512_grey.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_grey_base.png b/Templates/Full/game/core/art/grids/512_grey_base.png deleted file mode 100644 index a1e440f29..000000000 Binary files a/Templates/Full/game/core/art/grids/512_grey_base.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_orange.png b/Templates/Full/game/core/art/grids/512_orange.png deleted file mode 100644 index 43c4953e8..000000000 Binary files a/Templates/Full/game/core/art/grids/512_orange.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_orange_lines.png b/Templates/Full/game/core/art/grids/512_orange_lines.png deleted file mode 100644 index 51813d98c..000000000 Binary files a/Templates/Full/game/core/art/grids/512_orange_lines.png and /dev/null differ diff --git a/Templates/Full/game/core/art/grids/512_red.png b/Templates/Full/game/core/art/grids/512_red.png deleted file mode 100644 index a9f95638a..000000000 Binary files a/Templates/Full/game/core/art/grids/512_red.png and /dev/null differ diff --git a/Tools/CMake/modules/module_verve.cmake b/Tools/CMake/modules/module_verve.cmake new file mode 100644 index 000000000..e789f4a68 --- /dev/null +++ b/Tools/CMake/modules/module_verve.cmake @@ -0,0 +1,31 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) 2014 GarageGames, LLC +# +# 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. +# ----------------------------------------------------------------------------- + +option(TORQUE_VERVE_ENABLED "Enable Verve module" ON) +option(TORQUE_VERVE_TOOLS_ENABLED "Enable Verve's Tools" ON) +if(TORQUE_VERVE_ENABLED) + addPathRec( "${srcDir}/Verve" ) +endif() + +if(TORQUE_VERVE_ENABLED) + addDef(VT_EDITOR) +endif() \ No newline at end of file diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index acb0920cb..6eebaae59 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -349,6 +349,14 @@ addPathRec("${srcDir}/ts/assimp") addPathRec("${srcDir}/ts/loader") addPathRec("${projectSrcDir}") +# Load module-based files +if(EXISTS ${TORQUE_APP_DIR}/game/data) + message("Reading modules in ${TORQUE_APP_DIR}/game/data path...") + + addInclude("${TORQUE_APP_DIR}/game/data") + addPathRec("${TORQUE_APP_DIR}/game/data") +endif() + ############################################################################### # modular paths ###############################################################################