mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
Merge pull request #1019 from eightyeight/image-recoil-fix
Fix weapon image camera shake
This commit is contained in:
commit
27252b0864
4 changed files with 90 additions and 54 deletions
|
|
@ -940,8 +940,6 @@ ShapeBase::ShapeBase()
|
||||||
|
|
||||||
for (i = 0; i < MaxTriggerKeys; i++)
|
for (i = 0; i < MaxTriggerKeys; i++)
|
||||||
mTrigger[i] = false;
|
mTrigger[i] = false;
|
||||||
|
|
||||||
mWeaponCamShake = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1064,14 +1062,6 @@ void ShapeBase::onRemove()
|
||||||
if ( isClientObject() )
|
if ( isClientObject() )
|
||||||
{
|
{
|
||||||
mCubeReflector.unregisterReflector();
|
mCubeReflector.unregisterReflector();
|
||||||
|
|
||||||
if ( mWeaponCamShake )
|
|
||||||
{
|
|
||||||
if ( mWeaponCamShake->isAdded )
|
|
||||||
gCamFXMgr.removeFX( mWeaponCamShake );
|
|
||||||
|
|
||||||
SAFE_DELETE( mWeaponCamShake );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3161,40 +3151,9 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
|
||||||
{
|
{
|
||||||
if ( imageData->lightType == ShapeBaseImageData::WeaponFireLight )
|
if ( imageData->lightType == ShapeBaseImageData::WeaponFireLight )
|
||||||
image.lightStart = Sim::getCurrentTime();
|
image.lightStart = Sim::getCurrentTime();
|
||||||
|
|
||||||
// HACK: Only works properly if you are in control
|
|
||||||
// of the one and only shapeBase object in the scene
|
|
||||||
// which fires an image that uses camera shake.
|
|
||||||
if ( imageData->shakeCamera )
|
|
||||||
{
|
|
||||||
if ( !mWeaponCamShake )
|
|
||||||
{
|
|
||||||
mWeaponCamShake = new CameraShake();
|
|
||||||
mWeaponCamShake->remoteControlled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mWeaponCamShake->init();
|
|
||||||
mWeaponCamShake->setFrequency( imageData->camShakeFreq );
|
|
||||||
mWeaponCamShake->setAmplitude( imageData->camShakeAmp );
|
|
||||||
|
|
||||||
if ( !mWeaponCamShake->isAdded )
|
|
||||||
{
|
|
||||||
gCamFXMgr.addFX( mWeaponCamShake );
|
|
||||||
mWeaponCamShake->isAdded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateImageState(i,0);
|
updateImageState(i,0);
|
||||||
|
|
||||||
if ( !image.triggerDown && !image.altTriggerDown )
|
|
||||||
{
|
|
||||||
if ( mWeaponCamShake && mWeaponCamShake->isAdded )
|
|
||||||
{
|
|
||||||
gCamFXMgr.removeFX( mWeaponCamShake );
|
|
||||||
mWeaponCamShake->isAdded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,9 @@ struct ShapeBaseImageData: public GameBaseData {
|
||||||
bool shakeCamera;
|
bool shakeCamera;
|
||||||
VectorF camShakeFreq;
|
VectorF camShakeFreq;
|
||||||
VectorF camShakeAmp;
|
VectorF camShakeAmp;
|
||||||
|
F32 camShakeDuration;
|
||||||
|
F32 camShakeRadius;
|
||||||
|
F32 camShakeFalloff;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Maximum number of sounds this image can play at a time.
|
/// Maximum number of sounds this image can play at a time.
|
||||||
|
|
@ -903,9 +906,6 @@ protected:
|
||||||
|
|
||||||
bool mFlipFadeVal;
|
bool mFlipFadeVal;
|
||||||
|
|
||||||
/// Camera shake caused by weapon fire.
|
|
||||||
CameraShake *mWeaponCamShake;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @name Collision Notification
|
/// @name Collision Notification
|
||||||
|
|
@ -1101,6 +1101,7 @@ protected:
|
||||||
virtual void onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState, const char* anim, F32 pos, F32 timeScale, bool reset=false);
|
virtual void onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState, const char* anim, F32 pos, F32 timeScale, bool reset=false);
|
||||||
virtual void onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
|
virtual void onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
|
||||||
virtual void ejectShellCasing( U32 imageSlot );
|
virtual void ejectShellCasing( U32 imageSlot );
|
||||||
|
virtual void shakeCamera( U32 imageSlot );
|
||||||
virtual void updateDamageLevel();
|
virtual void updateDamageLevel();
|
||||||
virtual void updateDamageState();
|
virtual void updateDamageState();
|
||||||
virtual void onImpact(SceneObject* obj, VectorF vec);
|
virtual void onImpact(SceneObject* obj, VectorF vec);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "sfx/sfxTypes.h"
|
#include "sfx/sfxTypes.h"
|
||||||
#include "scene/sceneManager.h"
|
#include "scene/sceneManager.h"
|
||||||
#include "core/stream/fileStream.h"
|
#include "core/stream/fileStream.h"
|
||||||
|
#include "T3D/fx/cameraFXMgr.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -297,6 +298,9 @@ ShapeBaseImageData::ShapeBaseImageData()
|
||||||
shakeCamera = false;
|
shakeCamera = false;
|
||||||
camShakeFreq = Point3F::Zero;
|
camShakeFreq = Point3F::Zero;
|
||||||
camShakeAmp = Point3F::Zero;
|
camShakeAmp = Point3F::Zero;
|
||||||
|
camShakeDuration = 1.5f;
|
||||||
|
camShakeRadius = 3.0f;
|
||||||
|
camShakeFalloff = 10.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeBaseImageData::~ShapeBaseImageData()
|
ShapeBaseImageData::~ShapeBaseImageData()
|
||||||
|
|
@ -739,10 +743,7 @@ void ShapeBaseImageData::initPersistFields()
|
||||||
"@see lightType");
|
"@see lightType");
|
||||||
|
|
||||||
addField( "shakeCamera", TypeBool, Offset(shakeCamera, ShapeBaseImageData),
|
addField( "shakeCamera", TypeBool, Offset(shakeCamera, ShapeBaseImageData),
|
||||||
"@brief Flag indicating whether the camera should shake when this Image fires.\n\n"
|
"@brief Flag indicating whether the camera should shake when this Image fires.\n\n" );
|
||||||
"@note Camera shake only works properly if the player is in control of "
|
|
||||||
"the one and only shapeBase object in the scene which fires an Image that "
|
|
||||||
"uses camera shake." );
|
|
||||||
|
|
||||||
addField( "camShakeFreq", TypePoint3F, Offset(camShakeFreq, ShapeBaseImageData),
|
addField( "camShakeFreq", TypePoint3F, Offset(camShakeFreq, ShapeBaseImageData),
|
||||||
"@brief Frequency of the camera shaking effect.\n\n"
|
"@brief Frequency of the camera shaking effect.\n\n"
|
||||||
|
|
@ -752,6 +753,16 @@ void ShapeBaseImageData::initPersistFields()
|
||||||
"@brief Amplitude of the camera shaking effect.\n\n"
|
"@brief Amplitude of the camera shaking effect.\n\n"
|
||||||
"@see shakeCamera" );
|
"@see shakeCamera" );
|
||||||
|
|
||||||
|
addField( "camShakeDuration", TypeF32, Offset(camShakeDuration, ShapeBaseImageData),
|
||||||
|
"Duration (in seconds) to shake the camera." );
|
||||||
|
|
||||||
|
addField( "camShakeRadius", TypeF32, Offset(camShakeRadius, ShapeBaseImageData),
|
||||||
|
"Radial distance that a camera's position must be within relative to the "
|
||||||
|
"center of the explosion to be shaken." );
|
||||||
|
|
||||||
|
addField( "camShakeFalloff", TypeF32, Offset(camShakeFalloff, ShapeBaseImageData),
|
||||||
|
"Falloff value for the camera shake." );
|
||||||
|
|
||||||
addField( "casing", TYPEID< DebrisData >(), Offset(casing, ShapeBaseImageData),
|
addField( "casing", TYPEID< DebrisData >(), Offset(casing, ShapeBaseImageData),
|
||||||
"@brief DebrisData datablock to use for ejected casings.\n\n"
|
"@brief DebrisData datablock to use for ejected casings.\n\n"
|
||||||
"@see stateEjectShell" );
|
"@see stateEjectShell" );
|
||||||
|
|
@ -1028,6 +1039,9 @@ void ShapeBaseImageData::packData(BitStream* stream)
|
||||||
{
|
{
|
||||||
mathWrite( *stream, camShakeFreq );
|
mathWrite( *stream, camShakeFreq );
|
||||||
mathWrite( *stream, camShakeAmp );
|
mathWrite( *stream, camShakeAmp );
|
||||||
|
stream->write( camShakeDuration );
|
||||||
|
stream->write( camShakeRadius );
|
||||||
|
stream->write( camShakeFalloff );
|
||||||
}
|
}
|
||||||
|
|
||||||
mathWrite( *stream, shellExitDir );
|
mathWrite( *stream, shellExitDir );
|
||||||
|
|
@ -1209,6 +1223,9 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
|
||||||
{
|
{
|
||||||
mathRead( *stream, &camShakeFreq );
|
mathRead( *stream, &camShakeFreq );
|
||||||
mathRead( *stream, &camShakeAmp );
|
mathRead( *stream, &camShakeAmp );
|
||||||
|
stream->read( &camShakeDuration );
|
||||||
|
stream->read( &camShakeRadius );
|
||||||
|
stream->read( &camShakeFalloff );
|
||||||
}
|
}
|
||||||
|
|
||||||
mathRead( *stream, &shellExitDir );
|
mathRead( *stream, &shellExitDir );
|
||||||
|
|
@ -2596,6 +2613,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
|
||||||
ejectShellCasing( imageSlot );
|
ejectShellCasing( imageSlot );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shake camera on client.
|
||||||
|
if (isGhost() && nextStateData.fire && image.dataBlock->shakeCamera) {
|
||||||
|
shakeCamera( imageSlot );
|
||||||
|
}
|
||||||
|
|
||||||
// Server must animate the shape if it is a firestate...
|
// Server must animate the shape if it is a firestate...
|
||||||
if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
|
if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
|
||||||
|
|
@ -3342,3 +3363,57 @@ void ShapeBase::ejectShellCasing( U32 imageSlot )
|
||||||
|
|
||||||
casing->init( shellPos, shellVel );
|
casing->init( shellPos, shellVel );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShapeBase::shakeCamera( U32 imageSlot )
|
||||||
|
{
|
||||||
|
MountedImage& image = mMountedImageList[imageSlot];
|
||||||
|
ShapeBaseImageData* imageData = image.dataBlock;
|
||||||
|
|
||||||
|
if (!imageData->shakeCamera)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Warning: this logic was duplicated from Explosion.
|
||||||
|
|
||||||
|
// first check if explosion is near camera
|
||||||
|
GameConnection* connection = GameConnection::getConnectionToServer();
|
||||||
|
ShapeBase *obj = dynamic_cast<ShapeBase*>(connection->getControlObject());
|
||||||
|
|
||||||
|
bool applyShake = true;
|
||||||
|
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
ShapeBase* cObj = obj;
|
||||||
|
while ((cObj = cObj->getControlObject()) != 0)
|
||||||
|
{
|
||||||
|
if (cObj->useObjsEyePoint())
|
||||||
|
{
|
||||||
|
applyShake = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (applyShake && obj)
|
||||||
|
{
|
||||||
|
VectorF diff;
|
||||||
|
getMuzzlePoint(imageSlot, &diff);
|
||||||
|
diff = obj->getPosition() - diff;
|
||||||
|
F32 dist = diff.len();
|
||||||
|
if (dist < imageData->camShakeRadius)
|
||||||
|
{
|
||||||
|
CameraShake *camShake = new CameraShake;
|
||||||
|
camShake->setDuration(imageData->camShakeDuration);
|
||||||
|
camShake->setFrequency(imageData->camShakeFreq);
|
||||||
|
|
||||||
|
F32 falloff = dist / imageData->camShakeRadius;
|
||||||
|
falloff = 1.0f + falloff * 10.0f;
|
||||||
|
falloff = 1.0f / (falloff * falloff);
|
||||||
|
|
||||||
|
VectorF shakeAmp = imageData->camShakeAmp * falloff;
|
||||||
|
camShake->setAmplitude(shakeAmp);
|
||||||
|
camShake->setFalloff(imageData->camShakeFalloff);
|
||||||
|
camShake->init();
|
||||||
|
gCamFXMgr.addFX(camShake);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -192,9 +192,9 @@ datablock ShapeBaseImageData(RyderWeaponImage)
|
||||||
lightBrightness = 2;
|
lightBrightness = 2;
|
||||||
|
|
||||||
// Shake camera while firing.
|
// Shake camera while firing.
|
||||||
shakeCamera = false;
|
shakeCamera = "1";
|
||||||
camShakeFreq = "0 0 0";
|
camShakeFreq = "10 10 10";
|
||||||
camShakeAmp = "0 0 0";
|
camShakeAmp = "5 5 5";
|
||||||
|
|
||||||
// Images have a state system which controls how the animations
|
// Images have a state system which controls how the animations
|
||||||
// are run, which sounds are played, script callbacks, etc. This
|
// are run, which sounds are played, script callbacks, etc. This
|
||||||
|
|
@ -361,4 +361,5 @@ datablock ShapeBaseImageData(RyderWeaponImage)
|
||||||
stateSequenceTransitionOut[13] = true;
|
stateSequenceTransitionOut[13] = true;
|
||||||
stateAllowImageChange[13] = false;
|
stateAllowImageChange[13] = false;
|
||||||
stateSequence[13] = "sprint";
|
stateSequence[13] = "sprint";
|
||||||
|
camShakeDuration = "0.2";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue