mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-26 10:03:48 +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++)
|
||||
mTrigger[i] = false;
|
||||
|
||||
mWeaponCamShake = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1063,15 +1061,7 @@ void ShapeBase::onRemove()
|
|||
|
||||
if ( isClientObject() )
|
||||
{
|
||||
mCubeReflector.unregisterReflector();
|
||||
|
||||
if ( mWeaponCamShake )
|
||||
{
|
||||
if ( mWeaponCamShake->isAdded )
|
||||
gCamFXMgr.removeFX( mWeaponCamShake );
|
||||
|
||||
SAFE_DELETE( mWeaponCamShake );
|
||||
}
|
||||
mCubeReflector.unregisterReflector();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -903,9 +906,6 @@ protected:
|
|||
|
||||
bool mFlipFadeVal;
|
||||
|
||||
/// Camera shake caused by weapon fire.
|
||||
CameraShake *mWeaponCamShake;
|
||||
|
||||
public:
|
||||
|
||||
/// @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 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);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "sfx/sfxTypes.h"
|
||||
#include "scene/sceneManager.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "T3D/fx/cameraFXMgr.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -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()
|
||||
|
|
@ -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"
|
||||
|
|
@ -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" );
|
||||
|
|
@ -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 );
|
||||
|
|
@ -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 );
|
||||
|
|
@ -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))
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,9 +192,9 @@ datablock ShapeBaseImageData(RyderWeaponImage)
|
|||
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
|
||||
|
|
@ -361,4 +361,5 @@ datablock ShapeBaseImageData(RyderWeaponImage)
|
|||
stateSequenceTransitionOut[13] = true;
|
||||
stateAllowImageChange[13] = false;
|
||||
stateSequence[13] = "sprint";
|
||||
camShakeDuration = "0.2";
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue