Skip to content

Commit

Permalink
Merge pull request #1019 from eightyeight/image-recoil-fix
Browse files Browse the repository at this point in the history
Fix weapon image camera shake
  • Loading branch information
crabmusket committed Dec 10, 2014
2 parents 6338b8c + 9622f93 commit 27252b0
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 54 deletions.
43 changes: 1 addition & 42 deletions Engine/source/T3D/shapeBase.cpp
Expand Up @@ -940,8 +940,6 @@ ShapeBase::ShapeBase()

for (i = 0; i < MaxTriggerKeys; i++)
mTrigger[i] = false;

mWeaponCamShake = NULL;
}


Expand Down Expand Up @@ -1063,15 +1061,7 @@ void ShapeBase::onRemove()

if ( isClientObject() )
{
mCubeReflector.unregisterReflector();

if ( mWeaponCamShake )
{
if ( mWeaponCamShake->isAdded )
gCamFXMgr.removeFX( mWeaponCamShake );

SAFE_DELETE( mWeaponCamShake );
}
mCubeReflector.unregisterReflector();
}
}

Expand Down Expand Up @@ -3161,40 +3151,9 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
{
if ( imageData->lightType == ShapeBaseImageData::WeaponFireLight )
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);

if ( !image.triggerDown && !image.altTriggerDown )
{
if ( mWeaponCamShake && mWeaponCamShake->isAdded )
{
gCamFXMgr.removeFX( mWeaponCamShake );
mWeaponCamShake->isAdded = false;
}
}
}
else
{
Expand Down
9 changes: 5 additions & 4 deletions Engine/source/T3D/shapeBase.h
Expand Up @@ -324,7 +324,10 @@ struct ShapeBaseImageData: public GameBaseData {
/// @{
bool shakeCamera;
VectorF camShakeFreq;
VectorF camShakeAmp;
VectorF camShakeAmp;
F32 camShakeDuration;
F32 camShakeRadius;
F32 camShakeFalloff;
/// @}

/// Maximum number of sounds this image can play at a time.
Expand Down Expand Up @@ -903,9 +906,6 @@ class ShapeBase : public GameBase, public ISceneLight

bool mFlipFadeVal;

/// Camera shake caused by weapon fire.
CameraShake *mWeaponCamShake;

public:

/// @name Collision Notification
Expand Down Expand Up @@ -1101,6 +1101,7 @@ class ShapeBase : public GameBase, public ISceneLight
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 ejectShellCasing( U32 imageSlot );
virtual void shakeCamera( U32 imageSlot );
virtual void updateDamageLevel();
virtual void updateDamageState();
virtual void onImpact(SceneObject* obj, VectorF vec);
Expand Down
85 changes: 80 additions & 5 deletions Engine/source/T3D/shapeImage.cpp
Expand Up @@ -44,6 +44,7 @@
#include "sfx/sfxTypes.h"
#include "scene/sceneManager.h"
#include "core/stream/fileStream.h"
#include "T3D/fx/cameraFXMgr.h"

//----------------------------------------------------------------------------

Expand Down Expand Up @@ -297,6 +298,9 @@ ShapeBaseImageData::ShapeBaseImageData()
shakeCamera = false;
camShakeFreq = Point3F::Zero;
camShakeAmp = Point3F::Zero;
camShakeDuration = 1.5f;
camShakeRadius = 3.0f;
camShakeFalloff = 10.0f;
}

ShapeBaseImageData::~ShapeBaseImageData()
Expand Down Expand Up @@ -739,10 +743,7 @@ void ShapeBaseImageData::initPersistFields()
"@see lightType");

addField( "shakeCamera", TypeBool, Offset(shakeCamera, ShapeBaseImageData),
"@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." );
"@brief Flag indicating whether the camera should shake when this Image fires.\n\n" );

addField( "camShakeFreq", TypePoint3F, Offset(camShakeFreq, ShapeBaseImageData),
"@brief Frequency of the camera shaking effect.\n\n"
Expand All @@ -752,6 +753,16 @@ void ShapeBaseImageData::initPersistFields()
"@brief Amplitude of the camera shaking effect.\n\n"
"@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),
"@brief DebrisData datablock to use for ejected casings.\n\n"
"@see stateEjectShell" );
Expand Down Expand Up @@ -1028,6 +1039,9 @@ void ShapeBaseImageData::packData(BitStream* stream)
{
mathWrite( *stream, camShakeFreq );
mathWrite( *stream, camShakeAmp );
stream->write( camShakeDuration );
stream->write( camShakeRadius );
stream->write( camShakeFalloff );
}

mathWrite( *stream, shellExitDir );
Expand Down Expand Up @@ -1208,7 +1222,10 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
if ( shakeCamera )
{
mathRead( *stream, &camShakeFreq );
mathRead( *stream, &camShakeAmp );
mathRead( *stream, &camShakeAmp );
stream->read( &camShakeDuration );
stream->read( &camShakeRadius );
stream->read( &camShakeFalloff );
}

mathRead( *stream, &shellExitDir );
Expand Down Expand Up @@ -2596,6 +2613,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
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...
if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
Expand Down Expand Up @@ -3342,3 +3363,57 @@ void ShapeBase::ejectShellCasing( U32 imageSlot )

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);
}
}
}
7 changes: 4 additions & 3 deletions Templates/Full/game/art/datablocks/weapons/Ryder.cs
Expand Up @@ -192,9 +192,9 @@ class = "WeaponImage";
lightBrightness = 2;

// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
shakeCamera = "1";
camShakeFreq = "10 10 10";
camShakeAmp = "5 5 5";

// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
Expand Down Expand Up @@ -361,4 +361,5 @@ class = "WeaponImage";
stateSequenceTransitionOut[13] = true;
stateAllowImageChange[13] = false;
stateSequence[13] = "sprint";
camShakeDuration = "0.2";
};

0 comments on commit 27252b0

Please sign in to comment.