Torque3D/Engine/source/T3D/turret/turretShape.h
2012-09-19 11:15:01 -04:00

227 lines
8.6 KiB
C++

//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _TURRETSHAPE_H_
#define _TURRETSHAPE_H_
#ifndef _SHAPEBASE_H_
#include "T3D/item.h"
#endif
class PhysicsBody;
class TurretShape;
//----------------------------------------------------------------------------
class TurretShapeData: public ItemData {
typedef ItemData Parent;
public:
enum FireLinkType {
FireTogether, ///< All weapons fire under trigger 0
GroupedFire, ///< Weapon mounts 0,2 fire under trigger 0, mounts 1,3 fire under trigger 1
IndividualFire, ///< Each weapon mount fires under its own trigger 0-3
NumFireLinkTypeBits = 2
};
FireLinkType weaponLinkType; ///< How are the weapons linked together and triggered
enum {
NumMirrorDirectionNodes = 4,
};
enum Recoil {
LightRecoil,
MediumRecoil,
HeavyRecoil,
NumRecoilSequences
};
S32 recoilSequence[NumRecoilSequences];
S32 pitchSequence; ///< Optional sequence played when the turret pitches
S32 headingSequence; ///< Optional sequence played when the turret's heading changes
F32 cameraOffset; ///< Vertical offset
F32 maxHeading; ///< Max degrees to rotate from center. 180 or more indicates full rotation.
F32 minPitch; ///< Min degrees to rotate down from straight ahead
F32 maxPitch; ///< Max degrees to rotate up from straight ahead
F32 headingRate; ///< Degrees per second rotation. 0 means not allowed. Less than 0 means instantaneous.
F32 pitchRate; ///< Degrees per second rotation. 0 means not allowed. Less than 0 means instantaneous.
S32 headingNode; ///< Code controlled node for heading changes
S32 pitchNode; ///< Code controlled node for pitch changes
S32 pitchNodes[NumMirrorDirectionNodes]; ///< Additional nodes that mirror the movements of the pitch node.
S32 headingNodes[NumMirrorDirectionNodes]; ///< Additional nodes that mirror the movements of the heading node.
S32 weaponMountNode[ShapeBase::MaxMountedImages]; ///< Where ShapeBaseImageData weapons are mounted
bool startLoaded; ///< Should the turret's mounted weapon(s) start in a loaded state?
bool zRotOnly; ///< Should the turret allow only z rotations (like an item)?
public:
TurretShapeData();
DECLARE_CONOBJECT(TurretShapeData);
static void initPersistFields();
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
virtual bool preload(bool server, String &errorStr);
DECLARE_CALLBACK( void, onMountObject, ( TurretShape* turret, SceneObject* obj, S32 node ) );
DECLARE_CALLBACK( void, onUnmountObject, ( TurretShape* turret, SceneObject* obj ) );
DECLARE_CALLBACK( void, onStickyCollision, ( TurretShape* obj ) );
};
typedef TurretShapeData::FireLinkType TurretShapeFireLinkType;
DefineEnumType( TurretShapeFireLinkType );
//----------------------------------------------------------------------------
class TurretShape: public Item
{
typedef Item Parent;
typedef SceneObject GrandParent;
protected:
enum MaskBits {
TurretUpdateMask = Parent::NextFreeMask << 0, ///< using one mask because we're running out of maskbits
NextFreeMask = Parent::NextFreeMask << 1
};
// Client interpolation data for turret heading and pitch
struct TurretStateDelta {
Point3F rot;
VectorF rotVec;
F32 dt;
};
TurretStateDelta mTurretDelta;
Point3F mRot; ///< Current heading and pitch
bool mPitchAllowed; ///< Are pitch changes allowed
bool mHeadingAllowed; ///< Are heading changes allowed
F32 mPitchUp; ///< Pitch up limit, in radians
F32 mPitchDown; ///< Pitch down limit, in radians
F32 mHeadingMax; ///< Maximum heading limit from center, in radians
F32 mPitchRate; ///< How fast the turret may pitch, in radians per second
F32 mHeadingRate; ///< How fast the turret may yaw, in radians per second
bool mRespawn;
TSThread* mRecoilThread;
TSThread* mImageStateThread;
TSThread* mPitchThread;
TSThread* mHeadingThread;
// Static attributes
TurretShapeData* mDataBlock;
bool mSubclassTurretShapeHandlesScene; ///< A subclass of TurretShape will handle all of the adding to the scene
void _setRotation(const Point3F& rot);
void _updateNodes(const Point3F& rot);
void _applyLimits(Point3F& rot);
bool _outsideLimits(Point3F& rot); ///< Return true if any angle is outside of the limits
void onUnmount(ShapeBase* obj,S32 node);
// Script level control
bool allowManualRotation;
bool allowManualFire;
void updateAnimation(F32 dt);
virtual void onImage(U32 imageSlot, bool unmount);
virtual void onImageRecoil(U32 imageSlot,ShapeBaseImageData::StateData::RecoilState);
virtual void onImageStateAnimation(U32 imageSlot, const char* seqName, bool direction, bool scaleToState, F32 stateTimeOutValue);
public:
TurretShape();
virtual ~TurretShape();
static void initPersistFields();
bool onAdd();
void onRemove();
bool onNewDataBlock(GameBaseData *dptr, bool reload);
const char* getStateName();
virtual void updateDamageLevel();
virtual void processTick(const Move *move);
virtual void interpolateTick(F32 dt);
virtual void advanceTime(F32 dt);
virtual void setTransform( const MatrixF &mat );
virtual bool getAllowManualRotation() { return allowManualRotation; }
virtual void setAllowManualRotation(bool allow) { setMaskBits(TurretUpdateMask); allowManualRotation = allow; }
virtual bool getAllowManualFire() { return allowManualFire; }
virtual void setAllowManualFire(bool allow) { setMaskBits(TurretUpdateMask); allowManualFire = allow; }
virtual void updateMove(const Move* move);
bool getNodeTransform(S32 node, MatrixF& mat);
bool getWorldNodeTransform(S32 node, MatrixF& mat);
Point3F getTurretRotation() {return mRot;}
void setTurretRotation(const Point3F& rot) {_setRotation(rot);}
bool doRespawn() { return mRespawn; };
virtual void mountObject( SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity );
virtual void unmountObject( SceneObject *obj );
virtual void getCameraParameters(F32 *min,F32* max,Point3F* offset,MatrixF* rot);
virtual void getCameraTransform(F32* pos,MatrixF* mat);
virtual void writePacketData( GameConnection* conn, BitStream* stream );
virtual void readPacketData( GameConnection* conn, BitStream* stream );
virtual U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream);
virtual void unpackUpdate(NetConnection *conn, BitStream *stream);
virtual void getWeaponMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat );
virtual void getRenderWeaponMountTransform( F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat );
virtual void getImageTransform(U32 imageSlot,MatrixF* mat);
virtual void getRenderImageTransform(U32 imageSlot,MatrixF* mat,bool noEyeOffset=false);
virtual void getImageTransform(U32 imageSlot,S32 node, MatrixF* mat);
virtual void getRenderImageTransform(U32 imageSlot,S32 node, MatrixF* mat);
virtual void prepRenderImage( SceneRenderState* state );
virtual void prepBatchRender( SceneRenderState *state, S32 mountedImageIndex );
DECLARE_CONOBJECT(TurretShape);
};
#endif // _TURRETSHAPE_H_