mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-23 00:23:46 +00:00
Add all new AFX files
This commit is contained in:
parent
f2b86b7df3
commit
ace877b409
218 changed files with 54970 additions and 0 deletions
1189
Engine/source/afx/afxCamera.cpp
Normal file
1189
Engine/source/afx/afxCamera.cpp
Normal file
File diff suppressed because it is too large
Load diff
189
Engine/source/afx/afxCamera.h
Normal file
189
Engine/source/afx/afxCamera.h
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// afxCamera implements a modified camera for demonstrating a third person camera style
|
||||
// which is more common to RPG games than the standard FPS style camera. For the most part,
|
||||
// it is a hybrid of the standard TGE camera and the third person mode of the Advanced Camera
|
||||
// resource, authored by Thomas "Man of Ice" Lund. This camera implements the bare minimum
|
||||
// required for demonstrating an RPG style camera and leaves tons of room for improvement.
|
||||
// It should be replaced with a better camera if possible.
|
||||
//
|
||||
// Advanced Camera Resource by Thomas "Man of Ice" Lund:
|
||||
// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5471
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _AFX_CAMERA_H_
|
||||
#define _AFX_CAMERA_H_
|
||||
|
||||
#ifndef _SHAPEBASE_H_
|
||||
#include "game/shapeBase.h"
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct afxCameraData: public ShapeBaseData {
|
||||
typedef ShapeBaseData Parent;
|
||||
|
||||
static U32 sCameraCollisionMask;
|
||||
|
||||
//
|
||||
DECLARE_CONOBJECT(afxCameraData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
static void initPersistFields();
|
||||
virtual void packData(BitStream* stream);
|
||||
virtual void unpackData(BitStream* stream);
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Implements a basic camera object.
|
||||
class afxCamera: public ShapeBase
|
||||
{
|
||||
typedef ShapeBase Parent;
|
||||
|
||||
enum MaskBits {
|
||||
MoveMask = Parent::NextFreeMask,
|
||||
SubjectMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
struct StateDelta {
|
||||
Point3F pos;
|
||||
Point3F rot;
|
||||
VectorF posVec;
|
||||
VectorF rotVec;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ThirdPersonMode = 1,
|
||||
FlyMode = 2,
|
||||
OrbitObjectMode = 3,
|
||||
OrbitPointMode = 4,
|
||||
CameraFirstMode = 0,
|
||||
CameraLastMode = 4
|
||||
};
|
||||
|
||||
private:
|
||||
int mode;
|
||||
Point3F mRot;
|
||||
StateDelta delta;
|
||||
|
||||
SimObjectPtr<GameBase> mOrbitObject;
|
||||
F32 mMinOrbitDist;
|
||||
F32 mMaxOrbitDist;
|
||||
F32 mCurOrbitDist;
|
||||
Point3F mPosition;
|
||||
bool mObservingClientObject;
|
||||
|
||||
SceneObject* cam_subject;
|
||||
Point3F cam_offset;
|
||||
Point3F coi_offset;
|
||||
F32 cam_distance;
|
||||
F32 cam_angle;
|
||||
bool cam_dirty;
|
||||
|
||||
bool flymode_saved;
|
||||
Point3F flymode_saved_pos;
|
||||
S8 third_person_snap_c;
|
||||
S8 third_person_snap_s;
|
||||
|
||||
void set_cam_pos(const Point3F& pos, const Point3F& viewRot);
|
||||
void cam_update(F32 dt, bool on_server);
|
||||
|
||||
public:
|
||||
/*C*/ afxCamera();
|
||||
/*D*/ ~afxCamera();
|
||||
|
||||
Point3F& getPosition();
|
||||
void setFlyMode();
|
||||
void setOrbitMode(GameBase* obj, Point3F& pos, AngAxisF& rot, F32 minDist, F32 maxDist, F32 curDist, bool ownClientObject);
|
||||
void validateEyePoint(F32 pos, MatrixF *mat);
|
||||
|
||||
GameBase* getOrbitObject() { return(mOrbitObject); }
|
||||
bool isObservingClientObject() { return(mObservingClientObject); }
|
||||
|
||||
void snapToPosition(const Point3F& pos);
|
||||
void setCameraSubject(SceneObject* subject);
|
||||
void setThirdPersonOffset(const Point3F& offset);
|
||||
void setThirdPersonOffset(const Point3F& offset, const Point3F& coi_offset);
|
||||
const Point3F& getThirdPersonOffset() const { return cam_offset; }
|
||||
const Point3F& getThirdPersonCOIOffset() const { return coi_offset; }
|
||||
void setThirdPersonDistance(F32 distance);
|
||||
F32 getThirdPersonDistance();
|
||||
void setThirdPersonAngle(F32 angle);
|
||||
F32 getThirdPersonAngle();
|
||||
void setThirdPersonMode();
|
||||
void setThirdPersonSnap();
|
||||
void setThirdPersonSnapClient();
|
||||
const char* getMode();
|
||||
|
||||
bool isCamera() const { return true; }
|
||||
|
||||
DECLARE_CONOBJECT(afxCamera);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
private: // 3POV SECTION
|
||||
U32 blockers_mask_3pov;
|
||||
|
||||
void cam_update_3pov(F32 dt, bool on_server);
|
||||
bool avoid_blocked_view(const Point3F& start, const Point3F& end, Point3F& newpos);
|
||||
bool test_blocked_line(const Point3F& start, const Point3F& end);
|
||||
|
||||
public: // STD OVERRIDES SECTION
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual void onDeleteNotify(SimObject *obj);
|
||||
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual void processTick(const Move* move);
|
||||
virtual void interpolateTick(F32 delta);
|
||||
|
||||
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 onCameraScopeQuery(NetConnection* cr, CameraScopeQuery*);
|
||||
virtual void getCameraTransform(F32* pos,MatrixF* mat);
|
||||
virtual void setTransform(const MatrixF& mat);
|
||||
|
||||
virtual void onEditorEnable();
|
||||
virtual void onEditorDisable();
|
||||
|
||||
virtual F32 getCameraFov();
|
||||
virtual F32 getDefaultCameraFov();
|
||||
virtual bool isValidCameraFov(F32 fov);
|
||||
virtual void setCameraFov(F32 fov);
|
||||
|
||||
virtual F32 getDamageFlash() const;
|
||||
virtual F32 getWhiteOut() const;
|
||||
|
||||
virtual void setControllingClient( GameConnection* connection );
|
||||
};
|
||||
|
||||
|
||||
#endif // _AFX_CAMERA_H_
|
||||
1084
Engine/source/afx/afxChoreographer.cpp
Normal file
1084
Engine/source/afx/afxChoreographer.cpp
Normal file
File diff suppressed because it is too large
Load diff
222
Engine/source/afx/afxChoreographer.h
Normal file
222
Engine/source/afx/afxChoreographer.h
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_CHOREOGRAPHER_H_
|
||||
#define _AFX_CHOREOGRAPHER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "afxEffectDefs.h"
|
||||
#include "afxEffectWrapper.h"
|
||||
#include "afxMagicMissile.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxChoreographerData
|
||||
|
||||
class afxChoreographerData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
bool exec_on_new_clients;
|
||||
U8 echo_packet_usage;
|
||||
StringTableEntry client_script_file;
|
||||
StringTableEntry client_init_func;
|
||||
|
||||
public:
|
||||
/*C*/ afxChoreographerData();
|
||||
/*C*/ afxChoreographerData(const afxChoreographerData&, bool = false);
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxChoreographerData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxChoreographer
|
||||
|
||||
class afxConstraint;
|
||||
class afxConstraintMgr;
|
||||
class afxEffectWrapper;
|
||||
class afxParticlePool;
|
||||
class afxParticlePoolData;
|
||||
class SimSet;
|
||||
class afxForceSetMgr;
|
||||
|
||||
class afxChoreographer : public GameBase, public afxEffectDefs, public afxMagicMissileCallback
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
public:
|
||||
enum MaskBits
|
||||
{
|
||||
TriggerMask = Parent::NextFreeMask << 0,
|
||||
RemapConstraintMask = Parent::NextFreeMask << 1, // CONSTRAINT REMAPPING
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
USER_EXEC_CONDS_MASK = 0x00ffffff
|
||||
};
|
||||
|
||||
protected:
|
||||
struct dynConstraintDef
|
||||
{
|
||||
StringTableEntry cons_name;
|
||||
U8 cons_type;
|
||||
union
|
||||
{
|
||||
SceneObject* object;
|
||||
Point3F* point;
|
||||
MatrixF* xfm;
|
||||
U16 scope_id;
|
||||
} cons_obj;
|
||||
};
|
||||
|
||||
private:
|
||||
afxChoreographerData* datablock;
|
||||
SimSet named_effects;
|
||||
SimObject* exeblock;
|
||||
afxForceSetMgr* force_set_mgr;
|
||||
Vector<afxParticlePool*> particle_pools;
|
||||
Vector<dynConstraintDef> dc_defs_a;
|
||||
Vector<dynConstraintDef> dc_defs_b;
|
||||
GameBase* proc_after_obj;
|
||||
U32 trigger_mask;
|
||||
|
||||
protected:
|
||||
Vector<dynConstraintDef>* dyn_cons_defs;
|
||||
Vector<dynConstraintDef>* dyn_cons_defs2;
|
||||
afxConstraintMgr* constraint_mgr;
|
||||
U32 choreographer_id;
|
||||
U8 ranking;
|
||||
U8 lod;
|
||||
U32 exec_conds_mask;
|
||||
SimObject* extra;
|
||||
Vector<NetConnection*> explicit_clients;
|
||||
bool started_with_newop;
|
||||
bool postpone_activation;
|
||||
|
||||
virtual void pack_constraint_info(NetConnection* conn, BitStream* stream);
|
||||
virtual void unpack_constraint_info(NetConnection* conn, BitStream* stream);
|
||||
void setup_dynamic_constraints();
|
||||
void check_packet_usage(NetConnection*, BitStream*, S32 mark_stream_pos, const char* msg_tag);
|
||||
SceneObject* get_camera(Point3F* cam_pos=0) const;
|
||||
|
||||
public:
|
||||
/*C*/ afxChoreographer();
|
||||
virtual ~afxChoreographer();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
|
||||
virtual void sync_with_clients() { }
|
||||
|
||||
afxConstraintMgr* getConstraintMgr() { return constraint_mgr; }
|
||||
afxForceSetMgr* getForceSetMgr() { return force_set_mgr; }
|
||||
|
||||
afxParticlePool* findParticlePool(afxParticlePoolData* key_block, U32 key_index);
|
||||
void registerParticlePool(afxParticlePool*);
|
||||
void unregisterParticlePool(afxParticlePool*);
|
||||
|
||||
void setRanking(U8 value) { ranking = value; }
|
||||
U8 getRanking() const { return ranking; }
|
||||
bool testRanking(U8 low, U8 high) { return (ranking <= high && ranking >= low); }
|
||||
void setLevelOfDetail(U8 value) { lod = value; }
|
||||
U8 getLevelOfDetail() const { return lod; }
|
||||
bool testLevelOfDetail(U8 low, U8 high) { return (lod <= high && lod >= low); }
|
||||
void setExecConditions(U32 mask) { exec_conds_mask = mask; }
|
||||
U32 getExecConditions() const { return exec_conds_mask; }
|
||||
|
||||
virtual void executeScriptEvent(const char* method, afxConstraint*,
|
||||
const MatrixF& xfm, const char* data);
|
||||
|
||||
virtual void inflictDamage(const char * label, const char* flavor, SimObjectId target,
|
||||
F32 amt, U8 count, F32 ad_amt, F32 rad, Point3F pos, F32 imp) { }
|
||||
|
||||
void addObjectConstraint(SceneObject*, const char* cons_name);
|
||||
void addObjectConstraint(U16 scope_id, const char* cons_name, bool is_shape);
|
||||
void addPointConstraint(Point3F&, const char* cons_name);
|
||||
void addTransformConstraint(MatrixF&, const char* cons_name);
|
||||
bool addConstraint(const char* source_spec, const char* cons_name);
|
||||
|
||||
void addNamedEffect(afxEffectWrapper*);
|
||||
void removeNamedEffect(afxEffectWrapper*);
|
||||
afxEffectWrapper* findNamedEffect(StringTableEntry);
|
||||
|
||||
void clearChoreographerId() { choreographer_id = 0; }
|
||||
U32 getChoreographerId() { return choreographer_id; }
|
||||
void setGhostConstraintObject(SceneObject*, StringTableEntry cons_name);
|
||||
void setExtra(SimObject* extra) { this->extra = extra; }
|
||||
void addExplicitClient(NetConnection* conn);
|
||||
void removeExplicitClient(NetConnection* conn);
|
||||
U32 getExplicitClientCount() { return explicit_clients.size(); }
|
||||
|
||||
void restoreScopedObject(SceneObject* obj);
|
||||
virtual void restoreObject(SceneObject*) { };
|
||||
|
||||
void postProcessAfterObject(GameBase* obj);
|
||||
U32 getTriggerMask() const { return trigger_mask; }
|
||||
void setTriggerMask(U32 trigger_mask);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// missile watcher callbacks
|
||||
public:
|
||||
virtual void impactNotify(const Point3F& p, const Point3F& n, SceneObject*) { }
|
||||
|
||||
DECLARE_CONOBJECT(afxChoreographer);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
// CONSTRAINT REMAPPING <<
|
||||
protected:
|
||||
Vector<dynConstraintDef*> remapped_cons_defs;
|
||||
bool remapped_cons_sent;
|
||||
virtual bool remap_builtin_constraint(SceneObject*, const char* cons_name) { return false; }
|
||||
dynConstraintDef* find_cons_def_by_name(const char* cons_name);
|
||||
public:
|
||||
void remapObjectConstraint(SceneObject*, const char* cons_name);
|
||||
void remapObjectConstraint(U16 scope_id, const char* cons_name, bool is_shape);
|
||||
void remapPointConstraint(Point3F&, const char* cons_name);
|
||||
void remapTransformConstraint(MatrixF&, const char* cons_name);
|
||||
bool remapConstraint(const char* source_spec, const char* cons_name);
|
||||
// CONSTRAINT REMAPPING >>
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_CHOREOGRAPHER_H_
|
||||
2613
Engine/source/afx/afxConstraint.cpp
Normal file
2613
Engine/source/afx/afxConstraint.cpp
Normal file
File diff suppressed because it is too large
Load diff
677
Engine/source/afx/afxConstraint.h
Normal file
677
Engine/source/afx/afxConstraint.h
Normal file
|
|
@ -0,0 +1,677 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_CONSTRAINT_H_
|
||||
#define _AFX_CONSTRAINT_H_
|
||||
|
||||
#include "core/util/tVector.h"
|
||||
#include "T3D/shapeBase.h"
|
||||
|
||||
#include "afxEffectDefs.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxConstraintDef
|
||||
|
||||
class afxEffectBaseData;
|
||||
|
||||
struct afxConstraintDef : public afxEffectDefs
|
||||
{
|
||||
enum DefType
|
||||
{
|
||||
CONS_UNDEFINED,
|
||||
CONS_PREDEFINED,
|
||||
CONS_SCENE,
|
||||
CONS_EFFECT,
|
||||
CONS_GHOST
|
||||
};
|
||||
|
||||
DefType def_type;
|
||||
|
||||
StringTableEntry cons_src_name;
|
||||
StringTableEntry cons_node_name;
|
||||
F32 history_time;
|
||||
U8 sample_rate;
|
||||
|
||||
bool runs_on_server;
|
||||
bool runs_on_client;
|
||||
bool pos_at_box_center;
|
||||
bool treat_as_camera;
|
||||
|
||||
/*C*/ afxConstraintDef();
|
||||
|
||||
bool isDefined();
|
||||
|
||||
bool isArbitraryObject();
|
||||
void reset();
|
||||
bool parseSpec(const char* spec, bool runs_on_server, bool runs_on_client);
|
||||
|
||||
static void gather_cons_defs(Vector<afxConstraintDef>& defs, Vector<afxEffectBaseData*>& fx);
|
||||
|
||||
static StringTableEntry SCENE_CONS_KEY;
|
||||
static StringTableEntry EFFECT_CONS_KEY;
|
||||
static StringTableEntry GHOST_CONS_KEY;
|
||||
};
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxConstraint
|
||||
// Abstract base-class for a simple constraint mechanism used to constrain
|
||||
// special effects to spell related objects such as the spellcaster, target,
|
||||
// projectile, or impact location.
|
||||
//
|
||||
// note -- the direction vectors don't really fit... should probably consider separate
|
||||
// constraint types for position, orientation, and possibly a look-at constraint.
|
||||
//
|
||||
|
||||
class SceneObject;
|
||||
class afxConstraintMgr;
|
||||
|
||||
class afxConstraint : public SimObject, public afxEffectDefs
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef SimObject Parent;
|
||||
|
||||
protected:
|
||||
afxConstraintMgr* mgr;
|
||||
afxConstraintDef cons_def;
|
||||
bool is_defined;
|
||||
bool is_valid;
|
||||
Point3F last_pos;
|
||||
MatrixF last_xfm;
|
||||
F32 history_time;
|
||||
bool is_alive;
|
||||
bool gone_missing;
|
||||
U32 change_code;
|
||||
|
||||
public:
|
||||
/*C*/ afxConstraint(afxConstraintMgr*);
|
||||
virtual ~afxConstraint();
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f)
|
||||
{ pos = last_pos; return is_valid; }
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f)
|
||||
{ xfm = last_xfm; return is_valid;}
|
||||
virtual bool getAltitudes(F32& terrain_alt, F32& interior_alt) { return false; }
|
||||
|
||||
virtual bool isDefined() { return is_defined; }
|
||||
virtual bool isValid() { return is_valid; }
|
||||
virtual U32 getChangeCode() { return change_code; }
|
||||
|
||||
virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans, bool is_death_anim)
|
||||
{ return 0; };
|
||||
virtual void resetAnimation(U32 tag) { };
|
||||
virtual U32 lockAnimation() { return 0; }
|
||||
virtual void unlockAnimation(U32 tag) { }
|
||||
virtual F32 getAnimClipDuration(const char* clip) { return 0.0f; }
|
||||
|
||||
virtual S32 getDamageState() { return -1; }
|
||||
virtual void setLivingState(bool state) { is_alive = state; };
|
||||
virtual bool getLivingState() { return is_alive; };
|
||||
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos)=0;
|
||||
|
||||
virtual SceneObject* getSceneObject()=0;
|
||||
virtual void restoreObject(SceneObject*)=0;
|
||||
virtual U16 getScopeId()=0;
|
||||
|
||||
virtual U32 getTriggers()=0;
|
||||
|
||||
virtual void set_scope_id(U16 scope_id) { }
|
||||
virtual void unset() { }
|
||||
};
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxConstraintMgr
|
||||
|
||||
class ShapeBase;
|
||||
class afxEffectWrapper;
|
||||
class afxShapeConstraint;
|
||||
class afxObjectConstraint;
|
||||
class BitStream;
|
||||
class NetConnection;
|
||||
|
||||
struct afxConstraintID
|
||||
{
|
||||
S16 index;
|
||||
S16 sub_index;
|
||||
|
||||
afxConstraintID() { index = -1; sub_index = 0; }
|
||||
afxConstraintID(S16 idx, S16 sub=0) { index = idx; sub_index = sub; }
|
||||
bool undefined() const { return (index < 0); }
|
||||
};
|
||||
|
||||
typedef Vector<afxConstraint*> afxConstraintList;
|
||||
|
||||
class afxConstraintMgr : public afxEffectDefs
|
||||
{
|
||||
typedef SimObject Parent;
|
||||
|
||||
struct preDef
|
||||
{
|
||||
StringTableEntry name;
|
||||
U32 type;
|
||||
};
|
||||
|
||||
Vector<afxConstraintList*> constraints_v;
|
||||
|
||||
Vector<StringTableEntry> names_on_server;
|
||||
Vector<S32> ghost_ids;
|
||||
Vector<preDef> predefs;
|
||||
U32 starttime;
|
||||
bool on_server;
|
||||
bool initialized;
|
||||
F32 scoping_dist_sq;
|
||||
|
||||
SceneObject* find_object_from_name(StringTableEntry);
|
||||
S32 find_cons_idx_from_name(StringTableEntry);
|
||||
S32 find_effect_cons_idx_from_name(StringTableEntry);
|
||||
|
||||
void create_constraint(const afxConstraintDef&);
|
||||
void set_ref_shape(afxConstraintID which_id, ShapeBase*);
|
||||
void set_ref_shape(afxConstraintID which_id, U16 scope_id);
|
||||
|
||||
public:
|
||||
/*C*/ afxConstraintMgr();
|
||||
/*D*/ ~afxConstraintMgr();
|
||||
|
||||
void defineConstraint(U32 type, StringTableEntry);
|
||||
|
||||
afxConstraintID setReferencePoint(StringTableEntry which, Point3F point);
|
||||
afxConstraintID setReferencePoint(StringTableEntry which, Point3F point, Point3F vector);
|
||||
afxConstraintID setReferenceTransform(StringTableEntry which, MatrixF& xfm);
|
||||
afxConstraintID setReferenceObject(StringTableEntry which, SceneObject*);
|
||||
afxConstraintID setReferenceObjectByScopeId(StringTableEntry which, U16 scope_id, bool is_shape);
|
||||
afxConstraintID setReferenceEffect(StringTableEntry which, afxEffectWrapper*);
|
||||
afxConstraintID createReferenceEffect(StringTableEntry which, afxEffectWrapper*);
|
||||
|
||||
void setReferencePoint(afxConstraintID which_id, Point3F point);
|
||||
void setReferencePoint(afxConstraintID which_id, Point3F point, Point3F vector);
|
||||
void setReferenceTransform(afxConstraintID which_id, MatrixF& xfm);
|
||||
void setReferenceObject(afxConstraintID which_id, SceneObject*);
|
||||
void setReferenceObjectByScopeId(afxConstraintID which_id, U16 scope_id, bool is_shape);
|
||||
void setReferenceEffect(afxConstraintID which_id, afxEffectWrapper*);
|
||||
|
||||
void invalidateReference(afxConstraintID which_id);
|
||||
|
||||
afxConstraintID getConstraintId(const afxConstraintDef&);
|
||||
afxConstraint* getConstraint(afxConstraintID cons_id);
|
||||
|
||||
void sample(F32 dt, U32 now, const Point3F* cam_pos=0);
|
||||
|
||||
void setStartTime(U32 timestamp) { starttime = timestamp; }
|
||||
void initConstraintDefs(Vector<afxConstraintDef>&, bool on_server, F32 scoping_dist=-1.0f);
|
||||
void packConstraintNames(NetConnection* conn, BitStream* stream);
|
||||
void unpackConstraintNames(BitStream* stream);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// scope-tracking
|
||||
private:
|
||||
Vector<SceneObject*> scopeable_objs;
|
||||
Vector<U16> scopeable_ids;
|
||||
Vector<afxConstraint*>* missing_objs;
|
||||
Vector<afxConstraint*>* missing_objs2;
|
||||
Vector<afxConstraint*> missing_objs_a;
|
||||
Vector<afxConstraint*> missing_objs_b;
|
||||
|
||||
public:
|
||||
void addScopeableObject(SceneObject*);
|
||||
void removeScopeableObject(SceneObject*);
|
||||
void clearAllScopeableObjs();
|
||||
|
||||
void postMissingConstraintObject(afxConstraint*, bool is_deleting=false);
|
||||
void restoreScopedObject(SceneObject*, afxChoreographer* ch);
|
||||
void adjustProcessOrdering(afxChoreographer*);
|
||||
|
||||
F32 getScopingDistanceSquared() const { return scoping_dist_sq; }
|
||||
};
|
||||
|
||||
inline afxConstraintID afxConstraintMgr::setReferencePoint(StringTableEntry which, Point3F point)
|
||||
{
|
||||
return setReferencePoint(which, point, Point3F(0,0,1));
|
||||
}
|
||||
|
||||
inline void afxConstraintMgr::setReferencePoint(afxConstraintID which, Point3F point)
|
||||
{
|
||||
setReferencePoint(which, point, Point3F(0,0,1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPointConstraint
|
||||
// This constrains to a specific 3D position such as an impact location.
|
||||
//
|
||||
|
||||
class afxPointConstraint : public afxConstraint
|
||||
{
|
||||
typedef afxConstraint Parent;
|
||||
|
||||
protected:
|
||||
Point3F point;
|
||||
Point3F vector;
|
||||
|
||||
public:
|
||||
/*C*/ afxPointConstraint(afxConstraintMgr*);
|
||||
virtual ~afxPointConstraint();
|
||||
|
||||
virtual void set(Point3F point, Point3F vector);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual SceneObject* getSceneObject() { return 0; }
|
||||
virtual void restoreObject(SceneObject*) { }
|
||||
virtual U16 getScopeId() { return 0; }
|
||||
virtual U32 getTriggers() { return 0; }
|
||||
|
||||
virtual void unset() { set(Point3F::Zero, Point3F(0,0,1)); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxTransformConstraint
|
||||
// This constrains to a specific 3D transformation.
|
||||
//
|
||||
|
||||
class afxTransformConstraint : public afxConstraint
|
||||
{
|
||||
typedef afxConstraint Parent;
|
||||
|
||||
protected:
|
||||
MatrixF xfm;
|
||||
|
||||
public:
|
||||
/*C*/ afxTransformConstraint(afxConstraintMgr*);
|
||||
virtual ~afxTransformConstraint();
|
||||
|
||||
virtual void set(const MatrixF& xfm);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual SceneObject* getSceneObject() { return 0; }
|
||||
virtual void restoreObject(SceneObject*) { }
|
||||
virtual U16 getScopeId() { return 0; }
|
||||
virtual U32 getTriggers() { return 0; }
|
||||
|
||||
virtual void unset() { set(MatrixF::Identity); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxShapeConstraint
|
||||
// This constrains to a hierarchical shape (subclasses of ShapeBase), such as a
|
||||
// Player or a Vehicle. You can also constrain to named sub-nodes of a shape.
|
||||
|
||||
class ShapeBase;
|
||||
class SceneObject;
|
||||
|
||||
class afxShapeConstraint : public afxConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxConstraint Parent;
|
||||
|
||||
protected:
|
||||
StringTableEntry arb_name;
|
||||
ShapeBase* shape;
|
||||
U16 scope_id;
|
||||
U32 clip_tag;
|
||||
U32 lock_tag;
|
||||
|
||||
public:
|
||||
/*C*/ afxShapeConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxShapeConstraint(afxConstraintMgr*, StringTableEntry arb_name);
|
||||
virtual ~afxShapeConstraint();
|
||||
|
||||
virtual void set(ShapeBase* shape);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans, bool is_death_anim);
|
||||
virtual void resetAnimation(U32 tag);
|
||||
virtual U32 lockAnimation();
|
||||
virtual void unlockAnimation(U32 tag);
|
||||
virtual F32 getAnimClipDuration(const char* clip);
|
||||
|
||||
void remapAnimation(U32 tag, ShapeBase* other_shape);
|
||||
|
||||
virtual S32 getDamageState();
|
||||
|
||||
virtual SceneObject* getSceneObject() { return shape; }
|
||||
virtual void restoreObject(SceneObject*);
|
||||
virtual U16 getScopeId() { return scope_id; }
|
||||
virtual U32 getTriggers();
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
|
||||
virtual void unset() { set(0); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxShapeNodeConstraint
|
||||
|
||||
class afxShapeNodeConstraint : public afxShapeConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxShapeConstraint Parent;
|
||||
|
||||
protected:
|
||||
StringTableEntry arb_node;
|
||||
S32 shape_node_ID;
|
||||
|
||||
public:
|
||||
/*C*/ afxShapeNodeConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxShapeNodeConstraint(afxConstraintMgr*, StringTableEntry arb_name, StringTableEntry arb_node);
|
||||
|
||||
virtual void set(ShapeBase* shape);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
virtual void restoreObject(SceneObject*);
|
||||
|
||||
S32 getNodeID() const { return shape_node_ID; }
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxObjectConstraint
|
||||
// This constrains to a simple 3D object (subclasses of SceneObject), such as an
|
||||
// afxMagicMissile or a Projectile. You cannot constrain to sub-nodes with an
|
||||
// afxObjectConstraint, use afxShapeConstraint instead.
|
||||
|
||||
class SceneObject;
|
||||
|
||||
class afxObjectConstraint : public afxConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxConstraint Parent;
|
||||
|
||||
protected:
|
||||
StringTableEntry arb_name;
|
||||
SceneObject* obj;
|
||||
U16 scope_id;
|
||||
bool is_camera;
|
||||
|
||||
public:
|
||||
afxObjectConstraint(afxConstraintMgr*);
|
||||
afxObjectConstraint(afxConstraintMgr*, StringTableEntry arb_name);
|
||||
virtual ~afxObjectConstraint();
|
||||
|
||||
virtual void set(SceneObject* obj);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual SceneObject* getSceneObject() { return obj; }
|
||||
virtual void restoreObject(SceneObject*);
|
||||
virtual U16 getScopeId() { return scope_id; }
|
||||
virtual U32 getTriggers();
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
|
||||
virtual void unset() { set(0); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectConstraint
|
||||
// This constrains to a hierarchical shape (subclasses of ShapeBase), such as a
|
||||
// Player or a Vehicle. You can also constrain to named sub-nodes of a shape.
|
||||
|
||||
class afxEffectWrapper;
|
||||
|
||||
class afxEffectConstraint : public afxConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxConstraint Parent;
|
||||
|
||||
protected:
|
||||
StringTableEntry effect_name;
|
||||
afxEffectWrapper* effect;
|
||||
U32 clip_tag;
|
||||
bool is_death_clip;
|
||||
U32 lock_tag;
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxEffectConstraint(afxConstraintMgr*, StringTableEntry effect_name);
|
||||
virtual ~afxEffectConstraint();
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
virtual bool getAltitudes(F32& terrain_alt, F32& interior_alt);
|
||||
|
||||
virtual void set(afxEffectWrapper* effect);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos) { }
|
||||
|
||||
virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans, bool is_death_anim);
|
||||
virtual void resetAnimation(U32 tag);
|
||||
virtual F32 getAnimClipDuration(const char* clip);
|
||||
|
||||
virtual SceneObject* getSceneObject() { return 0; }
|
||||
virtual void restoreObject(SceneObject*) { }
|
||||
virtual U16 getScopeId() { return 0; }
|
||||
virtual U32 getTriggers();
|
||||
|
||||
virtual void unset() { set(0); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectNodeConstraint
|
||||
|
||||
class afxEffectNodeConstraint : public afxEffectConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxEffectConstraint Parent;
|
||||
|
||||
protected:
|
||||
StringTableEntry effect_node;
|
||||
S32 effect_node_ID;
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectNodeConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxEffectNodeConstraint(afxConstraintMgr*, StringTableEntry name, StringTableEntry node);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
|
||||
virtual void set(afxEffectWrapper* effect);
|
||||
|
||||
S32 getNodeID() const { return effect_node_ID; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxSampleBuffer
|
||||
|
||||
class afxSampleBuffer
|
||||
{
|
||||
protected:
|
||||
U32 buffer_sz;
|
||||
U32 buffer_ms;
|
||||
U32 ms_per_sample;
|
||||
U32 elapsed_ms;
|
||||
U32 last_sample_ms;
|
||||
U32 next_sample_num;
|
||||
U32 n_samples;
|
||||
|
||||
virtual void recSample(U32 idx, void* data) = 0;
|
||||
bool compute_idx_from_lag(F32 lag, U32& idx);
|
||||
bool compute_idx_from_lag(F32 lag, U32& idx1, U32& idx2, F32& t);
|
||||
|
||||
public:
|
||||
/*C*/ afxSampleBuffer();
|
||||
virtual ~afxSampleBuffer();
|
||||
|
||||
virtual void configHistory(F32 hist_len, U8 sample_rate);
|
||||
void recordSample(F32 dt, U32 elapsed_ms, void* data);
|
||||
virtual void getSample(F32 lag, void* data, bool& oob) = 0;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxSampleXfmBuffer
|
||||
|
||||
class afxSampleXfmBuffer : public afxSampleBuffer
|
||||
{
|
||||
typedef afxSampleBuffer Parent;
|
||||
|
||||
protected:
|
||||
MatrixF* xfm_buffer;
|
||||
|
||||
virtual void recSample(U32 idx, void* data);
|
||||
|
||||
public:
|
||||
/*C*/ afxSampleXfmBuffer();
|
||||
virtual ~afxSampleXfmBuffer();
|
||||
|
||||
virtual void configHistory(F32 hist_len, U8 sample_rate);
|
||||
virtual void getSample(F32 lag, void* data, bool& oob);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPointHistConstraint
|
||||
// This class extends afxPointConstraint to remember its values for a period of time.
|
||||
|
||||
class afxPointHistConstraint : public afxPointConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxPointConstraint Parent;
|
||||
|
||||
protected:
|
||||
afxSampleBuffer* samples;
|
||||
|
||||
public:
|
||||
/*C*/ afxPointHistConstraint(afxConstraintMgr*);
|
||||
virtual ~afxPointHistConstraint();
|
||||
|
||||
virtual void set(Point3F point, Point3F vector);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPointHistConstraint
|
||||
// This class extends afxTransformConstraint to remember its values for a period of time.
|
||||
|
||||
class afxTransformHistConstraint : public afxTransformConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxTransformConstraint Parent;
|
||||
|
||||
protected:
|
||||
afxSampleBuffer* samples;
|
||||
|
||||
public:
|
||||
/*C*/ afxTransformHistConstraint(afxConstraintMgr*);
|
||||
virtual ~afxTransformHistConstraint();
|
||||
|
||||
virtual void set(const MatrixF& xfm);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxShapeHistConstraint
|
||||
// This class extends afxShapeConstraint to remember its values for a period of time.
|
||||
|
||||
class afxShapeHistConstraint : public afxShapeConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxShapeConstraint Parent;
|
||||
|
||||
protected:
|
||||
afxSampleBuffer* samples;
|
||||
|
||||
public:
|
||||
/*C*/ afxShapeHistConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxShapeHistConstraint(afxConstraintMgr*, StringTableEntry arb_name);
|
||||
virtual ~afxShapeHistConstraint();
|
||||
|
||||
virtual void set(ShapeBase* shape);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxShapeNodeHistConstraint
|
||||
// This class extends afxShapeConstraint to remember its values for a period of time.
|
||||
|
||||
class afxShapeNodeHistConstraint : public afxShapeNodeConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxShapeNodeConstraint Parent;
|
||||
|
||||
protected:
|
||||
afxSampleBuffer* samples;
|
||||
|
||||
public:
|
||||
/*C*/ afxShapeNodeHistConstraint(afxConstraintMgr*);
|
||||
/*C*/ afxShapeNodeHistConstraint(afxConstraintMgr*, StringTableEntry arb_name, StringTableEntry arb_node);
|
||||
virtual ~afxShapeNodeHistConstraint();
|
||||
|
||||
virtual void set(ShapeBase* shape);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxObjectHistConstraint
|
||||
// This class extends afxObjectConstraint to remember its values for a period of time.
|
||||
|
||||
class SceneObject;
|
||||
|
||||
class afxObjectHistConstraint : public afxObjectConstraint
|
||||
{
|
||||
friend class afxConstraintMgr;
|
||||
typedef afxObjectConstraint Parent;
|
||||
|
||||
protected:
|
||||
afxSampleBuffer* samples;
|
||||
|
||||
public:
|
||||
afxObjectHistConstraint(afxConstraintMgr*);
|
||||
afxObjectHistConstraint(afxConstraintMgr*, StringTableEntry arb_name);
|
||||
virtual ~afxObjectHistConstraint();
|
||||
|
||||
virtual void set(SceneObject* obj);
|
||||
virtual void set_scope_id(U16 scope_id);
|
||||
virtual void sample(F32 dt, U32 elapsed_ms, const Point3F* cam_pos);
|
||||
|
||||
virtual bool getPosition(Point3F& pos, F32 hist=0.0f);
|
||||
virtual bool getTransform(MatrixF& xfm, F32 hist=0.0f);
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_CONSTRAINT_H_
|
||||
|
||||
114
Engine/source/afx/afxEffectDefs.h
Normal file
114
Engine/source/afx/afxEffectDefs.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_EFFECT_DEFS_H_
|
||||
#define _AFX_EFFECT_DEFS_H_
|
||||
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectBASE
|
||||
|
||||
class afxEffectDefs
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_EFFECTS_PER_PHRASE = 1023,
|
||||
EFFECTS_PER_PHRASE_BITS = 10
|
||||
};
|
||||
|
||||
// effect networking
|
||||
enum
|
||||
{
|
||||
SERVER_ONLY = BIT(0),
|
||||
SCOPE_ALWAYS = BIT(1),
|
||||
GHOSTABLE = BIT(2),
|
||||
CLIENT_ONLY = BIT(3),
|
||||
SERVER_AND_CLIENT = BIT(4)
|
||||
};
|
||||
|
||||
// effect condititons
|
||||
enum
|
||||
{
|
||||
DISABLED = BIT(0),
|
||||
ENABLED = BIT(1),
|
||||
FAILING = BIT(2),
|
||||
ALIVE = ENABLED,
|
||||
DEAD = DISABLED,
|
||||
DYING = FAILING,
|
||||
//
|
||||
IMPACTED_SOMETHING = BIT(31),
|
||||
IMPACTED_TARGET = BIT(30),
|
||||
IMPACTED_PRIMARY = BIT(29),
|
||||
IMPACT_IN_WATER = BIT(28),
|
||||
CASTER_IN_WATER = BIT(27),
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REQUIRES_STOP = BIT(0),
|
||||
RUNS_ON_SERVER = BIT(1),
|
||||
RUNS_ON_CLIENT = BIT(2),
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_XFM_MODIFIERS = 32,
|
||||
INFINITE_LIFETIME = (24*60*60)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
POINT_CONSTRAINT,
|
||||
TRANSFORM_CONSTRAINT,
|
||||
OBJECT_CONSTRAINT,
|
||||
CAMERA_CONSTRAINT,
|
||||
OBJECT_CONSTRAINT_SANS_OBJ,
|
||||
OBJECT_CONSTRAINT_SANS_SHAPE,
|
||||
UNDEFINED_CONSTRAINT_TYPE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DIRECT_DAMAGE,
|
||||
DAMAGE_OVER_TIME,
|
||||
AREA_DAMAGE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TIMING_DELAY = BIT(0),
|
||||
TIMING_LIFETIME = BIT(1),
|
||||
TIMING_FADE_IN = BIT(2),
|
||||
TIMING_FADE_OUT = BIT(3),
|
||||
TIMING_BITS = 2
|
||||
};
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_EFFECT_DEFS_H_
|
||||
270
Engine/source/afx/afxEffectGroup.cpp
Normal file
270
Engine/source/afx/afxEffectGroup.cpp
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#include "afx/afxEffectGroup.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectGroupData::egValidator
|
||||
//
|
||||
// When an effect is added using "addEffect", this validator intercepts the value
|
||||
// and adds it to the dynamic effects list.
|
||||
//
|
||||
void afxEffectGroupData::egValidator::validateType(SimObject* object, void* typePtr)
|
||||
{
|
||||
afxEffectGroupData* eff_data = dynamic_cast<afxEffectGroupData*>(object);
|
||||
afxEffectBaseData** ew = (afxEffectBaseData**)(typePtr);
|
||||
|
||||
if (eff_data && ew)
|
||||
{
|
||||
eff_data->fx_list.push_back(*ew);
|
||||
*ew = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectGroupData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxEffectGroupData);
|
||||
|
||||
ConsoleDocClass( afxEffectGroupData,
|
||||
"@brief A datablock that describes an Effect Group.\n\n"
|
||||
|
||||
"afxEffectGroupData provides a way for adding several effects to a choreographer as a "
|
||||
"group and can be used wherever an afxEffectWrapperData is used. Basically, an "
|
||||
"effect-group is a simple list of effect-wrappers. When an effect-group is added to a "
|
||||
"choreographer, the end result is almost the same as adding all of the group's "
|
||||
"effect-wrappers directly to the choreographer. The main difference is that the "
|
||||
"grouped effects can be turned on and off collectively and created in multiples. "
|
||||
"Effect-groups can also contain other effect-groups, forming a hierarchy of effects.\n\n"
|
||||
|
||||
"A great strength of effect-groups is that they have a count setting that multiplies "
|
||||
"the number of times the effects in the group are added to the owning choreographer "
|
||||
"and this doesn't happen until the choreographer instance is created and launched. "
|
||||
"This makes a big difference for certain kinds of effects, such as fireworks, that "
|
||||
"tend to consist of small groupings of effects that are repeated many times with "
|
||||
"slight variations. With groups, an effect like this has a very compact representation "
|
||||
"for transmitting from server to clients, that only expands when actually used.\n\n"
|
||||
|
||||
"Effect-groups with a count greater than one are extremely useful when some of the "
|
||||
"effects use field substitutions. When an effect-group is expanded, it essentially runs "
|
||||
"through a for-loop from 0 to count-1 and creates a new set of effect instances each "
|
||||
"time through the loop. For each new set of effects, their group-index is set to the "
|
||||
"index of this for-loop, which in turn replaces the ## token used in any field "
|
||||
"substitutions in the child effects. In essence, the for-loop index becomes a parameter "
|
||||
"of the child effects which can be used to vary the effects created in each loop.\n\n"
|
||||
|
||||
"@see afxEffectBaseData\n\n"
|
||||
"@see afxEffectWrapperData\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxEffectGroupData::afxEffectGroupData()
|
||||
{
|
||||
group_enabled = true;
|
||||
group_count = 1;
|
||||
idx_offset = 0;
|
||||
assign_idx = false;
|
||||
|
||||
// dummy entry holds effect-wrapper pointer while a special validator
|
||||
// grabs it and adds it to an appropriate effects list
|
||||
dummy_fx_entry = NULL;
|
||||
|
||||
// marked true if datablock ids need to
|
||||
// be converted into pointers
|
||||
do_id_convert = false;
|
||||
}
|
||||
|
||||
afxEffectGroupData::afxEffectGroupData(const afxEffectGroupData& other, bool temp_clone) : afxEffectBaseData(other, temp_clone)
|
||||
{
|
||||
group_enabled = other.group_enabled;
|
||||
group_count = other.group_count;
|
||||
idx_offset = other.idx_offset;
|
||||
assign_idx = other.assign_idx;
|
||||
timing = other.timing;
|
||||
dummy_fx_entry = other.dummy_fx_entry;
|
||||
do_id_convert = other.do_id_convert; // --
|
||||
fx_list = other.fx_list; // --
|
||||
}
|
||||
|
||||
void afxEffectGroupData::reloadReset()
|
||||
{
|
||||
fx_list.clear();
|
||||
}
|
||||
|
||||
void afxEffectGroupData::pack_fx(BitStream* stream, const afxEffectList& fx, bool packed)
|
||||
{
|
||||
stream->writeInt(fx.size(), EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < fx.size(); i++)
|
||||
writeDatablockID(stream, fx[i], packed);
|
||||
}
|
||||
|
||||
void afxEffectGroupData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
||||
{
|
||||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxEffectGroupData)
|
||||
|
||||
void afxEffectGroupData::initPersistFields()
|
||||
{
|
||||
addField("groupEnabled", TypeBool, myOffset(group_enabled),
|
||||
"...");
|
||||
addField("count", TypeS32, myOffset(group_count),
|
||||
"...");
|
||||
addField("indexOffset", TypeS8, myOffset(idx_offset),
|
||||
"...");
|
||||
addField("assignIndices", TypeBool, myOffset(assign_idx),
|
||||
"...");
|
||||
|
||||
addField("delay", TypeF32, myOffset(timing.delay),
|
||||
"...");
|
||||
addField("lifetime", TypeF32, myOffset(timing.lifetime),
|
||||
"...");
|
||||
addField("fadeInTime", TypeF32, myOffset(timing.fade_in_time),
|
||||
"...");
|
||||
addField("fadeOutTime", TypeF32, myOffset(timing.fade_out_time),
|
||||
"...");
|
||||
|
||||
// effect lists
|
||||
// for each of these, dummy_fx_entry is set and then a validator adds it to the appropriate effects list
|
||||
static egValidator emptyValidator(0);
|
||||
|
||||
addFieldV("addEffect", TYPEID<afxEffectBaseData>(), myOffset(dummy_fx_entry), &emptyValidator,
|
||||
"...");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// disallow some field substitutions
|
||||
disableFieldSubstitutions("addEffect");
|
||||
}
|
||||
|
||||
void afxEffectGroupData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeFlag(group_enabled);
|
||||
stream->write(group_count);
|
||||
stream->write(idx_offset);
|
||||
stream->writeFlag(assign_idx);
|
||||
stream->write(timing.delay);
|
||||
stream->write(timing.lifetime);
|
||||
stream->write(timing.fade_in_time);
|
||||
stream->write(timing.fade_out_time);
|
||||
|
||||
pack_fx(stream, fx_list, packed);
|
||||
}
|
||||
|
||||
void afxEffectGroupData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
group_enabled = stream->readFlag();
|
||||
stream->read(&group_count);
|
||||
stream->read(&idx_offset);
|
||||
assign_idx = stream->readFlag();
|
||||
stream->read(&timing.delay);
|
||||
stream->read(&timing.lifetime);
|
||||
stream->read(&timing.fade_in_time);
|
||||
stream->read(&timing.fade_out_time);
|
||||
|
||||
do_id_convert = true;
|
||||
unpack_fx(stream, fx_list);
|
||||
}
|
||||
|
||||
bool afxEffectGroupData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server)
|
||||
{
|
||||
if (do_id_convert)
|
||||
{
|
||||
for (S32 i = 0; i < fx_list.size(); i++)
|
||||
{
|
||||
SimObjectId db_id = SimObjectId((uintptr_t)fx_list[i]);
|
||||
if (db_id != 0)
|
||||
{
|
||||
// try to convert id to pointer
|
||||
if (!Sim::findObject(db_id, fx_list[i]))
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"afxEffectGroupData::preload() -- bad datablockId: 0x%x",
|
||||
db_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
do_id_convert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEffectGroupData::gather_cons_defs(Vector<afxConstraintDef>& defs)
|
||||
{
|
||||
for (S32 i = 0; i < fx_list.size(); i++)
|
||||
{
|
||||
if (fx_list[i])
|
||||
fx_list[i]->gather_cons_defs(defs);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
DefineEngineMethod(afxEffectGroupData, reset, void, (),,
|
||||
"Resets an effect-group datablock during reload.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
object->reloadReset();
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxEffectGroupData, addEffect, void, (afxEffectBaseData* effect),,
|
||||
"Adds an effect (wrapper or group) to an effect-group.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (!effect)
|
||||
{
|
||||
Con::errorf("afxEffectGroupData::addEffect() -- missing afxEffectWrapperData.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->fx_list.push_back(effect);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
103
Engine/source/afx/afxEffectGroup.h
Normal file
103
Engine/source/afx/afxEffectGroup.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_EFFECT_GROUP_H_
|
||||
#define _AFX_EFFECT_GROUP_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
|
||||
class afxEffectWrapperData;
|
||||
|
||||
struct afxGroupTimingData
|
||||
{
|
||||
F32 delay;
|
||||
F32 lifetime;
|
||||
F32 fade_in_time;
|
||||
F32 fade_out_time;
|
||||
|
||||
afxGroupTimingData()
|
||||
{
|
||||
delay = 0.0f;
|
||||
lifetime = 0.0f;
|
||||
fade_in_time = 0.0f;
|
||||
fade_out_time = 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
class afxEffectGroupData : public afxEffectBaseData
|
||||
{
|
||||
typedef afxEffectBaseData Parent;
|
||||
|
||||
class egValidator : public TypeValidator
|
||||
{
|
||||
U32 id;
|
||||
public:
|
||||
egValidator(U32 id) { this->id = id; }
|
||||
void validateType(SimObject *object, void *typePtr);
|
||||
};
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
afxEffectList fx_list;
|
||||
bool group_enabled;
|
||||
S32 group_count;
|
||||
U8 idx_offset;
|
||||
bool assign_idx;
|
||||
afxGroupTimingData timing;
|
||||
afxEffectBaseData* dummy_fx_entry;
|
||||
|
||||
private:
|
||||
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
|
||||
void unpack_fx(BitStream* stream, afxEffectList& fx);
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectGroupData();
|
||||
/*C*/ afxEffectGroupData(const afxEffectGroupData&, bool = false);
|
||||
|
||||
virtual void reloadReset();
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectGroupData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
#endif // _AFX_EFFECT_GROUP_H_
|
||||
358
Engine/source/afx/afxEffectVector.cpp
Normal file
358
Engine/source/afx/afxEffectVector.cpp
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "afxChoreographer.h"
|
||||
#include "afxEffectVector.h"
|
||||
#include "afxConstraint.h"
|
||||
#include "afxEffectWrapper.h"
|
||||
#include "afxEffectGroup.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxEffectVector::filter_client_server()
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
for (S32 i = 0; i < fx_v->size(); i++)
|
||||
{
|
||||
if ((*fx_v)[i]->datablock->runsHere(on_server))
|
||||
fx_v2->push_back((*fx_v)[i]);
|
||||
else
|
||||
{
|
||||
delete (*fx_v)[i];
|
||||
(*fx_v)[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
swap_vecs();
|
||||
|
||||
fx_v2->clear();
|
||||
}
|
||||
|
||||
void afxEffectVector::calc_fx_dur_and_afterlife()
|
||||
{
|
||||
total_fx_dur = 0.0f;
|
||||
after_life = 0.0f;
|
||||
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
for (S32 i = 0; i < fx_v->size(); i++)
|
||||
{
|
||||
afxEffectWrapper* ew = (*fx_v)[i];
|
||||
if (ew)
|
||||
{
|
||||
F32 ew_dur;
|
||||
if (ew->ew_timing.lifetime < 0)
|
||||
{
|
||||
if (phrase_dur > ew->ew_timing.delay)
|
||||
ew_dur = phrase_dur + ew->afterStopTime();
|
||||
else
|
||||
ew_dur = ew->ew_timing.delay + ew->afterStopTime();
|
||||
}
|
||||
else
|
||||
ew_dur = ew->ew_timing.delay + ew->ew_timing.lifetime + ew->ew_timing.fade_out_time;
|
||||
|
||||
if (ew_dur > total_fx_dur)
|
||||
total_fx_dur = ew_dur;
|
||||
|
||||
F32 after = ew->afterStopTime();
|
||||
if (after > after_life)
|
||||
after_life = after;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEffectVector::afxEffectVector()
|
||||
{
|
||||
fx_v = 0;
|
||||
fx_v2 = 0;
|
||||
active = false;
|
||||
on_server = false;
|
||||
total_fx_dur = 0;
|
||||
after_life = 0;
|
||||
}
|
||||
|
||||
afxEffectVector::~afxEffectVector()
|
||||
{
|
||||
stop(true);
|
||||
delete fx_v;
|
||||
delete fx_v2;
|
||||
}
|
||||
|
||||
void afxEffectVector::effects_init(afxChoreographer* chor, afxEffectList& effects, bool will_stop, F32 time_factor,
|
||||
S32 group_index, const afxGroupTimingData* group_timing)
|
||||
{
|
||||
afxConstraintMgr* cons_mgr = chor->getConstraintMgr();
|
||||
|
||||
for (S32 i = 0; i < effects.size(); i++)
|
||||
{
|
||||
if (dynamic_cast<afxEffectGroupData*>(effects[i]))
|
||||
{
|
||||
afxEffectGroupData* eg = (afxEffectGroupData*)effects[i];
|
||||
if (eg->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxEffectGroupData* orig_db = eg;
|
||||
eg = new afxEffectGroupData(*orig_db, true);
|
||||
orig_db->performSubstitutions(eg, chor, group_index);
|
||||
}
|
||||
|
||||
if (eg->group_enabled)
|
||||
{
|
||||
if (eg->assign_idx)
|
||||
{
|
||||
for (S32 j = 0; j < eg->group_count; j++)
|
||||
effects_init(chor, eg->fx_list, will_stop, time_factor, j+eg->idx_offset, &eg->timing);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 j = 0; j < eg->group_count; j++)
|
||||
effects_init(chor, eg->fx_list, will_stop, time_factor, group_index, &eg->timing);
|
||||
}
|
||||
}
|
||||
|
||||
if (eg->isTempClone())
|
||||
delete eg;
|
||||
}
|
||||
else if (dynamic_cast<afxEffectWrapperData*>(effects[i]))
|
||||
{
|
||||
afxEffectWrapperData* ewd = (afxEffectWrapperData*)effects[i];
|
||||
|
||||
if (ewd->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the ewd and perform substitutions
|
||||
afxEffectWrapperData* orig_db = ewd;
|
||||
ewd = new afxEffectWrapperData(*orig_db, true);
|
||||
orig_db->performSubstitutions(ewd, chor, group_index);
|
||||
}
|
||||
|
||||
if (ewd->effect_enabled)
|
||||
{
|
||||
static afxEffectTimingData inherited_timing;
|
||||
bool use_inherited_timing = false;
|
||||
if (ewd->inherit_timing != 0)
|
||||
{
|
||||
if (group_timing)
|
||||
{
|
||||
inherited_timing = ewd->ewd_timing;
|
||||
if ((ewd->inherit_timing & afxEffectDefs::TIMING_DELAY) != 0)
|
||||
inherited_timing.delay = group_timing->delay;
|
||||
if ((ewd->inherit_timing & afxEffectDefs::TIMING_LIFETIME) != 0)
|
||||
inherited_timing.lifetime = group_timing->lifetime;
|
||||
if ((ewd->inherit_timing & afxEffectDefs::TIMING_FADE_IN) != 0)
|
||||
inherited_timing.fade_in_time = group_timing->fade_in_time;
|
||||
if ((ewd->inherit_timing & afxEffectDefs::TIMING_FADE_OUT) != 0)
|
||||
inherited_timing.fade_out_time = group_timing->fade_out_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::warnf("afxEffectVector::effects_init() -- %s::inheritGroupTiming is non-zero but wrapper is not in a group.");
|
||||
}
|
||||
}
|
||||
|
||||
const afxEffectTimingData& timing = (use_inherited_timing) ? inherited_timing : ewd->ewd_timing;
|
||||
|
||||
if ( (will_stop || !ewd->requiresStop(timing)) &&
|
||||
(chor->testRanking(ewd->ranking_range.low, ewd->ranking_range.high)) &&
|
||||
(chor->testLevelOfDetail(ewd->lod_range.low, ewd->lod_range.high)) &&
|
||||
(ewd->testExecConditions(chor->getExecConditions()))
|
||||
)
|
||||
{
|
||||
afxEffectWrapper* effect;
|
||||
effect = afxEffectWrapper::ew_create(chor, ewd, cons_mgr, time_factor, group_index);
|
||||
if (effect)
|
||||
fx_v->push_back(effect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ewd->isTempClone())
|
||||
delete ewd;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afxEffectVector::ev_init(afxChoreographer* chor, afxEffectList& effects, bool on_server,
|
||||
bool will_stop, F32 time_factor, F32 phrase_dur, S32 group_index)
|
||||
{
|
||||
this->on_server = on_server;
|
||||
this->phrase_dur = phrase_dur;
|
||||
|
||||
fx_v = new Vector<afxEffectWrapper*>;
|
||||
|
||||
effects_init(chor, effects, will_stop, time_factor, group_index);
|
||||
|
||||
fx_v2 = new Vector<afxEffectWrapper*>(fx_v->size());
|
||||
}
|
||||
|
||||
void afxEffectVector::start(F32 timestamp)
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
// At this point both client and server effects are in the list.
|
||||
// Timing adjustments are made during prestart().
|
||||
for (S32 i = 0; i < fx_v->size(); i++)
|
||||
(*fx_v)[i]->prestart();
|
||||
|
||||
// duration and afterlife values are pre-calculated here
|
||||
calc_fx_dur_and_afterlife();
|
||||
|
||||
// now we filter out client-only or server-only effects that
|
||||
// don't belong here,
|
||||
filter_client_server();
|
||||
|
||||
active = true;
|
||||
|
||||
for (S32 j = 0; j < fx_v->size(); j++)
|
||||
{
|
||||
if ((*fx_v)[j]->start(timestamp))
|
||||
fx_v2->push_back((*fx_v)[j]);
|
||||
else
|
||||
{
|
||||
delete (*fx_v)[j];
|
||||
(*fx_v)[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
swap_vecs();
|
||||
fx_v2->clear();
|
||||
}
|
||||
|
||||
void afxEffectVector::update(F32 dt)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fx_v->size(); i++)
|
||||
{
|
||||
(*fx_v)[i]->update(dt);
|
||||
|
||||
if ((*fx_v)[i]->isDone() || (*fx_v)[i]->isAborted())
|
||||
{
|
||||
// effect has ended, cleanup and delete
|
||||
(*fx_v)[i]->cleanup();
|
||||
delete (*fx_v)[i];
|
||||
(*fx_v)[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// effect is still going, so keep it around
|
||||
fx_v2->push_back((*fx_v)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
swap_vecs();
|
||||
|
||||
fx_v2->clear();
|
||||
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
delete fx_v; fx_v =0;
|
||||
delete fx_v2; fx_v2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEffectVector::stop(bool force_cleanup)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fx_v->size(); i++)
|
||||
{
|
||||
(*fx_v)[i]->stop();
|
||||
|
||||
if (force_cleanup || (*fx_v)[i]->deleteWhenStopped())
|
||||
{
|
||||
// effect is over when stopped, cleanup and delete
|
||||
(*fx_v)[i]->cleanup();
|
||||
delete (*fx_v)[i];
|
||||
(*fx_v)[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// effect needs to fadeout or something, so keep it around
|
||||
fx_v2->push_back((*fx_v)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
swap_vecs();
|
||||
|
||||
fx_v2->clear();
|
||||
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
delete fx_v; fx_v =0;
|
||||
delete fx_v2; fx_v2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEffectVector::interrupt()
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fx_v->size(); i++)
|
||||
{
|
||||
(*fx_v)[i]->stop();
|
||||
(*fx_v)[i]->cleanup();
|
||||
delete (*fx_v)[i];
|
||||
(*fx_v)[i] = 0;
|
||||
}
|
||||
|
||||
swap_vecs();
|
||||
|
||||
fx_v2->clear();
|
||||
|
||||
if (empty())
|
||||
{
|
||||
active = false;
|
||||
delete fx_v; fx_v =0;
|
||||
delete fx_v2; fx_v2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
|
||||
86
Engine/source/afx/afxEffectVector.h
Normal file
86
Engine/source/afx/afxEffectVector.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_EFFECT_VECTOR_H_
|
||||
#define _AFX_EFFECT_VECTOR_H_
|
||||
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxEffectGroup.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectVector
|
||||
|
||||
class afxEffectWrapper;
|
||||
class afxChoreographer;
|
||||
|
||||
class afxEffectVector
|
||||
{
|
||||
Vector<afxEffectWrapper*>* fx_v;
|
||||
Vector<afxEffectWrapper*>* fx_v2;
|
||||
|
||||
bool active;
|
||||
bool on_server;
|
||||
F32 phrase_dur;
|
||||
F32 total_fx_dur;
|
||||
F32 after_life;
|
||||
|
||||
void swap_vecs();
|
||||
void filter_client_server();
|
||||
void calc_fx_dur_and_afterlife();
|
||||
|
||||
void effects_init(afxChoreographer*, afxEffectList&, bool will_stop, F32 time_factor,
|
||||
S32 group_index, const afxGroupTimingData* group_timing=0);
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectVector();
|
||||
/*D*/ ~afxEffectVector();
|
||||
|
||||
void ev_init(afxChoreographer*, afxEffectList&, bool on_server, bool will_stop,
|
||||
F32 time_factor, F32 phrase_dur, S32 group_index=0);
|
||||
|
||||
void start(F32 timestamp);
|
||||
void update(F32 dt);
|
||||
void stop(bool force_cleanup=false);
|
||||
void interrupt();
|
||||
bool empty() { return (!fx_v || fx_v->empty()); }
|
||||
bool isActive() { return active; }
|
||||
S32 count() { return (fx_v) ? fx_v->size() : 0; }
|
||||
|
||||
F32 getTotalDur() { return total_fx_dur; }
|
||||
F32 getAfterLife() { return after_life; }
|
||||
|
||||
Vector<afxEffectWrapper*>* getFX() { return fx_v; }
|
||||
};
|
||||
|
||||
inline void afxEffectVector::swap_vecs()
|
||||
{
|
||||
Vector<afxEffectWrapper*>* tmp = fx_v;
|
||||
fx_v = fx_v2;
|
||||
fx_v2 = tmp;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_EFFECT_VECTOR_H_
|
||||
1193
Engine/source/afx/afxEffectWrapper.cpp
Normal file
1193
Engine/source/afx/afxEffectWrapper.cpp
Normal file
File diff suppressed because it is too large
Load diff
392
Engine/source/afx/afxEffectWrapper.h
Normal file
392
Engine/source/afx/afxEffectWrapper.h
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_EFFECT_WRAPPER_H_
|
||||
#define _AFX_EFFECT_WRAPPER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afxEffectDefs.h"
|
||||
#include "afxConstraint.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
struct afxEffectTimingData
|
||||
{
|
||||
F32 delay;
|
||||
F32 lifetime;
|
||||
F32 fade_in_time;
|
||||
F32 fade_out_time;
|
||||
F32 residue_lifetime;
|
||||
F32 residue_fadetime;
|
||||
F32 life_bias;
|
||||
Point2F fadein_ease;
|
||||
Point2F fadeout_ease;
|
||||
|
||||
afxEffectTimingData()
|
||||
{
|
||||
delay = 0.0f;
|
||||
lifetime = 0.0f;
|
||||
fade_in_time = 0.0f;
|
||||
fade_out_time = 0.0f;
|
||||
residue_lifetime = 0.0f;
|
||||
residue_fadetime = 0.0f;
|
||||
life_bias = 1.0f;
|
||||
fadein_ease.set(0.0f, 1.0f);
|
||||
fadeout_ease.set(0.0f, 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEffectWrapperData;
|
||||
class afxAnimCurve;
|
||||
|
||||
class afxEffectAdapterDesc
|
||||
{
|
||||
private:
|
||||
static Vector<afxEffectAdapterDesc*>* adapters;
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectAdapterDesc();
|
||||
|
||||
virtual bool testEffectType(const SimDataBlock*) const=0;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const=0;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const=0;
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const=0;
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return true; }
|
||||
virtual void prepEffect(afxEffectWrapperData*) const { }
|
||||
|
||||
virtual afxEffectWrapper* create() const=0;
|
||||
|
||||
static bool identifyEffect(afxEffectWrapperData*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxXM_BaseData;
|
||||
|
||||
class afxEffectBaseData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectBaseData() { }
|
||||
/*C*/ afxEffectBaseData(const afxEffectBaseData& other, bool temp=false) : GameBaseData(other, temp){ }
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs) { };
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectBaseData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//class afxEffectWrapperData : public GameBaseData, public afxEffectDefs
|
||||
class afxEffectWrapperData : public afxEffectBaseData
|
||||
{
|
||||
//typedef GameBaseData Parent;
|
||||
typedef afxEffectBaseData Parent;
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
enum { MAX_CONDITION_STATES = 4 };
|
||||
|
||||
public:
|
||||
StringTableEntry effect_name;
|
||||
bool use_as_cons_obj;
|
||||
bool use_ghost_as_cons_obj;
|
||||
|
||||
StringTableEntry cons_spec;
|
||||
StringTableEntry pos_cons_spec;
|
||||
StringTableEntry orient_cons_spec;
|
||||
StringTableEntry aim_cons_spec;
|
||||
StringTableEntry life_cons_spec;
|
||||
//
|
||||
afxConstraintDef cons_def;
|
||||
afxConstraintDef pos_cons_def;
|
||||
afxConstraintDef orient_cons_def;
|
||||
afxConstraintDef aim_cons_def;
|
||||
afxConstraintDef life_cons_def;
|
||||
|
||||
afxEffectTimingData ewd_timing;
|
||||
U32 inherit_timing;
|
||||
|
||||
F32 scale_factor; // scale size if applicable
|
||||
F32 rate_factor; // scale rate if applicable
|
||||
F32 user_fade_out_time;
|
||||
|
||||
bool is_looping;
|
||||
U32 n_loops;
|
||||
F32 loop_gap_time;
|
||||
|
||||
bool ignore_time_factor;
|
||||
bool propagate_time_factor;
|
||||
|
||||
ByteRange ranking_range;
|
||||
ByteRange lod_range;
|
||||
S32 life_conds;
|
||||
bool effect_enabled;
|
||||
U32 exec_cond_on_bits[MAX_CONDITION_STATES];
|
||||
U32 exec_cond_off_bits[MAX_CONDITION_STATES];
|
||||
U32 exec_cond_bitmasks[MAX_CONDITION_STATES];
|
||||
|
||||
S32 data_ID;
|
||||
|
||||
afxXM_BaseData* xfm_modifiers[MAX_XFM_MODIFIERS];
|
||||
|
||||
Box3F forced_bbox;
|
||||
bool update_forced_bbox;
|
||||
|
||||
S8 sort_priority;
|
||||
Point3F direction;
|
||||
F32 speed;
|
||||
F32 mass;
|
||||
|
||||
bool borrow_altitudes;
|
||||
StringTableEntry vis_keys_spec;
|
||||
afxAnimCurve* vis_keys;
|
||||
|
||||
SimDataBlock* effect_data;
|
||||
afxEffectAdapterDesc* effect_desc;
|
||||
|
||||
S32 group_index;
|
||||
|
||||
void parse_cons_specs();
|
||||
void parse_vis_keys();
|
||||
void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
void pack_mods(BitStream*, afxXM_BaseData* mods[], bool packed);
|
||||
void unpack_mods(BitStream*, afxXM_BaseData* mods[]);
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectWrapperData();
|
||||
/*C*/ afxEffectWrapperData(const afxEffectWrapperData&, bool = false);
|
||||
/*D*/ ~afxEffectWrapperData();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual void onPerformSubstitutions();
|
||||
|
||||
bool requiresStop(const afxEffectTimingData& timing) { return effect_desc->requiresStop(this, timing); }
|
||||
bool runsOnServer() { return effect_desc->runsOnServer(this); }
|
||||
bool runsOnClient() { return effect_desc->runsOnClient(this); }
|
||||
bool runsHere(bool server_here) { return (server_here) ? runsOnServer() : runsOnClient(); }
|
||||
bool isPositional() { return effect_desc->isPositional(this); }
|
||||
bool testExecConditions(U32 conditions);
|
||||
|
||||
F32 afterStopTime() { return ewd_timing.fade_out_time; }
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectWrapperData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
inline bool afxEffectWrapperData::testExecConditions(U32 conditions)
|
||||
{
|
||||
if (exec_cond_bitmasks[0] == 0)
|
||||
return true;
|
||||
|
||||
if ((exec_cond_bitmasks[0] & conditions) == exec_cond_on_bits[0])
|
||||
return true;
|
||||
|
||||
for (S32 i = 1; i < MAX_CONDITION_STATES; i++)
|
||||
{
|
||||
if (exec_cond_bitmasks[i] == 0)
|
||||
return false;
|
||||
if ((exec_cond_bitmasks[i] & conditions) == exec_cond_on_bits[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef Vector<afxEffectBaseData*> afxEffectList;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectWrapper
|
||||
//
|
||||
// NOTE -- this not a subclass of GameBase... it is only meant to exist on
|
||||
// the client-side.
|
||||
|
||||
class ShapeBase;
|
||||
class GameBase;
|
||||
class TSShape;
|
||||
class TSShapeInstance;
|
||||
class SceneObject;
|
||||
class afxConstraint;
|
||||
class afxConstraintMgr;
|
||||
class afxChoreographer;
|
||||
class afxXM_Base;
|
||||
|
||||
class afxEffectWrapper : public SimObject, public afxEffectDefs
|
||||
{
|
||||
typedef SimObject Parent;
|
||||
friend class afxEffectVector;
|
||||
|
||||
private:
|
||||
bool test_life_conds();
|
||||
|
||||
protected:
|
||||
afxEffectWrapperData* datablock;
|
||||
|
||||
afxEffectTimingData ew_timing;
|
||||
|
||||
F32 fade_in_end;
|
||||
F32 fade_out_start;
|
||||
F32 full_lifetime;
|
||||
|
||||
F32 time_factor;
|
||||
F32 prop_time_factor;
|
||||
|
||||
afxChoreographer* choreographer;
|
||||
afxConstraintMgr* cons_mgr;
|
||||
|
||||
afxConstraintID pos_cons_id;
|
||||
afxConstraintID orient_cons_id;
|
||||
afxConstraintID aim_cons_id;
|
||||
afxConstraintID life_cons_id;
|
||||
|
||||
afxConstraintID effect_cons_id;
|
||||
|
||||
F32 elapsed;
|
||||
F32 life_elapsed;
|
||||
F32 life_end;
|
||||
bool stopped;
|
||||
bool cond_alive;
|
||||
|
||||
U32 n_updates;
|
||||
|
||||
MatrixF updated_xfm;
|
||||
Point3F updated_pos;
|
||||
Point3F updated_aim;
|
||||
Point3F updated_scale;
|
||||
LinearColorF updated_color;
|
||||
|
||||
F32 fade_value;
|
||||
F32 last_fade_value;
|
||||
|
||||
bool do_fade_inout;
|
||||
bool do_fades;
|
||||
bool in_scope;
|
||||
bool is_aborted;
|
||||
|
||||
U8 effect_flags;
|
||||
|
||||
afxXM_Base* xfm_modifiers[MAX_XFM_MODIFIERS];
|
||||
|
||||
F32 live_scale_factor;
|
||||
F32 live_fade_factor;
|
||||
F32 terrain_altitude;
|
||||
F32 interior_altitude;
|
||||
|
||||
S32 group_index;
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectWrapper();
|
||||
virtual ~afxEffectWrapper();
|
||||
|
||||
void ew_init(afxChoreographer*, afxEffectWrapperData*, afxConstraintMgr*,
|
||||
F32 time_factor);
|
||||
|
||||
F32 getFullLifetime() { return ew_timing.lifetime + ew_timing.fade_out_time; }
|
||||
F32 getTimeFactor() { return time_factor; }
|
||||
afxConstraint* getPosConstraint() { return cons_mgr->getConstraint(pos_cons_id); }
|
||||
afxConstraint* getOrientConstraint() { return cons_mgr->getConstraint(orient_cons_id); }
|
||||
afxConstraint* getAimConstraint() { return cons_mgr->getConstraint(aim_cons_id); }
|
||||
afxConstraint* getLifeConstraint() { return cons_mgr->getConstraint(life_cons_id); }
|
||||
afxChoreographer* getChoreographer() { return choreographer; }
|
||||
|
||||
virtual bool isDone();
|
||||
virtual bool deleteWhenStopped() { return false; }
|
||||
F32 afterStopTime() { return ew_timing.fade_out_time; }
|
||||
bool isAborted() const { return is_aborted; }
|
||||
|
||||
void prestart();
|
||||
bool start(F32 timestamp);
|
||||
bool update(F32 dt);
|
||||
void stop();
|
||||
void cleanup(bool was_stopped=false);
|
||||
void setScopeStatus(bool flag);
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*) { }
|
||||
virtual bool ea_start() { return true; }
|
||||
virtual bool ea_update(F32 dt) { return true; }
|
||||
virtual void ea_finish(bool was_stopped) { }
|
||||
virtual void ea_set_scope_status(bool flag) { }
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
virtual SceneObject* ea_get_scene_object() const { return 0; }
|
||||
U32 ea_get_triggers() const { return 0; }
|
||||
|
||||
void getUpdatedPosition(Point3F& pos) { pos = updated_pos;}
|
||||
void getUpdatedTransform(MatrixF& xfm) { xfm = updated_xfm; }
|
||||
void getUpdatedScale(Point3F& scale) { scale = updated_scale; }
|
||||
void getUpdatedColor(LinearColorF& color) { color = updated_color; }
|
||||
virtual void getUpdatedBoxCenter(Point3F& pos) { pos = updated_pos;}
|
||||
|
||||
virtual void getUnconstrainedPosition(Point3F& pos) { pos.zero();}
|
||||
virtual void getUnconstrainedTransform(MatrixF& xfm) { xfm.identity(); }
|
||||
virtual void getBaseColor(LinearColorF& color) { color.set(1.0f, 1.0f, 1.0f, 1.0f); }
|
||||
|
||||
SceneObject* getSceneObject() const { return ea_get_scene_object(); }
|
||||
U32 getTriggers() const { return ea_get_triggers(); }
|
||||
|
||||
F32 getMass() { return datablock->mass; }
|
||||
Point3F getDirection() { return datablock->direction; }
|
||||
F32 getSpeed() { return datablock->speed; }
|
||||
|
||||
virtual TSShape* getTSShape() { return 0; }
|
||||
virtual TSShapeInstance* getTSShapeInstance() { return 0; }
|
||||
|
||||
virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans) { return 0; }
|
||||
virtual void resetAnimation(U32 tag) { }
|
||||
virtual F32 getAnimClipDuration(const char* clip) { return 0.0f; }
|
||||
|
||||
void setTerrainAltitude(F32 alt) { terrain_altitude = alt; }
|
||||
void setInteriorAltitude(F32 alt) { interior_altitude = alt; }
|
||||
void getAltitudes(F32& terr_alt, F32& inter_alt) const { terr_alt = terrain_altitude; inter_alt = interior_altitude; }
|
||||
|
||||
void setGroupIndex(S32 idx) { group_index = idx; }
|
||||
S32 getGroupIndex() const { return group_index; }
|
||||
|
||||
bool inScope() const { return in_scope; }
|
||||
|
||||
public:
|
||||
static void initPersistFields();
|
||||
|
||||
static afxEffectWrapper* ew_create(afxChoreographer*, afxEffectWrapperData*, afxConstraintMgr*, F32 time_factor, S32 group_index=0);
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectWrapper);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_EFFECT_WRAPPER_H_
|
||||
1119
Engine/source/afx/afxEffectron.cpp
Normal file
1119
Engine/source/afx/afxEffectron.cpp
Normal file
File diff suppressed because it is too large
Load diff
216
Engine/source/afx/afxEffectron.h
Normal file
216
Engine/source/afx/afxEffectron.h
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_COMPOSITE_EFFECT_H_
|
||||
#define _AFX_COMPOSITE_EFFECT_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#include "afxChoreographer.h"
|
||||
#include "afxEffectWrapper.h"
|
||||
#include "afxPhrase.h"
|
||||
|
||||
class afxChoreographerData;
|
||||
class afxEffectWrapperData;
|
||||
|
||||
class afxEffectronData : public afxChoreographerData
|
||||
{
|
||||
typedef afxChoreographerData Parent;
|
||||
|
||||
class ewValidator : public TypeValidator
|
||||
{
|
||||
U32 id;
|
||||
public:
|
||||
ewValidator(U32 id) { this->id = id; }
|
||||
void validateType(SimObject *object, void *typePtr);
|
||||
};
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
F32 duration;
|
||||
S32 n_loops;
|
||||
|
||||
afxEffectBaseData* dummy_fx_entry;
|
||||
|
||||
afxEffectList fx_list;
|
||||
|
||||
private:
|
||||
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
|
||||
void unpack_fx(BitStream* stream, afxEffectList& fx);
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectronData();
|
||||
/*C*/ afxEffectronData(const afxEffectronData&, bool = false);
|
||||
|
||||
virtual void reloadReset();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
void gatherConstraintDefs(Vector<afxConstraintDef>&);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectronData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEffectron
|
||||
|
||||
class afxEffectron : public afxChoreographer
|
||||
{
|
||||
typedef afxChoreographer Parent;
|
||||
|
||||
public:
|
||||
enum MaskBits
|
||||
{
|
||||
StateEventMask = Parent::NextFreeMask << 0,
|
||||
SyncEventMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NULL_EVENT,
|
||||
ACTIVATE_EVENT,
|
||||
SHUTDOWN_EVENT,
|
||||
DEACTIVATE_EVENT,
|
||||
INTERRUPT_EVENT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
INACTIVE_STATE,
|
||||
ACTIVE_STATE,
|
||||
CLEANUP_STATE,
|
||||
DONE_STATE,
|
||||
LATE_STATE
|
||||
};
|
||||
|
||||
enum {
|
||||
MARK_ACTIVATE = BIT(0),
|
||||
MARK_SHUTDOWN = BIT(1),
|
||||
MARK_DEACTIVATE = BIT(2),
|
||||
MARK_INTERRUPT = BIT(3),
|
||||
};
|
||||
|
||||
class ObjectDeleteEvent : public SimEvent
|
||||
{
|
||||
public:
|
||||
void process(SimObject *obj) { if (obj) obj->deleteObject(); }
|
||||
};
|
||||
|
||||
private:
|
||||
static StringTableEntry CAMERA_CONS;
|
||||
static StringTableEntry LISTENER_CONS;
|
||||
|
||||
private:
|
||||
afxEffectronData* datablock;
|
||||
SimObject* exeblock;
|
||||
|
||||
bool constraints_initialized;
|
||||
bool scoping_initialized;
|
||||
|
||||
U8 effect_state;
|
||||
F32 effect_elapsed;
|
||||
U8 marks_mask;
|
||||
afxConstraintID listener_cons_id;
|
||||
afxConstraintID camera_cons_id;
|
||||
SceneObject* camera_cons_obj;
|
||||
afxPhrase* active_phrase;
|
||||
F32 time_factor;
|
||||
|
||||
private:
|
||||
void init();
|
||||
bool state_expired();
|
||||
void init_constraints();
|
||||
void init_scoping();
|
||||
void setup_active_fx();
|
||||
bool cleanup_over();
|
||||
|
||||
public:
|
||||
/*C*/ afxEffectron();
|
||||
/*C*/ afxEffectron(bool not_default);
|
||||
/*D*/ ~afxEffectron();
|
||||
|
||||
// STANDARD OVERLOADED METHODS //
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void processTick(const Move*);
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual bool onAdd();
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
|
||||
virtual void inflictDamage(const char * label, const char* flavor, SimObjectId target,
|
||||
F32 amt, U8 count, F32 ad_amt, F32 rad, Point3F pos, F32 imp);
|
||||
virtual void sync_with_clients();
|
||||
void finish_startup();
|
||||
|
||||
DECLARE_CONOBJECT(afxEffectron);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
private:
|
||||
void process_server();
|
||||
//
|
||||
void change_state_s(U8 pending_state);
|
||||
//
|
||||
void enter_active_state_s();
|
||||
void leave_active_state_s();
|
||||
void enter_cleanup_state_s();
|
||||
void enter_done_state_s();
|
||||
|
||||
private:
|
||||
void process_client(F32 dt);
|
||||
//
|
||||
void change_state_c(U8 pending_state);
|
||||
//
|
||||
void enter_active_state_c(F32 starttime);
|
||||
void leave_active_state_c();
|
||||
|
||||
void sync_client(U16 marks, U8 state, F32 elapsed);
|
||||
|
||||
public:
|
||||
void postEvent(U8 event);
|
||||
void setTimeFactor(F32 f) { time_factor = (f > 0) ? f : 1.0f; }
|
||||
F32 getTimeFactor() { return time_factor; }
|
||||
|
||||
bool activationCallInit(bool postponed=false);
|
||||
void activate();
|
||||
|
||||
public:
|
||||
static afxEffectron* start_effect(afxEffectronData*, SimObject* extra);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
#endif // _AFX_EFFECTRON_H_
|
||||
2116
Engine/source/afx/afxMagicMissile.cpp
Normal file
2116
Engine/source/afx/afxMagicMissile.cpp
Normal file
File diff suppressed because it is too large
Load diff
435
Engine/source/afx/afxMagicMissile.h
Normal file
435
Engine/source/afx/afxMagicMissile.h
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// afxMagicMissile is a heavily modified variation of the stock Projectile class. In
|
||||
// addition to numerous AFX customizations, it also incorporates functionality based on
|
||||
// the following TGE resources:
|
||||
//
|
||||
// Guided or Seeker Projectiles by Derk Adams
|
||||
// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6778
|
||||
//
|
||||
// Projectile Ballistic Coefficients (drag factors) by Mark Owen
|
||||
// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=5128
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _AFX_MAGIC_MISSILE_H_
|
||||
#define _AFX_MAGIC_MISSILE_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "T3D/lightDescription.h"
|
||||
#include "T3D/fx/particleEmitter.h"
|
||||
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
class SplashData;
|
||||
class ShapeBase;
|
||||
class TSShapeInstance;
|
||||
class PhysicsWorld;
|
||||
class SFXTrack;
|
||||
class SFXSource;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMagicMissileData
|
||||
|
||||
class afxMagicMissileData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
protected:
|
||||
bool onAdd();
|
||||
|
||||
public:
|
||||
enum { MaxLifetimeTicks = 4095 };
|
||||
|
||||
public:
|
||||
// variables set in datablock definition:
|
||||
// Shape related
|
||||
StringTableEntry projectileShapeName;
|
||||
|
||||
//bool hasLight;
|
||||
//F32 lightRadius;
|
||||
//LinearColorF lightColor;
|
||||
|
||||
//bool hasWaterLight;
|
||||
//LinearColorF waterLightColor;
|
||||
|
||||
/*
|
||||
/// Set to true if it is a billboard and want it to always face the viewer, false otherwise
|
||||
bool faceViewer;
|
||||
*/
|
||||
Point3F scale;
|
||||
|
||||
/*
|
||||
/// [0,1] scale of how much velocity should be inherited from the parent object
|
||||
F32 velInheritFactor;
|
||||
/// Speed of the projectile when fired
|
||||
*/
|
||||
F32 muzzleVelocity;
|
||||
|
||||
/// Should it arc?
|
||||
bool isBallistic;
|
||||
|
||||
/*
|
||||
/// How HIGH should it bounce (parallel to normal), [0,1]
|
||||
F32 bounceElasticity;
|
||||
/// How much momentum should be lost when it bounces (perpendicular to normal), [0,1]
|
||||
F32 bounceFriction;
|
||||
*/
|
||||
|
||||
/// Should this projectile fall/rise different than a default object?
|
||||
F32 gravityMod;
|
||||
|
||||
/// How long the projectile should exist before deleting itself
|
||||
U32 lifetime; // ticks
|
||||
/*
|
||||
/// How long it should not detonate on impact
|
||||
S32 armingDelay; // the values are converted on initialization with
|
||||
*/
|
||||
S32 fadeDelay; // ticks
|
||||
|
||||
/*
|
||||
ExplosionData* explosion; // Explosion Datablock
|
||||
S32 explosionId; // Explosion ID
|
||||
ExplosionData* waterExplosion; // Water Explosion Datablock
|
||||
S32 waterExplosionId; // Water Explosion ID
|
||||
*/
|
||||
|
||||
SplashData* splash; // Water Splash Datablock
|
||||
S32 splashId; // Water splash ID
|
||||
|
||||
SFXTrack* sound; // Projectile Sound
|
||||
|
||||
LightDescription *lightDesc;
|
||||
S32 lightDescId;
|
||||
|
||||
/*
|
||||
enum DecalConstants { // Number of decals constant
|
||||
NumDecals = 6,
|
||||
};
|
||||
DecalData* decals[NumDecals]; // Decal Datablocks
|
||||
S32 decalId[NumDecals]; // Decal IDs
|
||||
U32 decalCount; // # of loaded Decal Datablocks
|
||||
*/
|
||||
|
||||
// variables set on preload:
|
||||
Resource<TSShape> projectileShape;
|
||||
/*
|
||||
S32 activateSeq;
|
||||
S32 maintainSeq;
|
||||
*/
|
||||
|
||||
ParticleEmitterData* particleEmitter;
|
||||
S32 particleEmitterId;
|
||||
ParticleEmitterData* particleWaterEmitter;
|
||||
S32 particleWaterEmitterId;
|
||||
|
||||
U32 collision_mask;
|
||||
|
||||
Point3F starting_vel_vec;
|
||||
|
||||
// guidance behavior
|
||||
bool isGuided;
|
||||
F32 precision;
|
||||
S32 trackDelay;
|
||||
|
||||
// simple physics
|
||||
F32 ballisticCoefficient;
|
||||
|
||||
// terrain following
|
||||
bool followTerrain;
|
||||
F32 followTerrainHeight;
|
||||
F32 followTerrainAdjustRate;
|
||||
S32 followTerrainAdjustDelay;
|
||||
|
||||
F32 acceleration;
|
||||
S32 accelDelay;
|
||||
U32 accelLifetime;
|
||||
|
||||
StringTableEntry launch_node;
|
||||
Point3F launch_offset;
|
||||
Point3F launch_offset_server;
|
||||
Point3F launch_offset_client;
|
||||
Point3F launch_node_offset;
|
||||
F32 launch_pitch;
|
||||
F32 launch_pan;
|
||||
bool echo_launch_offset;
|
||||
|
||||
StringTableEntry launch_cons_s_spec;
|
||||
afxConstraintDef launch_cons_s_def;
|
||||
StringTableEntry launch_cons_c_spec;
|
||||
afxConstraintDef launch_cons_c_def;
|
||||
|
||||
// wiggle behavior
|
||||
Vector<F32> wiggle_magnitudes;
|
||||
Vector<F32> wiggle_speeds;
|
||||
StringTableEntry wiggle_axis_string;
|
||||
Point3F* wiggle_axis;
|
||||
U32 wiggle_num_axis;
|
||||
|
||||
// hover behavior
|
||||
F32 hover_altitude;
|
||||
F32 hover_attack_distance;
|
||||
F32 hover_attack_gradient;
|
||||
U32 hover_time;
|
||||
|
||||
bool reverse_targeting;
|
||||
|
||||
U32 caster_safety_time;
|
||||
|
||||
public:
|
||||
/*C*/ afxMagicMissileData();
|
||||
/*D*/ ~afxMagicMissileData();
|
||||
|
||||
void packData(BitStream*);
|
||||
void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxMagicMissileData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
public:
|
||||
/*C*/ afxMagicMissileData(const afxMagicMissileData&, bool = false);
|
||||
|
||||
afxMagicMissileData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMagicMissile
|
||||
|
||||
//class afxMagicSpell;
|
||||
class afxChoreographer;
|
||||
|
||||
class afxMagicMissile : public GameBase, public ISceneLight
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
public:
|
||||
/*
|
||||
// Initial conditions
|
||||
enum ProjectileConstants {
|
||||
SourceIdTimeoutTicks = 7, // = 231 ms
|
||||
DeleteWaitTime = 500, ///< 500 ms delete timeout (for network transmission delays)
|
||||
ExcessVelDirBits = 7,
|
||||
MaxLivingTicks = 4095,
|
||||
};
|
||||
*/
|
||||
enum UpdateMasks {
|
||||
/*
|
||||
BounceMask = Parent::NextFreeMask,
|
||||
ExplosionMask = Parent::NextFreeMask << 1,
|
||||
*/
|
||||
GuideMask = Parent::NextFreeMask << 0,
|
||||
LaunchMask = Parent::NextFreeMask << 1,
|
||||
ImpactMask = Parent::NextFreeMask << 2,
|
||||
NextFreeMask = Parent::NextFreeMask << 3
|
||||
};
|
||||
protected:
|
||||
PhysicsWorld *mPhysicsWorld;
|
||||
|
||||
afxMagicMissileData* mDataBlock;
|
||||
|
||||
ParticleEmitter* mParticleEmitter;
|
||||
ParticleEmitter* mParticleWaterEmitter;
|
||||
SFXSource* mSound;
|
||||
|
||||
Point3F mCurrPosition;
|
||||
Point3F mCurrVelocity;
|
||||
/*
|
||||
S32 mSourceObjectId;
|
||||
S32 mSourceObjectSlot;
|
||||
*/
|
||||
|
||||
// Time related variables common to all projectiles, managed by processTick
|
||||
|
||||
U32 mCurrTick; ///< Current time in ticks
|
||||
/*
|
||||
SimObjectPtr<ShapeBase> mSourceObject; ///< Actual pointer to the source object, times out after SourceIdTimeoutTicks
|
||||
*/
|
||||
|
||||
// Rendering related variables
|
||||
TSShapeInstance* mProjectileShape;
|
||||
/*
|
||||
TSThread* mActivateThread;
|
||||
TSThread* mMaintainThread;
|
||||
|
||||
Point3F mLastRenderPos;
|
||||
*/
|
||||
|
||||
// ISceneLight
|
||||
virtual void submitLights( LightManager *lm, bool staticLighting );
|
||||
virtual LightInfo* getLight() { return mLight; }
|
||||
|
||||
LightInfo *mLight;
|
||||
LightState mLightState;
|
||||
|
||||
/*
|
||||
bool mHidden; ///< set by the derived class, if true, projectile doesn't render
|
||||
F32 mFadeValue; ///< set in processTick, interpolation between fadeDelay and lifetime
|
||||
///< in data block
|
||||
*/
|
||||
|
||||
/*
|
||||
// Warping and back delta variables. Only valid on the client
|
||||
//
|
||||
Point3F mWarpStart;
|
||||
Point3F mWarpEnd;
|
||||
U32 mWarpTicksRemaining;
|
||||
*/
|
||||
|
||||
Point3F mCurrDeltaBase;
|
||||
Point3F mCurrBackDelta;
|
||||
|
||||
/*
|
||||
Point3F mExplosionPosition;
|
||||
Point3F mExplosionNormal;
|
||||
U32 mCollideHitType;
|
||||
*/
|
||||
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
bool onNewDataBlock(GameBaseData *dptr, bool reload);
|
||||
|
||||
// Rendering
|
||||
virtual void prepRenderImage(SceneRenderState*);
|
||||
void prepBatchRender( SceneRenderState *state);
|
||||
|
||||
void processTick(const Move *move);
|
||||
/*
|
||||
void advanceTime(F32 dt);
|
||||
*/
|
||||
void interpolateTick(F32 delta);
|
||||
|
||||
/*
|
||||
/// What to do once this projectile collides with something
|
||||
virtual void onCollision(const Point3F& p, const Point3F& n, SceneObject*);
|
||||
|
||||
/// What to do when this projectile explodes
|
||||
virtual void explode(const Point3F& p, const Point3F& n, const U32 collideType );
|
||||
|
||||
/// Returns the velocity of the projectile
|
||||
Point3F getVelocity() const;
|
||||
*/
|
||||
|
||||
void emitParticles(const Point3F&, const Point3F&, const Point3F&, const U32);
|
||||
void updateSound();
|
||||
|
||||
// Rendering
|
||||
/*
|
||||
void prepModelView ( SceneRenderState *state);
|
||||
*/
|
||||
|
||||
// These are stolen from the player class ..
|
||||
bool pointInWater(const Point3F &point);
|
||||
|
||||
U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
|
||||
void unpackUpdate(NetConnection *conn, BitStream *stream);
|
||||
|
||||
afxChoreographer* choreographer;
|
||||
|
||||
bool client_only;
|
||||
bool server_only;
|
||||
bool use_accel;
|
||||
U32 collision_mask;
|
||||
F32 prec_inc;
|
||||
|
||||
bool did_launch;
|
||||
bool did_impact;
|
||||
|
||||
SceneObject* missile_target;
|
||||
SceneObject* collide_exempt;
|
||||
|
||||
bool hover_attack_go;
|
||||
U32 hover_attack_tick;
|
||||
|
||||
F32 starting_velocity;
|
||||
Point3F starting_vel_vec;
|
||||
|
||||
SimObject* ss_object;
|
||||
S32 ss_index;
|
||||
|
||||
private:
|
||||
void init(bool on_server, bool on_client);
|
||||
void create_splash(const Point3F& pos);
|
||||
SceneObject* get_default_launcher() const;
|
||||
void get_launch_constraint_data(Point3F& pos, Point3F& vel);
|
||||
void get_launch_data(Point3F& pos, Point3F& vel);
|
||||
bool is_active() const { return (did_launch && !did_impact); }
|
||||
|
||||
public:
|
||||
/*
|
||||
F32 getUpdatePriority(CameraScopeQuery *focusObject, U32 updateMask, S32 updateSkips);
|
||||
*/
|
||||
/*C*/ afxMagicMissile();
|
||||
/*C*/ afxMagicMissile(bool on_server, bool on_client);
|
||||
/*D*/ ~afxMagicMissile();
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
|
||||
DECLARE_CONOBJECT(afxMagicMissile);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
/*
|
||||
virtual bool calculateImpact(float simTime,
|
||||
Point3F& pointOfImpact,
|
||||
float& impactTime);
|
||||
|
||||
static U32 smProjectileWarpTicks;
|
||||
|
||||
protected:
|
||||
static const U32 csmStaticCollisionMask;
|
||||
static const U32 csmDynamicCollisionMask;
|
||||
static const U32 csmDamageableMask;
|
||||
*/
|
||||
|
||||
void launch();
|
||||
void setChoreographer(afxChoreographer*);
|
||||
void setStartingVelocityVector(const Point3F& vel_vec);
|
||||
void setStartingVelocity(const F32 vel);
|
||||
void getStartingVelocityValues(F32& vel, Point3F& vel_vec);
|
||||
void setSubstitutionData(SimObject* obj, S32 idx=0) { ss_object = obj; ss_index = idx; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMagicMissileCallback
|
||||
|
||||
class afxMagicMissileCallback
|
||||
{
|
||||
public:
|
||||
virtual void impactNotify(const Point3F& p, const Point3F& n, SceneObject*)=0;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MAGIC_MISSILE_H_
|
||||
|
||||
2709
Engine/source/afx/afxMagicSpell.cpp
Normal file
2709
Engine/source/afx/afxMagicSpell.cpp
Normal file
File diff suppressed because it is too large
Load diff
390
Engine/source/afx/afxMagicSpell.h
Normal file
390
Engine/source/afx/afxMagicSpell.h
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_MAGIC_SPELL_H_
|
||||
#define _AFX_MAGIC_SPELL_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "core/util/tVector.h"
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#include "afxChoreographer.h"
|
||||
#include "afxEffectDefs.h"
|
||||
#include "afxEffectWrapper.h"
|
||||
#include "afxMagicMissile.h"
|
||||
|
||||
class afxChoreographerData;
|
||||
class afxMagicMissileData;
|
||||
class afxEffectWrapperData;
|
||||
class SceneObject;
|
||||
class afxMagicSpell;
|
||||
|
||||
class afxMagicSpellDefs
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
CASTING_PHRASE,
|
||||
LAUNCH_PHRASE,
|
||||
DELIVERY_PHRASE,
|
||||
IMPACT_PHRASE,
|
||||
LINGER_PHRASE,
|
||||
NUM_PHRASES
|
||||
};
|
||||
};
|
||||
|
||||
class afxMagicSpellData : public afxChoreographerData, public afxMagicSpellDefs
|
||||
{
|
||||
typedef afxChoreographerData Parent;
|
||||
|
||||
class ewValidator : public TypeValidator
|
||||
{
|
||||
U32 id;
|
||||
public:
|
||||
ewValidator(U32 id) { this->id = id; }
|
||||
void validateType(SimObject *object, void *typePtr);
|
||||
};
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
F32 casting_dur;
|
||||
F32 delivery_dur;
|
||||
F32 linger_dur;
|
||||
//
|
||||
S32 n_casting_loops;
|
||||
S32 n_delivery_loops;
|
||||
S32 n_linger_loops;
|
||||
//
|
||||
F32 extra_casting_time;
|
||||
F32 extra_delivery_time;
|
||||
F32 extra_linger_time;
|
||||
//
|
||||
bool do_move_interrupts;
|
||||
F32 move_interrupt_speed;
|
||||
//
|
||||
afxMagicMissileData* missile_db;
|
||||
bool launch_on_server_signal;
|
||||
U32 primary_target_types;
|
||||
//
|
||||
afxEffectWrapperData* dummy_fx_entry;
|
||||
|
||||
// various effects lists
|
||||
afxEffectList casting_fx_list;
|
||||
afxEffectList launch_fx_list;
|
||||
afxEffectList delivery_fx_list;
|
||||
afxEffectList impact_fx_list;
|
||||
afxEffectList linger_fx_list;
|
||||
|
||||
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
|
||||
void unpack_fx(BitStream* stream, afxEffectList& fx);
|
||||
|
||||
public:
|
||||
/*C*/ afxMagicSpellData();
|
||||
/*C*/ afxMagicSpellData(const afxMagicSpellData&, bool = false);
|
||||
|
||||
virtual void reloadReset();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
virtual bool writeField(StringTableEntry fieldname, const char* value);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
void gatherConstraintDefs(Vector<afxConstraintDef>&);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxMagicSpellData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
/// @name Callbacks
|
||||
/// @{
|
||||
DECLARE_CALLBACK( void, onDamage, (afxMagicSpell* spell, const char* label, const char* flaver, U32 target_id, F32 amount, U8 n, Point3F pos, F32 ad_amount, F32 radius, F32 impulse) );
|
||||
DECLARE_CALLBACK( void, onDeactivate, (afxMagicSpell* spell) );
|
||||
DECLARE_CALLBACK( void, onInterrupt, (afxMagicSpell* spell, ShapeBase* caster) );
|
||||
DECLARE_CALLBACK( void, onLaunch, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* target, afxMagicMissile* missile) );
|
||||
DECLARE_CALLBACK( void, onImpact, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* impacted, Point3F pos, Point3F normal) );
|
||||
DECLARE_CALLBACK( bool, onPreactivate, (SimObject* param_holder, ShapeBase* caster, SceneObject* target, SimObject* extra) );
|
||||
DECLARE_CALLBACK( void, onActivate, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* target) );
|
||||
/// @}
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMagicSpell
|
||||
|
||||
class ShapeBase;
|
||||
class GameConnection;
|
||||
class afxEffectVector;
|
||||
class afxConstraint;
|
||||
class afxConstraintMgr;
|
||||
class afxMagicMissile;
|
||||
class afxChoreographer;
|
||||
class afxPhrase;
|
||||
|
||||
class afxMagicSpell : public afxChoreographer, public afxMagicSpellDefs
|
||||
{
|
||||
typedef afxChoreographer Parent;
|
||||
friend class afxMagicMissile;
|
||||
|
||||
enum MaskBits
|
||||
{
|
||||
MagicMissileMask = Parent::NextFreeMask << 0,
|
||||
StateEventMask = Parent::NextFreeMask << 1,
|
||||
LaunchEventMask = Parent::NextFreeMask << 2,
|
||||
ImpactEventMask = Parent::NextFreeMask << 3,
|
||||
SyncEventMask = Parent::NextFreeMask << 4,
|
||||
RemapConstraintMask = Parent::NextFreeMask << 5, // CONSTRAINT REMAPPING
|
||||
NextFreeMask = Parent::NextFreeMask << 6
|
||||
};
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
NULL_EVENT,
|
||||
ACTIVATE_EVENT,
|
||||
LAUNCH_EVENT,
|
||||
IMPACT_EVENT,
|
||||
SHUTDOWN_EVENT,
|
||||
DEACTIVATE_EVENT,
|
||||
INTERRUPT_PHASE_EVENT,
|
||||
INTERRUPT_SPELL_EVENT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
INACTIVE_STATE,
|
||||
CASTING_STATE,
|
||||
DELIVERY_STATE,
|
||||
LINGER_STATE,
|
||||
CLEANUP_STATE,
|
||||
DONE_STATE,
|
||||
LATE_STATE
|
||||
};
|
||||
|
||||
enum {
|
||||
MARK_ACTIVATE = BIT(0),
|
||||
MARK_LAUNCH = BIT(1),
|
||||
MARK_IMPACT = BIT(2),
|
||||
MARK_SHUTDOWN = BIT(3),
|
||||
MARK_DEACTIVATE = BIT(4),
|
||||
MARK_END_CASTING = BIT(5),
|
||||
MARK_END_DELIVERY = BIT(6),
|
||||
MARK_END_LINGER = BIT(7),
|
||||
MARK_INTERRUPT_CASTING = BIT(8),
|
||||
MARK_INTERRUPT_DELIVERY = BIT(9),
|
||||
MARK_INTERRUPT_LINGER = BIT(10),
|
||||
MARK_INTERRUPT_CLEANUP = BIT(11),
|
||||
//
|
||||
MARK_ENDINGS = MARK_END_CASTING | MARK_END_DELIVERY | MARK_END_LINGER,
|
||||
MARK_INTERRUPTS = MARK_INTERRUPT_CASTING | MARK_INTERRUPT_DELIVERY | MARK_INTERRUPT_LINGER | MARK_INTERRUPT_CLEANUP
|
||||
};
|
||||
|
||||
class ObjectDeleteEvent : public SimEvent
|
||||
{
|
||||
public:
|
||||
void process(SimObject *obj) { if (obj) obj->deleteObject(); }
|
||||
};
|
||||
|
||||
private:
|
||||
static StringTableEntry CASTER_CONS;
|
||||
static StringTableEntry TARGET_CONS;
|
||||
static StringTableEntry MISSILE_CONS;
|
||||
static StringTableEntry CAMERA_CONS;
|
||||
static StringTableEntry LISTENER_CONS;
|
||||
static StringTableEntry IMPACT_POINT_CONS;
|
||||
static StringTableEntry IMPACTED_OBJECT_CONS;
|
||||
|
||||
private:
|
||||
afxMagicSpellData* datablock;
|
||||
SimObject* exeblock;
|
||||
afxMagicMissileData* missile_db;
|
||||
|
||||
ShapeBase* caster;
|
||||
SceneObject* target;
|
||||
SimObject* caster_field;
|
||||
SimObject* target_field;
|
||||
|
||||
U16 caster_scope_id;
|
||||
U16 target_scope_id;
|
||||
bool target_is_shape;
|
||||
|
||||
bool constraints_initialized;
|
||||
bool scoping_initialized;
|
||||
|
||||
U8 spell_state;
|
||||
F32 spell_elapsed;
|
||||
|
||||
afxConstraintID listener_cons_id;
|
||||
afxConstraintID caster_cons_id;
|
||||
afxConstraintID target_cons_id;
|
||||
afxConstraintID impacted_cons_id;
|
||||
afxConstraintID camera_cons_id;
|
||||
SceneObject* camera_cons_obj;
|
||||
|
||||
afxPhrase* phrases[NUM_PHRASES];
|
||||
F32 tfactors[NUM_PHRASES];
|
||||
|
||||
bool notify_castbar;
|
||||
F32 overall_time_factor;
|
||||
|
||||
U16 marks_mask;
|
||||
|
||||
private:
|
||||
void init();
|
||||
bool state_expired();
|
||||
F32 state_elapsed();
|
||||
void init_constraints();
|
||||
void init_scoping();
|
||||
void setup_casting_fx();
|
||||
void setup_launch_fx();
|
||||
void setup_delivery_fx();
|
||||
void setup_impact_fx();
|
||||
void setup_linger_fx();
|
||||
bool cleanup_over();
|
||||
bool is_caster_moving();
|
||||
bool is_caster_client(ShapeBase* caster, GameConnection* conn);
|
||||
bool is_impact_in_water(SceneObject* obj, const Point3F& p);
|
||||
|
||||
protected:
|
||||
virtual bool remap_builtin_constraint(SceneObject*, const char* cons_name); // CONSTRAINT REMAPPING
|
||||
virtual void pack_constraint_info(NetConnection* conn, BitStream* stream);
|
||||
virtual void unpack_constraint_info(NetConnection* conn, BitStream* stream);
|
||||
|
||||
private:
|
||||
afxMagicMissile* missile;
|
||||
bool missile_is_armed;
|
||||
SceneObject* impacted_obj;
|
||||
Point3F impact_pos;
|
||||
Point3F impact_norm;
|
||||
U16 impacted_scope_id;
|
||||
bool impacted_is_shape;
|
||||
|
||||
void init_missile_s(afxMagicMissileData* mm);
|
||||
void launch_missile_s();
|
||||
|
||||
void init_missile_c(afxMagicMissileData* mm);
|
||||
void launch_missile_c();
|
||||
|
||||
public:
|
||||
virtual void impactNotify(const Point3F& p, const Point3F& n, SceneObject*);
|
||||
virtual void executeScriptEvent(const char* method, afxConstraint*,
|
||||
const MatrixF& pos, const char* data);
|
||||
virtual void inflictDamage(const char * label, const char* flavor, SimObjectId target,
|
||||
F32 amt, U8 count, F32 ad_amt, F32 rad, Point3F pos, F32 imp);
|
||||
|
||||
public:
|
||||
/*C*/ afxMagicSpell();
|
||||
/*C*/ afxMagicSpell(ShapeBase* caster, SceneObject* target);
|
||||
/*D*/ ~afxMagicSpell();
|
||||
|
||||
// STANDARD OVERLOADED METHODS //
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void processTick(const Move*);
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
|
||||
virtual void sync_with_clients();
|
||||
void finish_startup();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxMagicSpell);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
private:
|
||||
void process_server();
|
||||
//
|
||||
void change_state_s(U8 pending_state);
|
||||
//
|
||||
void enter_casting_state_s();
|
||||
void leave_casting_state_s();
|
||||
void enter_delivery_state_s();
|
||||
void leave_delivery_state_s();
|
||||
void enter_linger_state_s();
|
||||
void leave_linger_state_s();
|
||||
void enter_done_state_s();
|
||||
|
||||
private:
|
||||
void process_client(F32 dt);
|
||||
//
|
||||
void change_state_c(U8 pending_state);
|
||||
//
|
||||
void enter_casting_state_c(F32 starttime);
|
||||
void leave_casting_state_c();
|
||||
void enter_delivery_state_c(F32 starttime);
|
||||
void leave_delivery_state_c();
|
||||
void enter_linger_state_c(F32 starttime);
|
||||
void leave_linger_state_c();
|
||||
//
|
||||
void sync_client(U16 marks, U8 state, F32 state_elapsed, F32 spell_elapsed);
|
||||
|
||||
public:
|
||||
void postSpellEvent(U8 event);
|
||||
void resolveTimeFactors();
|
||||
|
||||
void setTimeFactor(F32 f) { overall_time_factor = (f > 0) ? f : 1.0f; }
|
||||
F32 getTimeFactor() { return overall_time_factor; }
|
||||
void setTimeFactor(U8 phase, F32 f) { tfactors[phase] = (f > 0) ? f : 1.0f; }
|
||||
F32 getTimeFactor(U8 phase) { return tfactors[phase]; }
|
||||
|
||||
ShapeBase* getCaster() const { return caster; }
|
||||
SceneObject* getTarget() const { return target; }
|
||||
afxMagicMissile* getMissile() const { return missile; }
|
||||
SceneObject* getImpactedObject() const { return impacted_obj; }
|
||||
|
||||
virtual void restoreObject(SceneObject*);
|
||||
|
||||
bool activationCallInit(bool postponed=false);
|
||||
void activate();
|
||||
|
||||
public:
|
||||
static afxMagicSpell* cast_spell(afxMagicSpellData*, ShapeBase* caster, SceneObject* target, SimObject* extra);
|
||||
|
||||
static void displayScreenMessage(ShapeBase* caster, const char* msg);
|
||||
static Point3F getShapeImpactPos(SceneObject*);
|
||||
};
|
||||
|
||||
inline bool afxMagicSpell::is_caster_moving()
|
||||
{
|
||||
return (caster) ? (caster->getVelocity().len() > datablock->move_interrupt_speed) : false;
|
||||
}
|
||||
|
||||
inline bool afxMagicSpell::is_caster_client(ShapeBase* caster, GameConnection* conn)
|
||||
{
|
||||
return (caster) ? (caster->getControllingClient() == conn) : false;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MAGIC_SPELL_H_
|
||||
196
Engine/source/afx/afxPhrase.cpp
Normal file
196
Engine/source/afx/afxPhrase.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/afxEffectVector.h"
|
||||
#include "afx/afxPhrase.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhrase
|
||||
|
||||
void
|
||||
afxPhrase::init_fx(S32 group_index)
|
||||
{
|
||||
fx->ev_init(init_chor, *init_fx_list, on_server, will_stop, init_time_factor, init_dur, group_index);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxPhrase::afxPhrase(bool on_server, bool will_stop)
|
||||
{
|
||||
this->on_server = on_server;
|
||||
this->will_stop = will_stop;
|
||||
|
||||
init_fx_list = NULL;
|
||||
init_dur = 0.0f;
|
||||
init_chor = NULL;
|
||||
init_time_factor = 1.0f;
|
||||
|
||||
fx = new afxEffectVector;
|
||||
fx2 = NULL;
|
||||
starttime = 0;
|
||||
dur = 0;
|
||||
|
||||
n_loops = 1;
|
||||
loop_cnt = 1;
|
||||
|
||||
extra_time = 0.0f;
|
||||
extra_stoptime = 0.0f;
|
||||
}
|
||||
|
||||
afxPhrase::~afxPhrase()
|
||||
{
|
||||
delete fx;
|
||||
delete fx2;
|
||||
};
|
||||
|
||||
void
|
||||
afxPhrase::init(afxEffectList& fx_list, F32 dur, afxChoreographer* chor, F32 time_factor,
|
||||
S32 n_loops, S32 group_index, F32 extra_time)
|
||||
{
|
||||
init_fx_list = &fx_list;
|
||||
init_dur = dur;
|
||||
init_chor = chor;
|
||||
init_time_factor = time_factor;
|
||||
|
||||
this->n_loops = n_loops;
|
||||
this->extra_time = extra_time;
|
||||
this->dur = (init_dur < 0) ? init_dur : init_dur*init_time_factor;
|
||||
|
||||
init_fx(group_index);
|
||||
}
|
||||
|
||||
void
|
||||
afxPhrase::start(F32 startstamp, F32 timestamp)
|
||||
{
|
||||
starttime = startstamp;
|
||||
|
||||
F32 loopstart = timestamp - startstamp;
|
||||
|
||||
if (dur > 0 && loopstart > dur)
|
||||
{
|
||||
loop_cnt += (S32) (loopstart/dur);
|
||||
loopstart = mFmod(loopstart, dur);
|
||||
}
|
||||
|
||||
if (!fx->empty())
|
||||
fx->start(loopstart);
|
||||
}
|
||||
|
||||
void
|
||||
afxPhrase::update(F32 dt, F32 timestamp)
|
||||
{
|
||||
if (fx->isActive())
|
||||
fx->update(dt);
|
||||
|
||||
if (fx2 && fx2->isActive())
|
||||
fx2->update(dt);
|
||||
|
||||
if (extra_stoptime > 0 && timestamp > extra_stoptime)
|
||||
{
|
||||
stop(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
afxPhrase::stop(F32 timestamp)
|
||||
{
|
||||
if (extra_time > 0 && !(extra_stoptime > 0))
|
||||
{
|
||||
extra_stoptime = timestamp + extra_time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fx->isActive())
|
||||
fx->stop();
|
||||
|
||||
if (fx2 && fx2->isActive())
|
||||
fx2->stop();
|
||||
}
|
||||
|
||||
bool
|
||||
afxPhrase::expired(F32 timestamp)
|
||||
{
|
||||
if (dur < 0)
|
||||
return false;
|
||||
|
||||
return ((timestamp - starttime) > loop_cnt*dur);
|
||||
}
|
||||
|
||||
F32
|
||||
afxPhrase::elapsed(F32 timestamp)
|
||||
{
|
||||
return (timestamp - starttime);
|
||||
}
|
||||
|
||||
bool
|
||||
afxPhrase::recycle(F32 timestamp)
|
||||
{
|
||||
if (n_loops < 0 || loop_cnt < n_loops)
|
||||
{
|
||||
if (fx2)
|
||||
delete fx2;
|
||||
|
||||
fx2 = fx;
|
||||
|
||||
fx = new afxEffectVector;
|
||||
init_fx();
|
||||
|
||||
if (fx2 && !fx2->empty())
|
||||
fx2->stop();
|
||||
|
||||
if (!fx->empty())
|
||||
fx->start(0.0F);
|
||||
|
||||
loop_cnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
afxPhrase::interrupt(F32 timestamp)
|
||||
{
|
||||
if (fx->isActive())
|
||||
fx->interrupt();
|
||||
|
||||
if (fx2 && fx2->isActive())
|
||||
fx2->interrupt();
|
||||
}
|
||||
|
||||
F32 afxPhrase::calcDoneTime()
|
||||
{
|
||||
return starttime + fx->getTotalDur();
|
||||
}
|
||||
|
||||
F32 afxPhrase::calcAfterLife()
|
||||
{
|
||||
return fx->getAfterLife();
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
87
Engine/source/afx/afxPhrase.h
Normal file
87
Engine/source/afx/afxPhrase.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PHRASE_H_
|
||||
#define _AFX_PHRASE_H_
|
||||
|
||||
#include "afxEffectVector.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhrase
|
||||
|
||||
class afxChoreographer;
|
||||
class afxConstraintMgr;
|
||||
class afxEffectVector;
|
||||
|
||||
class afxPhrase
|
||||
{
|
||||
protected:
|
||||
afxEffectList* init_fx_list;
|
||||
F32 init_dur;
|
||||
afxChoreographer* init_chor;
|
||||
F32 init_time_factor;
|
||||
F32 extra_time;
|
||||
|
||||
afxEffectVector* fx;
|
||||
afxEffectVector* fx2;
|
||||
|
||||
bool on_server;
|
||||
bool will_stop;
|
||||
|
||||
F32 starttime;
|
||||
F32 dur;
|
||||
S32 n_loops;
|
||||
S32 loop_cnt;
|
||||
F32 extra_stoptime;
|
||||
|
||||
void init_fx(S32 group_index=0);
|
||||
|
||||
public:
|
||||
/*C*/ afxPhrase(bool on_server, bool will_stop);
|
||||
virtual ~afxPhrase();
|
||||
|
||||
virtual void init(afxEffectList&, F32 dur, afxChoreographer*, F32 time_factor,
|
||||
S32 n_loops, S32 group_index=0, F32 extra_time=0.0f);
|
||||
|
||||
virtual void start(F32 startstamp, F32 timestamp);
|
||||
virtual void update(F32 dt, F32 timestamp);
|
||||
virtual void stop(F32 timestamp);
|
||||
virtual void interrupt(F32 timestamp);
|
||||
virtual bool expired(F32 timestamp);
|
||||
virtual bool recycle(F32 timestamp);
|
||||
virtual F32 elapsed(F32 timestamp);
|
||||
|
||||
bool isEmpty() { return fx->empty(); }
|
||||
bool isInfinite() { return (init_dur < 0); }
|
||||
F32 calcDoneTime();
|
||||
F32 calcAfterLife();
|
||||
bool willStop() { return will_stop; }
|
||||
bool onServer() { return on_server; }
|
||||
S32 count() { return fx->count(); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PHRASE_H_
|
||||
176
Engine/source/afx/afxRenderHighlightMgr.cpp
Normal file
176
Engine/source/afx/afxRenderHighlightMgr.cpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// The afxRenderHighlightMgr class is adapted from the resource,
|
||||
// "Silhoute selection via postFX for Torque3D" posted by Konrad Kiss.
|
||||
// http://www.garagegames.com/community/resources/view/17821
|
||||
// Supporting code mods in other areas of the engine are marked as
|
||||
// "(selection-highlight)".
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "afxRenderHighlightMgr.h"
|
||||
|
||||
#include "scene/sceneManager.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "materials/matInstance.h"
|
||||
//#include "materials/materialFeatureTypes.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
#include "postFx/postEffect.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "gfx/gfxDebugEvent.h"
|
||||
#include "math/util/matrixSet.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT( afxRenderHighlightMgr );
|
||||
|
||||
afxRenderHighlightMgr::afxRenderHighlightMgr()
|
||||
: RenderTexTargetBinManager( RenderPassManager::RIT_Mesh,
|
||||
1.0f,
|
||||
1.0f,
|
||||
GFXFormatR8G8B8A8,
|
||||
Point2I( 512, 512 ) )
|
||||
{
|
||||
mNamedTarget.registerWithName( "highlight" );
|
||||
mTargetSizeType = WindowSize;
|
||||
}
|
||||
|
||||
afxRenderHighlightMgr::~afxRenderHighlightMgr()
|
||||
{
|
||||
}
|
||||
|
||||
PostEffect* afxRenderHighlightMgr::getSelectionEffect()
|
||||
{
|
||||
if ( !mSelectionEffect )
|
||||
mSelectionEffect = dynamic_cast<PostEffect*>( Sim::findObject( "afxHighlightPostFX" ) );
|
||||
|
||||
return mSelectionEffect;
|
||||
}
|
||||
|
||||
bool afxRenderHighlightMgr::isSelectionEnabled()
|
||||
{
|
||||
return getSelectionEffect() && getSelectionEffect()->isEnabled();
|
||||
}
|
||||
|
||||
void afxRenderHighlightMgr::addElement( RenderInst *inst )
|
||||
{
|
||||
// Skip out if we don't have the selection post
|
||||
// effect enabled at this time.
|
||||
if ( !isSelectionEnabled() )
|
||||
return;
|
||||
|
||||
// Skip it if we don't have a selection material.
|
||||
BaseMatInstance *matInst = getMaterial( inst );
|
||||
if ( !matInst || !matInst->needsSelectionHighlighting() )
|
||||
return;
|
||||
|
||||
internalAddElement(inst);
|
||||
}
|
||||
|
||||
void afxRenderHighlightMgr::render( SceneRenderState *state )
|
||||
{
|
||||
PROFILE_SCOPE( RenderSelectionMgr_Render );
|
||||
|
||||
if ( !isSelectionEnabled() )
|
||||
return;
|
||||
|
||||
const U32 binSize = mElementList.size();
|
||||
|
||||
// If this is a non-diffuse pass or we have no objects to
|
||||
// render then tell the effect to skip rendering.
|
||||
if ( !state->isDiffusePass() || binSize == 0 )
|
||||
{
|
||||
getSelectionEffect()->setSkip( true );
|
||||
return;
|
||||
}
|
||||
|
||||
GFXDEBUGEVENT_SCOPE( RenderSelectionMgr_Render, ColorI::GREEN );
|
||||
|
||||
GFXTransformSaver saver;
|
||||
|
||||
// Tell the superclass we're about to render, preserve contents
|
||||
const bool isRenderingToTarget = _onPreRender( state, true );
|
||||
|
||||
// Clear all the buffers to black.
|
||||
//GFX->clear( GFXClearTarget, ColorI::BLACK, 1.0f, 0);
|
||||
GFX->clear( GFXClearTarget, ColorI::ZERO, 1.0f, 0);
|
||||
|
||||
// Restore transforms
|
||||
MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
|
||||
matrixSet.restoreSceneViewProjection();
|
||||
|
||||
// init loop data
|
||||
SceneData sgData;
|
||||
sgData.init( state, SceneData::HighlightBin );
|
||||
|
||||
for( U32 j=0; j<binSize; )
|
||||
{
|
||||
MeshRenderInst *ri = static_cast<MeshRenderInst*>(mElementList[j].inst);
|
||||
|
||||
setupSGData( ri, sgData );
|
||||
|
||||
BaseMatInstance *mat = ri->matInst;
|
||||
|
||||
U32 matListEnd = j;
|
||||
|
||||
while( mat && mat->setupPass( state, sgData ) )
|
||||
{
|
||||
U32 a;
|
||||
for( a=j; a<binSize; a++ )
|
||||
{
|
||||
MeshRenderInst *passRI = static_cast<MeshRenderInst*>(mElementList[a].inst);
|
||||
|
||||
if ( newPassNeeded( ri, passRI ) )
|
||||
break;
|
||||
|
||||
matrixSet.setWorld(*passRI->objectToWorld);
|
||||
matrixSet.setView(*passRI->worldToCamera);
|
||||
matrixSet.setProjection(*passRI->projection);
|
||||
mat->setTransforms(matrixSet, state);
|
||||
|
||||
mat->setSceneInfo(state, sgData);
|
||||
mat->setBuffers(passRI->vertBuff, passRI->primBuff);
|
||||
|
||||
if ( passRI->prim )
|
||||
GFX->drawPrimitive( *passRI->prim );
|
||||
else
|
||||
GFX->drawPrimitive( passRI->primBuffIndex );
|
||||
}
|
||||
matListEnd = a;
|
||||
setupSGData( ri, sgData );
|
||||
}
|
||||
|
||||
// force increment if none happened, otherwise go to end of batch
|
||||
j = ( j == matListEnd ) ? j+1 : matListEnd;
|
||||
}
|
||||
|
||||
// Finish up.
|
||||
if ( isRenderingToTarget )
|
||||
_onPostRender();
|
||||
|
||||
// Make sure the effect is gonna render.
|
||||
getSelectionEffect()->setSkip( false );
|
||||
}
|
||||
76
Engine/source/afx/afxRenderHighlightMgr.h
Normal file
76
Engine/source/afx/afxRenderHighlightMgr.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// The afxRenderHighlightMgr class is adapted from the resource,
|
||||
// "Silhoute selection via postFX for Torque3D" posted by Konrad Kiss.
|
||||
// http://www.garagegames.com/community/resources/view/17821
|
||||
// Supporting code mods in other areas of the engine are marked as
|
||||
// "(selection-highlight)".
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _afxRENDERHIGHLIGHTMGR_H_
|
||||
#define _afxRENDERHIGHLIGHTMGR_H_
|
||||
|
||||
#ifndef _TEXTARGETBIN_MGR_H_
|
||||
#include "renderInstance/renderTexTargetBinManager.h"
|
||||
#endif
|
||||
|
||||
|
||||
class PostEffect;
|
||||
|
||||
|
||||
///
|
||||
class afxRenderHighlightMgr : public RenderTexTargetBinManager
|
||||
{
|
||||
typedef RenderTexTargetBinManager Parent;
|
||||
|
||||
public:
|
||||
|
||||
afxRenderHighlightMgr();
|
||||
virtual ~afxRenderHighlightMgr();
|
||||
|
||||
/// Returns the selection post effect.
|
||||
PostEffect* getSelectionEffect();
|
||||
|
||||
/// Returns true if the highlight post effect is
|
||||
/// enabled and the selection buffer should be updated.
|
||||
bool isSelectionEnabled();
|
||||
|
||||
// RenderBinManager
|
||||
virtual void addElement( RenderInst *inst );
|
||||
virtual void render( SceneRenderState *state );
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT( afxRenderHighlightMgr );
|
||||
|
||||
protected:
|
||||
|
||||
SimObjectPtr<PostEffect> mSelectionEffect;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _afxRENDERHIGHLIGHTMGR_H_
|
||||
469
Engine/source/afx/afxResidueMgr.cpp
Normal file
469
Engine/source/afx/afxResidueMgr.cpp
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "ts/tsShapeInstance.h"
|
||||
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
#include "afx/ce/afxModel.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
int QSORT_CALLBACK afxResidueMgr::ResidueList::compare_residue(const void* p1, const void* p2)
|
||||
{
|
||||
const afxResidueMgr::Residue** pd1 = (const afxResidueMgr::Residue**)p1;
|
||||
const afxResidueMgr::Residue** pd2 = (const afxResidueMgr::Residue**)p2;
|
||||
|
||||
return int(((char*)(*pd1)->data.simobject) - ((char*)(*pd2)->data.simobject));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
inline void afxResidueMgr::ResidueList::swap_array_ptrs()
|
||||
{
|
||||
Vector<Residue*>* tmp = m_array;
|
||||
m_array = m_scratch_array;
|
||||
m_scratch_array = tmp;
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::free_residue(Residue* residue)
|
||||
{
|
||||
if (the_mgr == NULL)
|
||||
return;
|
||||
|
||||
if (the_mgr->requires_delete_tracking(residue))
|
||||
the_mgr->disable_delete_tracking(residue);
|
||||
the_mgr->free_residue(residue);
|
||||
}
|
||||
|
||||
afxResidueMgr::ResidueList::ResidueList()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(m_array_a);
|
||||
VECTOR_SET_ASSOCIATION(m_array_b);
|
||||
|
||||
m_array = &m_array_a;
|
||||
m_scratch_array = &m_array_b ;
|
||||
|
||||
m_dirty = false;
|
||||
m_pending = -1;
|
||||
}
|
||||
|
||||
afxResidueMgr::ResidueList::~ResidueList()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::clear()
|
||||
{
|
||||
if (the_mgr)
|
||||
{
|
||||
for (S32 i = 0; i < m_array->size(); i++)
|
||||
{
|
||||
Residue* r = (*m_array)[i];
|
||||
the_mgr->free_residue(r);
|
||||
}
|
||||
}
|
||||
|
||||
m_array_a.clear();
|
||||
m_array_b.clear();
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::sort()
|
||||
{
|
||||
dQsort(m_array->address(), m_array->size(), sizeof(Residue*), compare_residue);
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::fadeAndCull(U32 now)
|
||||
{
|
||||
for (S32 i = 0; i < m_array->size(); i++)
|
||||
{
|
||||
Residue* r = (*m_array)[i];
|
||||
|
||||
// done
|
||||
if (now >= r->stop_time)
|
||||
{
|
||||
free_residue(r);
|
||||
}
|
||||
// fading
|
||||
else if (now >= r->fade_time)
|
||||
{
|
||||
r->fade = 1.0f - ((F32)(now - r->fade_time))/((F32)(r->stop_time - r->fade_time));
|
||||
m_scratch_array->push_back(r);
|
||||
}
|
||||
// opaque
|
||||
else
|
||||
{
|
||||
r->fade = 1.0f;
|
||||
m_scratch_array->push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
m_array->clear();
|
||||
swap_array_ptrs();
|
||||
}
|
||||
|
||||
// removes all residue with datablock matching obj
|
||||
void afxResidueMgr::ResidueList::stripMatchingObjects(SimObject* db, bool del_notify)
|
||||
{
|
||||
if (del_notify)
|
||||
{
|
||||
for (S32 i = 0; i < m_array->size(); i++)
|
||||
{
|
||||
Residue* r = (*m_array)[i];
|
||||
if (db == r->data.simobject && the_mgr != NULL)
|
||||
the_mgr->free_residue(r);
|
||||
else
|
||||
m_scratch_array->push_back(r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < m_array->size(); i++)
|
||||
{
|
||||
Residue* r = (*m_array)[i];
|
||||
if (db == r->data.simobject)
|
||||
free_residue(r);
|
||||
else
|
||||
m_scratch_array->push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
m_array->clear();
|
||||
swap_array_ptrs();
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::add(Residue* residue)
|
||||
{
|
||||
m_array->push_back(residue);
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void afxResidueMgr::manage_residue(const Residue* r)
|
||||
{
|
||||
if (r == NULL || r->fade < 0.01f)
|
||||
return;
|
||||
|
||||
if (r->type == ZODIAC)
|
||||
{
|
||||
LinearColorF zode_color = ColorI(r->params.zodiac.r, r->params.zodiac.g, r->params.zodiac.b, r->params.zodiac.a);
|
||||
|
||||
afxZodiacData* zd = (afxZodiacData*) r->data.zodiac;
|
||||
if (zd->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
|
||||
zode_color *= r->fade;
|
||||
else
|
||||
zode_color.alpha *= r->fade;
|
||||
|
||||
Point3F zode_pos(r->params.zodiac.pos_x, r->params.zodiac.pos_y, r->params.zodiac.pos_z);
|
||||
Point2F zode_vrange(r->params.zodiac.vrange_dn, r->params.zodiac.vrange_dn);
|
||||
if (r->params.zodiac.on_terrain)
|
||||
{
|
||||
afxZodiacMgr::addTerrainZodiac(zode_pos, r->params.zodiac.rad, zode_color, r->params.zodiac.ang, zd);
|
||||
}
|
||||
else
|
||||
{
|
||||
afxZodiacMgr::addInteriorZodiac(zode_pos, r->params.zodiac.rad, zode_vrange, zode_color, r->params.zodiac.ang, zd);
|
||||
}
|
||||
}
|
||||
else if (r->type == MODEL)
|
||||
{
|
||||
r->data.model->setFadeAmount(r->fade);
|
||||
}
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::manage()
|
||||
{
|
||||
if (the_mgr == NULL)
|
||||
return;
|
||||
|
||||
S32 n_residue = m_array->size();
|
||||
|
||||
for (S32 x = 0; x < n_residue; x++)
|
||||
the_mgr->manage_residue((*m_array)[x]);
|
||||
}
|
||||
|
||||
U32 afxResidueMgr::ResidueList::findPendingBestBump(U32 look_max)
|
||||
{
|
||||
U32 soonest = 1000*60*60*24;
|
||||
m_pending = -1;
|
||||
|
||||
U32 n = m_array->size();
|
||||
for (U32 i = 0; i < n && i < look_max; i++)
|
||||
{
|
||||
Residue* r = (*m_array)[i];
|
||||
if (r->stop_time < soonest)
|
||||
{
|
||||
soonest = r->stop_time;
|
||||
m_pending = i;
|
||||
}
|
||||
}
|
||||
|
||||
return soonest;
|
||||
}
|
||||
|
||||
void afxResidueMgr::ResidueList::bumpPending()
|
||||
{
|
||||
if (m_pending >= 0 && m_pending < m_array->size())
|
||||
{
|
||||
Residue* r = (*m_array)[m_pending];
|
||||
m_array->erase(m_pending);
|
||||
free_residue(r);
|
||||
}
|
||||
|
||||
m_pending = -1;
|
||||
}
|
||||
|
||||
bool afxResidueMgr::requires_delete_tracking(Residue* r)
|
||||
{
|
||||
return (r->type == MODEL);
|
||||
}
|
||||
|
||||
void afxResidueMgr::enable_delete_tracking(Residue* r)
|
||||
{
|
||||
deleteNotify(r->data.simobject);
|
||||
}
|
||||
|
||||
void afxResidueMgr::disable_delete_tracking(Residue* r)
|
||||
{
|
||||
clearNotify(r->data.simobject);
|
||||
r->data.simobject->deleteObject();
|
||||
r->data.simobject = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxResidueMgr* afxResidueMgr::the_mgr = NULL;
|
||||
U32 afxResidueMgr::m_max_residue_objs = 256;
|
||||
bool afxResidueMgr::enabled = true;
|
||||
|
||||
IMPLEMENT_CONOBJECT(afxResidueMgr);
|
||||
|
||||
ConsoleDocClass( afxResidueMgr,
|
||||
"@brief A class that manages certain AFX effects that can persist for long durations.\n\n"
|
||||
|
||||
"A class that manages certain AFX effects that can persist much longer than the duration of choreographers.\n"
|
||||
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// free-list management
|
||||
|
||||
afxResidueMgr::Residue* afxResidueMgr::alloc_free_pool_block()
|
||||
{
|
||||
// allocate new block for the free-list
|
||||
m_free_pool_blocks.push_back(new Residue[FREE_POOL_BLOCK_SIZE]);
|
||||
|
||||
// link them onto the free-list
|
||||
Residue* new_block = m_free_pool_blocks.last();
|
||||
for (U32 i = 0; i < FREE_POOL_BLOCK_SIZE - 1; i++)
|
||||
new_block[i].next = &new_block[i + 1];
|
||||
|
||||
// tail of free-list points to NULL
|
||||
new_block[FREE_POOL_BLOCK_SIZE - 1].next = NULL;
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
afxResidueMgr::Residue* afxResidueMgr::alloc_residue()
|
||||
{
|
||||
// need new free-list-block if m_next_free is null
|
||||
if (!m_next_free)
|
||||
m_next_free = alloc_free_pool_block();
|
||||
|
||||
// pop new residue from head of free-list
|
||||
Residue* residue = m_next_free;
|
||||
m_next_free = residue->next;
|
||||
residue->next = NULL;
|
||||
|
||||
return residue;
|
||||
}
|
||||
|
||||
void afxResidueMgr::free_residue(Residue* residue)
|
||||
{
|
||||
if (residue && residue->type == ZODIAC)
|
||||
{
|
||||
if (residue->data.zodiac && residue->data.zodiac->isTempClone())
|
||||
{
|
||||
delete residue->data.zodiac;
|
||||
residue->data.zodiac = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// push residue onto head of free-list
|
||||
residue->next = m_next_free;
|
||||
m_next_free = residue;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxResidueMgr::deleteResidueObject(SimObject* obj, bool del_notify)
|
||||
{
|
||||
m_managed.stripMatchingObjects(obj, del_notify);
|
||||
}
|
||||
|
||||
void afxResidueMgr::bump_residue()
|
||||
{
|
||||
if (m_managed.findPendingBestBump())
|
||||
m_managed.bumpPending();
|
||||
}
|
||||
|
||||
void afxResidueMgr::add_residue(Residue* residue)
|
||||
{
|
||||
AssertFatal(residue != NULL, "residue pointer is NULL.");
|
||||
|
||||
if (m_managed.size() >= m_max_residue_objs)
|
||||
bump_residue();
|
||||
|
||||
m_managed.add(residue);
|
||||
manage_residue(residue);
|
||||
|
||||
if (requires_delete_tracking(residue))
|
||||
enable_delete_tracking(residue);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxResidueMgr::afxResidueMgr()
|
||||
{
|
||||
mObjBox.minExtents.set(-1e7, -1e7, -1e7);
|
||||
mObjBox.maxExtents.set( 1e7, 1e7, 1e7);
|
||||
mWorldBox.minExtents.set(-1e7, -1e7, -1e7);
|
||||
mWorldBox.maxExtents.set( 1e7, 1e7, 1e7);
|
||||
|
||||
m_next_free = NULL;
|
||||
|
||||
VECTOR_SET_ASSOCIATION(m_free_pool_blocks);
|
||||
}
|
||||
|
||||
afxResidueMgr::~afxResidueMgr()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void afxResidueMgr::cleanup()
|
||||
{
|
||||
m_managed.clear();
|
||||
|
||||
m_next_free = NULL;
|
||||
|
||||
for (S32 i = 0; i < m_free_pool_blocks.size(); i++)
|
||||
delete [] m_free_pool_blocks[i];
|
||||
|
||||
m_free_pool_blocks.clear();
|
||||
}
|
||||
|
||||
void afxResidueMgr::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
deleteResidueObject(obj, true);
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxResidueMgr::residueAdvanceTime()
|
||||
{
|
||||
U32 now = Platform::getVirtualMilliseconds();
|
||||
m_managed.fadeAndCull(now);
|
||||
m_managed.sortIfDirty();
|
||||
m_managed.manage();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// add ZODIAC residue
|
||||
void afxResidueMgr::add_interior_zodiac(F32 dur, F32 fade_dur, afxZodiacData* zode, const Point3F& pos,
|
||||
F32 rad, const Point2F& vrange, const LinearColorF& col, F32 ang)
|
||||
{
|
||||
add_zodiac(dur, fade_dur, zode, pos, rad, vrange, col, ang, false);
|
||||
}
|
||||
|
||||
void afxResidueMgr::add_terrain_zodiac(F32 dur, F32 fade_dur, afxZodiacData* zode, const Point3F& pos,
|
||||
F32 rad, const LinearColorF& col, F32 ang)
|
||||
{
|
||||
static Point2F vrange(0.0, 0.0);
|
||||
add_zodiac(dur, fade_dur, zode, pos, rad, vrange, col, ang, true);
|
||||
}
|
||||
|
||||
void afxResidueMgr::add_zodiac(F32 dur, F32 fade_dur, afxZodiacData* zode, const Point3F& pos,
|
||||
F32 rad, const Point2F& vrange, const LinearColorF& col, F32 ang, bool on_terrain)
|
||||
{
|
||||
if (m_max_residue_objs == 0 || dur <= 0 || the_mgr == NULL)
|
||||
return;
|
||||
|
||||
ColorI col_i = LinearColorF(col).toColorI();
|
||||
U32 now = Platform::getVirtualMilliseconds();
|
||||
|
||||
Residue* residue = the_mgr->alloc_residue();
|
||||
//
|
||||
residue->type = ZODIAC;
|
||||
residue->data.zodiac = zode;
|
||||
residue->fade_time = now + (U32)(dur*1000);
|
||||
residue->stop_time = residue->fade_time + (U32)(fade_dur*1000);
|
||||
residue->fade = 1.0f;
|
||||
//
|
||||
residue->params.zodiac.pos_x = pos.x;
|
||||
residue->params.zodiac.pos_y = pos.y;
|
||||
residue->params.zodiac.pos_z = pos.z;
|
||||
residue->params.zodiac.rad = rad;
|
||||
residue->params.zodiac.vrange_dn = vrange.x;
|
||||
residue->params.zodiac.vrange_up = vrange.y;
|
||||
residue->params.zodiac.r = col_i.red;
|
||||
residue->params.zodiac.g = col_i.green;
|
||||
residue->params.zodiac.b = col_i.blue;
|
||||
residue->params.zodiac.a = col_i.alpha;
|
||||
residue->params.zodiac.ang = ang;
|
||||
residue->params.zodiac.on_terrain = on_terrain;
|
||||
//
|
||||
residue->next = 0;
|
||||
|
||||
the_mgr->add_residue(residue);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// add MODEL residue
|
||||
|
||||
void afxResidueMgr::add(F32 dur, F32 fade_dur, afxModel* model)
|
||||
{
|
||||
if (m_max_residue_objs == 0 || dur <= 0 || the_mgr == NULL)
|
||||
return;
|
||||
|
||||
U32 now = Platform::getVirtualMilliseconds();
|
||||
|
||||
Residue* residue = the_mgr->alloc_residue();
|
||||
//
|
||||
residue->type = MODEL;
|
||||
residue->data.model = model;
|
||||
residue->fade_time = now + (U32)(dur*1000);
|
||||
residue->stop_time = residue->fade_time + (U32)(fade_dur*1000);
|
||||
residue->fade = 1.0f;
|
||||
//
|
||||
residue->next = 0;
|
||||
|
||||
the_mgr->add_residue(residue);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
179
Engine/source/afx/afxResidueMgr.h
Normal file
179
Engine/source/afx/afxResidueMgr.h
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_RESIDUE_MGR_H_
|
||||
#define _AFX_RESIDUE_MGR_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxZodiacData;
|
||||
class afxModel;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxResidueMgr
|
||||
//
|
||||
// Manage transient objects in the world.
|
||||
|
||||
class afxResidueMgr : public GameBase
|
||||
{
|
||||
|
||||
typedef GameBase Parent;
|
||||
|
||||
enum {
|
||||
ZODIAC,
|
||||
MODEL
|
||||
};
|
||||
|
||||
struct Residue
|
||||
{
|
||||
struct ZodiacParams
|
||||
{
|
||||
F32 pos_x, pos_y, pos_z;
|
||||
F32 rad, vrange_dn, vrange_up;
|
||||
U8 r,g,b,a;
|
||||
F32 ang;
|
||||
bool on_terrain;
|
||||
};
|
||||
|
||||
union ResidueParams
|
||||
{
|
||||
ZodiacParams zodiac;
|
||||
};
|
||||
|
||||
union ResidueData
|
||||
{
|
||||
afxZodiacData* zodiac;
|
||||
afxModel* model;
|
||||
SimObject* simobject;
|
||||
};
|
||||
|
||||
|
||||
U32 type;
|
||||
ResidueData data;
|
||||
ResidueParams params;
|
||||
U32 fade_time;
|
||||
U32 stop_time;
|
||||
F32 fade;
|
||||
|
||||
Residue* next;
|
||||
};
|
||||
|
||||
class ResidueList
|
||||
{
|
||||
Vector<Residue*> m_array_a;
|
||||
Vector<Residue*> m_array_b;
|
||||
|
||||
Vector<Residue*>* m_array;
|
||||
Vector<Residue*>* m_scratch_array;
|
||||
bool m_dirty;
|
||||
S32 m_pending;
|
||||
|
||||
void swap_array_ptrs();
|
||||
void free_residue(Residue*);
|
||||
|
||||
public:
|
||||
/*C*/ ResidueList();
|
||||
/*D*/ ~ResidueList();
|
||||
|
||||
void clear();
|
||||
S32 size() { return m_array->size(); }
|
||||
bool empty() { return m_array->empty(); }
|
||||
void sortIfDirty() { if (m_dirty) sort(); }
|
||||
|
||||
void sort();
|
||||
void fadeAndCull(U32 now);
|
||||
void stripMatchingObjects(SimObject* db, bool del_notify=false);
|
||||
void add(Residue*);
|
||||
|
||||
void manage();
|
||||
|
||||
U32 findPendingBestBump(U32 look_max=256);
|
||||
void bumpPending();
|
||||
|
||||
static int QSORT_CALLBACK compare_residue(const void* p1, const void* p2);
|
||||
};
|
||||
|
||||
friend class ResidueList;
|
||||
|
||||
private:
|
||||
enum { FREE_POOL_BLOCK_SIZE = 256 };
|
||||
|
||||
static afxResidueMgr* the_mgr;
|
||||
|
||||
static U32 m_max_residue_objs;
|
||||
static bool enabled;
|
||||
|
||||
ResidueList m_managed;
|
||||
|
||||
Vector<Residue*> m_free_pool_blocks;
|
||||
Residue* m_next_free;
|
||||
|
||||
Residue* alloc_free_pool_block();
|
||||
Residue* alloc_residue();
|
||||
void free_residue(Residue*);
|
||||
|
||||
void bump_residue();
|
||||
void add_residue(Residue*);
|
||||
static void add_zodiac(F32 dur, F32 fade_dur, afxZodiacData*, const Point3F& pos, F32 rad,
|
||||
const Point2F& vrange, const LinearColorF& col, F32 ang, bool on_terrain);
|
||||
|
||||
protected:
|
||||
void deleteResidueObject(SimObject* obj, bool del_notify=false);
|
||||
|
||||
void manage_residue(const Residue* r);
|
||||
|
||||
bool requires_delete_tracking(Residue*);
|
||||
void enable_delete_tracking(Residue*);
|
||||
void disable_delete_tracking(Residue*);
|
||||
|
||||
public:
|
||||
/*C*/ afxResidueMgr();
|
||||
/*D*/ ~afxResidueMgr();
|
||||
|
||||
void cleanup();
|
||||
virtual void onDeleteNotify(SimObject *obj);
|
||||
|
||||
public:
|
||||
void residueAdvanceTime();
|
||||
|
||||
// ZODIAC
|
||||
static void add_terrain_zodiac(F32 dur, F32 fade_dur, afxZodiacData*, const Point3F& pos, F32 rad,
|
||||
const LinearColorF& col, F32 ang);
|
||||
static void add_interior_zodiac(F32 dur, F32 fade_dur, afxZodiacData*, const Point3F& pos, F32 rad,
|
||||
const Point2F& vrange, const LinearColorF& col, F32 ang);
|
||||
|
||||
// MODEL
|
||||
static void add(F32 dur, F32 fade_dur, afxModel*);
|
||||
|
||||
static afxResidueMgr* getMaster() { return the_mgr; }
|
||||
static void setMaster(afxResidueMgr* m) { the_mgr = m; }
|
||||
|
||||
DECLARE_CONOBJECT(afxResidueMgr);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_RESIDUE_MGR_H_
|
||||
1173
Engine/source/afx/afxSelectron.cpp
Normal file
1173
Engine/source/afx/afxSelectron.cpp
Normal file
File diff suppressed because it is too large
Load diff
258
Engine/source/afx/afxSelectron.h
Normal file
258
Engine/source/afx/afxSelectron.h
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_SELECTION_EFFECT_H_
|
||||
#define _AFX_SELECTION_EFFECT_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#include "afxChoreographer.h"
|
||||
#include "afxEffectWrapper.h"
|
||||
#include "afxPhrase.h"
|
||||
|
||||
class afxChoreographerData;
|
||||
class afxEffectBaseData;
|
||||
|
||||
class afxSelectronDefs
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
MAIN_PHRASE,
|
||||
SELECT_PHRASE,
|
||||
DESELECT_PHRASE,
|
||||
NUM_PHRASES
|
||||
};
|
||||
};
|
||||
|
||||
class afxSelectronData : public afxChoreographerData, public afxSelectronDefs
|
||||
{
|
||||
typedef afxChoreographerData Parent;
|
||||
|
||||
class ewValidator : public TypeValidator
|
||||
{
|
||||
U32 id;
|
||||
public:
|
||||
ewValidator(U32 id) { this->id = id; }
|
||||
void validateType(SimObject *object, void *typePtr);
|
||||
};
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
F32 main_dur;
|
||||
F32 select_dur;
|
||||
F32 deselect_dur;
|
||||
|
||||
S32 n_main_loops;
|
||||
S32 n_select_loops;
|
||||
S32 n_deselect_loops;
|
||||
|
||||
bool registered;
|
||||
U8 obj_type_style;
|
||||
U32 obj_type_mask;
|
||||
|
||||
afxEffectBaseData* dummy_fx_entry;
|
||||
|
||||
afxEffectList main_fx_list;
|
||||
afxEffectList select_fx_list;
|
||||
afxEffectList deselect_fx_list;
|
||||
|
||||
private:
|
||||
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
|
||||
void unpack_fx(BitStream* stream, afxEffectList& fx);
|
||||
|
||||
public:
|
||||
/*C*/ afxSelectronData();
|
||||
/*C*/ afxSelectronData(const afxSelectronData&, bool = false);
|
||||
/*D*/ ~afxSelectronData();
|
||||
|
||||
virtual void reloadReset();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
bool matches(U32 mask, U8 style);
|
||||
void gatherConstraintDefs(Vector<afxConstraintDef>&);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxSelectronData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
inline bool afxSelectronData::matches(U32 mask, U8 style)
|
||||
{
|
||||
if (obj_type_style != style)
|
||||
return false;
|
||||
|
||||
if (obj_type_mask == 0 && mask == 0)
|
||||
return true;
|
||||
|
||||
return ((obj_type_mask & mask) != 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxSelectron
|
||||
|
||||
class afxSelectron : public afxChoreographer, public afxSelectronDefs
|
||||
{
|
||||
typedef afxChoreographer Parent;
|
||||
friend class arcaneFX;
|
||||
|
||||
public:
|
||||
enum MaskBits
|
||||
{
|
||||
StateEventMask = Parent::NextFreeMask << 0,
|
||||
SyncEventMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NULL_EVENT,
|
||||
ACTIVATE_EVENT,
|
||||
SHUTDOWN_EVENT,
|
||||
DEACTIVATE_EVENT,
|
||||
INTERRUPT_EVENT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
INACTIVE_STATE,
|
||||
ACTIVE_STATE,
|
||||
CLEANUP_STATE,
|
||||
DONE_STATE,
|
||||
LATE_STATE
|
||||
};
|
||||
|
||||
enum {
|
||||
MARK_ACTIVATE = BIT(0),
|
||||
MARK_SHUTDOWN = BIT(1),
|
||||
MARK_DEACTIVATE = BIT(2),
|
||||
MARK_INTERRUPT = BIT(3),
|
||||
};
|
||||
|
||||
class ObjectDeleteEvent : public SimEvent
|
||||
{
|
||||
public:
|
||||
void process(SimObject *obj) { if (obj) obj->deleteObject(); }
|
||||
};
|
||||
|
||||
private:
|
||||
static StringTableEntry CAMERA_CONS;
|
||||
static StringTableEntry LISTENER_CONS;
|
||||
static StringTableEntry FREE_TARGET_CONS;
|
||||
|
||||
private:
|
||||
afxSelectronData* datablock;
|
||||
SimObject* exeblock;
|
||||
|
||||
bool constraints_initialized;
|
||||
bool client_only;
|
||||
|
||||
U8 effect_state;
|
||||
F32 effect_elapsed;
|
||||
|
||||
afxConstraintID listener_cons_id;
|
||||
afxConstraintID free_target_cons_id;
|
||||
afxConstraintID camera_cons_id;
|
||||
SceneObject* camera_cons_obj;
|
||||
|
||||
afxPhrase* phrases[NUM_PHRASES];
|
||||
|
||||
F32 time_factor;
|
||||
U8 marks_mask;
|
||||
|
||||
private:
|
||||
void init();
|
||||
bool state_expired();
|
||||
void init_constraints();
|
||||
void setup_main_fx();
|
||||
void setup_select_fx();
|
||||
void setup_deselect_fx();
|
||||
bool cleanup_over();
|
||||
|
||||
public:
|
||||
/*C*/ afxSelectron();
|
||||
/*C*/ afxSelectron(bool not_default);
|
||||
/*D*/ ~afxSelectron();
|
||||
|
||||
// STANDARD OVERLOADED METHODS //
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void processTick(const Move*);
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
|
||||
virtual void sync_with_clients();
|
||||
void finish_startup();
|
||||
|
||||
DECLARE_CONOBJECT(afxSelectron);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
|
||||
private:
|
||||
void process_server();
|
||||
//
|
||||
void change_state_s(U8 pending_state);
|
||||
//
|
||||
void enter_active_state_s();
|
||||
void leave_active_state_s();
|
||||
void enter_cleanup_state_s();
|
||||
void enter_done_state_s();
|
||||
|
||||
private:
|
||||
void process_client(F32 dt);
|
||||
//
|
||||
void change_state_c(U8 pending_state);
|
||||
//
|
||||
void enter_active_state_c(F32 starttime);
|
||||
void enter_cleanup_state_c();
|
||||
void enter_done_state_c();
|
||||
void leave_active_state_c();
|
||||
|
||||
void sync_client(U16 marks, U8 state, F32 elapsed);
|
||||
|
||||
public:
|
||||
void postEvent(U8 event);
|
||||
void setTimeFactor(F32 f) { time_factor = (f > 0) ? f : 1.0f; }
|
||||
F32 getTimeFactor() { return time_factor; }
|
||||
|
||||
void activate();
|
||||
|
||||
public:
|
||||
static afxSelectron* start_selectron(SceneObject* picked, U8 subcode, SimObject* extra);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
#endif // _AFX_SELECTION_EFFECT_H_
|
||||
357
Engine/source/afx/afxSpellBook.cpp
Normal file
357
Engine/source/afx/afxSpellBook.cpp
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
|
||||
#include "afx/afxSpellBook.h"
|
||||
#include "afx/afxMagicSpell.h"
|
||||
#include "afx/rpg/afxRPGMagicSpell.h"
|
||||
#include "afx/ui/afxSpellButton.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxSpellBookData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxSpellBookData);
|
||||
|
||||
ConsoleDocClass( afxSpellBookData,
|
||||
"@brief A spellbook datablock.\n\n"
|
||||
|
||||
"@ingroup afxMisc\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxSpellBookData::afxSpellBookData()
|
||||
{
|
||||
spells_per_page = 12;
|
||||
pages_per_book = 12;
|
||||
dMemset(spells, 0, sizeof(spells));
|
||||
dMemset(rpg_spells, 0, sizeof(rpg_spells));
|
||||
|
||||
// marked true if datablock ids need to
|
||||
// be converted into pointers
|
||||
do_id_convert = false;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxSpellBookData)
|
||||
|
||||
void afxSpellBookData::initPersistFields()
|
||||
{
|
||||
addField("spellsPerPage", TypeS8, myOffset(spells_per_page),
|
||||
"...");
|
||||
addField("pagesPerBook", TypeS8, myOffset(pages_per_book),
|
||||
"...");
|
||||
|
||||
addField("spells", TYPEID<GameBaseData>(), myOffset(spells), MAX_PAGES_PER_BOOK*MAX_SPELLS_PER_PAGE,
|
||||
"...");
|
||||
addField("rpgSpells", TYPEID<GameBaseData>(), myOffset(rpg_spells), MAX_PAGES_PER_BOOK*MAX_SPELLS_PER_PAGE,
|
||||
"...");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxSpellBookData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server)
|
||||
{
|
||||
if (do_id_convert)
|
||||
{
|
||||
for (S32 i = 0; i < pages_per_book*spells_per_page; i++)
|
||||
{
|
||||
SimObjectId db_id = SimObjectId((uintptr_t)rpg_spells[i]);
|
||||
if (db_id != 0)
|
||||
{
|
||||
// try to convert id to pointer
|
||||
if (!Sim::findObject(db_id, rpg_spells[i]))
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"afxSpellBookData::preload() -- bad datablockId: 0x%x (afxRPGMagicSpellData)",
|
||||
db_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
do_id_convert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxSpellBookData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(spells_per_page);
|
||||
stream->write(pages_per_book);
|
||||
|
||||
for (S32 i = 0; i < pages_per_book*spells_per_page; i++)
|
||||
writeDatablockID(stream, rpg_spells[i], packed);
|
||||
}
|
||||
|
||||
void afxSpellBookData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&spells_per_page);
|
||||
stream->read(&pages_per_book);
|
||||
|
||||
do_id_convert = true;
|
||||
for (S32 i = 0; i < pages_per_book*spells_per_page; i++)
|
||||
rpg_spells[i] = (afxRPGMagicSpellData*) readDatablockID(stream);
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBookData, getPageSlotIndex, S32, (Point2I bookSlot),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return object->getPageSlotIndex(bookSlot.x, bookSlot.y);
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBookData, getCapacity, S32, (),,
|
||||
"Get the capacity (total number of spell slots) in a spellbook.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return object->spells_per_page*object->pages_per_book;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxSpellBook
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxSpellBook);
|
||||
|
||||
ConsoleDocClass( afxSpellBook,
|
||||
"@brief A spellbook object.\n\n"
|
||||
|
||||
"@ingroup afxMisc\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxSpellBook::afxSpellBook()
|
||||
{
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
mDataBlock = NULL;
|
||||
all_spell_cooldown = 1.0f;
|
||||
}
|
||||
|
||||
afxSpellBook::~afxSpellBook()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxSpellBook::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxSpellBook::processTick(const Move* m)
|
||||
{
|
||||
Parent::processTick(m);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxSpellBook::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if (all_spell_cooldown < 1.0f)
|
||||
{
|
||||
all_spell_cooldown += dt/2.0f;
|
||||
if (all_spell_cooldown > 1.0f)
|
||||
all_spell_cooldown = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxSpellBook::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<afxSpellBookData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxSpellBook::onAdd()
|
||||
{
|
||||
if (!Parent::onAdd())
|
||||
return(false);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void afxSpellBook::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
U32 afxSpellBook::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(con, mask, stream);
|
||||
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
}
|
||||
|
||||
// AllSpellCooldown
|
||||
if (stream->writeFlag(mask & AllSpellCooldownMask))
|
||||
{
|
||||
}
|
||||
|
||||
return(retMask);
|
||||
}
|
||||
|
||||
void afxSpellBook::unpackUpdate(NetConnection * con, BitStream * stream)
|
||||
{
|
||||
Parent::unpackUpdate(con, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->readFlag())
|
||||
{
|
||||
}
|
||||
|
||||
// AllSpellCooldown
|
||||
if (stream->readFlag())
|
||||
{
|
||||
all_spell_cooldown = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#define SPELL_DATA_NOT_FOUND "\n<just:center><font:Arial:20><color:FF0000>** Spell data not found **\n\n\n\n"
|
||||
|
||||
char* afxSpellBook::formatDesc(char* buffer, int len, S32 page, S32 slot) const
|
||||
{
|
||||
S32 idx = mDataBlock->getPageSlotIndex(page, slot);
|
||||
if (idx < 0 || !mDataBlock->rpg_spells[idx])
|
||||
return SPELL_DATA_NOT_FOUND;
|
||||
|
||||
return mDataBlock->rpg_spells[idx]->formatDesc(buffer, len);
|
||||
}
|
||||
|
||||
const char* afxSpellBook::getSpellIcon(S32 page, S32 slot) const
|
||||
{
|
||||
S32 idx = mDataBlock->getPageSlotIndex(page, slot);
|
||||
if (idx < 0 || !mDataBlock->rpg_spells[idx])
|
||||
return 0;
|
||||
|
||||
return mDataBlock->rpg_spells[idx]->icon_name;
|
||||
}
|
||||
|
||||
bool afxSpellBook::isPlaceholder(S32 page, S32 slot) const
|
||||
{
|
||||
S32 idx = mDataBlock->getPageSlotIndex(page, slot);
|
||||
if (idx < 0 || !mDataBlock->rpg_spells[idx])
|
||||
return false;
|
||||
|
||||
return mDataBlock->rpg_spells[idx]->is_placeholder;
|
||||
}
|
||||
|
||||
|
||||
afxMagicSpellData* afxSpellBook::getSpellData(S32 page, S32 slot)
|
||||
{
|
||||
S32 idx = mDataBlock->getPageSlotIndex(page, slot);
|
||||
if (idx < 0 || !mDataBlock->spells[idx])
|
||||
return 0;
|
||||
|
||||
return mDataBlock->spells[idx];
|
||||
}
|
||||
|
||||
afxRPGMagicSpellData* afxSpellBook::getSpellRPGData(S32 page, S32 slot)
|
||||
{
|
||||
S32 idx = mDataBlock->getPageSlotIndex(page, slot);
|
||||
if (idx < 0 || !mDataBlock->rpg_spells[idx])
|
||||
return 0;
|
||||
|
||||
return mDataBlock->rpg_spells[idx];
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxSpellBook::startAllSpellCooldown()
|
||||
{
|
||||
//all_spell_cooldown = 0.0f;
|
||||
setMaskBits(AllSpellCooldownMask);
|
||||
}
|
||||
|
||||
F32 afxSpellBook::getCooldownFactor(S32 page, S32 slot)
|
||||
{
|
||||
return all_spell_cooldown;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
DefineEngineMethod(afxSpellBook, getPageSlotIndex, S32, (Point2I bookSlot),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return object->getPageSlotIndex(bookSlot.x, bookSlot.y);
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBook, getSpellData, S32, (Point2I bookSlot),,
|
||||
"Get spell datablock for spell stored at spellbook index, (page, slot).\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
afxMagicSpellData* spell_data = object->getSpellData(bookSlot.x, bookSlot.y);
|
||||
return (spell_data) ? spell_data->getId() : 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBook, getSpellRPGData, S32, (Point2I bookSlot),,
|
||||
"Get spell RPG datablock for spell stored at spellbook index, (page, slot).\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
afxRPGMagicSpellData* spell_data = object->getSpellRPGData(bookSlot.x, bookSlot.y);
|
||||
return (spell_data) ? spell_data->getId() : 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBook, startAllSpellCooldown, void, (),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
object->startAllSpellCooldown();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
|
||||
|
||||
142
Engine/source/afx/afxSpellBook.h
Normal file
142
Engine/source/afx/afxSpellBook.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_SPELL_BOOK_H_
|
||||
#define _AFX_SPELL_BOOK_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
|
||||
class afxSpellBookDefs
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
MAX_SPELLS_PER_PAGE = 12,
|
||||
MAX_PAGES_PER_BOOK = 12
|
||||
};
|
||||
};
|
||||
|
||||
class afxMagicSpellData;
|
||||
class afxRPGMagicSpellData;
|
||||
|
||||
class afxSpellBookData : public GameBaseData, public afxSpellBookDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
U8 spells_per_page;
|
||||
U8 pages_per_book;
|
||||
afxMagicSpellData* spells[MAX_PAGES_PER_BOOK*MAX_SPELLS_PER_PAGE];
|
||||
afxRPGMagicSpellData* rpg_spells[MAX_PAGES_PER_BOOK*MAX_SPELLS_PER_PAGE];
|
||||
|
||||
public:
|
||||
/*C*/ afxSpellBookData();
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
bool verifyPageSlot(S32 page, S32 slot);
|
||||
S32 getPageSlotIndex(S32 page, S32 slot);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxSpellBookData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
inline bool afxSpellBookData::verifyPageSlot(S32 page, S32 slot)
|
||||
{
|
||||
return (page >= 0 && page < pages_per_book && slot >= 0 && slot < spells_per_page);
|
||||
}
|
||||
|
||||
inline S32 afxSpellBookData::getPageSlotIndex(S32 page, S32 slot)
|
||||
{
|
||||
return (verifyPageSlot(page, slot)) ? page*spells_per_page + slot : -1;
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxMagicSpellData;
|
||||
class afxSpellButton;
|
||||
|
||||
class afxSpellBook : public GameBase, public afxSpellBookDefs
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
enum MaskBits
|
||||
{
|
||||
AllSpellCooldownMask = Parent::NextFreeMask << 0,
|
||||
NextFreeMask = Parent::NextFreeMask << 1
|
||||
};
|
||||
|
||||
private:
|
||||
afxSpellBookData* mDataBlock;
|
||||
F32 all_spell_cooldown;
|
||||
|
||||
public:
|
||||
/*C*/ afxSpellBook();
|
||||
/*D*/ ~afxSpellBook();
|
||||
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void processTick(const Move*);
|
||||
virtual void advanceTime(F32 dt);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
S32 getPageSlotIndex(S32 page, S32 slot);
|
||||
char* formatDesc(char* buffer, int len, S32 page, S32 slot) const;
|
||||
const char* getSpellIcon(S32 page, S32 slot) const;
|
||||
bool isPlaceholder(S32 page, S32 slot) const;
|
||||
afxMagicSpellData* getSpellData(S32 page, S32 slot);
|
||||
afxRPGMagicSpellData* getSpellRPGData(S32 page, S32 slot);
|
||||
|
||||
void startAllSpellCooldown();
|
||||
F32 getCooldownFactor(S32 page, S32 slot);
|
||||
|
||||
DECLARE_CONOBJECT(afxSpellBook);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
inline S32 afxSpellBook::getPageSlotIndex(S32 page, S32 slot)
|
||||
{
|
||||
return (mDataBlock) ? mDataBlock->getPageSlotIndex(page, slot) : -1;
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_SPELL_BOOK_H_
|
||||
311
Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.cpp
Normal file
311
Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.cpp
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "materials/shaderData.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "collision/concretePolyList.h"
|
||||
#include "T3D/tsStatic.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
#include "afx/afxZodiacGroundPlaneRenderer_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
const RenderInstType afxZodiacGroundPlaneRenderer::RIT_GroundPlaneZodiac("GroundPlaneZodiac");
|
||||
|
||||
afxZodiacGroundPlaneRenderer* afxZodiacGroundPlaneRenderer::master = 0;
|
||||
|
||||
IMPLEMENT_CONOBJECT(afxZodiacGroundPlaneRenderer);
|
||||
|
||||
ConsoleDocClass( afxZodiacGroundPlaneRenderer,
|
||||
"@brief A render bin for zodiac rendering on GroundPlane objects.\n\n"
|
||||
|
||||
"This bin renders instances of AFX zodiac effects onto GroundPlane surfaces.\n\n"
|
||||
|
||||
"@ingroup RenderBin\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxZodiacGroundPlaneRenderer::afxZodiacGroundPlaneRenderer()
|
||||
: RenderBinManager(RIT_GroundPlaneZodiac, 1.0f, 1.0f)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacGroundPlaneRenderer::afxZodiacGroundPlaneRenderer(F32 renderOrder, F32 processAddOrder)
|
||||
: RenderBinManager(RIT_GroundPlaneZodiac, renderOrder, processAddOrder)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacGroundPlaneRenderer::~afxZodiacGroundPlaneRenderer()
|
||||
{
|
||||
if (this == master)
|
||||
master = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxZodiacGroundPlaneRenderer::initShader()
|
||||
{
|
||||
if (shader_initialized)
|
||||
return;
|
||||
|
||||
shader_initialized = true;
|
||||
|
||||
shader_consts = 0;
|
||||
norm_norefl_zb_SB = norm_refl_zb_SB;
|
||||
add_norefl_zb_SB = add_refl_zb_SB;
|
||||
sub_norefl_zb_SB = sub_refl_zb_SB;
|
||||
|
||||
zodiac_shader = afxZodiacMgr::getGroundPlaneZodiacShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
GFXStateBlockDesc d;
|
||||
|
||||
d.cullDefined = true;
|
||||
d.ffLighting = false;
|
||||
d.blendDefined = true;
|
||||
d.blendEnable = true;
|
||||
d.zDefined = false;
|
||||
d.zEnable = true;
|
||||
d.zWriteEnable = false;
|
||||
d.zFunc = GFXCmpLessEqual;
|
||||
d.zSlopeBias = 0;
|
||||
d.alphaDefined = true;
|
||||
d.alphaTestEnable = true;
|
||||
d.alphaTestRef = 0;
|
||||
d.alphaTestFunc = GFXCmpGreater;
|
||||
d.samplersDefined = true;
|
||||
d.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
||||
|
||||
// normal
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendInvSrcAlpha;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// additive
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendOne;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// subtractive
|
||||
d.blendSrc = GFXBlendZero;
|
||||
d.blendDest = GFXBlendInvSrcColor;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
shader_consts = zodiac_shader->getShader()->allocConstBuffer();
|
||||
projection_sc = zodiac_shader->getShader()->getShaderConstHandle("$modelView");
|
||||
color_sc = zodiac_shader->getShader()->getShaderConstHandle("$zodiacColor");
|
||||
}
|
||||
|
||||
void afxZodiacGroundPlaneRenderer::clear()
|
||||
{
|
||||
Parent::clear();
|
||||
groundPlane_zodiacs.clear();
|
||||
}
|
||||
|
||||
void afxZodiacGroundPlaneRenderer::addZodiac(U32 zode_idx, const Point3F& pos, F32 ang, const GroundPlane* gp, F32 camDist)
|
||||
{
|
||||
groundPlane_zodiacs.increment();
|
||||
GroundPlaneZodiacElem& elem = groundPlane_zodiacs.last();
|
||||
|
||||
elem.gp = gp;
|
||||
elem.zode_idx = zode_idx;
|
||||
elem.ang = ang;
|
||||
elem.camDist = camDist;
|
||||
}
|
||||
|
||||
afxZodiacGroundPlaneRenderer* afxZodiacGroundPlaneRenderer::getMaster()
|
||||
{
|
||||
if (!master)
|
||||
master = new afxZodiacGroundPlaneRenderer;
|
||||
return master;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
GFXStateBlock* afxZodiacGroundPlaneRenderer::chooseStateBlock(U32 blend, bool isReflectPass)
|
||||
{
|
||||
GFXStateBlock* sb = 0;
|
||||
|
||||
switch (blend)
|
||||
{
|
||||
case afxZodiacData::BLEND_ADDITIVE:
|
||||
sb = (isReflectPass) ? add_refl_zb_SB : add_norefl_zb_SB;
|
||||
break;
|
||||
case afxZodiacData::BLEND_SUBTRACTIVE:
|
||||
sb = (isReflectPass) ? sub_refl_zb_SB : sub_norefl_zb_SB;
|
||||
break;
|
||||
default: // afxZodiacData::BLEND_NORMAL:
|
||||
sb = (isReflectPass) ? norm_refl_zb_SB : norm_norefl_zb_SB;
|
||||
break;
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void afxZodiacGroundPlaneRenderer::render(SceneRenderState* state)
|
||||
{
|
||||
PROFILE_SCOPE(afxRenderZodiacGroundPlaneMgr_render);
|
||||
|
||||
// Early out if no ground-plane zodiacs to draw.
|
||||
if (groundPlane_zodiacs.size() == 0)
|
||||
return;
|
||||
|
||||
initShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
bool is_reflect_pass = state->isReflectPass();
|
||||
|
||||
// Automagically save & restore our viewport and transforms.
|
||||
GFXTransformSaver saver;
|
||||
|
||||
MatrixF proj = GFX->getProjectionMatrix();
|
||||
|
||||
// Set up world transform
|
||||
MatrixF world = GFX->getWorldMatrix();
|
||||
proj.mul(world);
|
||||
shader_consts->set(projection_sc, proj);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// RENDER EACH ZODIAC
|
||||
//
|
||||
for (S32 zz = 0; zz < groundPlane_zodiacs.size(); zz++)
|
||||
{
|
||||
GroundPlaneZodiacElem& elem = groundPlane_zodiacs[zz];
|
||||
|
||||
afxZodiacMgr::ZodiacSpec* zode = &afxZodiacMgr::terr_zodes[elem.zode_idx];
|
||||
if (!zode)
|
||||
continue;
|
||||
|
||||
if (is_reflect_pass)
|
||||
{
|
||||
//if ((zode->zflags & afxZodiacData::SHOW_IN_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_NON_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
F32 fadebias = zode->calcDistanceFadeBias(elem.camDist);
|
||||
if (fadebias < 0.01f)
|
||||
continue;
|
||||
|
||||
F32 cos_ang = mCos(elem.ang);
|
||||
F32 sin_ang = mSin(elem.ang);
|
||||
|
||||
GFXStateBlock* sb = chooseStateBlock(zode->zflags & afxZodiacData::BLEND_MASK, is_reflect_pass);
|
||||
|
||||
GFX->setShader(zodiac_shader->getShader());
|
||||
GFX->setStateBlock(sb);
|
||||
GFX->setShaderConstBuffer(shader_consts);
|
||||
|
||||
// set the texture
|
||||
GFX->setTexture(0, *zode->txr);
|
||||
LinearColorF zode_color = (LinearColorF)zode->color;
|
||||
zode_color.alpha *= fadebias;
|
||||
shader_consts->set(color_sc, zode_color);
|
||||
|
||||
F32 rad_xy = zode->radius_xy;
|
||||
F32 inv_radius = 1.0f/rad_xy;
|
||||
F32 offset_xy = mSqrt(2*rad_xy*rad_xy);
|
||||
|
||||
F32 zx = zode->pos.x;
|
||||
F32 zy = zode->pos.y;
|
||||
F32 z = 0.00001f;
|
||||
|
||||
Point3F verts[4];
|
||||
verts[0].set(zx+offset_xy, zy+offset_xy, z);
|
||||
verts[1].set(zx-offset_xy, zy+offset_xy, z);
|
||||
verts[2].set(zx-offset_xy, zy-offset_xy, z);
|
||||
verts[3].set(zx+offset_xy, zy-offset_xy, z);
|
||||
|
||||
S32 vertind[6];
|
||||
vertind[0] = 2;
|
||||
vertind[1] = 1;
|
||||
vertind[2] = 0;
|
||||
vertind[3] = 3;
|
||||
vertind[4] = 2;
|
||||
vertind[5] = 0;
|
||||
|
||||
PrimBuild::begin(GFXTriangleList, 6);
|
||||
for (U32 i = 0; i < 2; i++)
|
||||
{
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
const Point3F& vtx = verts[vertind[i*3+j]];
|
||||
|
||||
// compute UV
|
||||
F32 u1 = (vtx.x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (vtx.y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(vtx);
|
||||
}
|
||||
}
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
91
Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.h
Normal file
91
Engine/source/afx/afxZodiacGroundPlaneRenderer_T3D.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ZODIAC_GROUNDPLANE_RENDERER_H_
|
||||
#define _AFX_ZODIAC_GROUNDPLANE_RENDERER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "renderInstance/renderBinManager.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class ConcretePolyList;
|
||||
class GroundPlane;
|
||||
|
||||
class afxZodiacGroundPlaneRenderer : public RenderBinManager
|
||||
{
|
||||
typedef RenderBinManager Parent;
|
||||
|
||||
struct GroundPlaneZodiacElem
|
||||
{
|
||||
const GroundPlane* gp;
|
||||
U32 zode_idx;
|
||||
F32 ang;
|
||||
F32 camDist;
|
||||
};
|
||||
|
||||
Vector<GroundPlaneZodiacElem> groundPlane_zodiacs;
|
||||
static afxZodiacGroundPlaneRenderer* master;
|
||||
|
||||
GFXStateBlockRef norm_norefl_zb_SB, norm_refl_zb_SB;
|
||||
GFXStateBlockRef add_norefl_zb_SB, add_refl_zb_SB;
|
||||
GFXStateBlockRef sub_norefl_zb_SB, sub_refl_zb_SB;
|
||||
|
||||
ShaderData* zodiac_shader;
|
||||
GFXShaderConstBufferRef shader_consts;
|
||||
GFXShaderConstHandle* projection_sc;
|
||||
GFXShaderConstHandle* color_sc;
|
||||
|
||||
bool shader_initialized;
|
||||
|
||||
GFXStateBlock* chooseStateBlock(U32 blend, bool isReflectPass);
|
||||
|
||||
public:
|
||||
static const RenderInstType RIT_GroundPlaneZodiac;
|
||||
|
||||
/*C*/ afxZodiacGroundPlaneRenderer();
|
||||
/*C*/ afxZodiacGroundPlaneRenderer(F32 renderOrder, F32 processAddOrder);
|
||||
/*D*/ ~afxZodiacGroundPlaneRenderer();
|
||||
|
||||
// RenderBinManager
|
||||
virtual void sort(){} // don't sort them
|
||||
virtual void clear();
|
||||
|
||||
void initShader();
|
||||
void addZodiac(U32 zode_idx, const Point3F& pos, F32 ang, const GroundPlane*, F32 camDist);
|
||||
|
||||
virtual void render(SceneRenderState* state);
|
||||
|
||||
static afxZodiacGroundPlaneRenderer* getMaster();
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT(afxZodiacGroundPlaneRenderer);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ZODIAC_GROUNDPLANE_RENDERER_H_
|
||||
302
Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.cpp
Normal file
302
Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.cpp
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "materials/shaderData.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "collision/concretePolyList.h"
|
||||
#include "T3D/tsStatic.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
#include "afx/afxZodiacMeshRoadRenderer_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
const RenderInstType afxZodiacMeshRoadRenderer::RIT_MeshRoadZodiac("MeshRoadZodiac");
|
||||
|
||||
afxZodiacMeshRoadRenderer* afxZodiacMeshRoadRenderer::master = 0;
|
||||
|
||||
IMPLEMENT_CONOBJECT(afxZodiacMeshRoadRenderer);
|
||||
|
||||
ConsoleDocClass( afxZodiacMeshRoadRenderer,
|
||||
"@brief A render bin for zodiac rendering on MeshRoad objects.\n\n"
|
||||
|
||||
"This bin renders instances of AFX zodiac effects onto MeshRoad surfaces.\n\n"
|
||||
|
||||
"@ingroup RenderBin\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxZodiacMeshRoadRenderer::afxZodiacMeshRoadRenderer()
|
||||
: RenderBinManager(RIT_MeshRoadZodiac, 1.0f, 1.0f)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacMeshRoadRenderer::afxZodiacMeshRoadRenderer(F32 renderOrder, F32 processAddOrder)
|
||||
: RenderBinManager(RIT_MeshRoadZodiac, renderOrder, processAddOrder)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacMeshRoadRenderer::~afxZodiacMeshRoadRenderer()
|
||||
{
|
||||
if (this == master)
|
||||
master = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxZodiacMeshRoadRenderer::initShader()
|
||||
{
|
||||
if (shader_initialized)
|
||||
return;
|
||||
|
||||
shader_initialized = true;
|
||||
|
||||
shader_consts = 0;
|
||||
norm_norefl_zb_SB = norm_refl_zb_SB;
|
||||
add_norefl_zb_SB = add_refl_zb_SB;
|
||||
sub_norefl_zb_SB = sub_refl_zb_SB;
|
||||
|
||||
zodiac_shader = afxZodiacMgr::getMeshRoadZodiacShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
GFXStateBlockDesc d;
|
||||
|
||||
d.cullDefined = true;
|
||||
d.ffLighting = false;
|
||||
d.blendDefined = true;
|
||||
d.blendEnable = true;
|
||||
d.zDefined = false;
|
||||
d.zEnable = true;
|
||||
d.zWriteEnable = false;
|
||||
d.zFunc = GFXCmpLessEqual;
|
||||
d.zSlopeBias = 0;
|
||||
d.alphaDefined = true;
|
||||
d.alphaTestEnable = true;
|
||||
d.alphaTestRef = 0;
|
||||
d.alphaTestFunc = GFXCmpGreater;
|
||||
d.samplersDefined = true;
|
||||
d.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
||||
|
||||
// normal
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendInvSrcAlpha;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// additive
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendOne;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// subtractive
|
||||
d.blendSrc = GFXBlendZero;
|
||||
d.blendDest = GFXBlendInvSrcColor;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
shader_consts = zodiac_shader->getShader()->allocConstBuffer();
|
||||
projection_sc = zodiac_shader->getShader()->getShaderConstHandle("$modelView");
|
||||
color_sc = zodiac_shader->getShader()->getShaderConstHandle("$zodiacColor");
|
||||
}
|
||||
|
||||
void afxZodiacMeshRoadRenderer::clear()
|
||||
{
|
||||
Parent::clear();
|
||||
for (S32 i = 0; i < meshRoad_zodiacs.size(); i++)
|
||||
if (meshRoad_zodiacs[i].polys)
|
||||
delete meshRoad_zodiacs[i].polys;
|
||||
meshRoad_zodiacs.clear();
|
||||
}
|
||||
|
||||
void afxZodiacMeshRoadRenderer::addZodiac(U32 zode_idx, ConcretePolyList* polys, const Point3F& pos, F32 ang, const MeshRoad* road, F32 camDist)
|
||||
{
|
||||
meshRoad_zodiacs.increment();
|
||||
MeshRoadZodiacElem& elem = meshRoad_zodiacs.last();
|
||||
|
||||
elem.road = road;
|
||||
elem.polys = polys;
|
||||
elem.zode_idx = zode_idx;
|
||||
elem.ang = ang;
|
||||
elem.camDist = camDist;
|
||||
}
|
||||
|
||||
afxZodiacMeshRoadRenderer* afxZodiacMeshRoadRenderer::getMaster()
|
||||
{
|
||||
if (!master)
|
||||
master = new afxZodiacMeshRoadRenderer;
|
||||
return master;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
GFXStateBlock* afxZodiacMeshRoadRenderer::chooseStateBlock(U32 blend, bool isReflectPass)
|
||||
{
|
||||
GFXStateBlock* sb = 0;
|
||||
|
||||
switch (blend)
|
||||
{
|
||||
case afxZodiacData::BLEND_ADDITIVE:
|
||||
sb = (isReflectPass) ? add_refl_zb_SB : add_norefl_zb_SB;
|
||||
break;
|
||||
case afxZodiacData::BLEND_SUBTRACTIVE:
|
||||
sb = (isReflectPass) ? sub_refl_zb_SB : sub_norefl_zb_SB;
|
||||
break;
|
||||
default: // afxZodiacData::BLEND_NORMAL:
|
||||
sb = (isReflectPass) ? norm_refl_zb_SB : norm_norefl_zb_SB;
|
||||
break;
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void afxZodiacMeshRoadRenderer::render(SceneRenderState* state)
|
||||
{
|
||||
PROFILE_SCOPE(afxRenderZodiacMeshRoadMgr_render);
|
||||
|
||||
// Early out if no ground-plane zodiacs to draw.
|
||||
if (meshRoad_zodiacs.size() == 0)
|
||||
return;
|
||||
|
||||
initShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
bool is_reflect_pass = state->isReflectPass();
|
||||
|
||||
// Automagically save & restore our viewport and transforms.
|
||||
GFXTransformSaver saver;
|
||||
|
||||
MatrixF proj = GFX->getProjectionMatrix();
|
||||
|
||||
// Set up world transform
|
||||
MatrixF world = GFX->getWorldMatrix();
|
||||
proj.mul(world);
|
||||
shader_consts->set(projection_sc, proj);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// RENDER EACH ZODIAC
|
||||
//
|
||||
for (S32 zz = 0; zz < meshRoad_zodiacs.size(); zz++)
|
||||
{
|
||||
MeshRoadZodiacElem& elem = meshRoad_zodiacs[zz];
|
||||
|
||||
afxZodiacMgr::ZodiacSpec* zode = &afxZodiacMgr::terr_zodes[elem.zode_idx];
|
||||
if (!zode)
|
||||
continue;
|
||||
|
||||
if (is_reflect_pass)
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_NON_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
F32 fadebias = zode->calcDistanceFadeBias(elem.camDist);
|
||||
if (fadebias < 0.01f)
|
||||
continue;
|
||||
|
||||
F32 cos_ang = mCos(elem.ang);
|
||||
F32 sin_ang = mSin(elem.ang);
|
||||
|
||||
GFXStateBlock* sb = chooseStateBlock(zode->zflags & afxZodiacData::BLEND_MASK, is_reflect_pass);
|
||||
|
||||
GFX->setShader(zodiac_shader->getShader());
|
||||
GFX->setStateBlock(sb);
|
||||
GFX->setShaderConstBuffer(shader_consts);
|
||||
|
||||
// set the texture
|
||||
GFX->setTexture(0, *zode->txr);
|
||||
LinearColorF zode_color = (LinearColorF)zode->color;
|
||||
zode_color.alpha *= fadebias;
|
||||
shader_consts->set(color_sc, zode_color);
|
||||
|
||||
F32 inv_radius = 1.0f/zode->radius_xy;
|
||||
|
||||
PrimBuild::begin(GFXTriangleList, 3*elem.polys->mPolyList.size());
|
||||
for (U32 i = 0; i < elem.polys->mPolyList.size(); i++)
|
||||
{
|
||||
ConcretePolyList::Poly* poly = &elem.polys->mPolyList[i];
|
||||
|
||||
S32 vertind[3];
|
||||
vertind[0] = elem.polys->mIndexList[poly->vertexStart];
|
||||
vertind[1] = elem.polys->mIndexList[poly->vertexStart + 1];
|
||||
vertind[2] = elem.polys->mIndexList[poly->vertexStart + 2];
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
Point3F vtx = elem.polys->mVertexList[vertind[j]];
|
||||
|
||||
// compute UV
|
||||
F32 u1 = (vtx.x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (vtx.y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(vtx);
|
||||
}
|
||||
}
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
92
Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.h
Normal file
92
Engine/source/afx/afxZodiacMeshRoadRenderer_T3D.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ZODIAC_MESHROAD_RENDERER_H_
|
||||
#define _AFX_ZODIAC_MESHROAD_RENDERER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "renderInstance/renderBinManager.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class ConcretePolyList;
|
||||
class MeshRoad;
|
||||
|
||||
class afxZodiacMeshRoadRenderer : public RenderBinManager
|
||||
{
|
||||
typedef RenderBinManager Parent;
|
||||
|
||||
struct MeshRoadZodiacElem
|
||||
{
|
||||
const MeshRoad* road;
|
||||
U32 zode_idx;
|
||||
ConcretePolyList* polys;
|
||||
F32 ang;
|
||||
F32 camDist;
|
||||
};
|
||||
|
||||
Vector<MeshRoadZodiacElem> meshRoad_zodiacs;
|
||||
static afxZodiacMeshRoadRenderer* master;
|
||||
|
||||
GFXStateBlockRef norm_norefl_zb_SB, norm_refl_zb_SB;
|
||||
GFXStateBlockRef add_norefl_zb_SB, add_refl_zb_SB;
|
||||
GFXStateBlockRef sub_norefl_zb_SB, sub_refl_zb_SB;
|
||||
|
||||
ShaderData* zodiac_shader;
|
||||
GFXShaderConstBufferRef shader_consts;
|
||||
GFXShaderConstHandle* projection_sc;
|
||||
GFXShaderConstHandle* color_sc;
|
||||
|
||||
bool shader_initialized;
|
||||
|
||||
GFXStateBlock* chooseStateBlock(U32 blend, bool isReflectPass);
|
||||
|
||||
public:
|
||||
static const RenderInstType RIT_MeshRoadZodiac;
|
||||
|
||||
/*C*/ afxZodiacMeshRoadRenderer();
|
||||
/*C*/ afxZodiacMeshRoadRenderer(F32 renderOrder, F32 processAddOrder);
|
||||
/*D*/ ~afxZodiacMeshRoadRenderer();
|
||||
|
||||
// RenderBinManager
|
||||
virtual void sort(){} // don't sort them
|
||||
virtual void clear();
|
||||
|
||||
void initShader();
|
||||
void addZodiac(U32 zode_idx, ConcretePolyList*, const Point3F& pos, F32 ang, const MeshRoad*, F32 camDist);
|
||||
|
||||
virtual void render(SceneRenderState*);
|
||||
|
||||
static afxZodiacMeshRoadRenderer* getMaster();
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT(afxZodiacMeshRoadRenderer);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ZODIAC_MESHROAD_RENDERER_H_
|
||||
420
Engine/source/afx/afxZodiacPolysoupRenderer_T3D.cpp
Normal file
420
Engine/source/afx/afxZodiacPolysoupRenderer_T3D.cpp
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "materials/shaderData.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "collision/concretePolyList.h"
|
||||
#include "T3D/tsStatic.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
#include "afx/afxZodiacPolysoupRenderer_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
const RenderInstType afxZodiacPolysoupRenderer::RIT_PolysoupZodiac("PolysoupZodiac");
|
||||
|
||||
afxZodiacPolysoupRenderer* afxZodiacPolysoupRenderer::master = 0;
|
||||
|
||||
IMPLEMENT_CONOBJECT(afxZodiacPolysoupRenderer);
|
||||
|
||||
ConsoleDocClass( afxZodiacPolysoupRenderer,
|
||||
"@brief A render bin for zodiac rendering on polysoup TSStatic objects.\n\n"
|
||||
|
||||
"This bin renders instances of AFX zodiac effects onto polysoup TSStatic surfaces.\n\n"
|
||||
|
||||
"@ingroup RenderBin\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxZodiacPolysoupRenderer::afxZodiacPolysoupRenderer()
|
||||
: RenderBinManager(RIT_PolysoupZodiac, 1.0f, 1.0f)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacPolysoupRenderer::afxZodiacPolysoupRenderer(F32 renderOrder, F32 processAddOrder)
|
||||
: RenderBinManager(RIT_PolysoupZodiac, renderOrder, processAddOrder)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacPolysoupRenderer::~afxZodiacPolysoupRenderer()
|
||||
{
|
||||
if (this == master)
|
||||
master = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxZodiacPolysoupRenderer::initShader()
|
||||
{
|
||||
if (shader_initialized)
|
||||
return;
|
||||
|
||||
shader_initialized = true;
|
||||
|
||||
shader_consts = 0;
|
||||
norm_norefl_zb_SB = norm_refl_zb_SB;
|
||||
add_norefl_zb_SB = add_refl_zb_SB;
|
||||
sub_norefl_zb_SB = sub_refl_zb_SB;
|
||||
|
||||
zodiac_shader = afxZodiacMgr::getPolysoupZodiacShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
GFXStateBlockDesc d;
|
||||
|
||||
d.cullDefined = true;
|
||||
d.ffLighting = false;
|
||||
d.blendDefined = true;
|
||||
d.blendEnable = true;
|
||||
d.zDefined = false;
|
||||
d.zEnable = true;
|
||||
d.zWriteEnable = false;
|
||||
d.zFunc = GFXCmpLessEqual;
|
||||
d.zSlopeBias = 0;
|
||||
d.alphaDefined = true;
|
||||
d.alphaTestEnable = true;
|
||||
d.alphaTestRef = 0;
|
||||
d.alphaTestFunc = GFXCmpGreater;
|
||||
d.samplersDefined = true;
|
||||
d.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
||||
|
||||
// normal
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendInvSrcAlpha;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
norm_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// additive
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendOne;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
add_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// subtractive
|
||||
d.blendSrc = GFXBlendZero;
|
||||
d.blendDest = GFXBlendInvSrcColor;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sPolysoupZodiacZBias;
|
||||
sub_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
shader_consts = zodiac_shader->getShader()->allocConstBuffer();
|
||||
projection_sc = zodiac_shader->getShader()->getShaderConstHandle("$modelView");
|
||||
color_sc = zodiac_shader->getShader()->getShaderConstHandle("$zodiacColor");
|
||||
}
|
||||
|
||||
void afxZodiacPolysoupRenderer::clear()
|
||||
{
|
||||
Parent::clear();
|
||||
for (S32 i = 0; i < polysoup_zodes.size(); i++)
|
||||
if (polysoup_zodes[i].polys)
|
||||
delete polysoup_zodes[i].polys;
|
||||
polysoup_zodes.clear();
|
||||
}
|
||||
|
||||
void afxZodiacPolysoupRenderer::addZodiac(U32 zode_idx, ConcretePolyList* polys, const Point3F& pos, F32 ang, const TSStatic* tss, F32 camDist)
|
||||
{
|
||||
polysoup_zodes.increment();
|
||||
PolysoupZodiacElem& elem = polysoup_zodes.last();
|
||||
|
||||
elem.tss = tss;
|
||||
elem.polys = polys;
|
||||
elem.zode_idx = zode_idx;
|
||||
elem.ang = ang;
|
||||
elem.camDist = camDist;
|
||||
}
|
||||
|
||||
afxZodiacPolysoupRenderer* afxZodiacPolysoupRenderer::getMaster()
|
||||
{
|
||||
if (!master)
|
||||
master = new afxZodiacPolysoupRenderer;
|
||||
return master;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
GFXStateBlock* afxZodiacPolysoupRenderer::chooseStateBlock(U32 blend, bool isReflectPass)
|
||||
{
|
||||
GFXStateBlock* sb = 0;
|
||||
|
||||
switch (blend)
|
||||
{
|
||||
case afxZodiacData::BLEND_ADDITIVE:
|
||||
sb = (isReflectPass) ? add_refl_zb_SB : add_norefl_zb_SB;
|
||||
break;
|
||||
case afxZodiacData::BLEND_SUBTRACTIVE:
|
||||
sb = (isReflectPass) ? sub_refl_zb_SB : sub_norefl_zb_SB;
|
||||
break;
|
||||
default: // afxZodiacData::BLEND_NORMAL:
|
||||
sb = (isReflectPass) ? norm_refl_zb_SB : norm_norefl_zb_SB;
|
||||
break;
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void afxZodiacPolysoupRenderer::render(SceneRenderState* state)
|
||||
{
|
||||
PROFILE_SCOPE(afxRenderZodiacPolysoupMgr_render);
|
||||
|
||||
// Early out if no polysoup zodiacs to draw.
|
||||
if (polysoup_zodes.size() == 0)
|
||||
return;
|
||||
|
||||
initShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
bool is_reflect_pass = state->isReflectPass();
|
||||
|
||||
// Automagically save & restore our viewport and transforms.
|
||||
GFXTransformSaver saver;
|
||||
|
||||
MatrixF proj = GFX->getProjectionMatrix();
|
||||
|
||||
// Set up world transform
|
||||
MatrixF world = GFX->getWorldMatrix();
|
||||
proj.mul(world);
|
||||
shader_consts->set(projection_sc, proj);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// RENDER EACH ZODIAC
|
||||
//
|
||||
for (S32 zz = 0; zz < polysoup_zodes.size(); zz++)
|
||||
{
|
||||
PolysoupZodiacElem& elem = polysoup_zodes[zz];
|
||||
|
||||
afxZodiacMgr::ZodiacSpec* zode = &afxZodiacMgr::inter_zodes[elem.zode_idx];
|
||||
if (!zode)
|
||||
continue;
|
||||
|
||||
if (is_reflect_pass)
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_NON_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
F32 fadebias = zode->calcDistanceFadeBias(elem.camDist);
|
||||
if (fadebias < 0.01f)
|
||||
continue;
|
||||
|
||||
F32 cos_ang = mCos(elem.ang);
|
||||
F32 sin_ang = mSin(elem.ang);
|
||||
|
||||
GFXStateBlock* sb = chooseStateBlock(zode->zflags & afxZodiacData::BLEND_MASK, is_reflect_pass);
|
||||
|
||||
GFX->setShader(zodiac_shader->getShader());
|
||||
GFX->setStateBlock(sb);
|
||||
GFX->setShaderConstBuffer(shader_consts);
|
||||
|
||||
// set the texture
|
||||
GFX->setTexture(0, *zode->txr);
|
||||
LinearColorF zode_color = (LinearColorF)zode->color;
|
||||
zode_color.alpha *= fadebias;
|
||||
shader_consts->set(color_sc, zode_color);
|
||||
|
||||
F32 inv_radius = 1.0f/zode->radius_xy;
|
||||
|
||||
// FILTER USING GRADIENT RANGE
|
||||
if ((zode->zflags & afxZodiacData::USE_GRADE_RANGE) != 0)
|
||||
{
|
||||
bool skip_oob;
|
||||
F32 grade_min, grade_max;
|
||||
if (elem.tss->mHasGradients && ((zode->zflags & afxZodiacData::PREFER_DEST_GRADE) != 0))
|
||||
{
|
||||
skip_oob = (elem.tss->mInvertGradientRange == false);
|
||||
grade_min = elem.tss->mGradientRange.x;
|
||||
grade_max = elem.tss->mGradientRange.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
skip_oob = ((zode->zflags & afxZodiacData::INVERT_GRADE_RANGE) == 0);
|
||||
grade_min = zode->grade_range.x;
|
||||
grade_max = zode->grade_range.y;
|
||||
}
|
||||
|
||||
PrimBuild::begin(GFXTriangleList, 3*elem.polys->mPolyList.size());
|
||||
for (U32 i = 0; i < elem.polys->mPolyList.size(); i++)
|
||||
{
|
||||
ConcretePolyList::Poly* poly = &elem.polys->mPolyList[i];
|
||||
|
||||
const PlaneF& plane = poly->plane;
|
||||
|
||||
bool oob = (plane.z > grade_max || plane.z < grade_min);
|
||||
if (oob == skip_oob)
|
||||
continue;
|
||||
|
||||
S32 vertind[3];
|
||||
vertind[0] = elem.polys->mIndexList[poly->vertexStart];
|
||||
vertind[1] = elem.polys->mIndexList[poly->vertexStart + 1];
|
||||
vertind[2] = elem.polys->mIndexList[poly->vertexStart + 2];
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
Point3F vtx = elem.polys->mVertexList[vertind[j]];
|
||||
|
||||
// compute UV
|
||||
F32 u1 = (vtx.x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (vtx.y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(vtx);
|
||||
}
|
||||
}
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
|
||||
// FILTER USING OTHER FILTERS
|
||||
else if (zode->zflags & afxZodiacData::INTERIOR_FILTERS)
|
||||
{
|
||||
PrimBuild::begin(GFXTriangleList, 3*elem.polys->mPolyList.size());
|
||||
for (U32 i = 0; i < elem.polys->mPolyList.size(); i++)
|
||||
{
|
||||
ConcretePolyList::Poly* poly = &elem.polys->mPolyList[i];
|
||||
|
||||
const PlaneF& plane = poly->plane;
|
||||
if (zode->zflags & afxZodiacData::INTERIOR_HORIZ_ONLY)
|
||||
{
|
||||
if (!plane.isHorizontal())
|
||||
continue;
|
||||
|
||||
if (zode->zflags & afxZodiacData::INTERIOR_BACK_IGNORE)
|
||||
{
|
||||
if (plane.whichSide(zode->pos) == PlaneF::Back)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zode->zflags & afxZodiacData::INTERIOR_VERT_IGNORE)
|
||||
{
|
||||
if (plane.isVertical())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zode->zflags & afxZodiacData::INTERIOR_BACK_IGNORE)
|
||||
{
|
||||
if (plane.whichSide(zode->pos) == PlaneF::Back)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
S32 vertind[3];
|
||||
vertind[0] = elem.polys->mIndexList[poly->vertexStart];
|
||||
vertind[1] = elem.polys->mIndexList[poly->vertexStart + 1];
|
||||
vertind[2] = elem.polys->mIndexList[poly->vertexStart + 2];
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
Point3F vtx = elem.polys->mVertexList[vertind[j]];
|
||||
|
||||
// compute UV
|
||||
F32 u1 = (vtx.x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (vtx.y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(vtx);
|
||||
}
|
||||
}
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
|
||||
// NO FILTERING
|
||||
else
|
||||
{
|
||||
PrimBuild::begin(GFXTriangleList, 3*elem.polys->mPolyList.size());
|
||||
for (U32 i = 0; i < elem.polys->mPolyList.size(); i++)
|
||||
{
|
||||
ConcretePolyList::Poly* poly = &elem.polys->mPolyList[i];
|
||||
|
||||
S32 vertind[3];
|
||||
vertind[0] = elem.polys->mIndexList[poly->vertexStart];
|
||||
vertind[1] = elem.polys->mIndexList[poly->vertexStart + 1];
|
||||
vertind[2] = elem.polys->mIndexList[poly->vertexStart + 2];
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
Point3F vtx = elem.polys->mVertexList[vertind[j]];
|
||||
|
||||
// compute UV
|
||||
F32 u1 = (vtx.x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (vtx.y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(vtx);
|
||||
}
|
||||
}
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
92
Engine/source/afx/afxZodiacPolysoupRenderer_T3D.h
Normal file
92
Engine/source/afx/afxZodiacPolysoupRenderer_T3D.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ZODIAC_POLYSOUP_RENDERER_H_
|
||||
#define _AFX_ZODIAC_POLYSOUP_RENDERER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "renderInstance/renderBinManager.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class ConcretePolyList;
|
||||
class TSStatic;
|
||||
|
||||
class afxZodiacPolysoupRenderer : public RenderBinManager
|
||||
{
|
||||
typedef RenderBinManager Parent;
|
||||
|
||||
struct PolysoupZodiacElem
|
||||
{
|
||||
const TSStatic* tss;
|
||||
U32 zode_idx;
|
||||
ConcretePolyList* polys;
|
||||
F32 ang;
|
||||
F32 camDist;
|
||||
};
|
||||
|
||||
Vector<PolysoupZodiacElem> polysoup_zodes;
|
||||
static afxZodiacPolysoupRenderer* master;
|
||||
|
||||
GFXStateBlockRef norm_norefl_zb_SB, norm_refl_zb_SB;
|
||||
GFXStateBlockRef add_norefl_zb_SB, add_refl_zb_SB;
|
||||
GFXStateBlockRef sub_norefl_zb_SB, sub_refl_zb_SB;
|
||||
|
||||
ShaderData* zodiac_shader;
|
||||
GFXShaderConstBufferRef shader_consts;
|
||||
GFXShaderConstHandle* projection_sc;
|
||||
GFXShaderConstHandle* color_sc;
|
||||
|
||||
bool shader_initialized;
|
||||
|
||||
GFXStateBlock* chooseStateBlock(U32 blend, bool isReflectPass);
|
||||
|
||||
public:
|
||||
static const RenderInstType RIT_PolysoupZodiac;
|
||||
|
||||
/*C*/ afxZodiacPolysoupRenderer();
|
||||
/*C*/ afxZodiacPolysoupRenderer(F32 renderOrder, F32 processAddOrder);
|
||||
/*D*/ ~afxZodiacPolysoupRenderer();
|
||||
|
||||
// RenderBinManager
|
||||
virtual void sort(){} // don't sort them
|
||||
virtual void clear();
|
||||
|
||||
void initShader();
|
||||
void addZodiac(U32 zode_idx, ConcretePolyList*, const Point3F& pos, F32 ang, const TSStatic*, F32 camDist);
|
||||
|
||||
virtual void render(SceneRenderState*);
|
||||
|
||||
static afxZodiacPolysoupRenderer* getMaster();
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT(afxZodiacPolysoupRenderer);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ZODIAC_POLYSOUP_RENDERER_H_
|
||||
344
Engine/source/afx/afxZodiacTerrainRenderer_T3D.cpp
Normal file
344
Engine/source/afx/afxZodiacTerrainRenderer_T3D.cpp
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "materials/shaderData.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "terrain/terrData.h"
|
||||
#include "terrain/terrCell.h"
|
||||
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
#include "afx/afxZodiacTerrainRenderer_T3D.h"
|
||||
#include "afx/util/afxTriBoxCheck2D_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class TerrCellSpy : public TerrCell
|
||||
{
|
||||
public:
|
||||
static const U32 getMinCellSize() { return smMinCellSize; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
const RenderInstType afxZodiacTerrainRenderer::RIT_TerrainZodiac("TerrainZodiac");
|
||||
|
||||
afxZodiacTerrainRenderer* afxZodiacTerrainRenderer::master = 0;
|
||||
|
||||
IMPLEMENT_CONOBJECT(afxZodiacTerrainRenderer);
|
||||
|
||||
ConsoleDocClass( afxZodiacTerrainRenderer,
|
||||
"@brief A render bin for zodiac rendering on Terrain objects.\n\n"
|
||||
|
||||
"This bin renders instances of AFX zodiac effects onto Terrain surfaces.\n\n"
|
||||
|
||||
"@ingroup RenderBin\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxZodiacTerrainRenderer::afxZodiacTerrainRenderer()
|
||||
: RenderBinManager(RIT_TerrainZodiac, 1.0f, 1.0f)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacTerrainRenderer::afxZodiacTerrainRenderer(F32 renderOrder, F32 processAddOrder)
|
||||
: RenderBinManager(RIT_TerrainZodiac, renderOrder, processAddOrder)
|
||||
{
|
||||
if (!master)
|
||||
master = this;
|
||||
shader_initialized = false;
|
||||
}
|
||||
|
||||
afxZodiacTerrainRenderer::~afxZodiacTerrainRenderer()
|
||||
{
|
||||
if (this == master)
|
||||
master = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxZodiacTerrainRenderer::initShader()
|
||||
{
|
||||
if (shader_initialized)
|
||||
return;
|
||||
|
||||
shader_initialized = true;
|
||||
|
||||
shader_consts = 0;
|
||||
norm_norefl_zb_SB = norm_refl_zb_SB;
|
||||
add_norefl_zb_SB = add_refl_zb_SB;
|
||||
sub_norefl_zb_SB = sub_refl_zb_SB;
|
||||
|
||||
zodiac_shader = afxZodiacMgr::getTerrainZodiacShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
GFXStateBlockDesc d;
|
||||
|
||||
d.cullDefined = true;
|
||||
d.ffLighting = false;
|
||||
d.blendDefined = true;
|
||||
d.blendEnable = true;
|
||||
d.zDefined = false;
|
||||
d.zEnable = true;
|
||||
d.zWriteEnable = false;
|
||||
d.zFunc = GFXCmpLessEqual;
|
||||
d.zSlopeBias = 0;
|
||||
d.alphaDefined = true;
|
||||
d.alphaTestEnable = true;
|
||||
d.alphaTestRef = 0;
|
||||
d.alphaTestFunc = GFXCmpGreater;
|
||||
d.samplersDefined = true;
|
||||
d.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
||||
|
||||
// normal
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendInvSrcAlpha;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
norm_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
norm_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// additive
|
||||
d.blendSrc = GFXBlendSrcAlpha;
|
||||
d.blendDest = GFXBlendOne;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
add_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
add_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
// subtractive
|
||||
d.blendSrc = GFXBlendZero;
|
||||
d.blendDest = GFXBlendInvSrcColor;
|
||||
//
|
||||
d.cullMode = GFXCullCCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
sub_norefl_zb_SB = GFX->createStateBlock(d);
|
||||
//
|
||||
d.cullMode = GFXCullCW;
|
||||
d.zBias = arcaneFX::sTerrainZodiacZBias;
|
||||
sub_refl_zb_SB = GFX->createStateBlock(d);
|
||||
|
||||
shader_consts = zodiac_shader->getShader()->allocConstBuffer();
|
||||
projection_sc = zodiac_shader->getShader()->getShaderConstHandle("$modelView");
|
||||
color_sc = zodiac_shader->getShader()->getShaderConstHandle("$zodiacColor");
|
||||
}
|
||||
|
||||
void afxZodiacTerrainRenderer::clear()
|
||||
{
|
||||
Parent::clear();
|
||||
|
||||
terrain_zodes.clear();
|
||||
}
|
||||
|
||||
void afxZodiacTerrainRenderer::addZodiac(U32 zode_idx, const Point3F& pos, F32 ang,
|
||||
const TerrainBlock* block, const TerrCell* cell,
|
||||
const MatrixF& mRenderObjToWorld, F32 camDist)
|
||||
{
|
||||
terrain_zodes.increment();
|
||||
TerrainZodiacElem& elem = terrain_zodes.last();
|
||||
|
||||
elem.block = block;
|
||||
elem.cell = cell;
|
||||
elem.zode_idx = zode_idx;
|
||||
elem.ang = ang;
|
||||
elem.mRenderObjToWorld = mRenderObjToWorld;
|
||||
elem.camDist = camDist;
|
||||
}
|
||||
|
||||
afxZodiacTerrainRenderer* afxZodiacTerrainRenderer::getMaster()
|
||||
{
|
||||
if (!master)
|
||||
master = new afxZodiacTerrainRenderer;
|
||||
return master;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
GFXStateBlock* afxZodiacTerrainRenderer::chooseStateBlock(U32 blend, bool isReflectPass)
|
||||
{
|
||||
GFXStateBlock* sb = 0;
|
||||
|
||||
switch (blend)
|
||||
{
|
||||
case afxZodiacData::BLEND_ADDITIVE:
|
||||
sb = (isReflectPass) ? add_refl_zb_SB : add_norefl_zb_SB;
|
||||
break;
|
||||
case afxZodiacData::BLEND_SUBTRACTIVE:
|
||||
sb = (isReflectPass) ? sub_refl_zb_SB : sub_norefl_zb_SB;
|
||||
break;
|
||||
default: // afxZodiacData::BLEND_NORMAL:
|
||||
sb = (isReflectPass) ? norm_refl_zb_SB : norm_norefl_zb_SB;
|
||||
break;
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void afxZodiacTerrainRenderer::render(SceneRenderState* state)
|
||||
{
|
||||
PROFILE_SCOPE(afxRenderZodiacTerrainMgr_render);
|
||||
|
||||
// Early out if no terrain zodiacs to draw.
|
||||
if (terrain_zodes.size() == 0)
|
||||
return;
|
||||
|
||||
initShader();
|
||||
if (!zodiac_shader)
|
||||
return;
|
||||
|
||||
bool is_reflect_pass = state->isReflectPass();
|
||||
|
||||
// Automagically save & restore our viewport and transforms.
|
||||
GFXTransformSaver saver;
|
||||
|
||||
MatrixF proj = GFX->getProjectionMatrix();
|
||||
|
||||
// Set up world transform
|
||||
MatrixF world = GFX->getWorldMatrix();
|
||||
proj.mul(world);
|
||||
shader_consts->set(projection_sc, proj);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// RENDER EACH ZODIAC
|
||||
//
|
||||
for (S32 zz = 0; zz < terrain_zodes.size(); zz++)
|
||||
{
|
||||
TerrainZodiacElem& elem = terrain_zodes[zz];
|
||||
|
||||
TerrainBlock* block = (TerrainBlock*) elem.block;
|
||||
|
||||
afxZodiacMgr::ZodiacSpec* zode = &afxZodiacMgr::terr_zodes[elem.zode_idx];
|
||||
if (!zode)
|
||||
continue;
|
||||
|
||||
if (is_reflect_pass)
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((zode->zflags & afxZodiacData::SHOW_IN_NON_REFLECTIONS) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
F32 fadebias = zode->calcDistanceFadeBias(elem.camDist);
|
||||
if (fadebias < 0.01f)
|
||||
continue;
|
||||
|
||||
F32 cos_ang = mCos(elem.ang);
|
||||
F32 sin_ang = mSin(elem.ang);
|
||||
|
||||
GFXStateBlock* sb = chooseStateBlock(zode->zflags & afxZodiacData::BLEND_MASK, is_reflect_pass);
|
||||
|
||||
GFX->setShader(zodiac_shader->getShader());
|
||||
GFX->setStateBlock(sb);
|
||||
GFX->setShaderConstBuffer(shader_consts);
|
||||
|
||||
// set the texture
|
||||
GFX->setTexture(0, *zode->txr);
|
||||
LinearColorF zode_color = (LinearColorF)zode->color;
|
||||
zode_color.alpha *= fadebias;
|
||||
shader_consts->set(color_sc, zode_color);
|
||||
|
||||
Point3F half_size(zode->radius_xy,zode->radius_xy,zode->radius_xy);
|
||||
|
||||
F32 inv_radius = 1.0f/zode->radius_xy;
|
||||
|
||||
GFXPrimitive cell_prim;
|
||||
GFXVertexBufferHandle<TerrVertex> cell_verts;
|
||||
GFXPrimitiveBufferHandle primBuff;
|
||||
elem.cell->getRenderPrimitive(&cell_prim, &cell_verts, &primBuff);
|
||||
|
||||
U32 n_nonskirt_tris = TerrCellSpy::getMinCellSize()*TerrCellSpy::getMinCellSize()*2;
|
||||
|
||||
const Point3F* verts = ((TerrCell*)elem.cell)->getZodiacVertexBuffer();
|
||||
const U16 *tris = block->getZodiacPrimitiveBuffer();
|
||||
if (!tris)
|
||||
continue;
|
||||
|
||||
PrimBuild::begin(GFXTriangleList, 3*n_nonskirt_tris);
|
||||
|
||||
/////////////////////////////////
|
||||
U32 n_overlapping_tris = 0;
|
||||
U32 idx = 0;
|
||||
for (U32 i = 0; i < n_nonskirt_tris; i++)
|
||||
{
|
||||
Point3F tri_v[3];
|
||||
tri_v[0] = verts[tris[idx++]];
|
||||
tri_v[1] = verts[tris[idx++]];
|
||||
tri_v[2] = verts[tris[idx++]];
|
||||
|
||||
elem.mRenderObjToWorld.mulP(tri_v[0]);
|
||||
elem.mRenderObjToWorld.mulP(tri_v[1]);
|
||||
elem.mRenderObjToWorld.mulP(tri_v[2]);
|
||||
|
||||
if (!afxTriBoxOverlap2D(zode->pos, half_size, tri_v[0], tri_v[1], tri_v[2]))
|
||||
continue;
|
||||
|
||||
n_overlapping_tris++;
|
||||
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
{
|
||||
// compute UV
|
||||
F32 u1 = (tri_v[j].x - zode->pos.x)*inv_radius;
|
||||
F32 v1 = (tri_v[j].y - zode->pos.y)*inv_radius;
|
||||
F32 ru1 = u1*cos_ang - v1*sin_ang;
|
||||
F32 rv1 = u1*sin_ang + v1*cos_ang;
|
||||
|
||||
F32 uu = (ru1 + 1.0f)/2.0f;
|
||||
F32 vv = 1.0f - (rv1 + 1.0f)/2.0f;
|
||||
|
||||
PrimBuild::texCoord2f(uu, vv);
|
||||
PrimBuild::vertex3fv(tri_v[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
PrimBuild::end(false);
|
||||
}
|
||||
//
|
||||
// RENDER EACH ZODIAC
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
92
Engine/source/afx/afxZodiacTerrainRenderer_T3D.h
Normal file
92
Engine/source/afx/afxZodiacTerrainRenderer_T3D.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ZODIAC_TERRAIN_RENDERER_H_
|
||||
#define _AFX_ZODIAC_TERRAIN_RENDERER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "renderInstance/renderBinManager.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class TerrCell;
|
||||
|
||||
class afxZodiacTerrainRenderer : public RenderBinManager
|
||||
{
|
||||
typedef RenderBinManager Parent;
|
||||
|
||||
struct TerrainZodiacElem
|
||||
{
|
||||
const TerrainBlock* block;
|
||||
const TerrCell* cell;
|
||||
U32 zode_idx;
|
||||
F32 ang;
|
||||
MatrixF mRenderObjToWorld;
|
||||
F32 camDist;
|
||||
};
|
||||
|
||||
Vector<TerrainZodiacElem> terrain_zodes;
|
||||
static afxZodiacTerrainRenderer* master;
|
||||
|
||||
GFXStateBlockRef norm_norefl_zb_SB, norm_refl_zb_SB;
|
||||
GFXStateBlockRef add_norefl_zb_SB, add_refl_zb_SB;
|
||||
GFXStateBlockRef sub_norefl_zb_SB, sub_refl_zb_SB;
|
||||
|
||||
ShaderData* zodiac_shader;
|
||||
GFXShaderConstBufferRef shader_consts;
|
||||
GFXShaderConstHandle* projection_sc;
|
||||
GFXShaderConstHandle* color_sc;
|
||||
|
||||
bool shader_initialized;
|
||||
|
||||
GFXStateBlock* chooseStateBlock(U32 blend, bool isReflectPass);
|
||||
|
||||
public:
|
||||
static const RenderInstType RIT_TerrainZodiac;
|
||||
|
||||
/*C*/ afxZodiacTerrainRenderer();
|
||||
/*C*/ afxZodiacTerrainRenderer(F32 renderOrder, F32 processAddOrder);
|
||||
/*D*/ ~afxZodiacTerrainRenderer();
|
||||
|
||||
// RenderBinManager
|
||||
virtual void sort(){} // don't sort them
|
||||
virtual void clear();
|
||||
|
||||
void initShader();
|
||||
void addZodiac(U32 zode_idx, const Point3F& pos, F32 ang, const TerrainBlock*, const TerrCell*, const MatrixF& mRenderObjToWorld, F32 camDist);
|
||||
|
||||
virtual void render(SceneRenderState*);
|
||||
|
||||
static afxZodiacTerrainRenderer* getMaster();
|
||||
|
||||
// ConsoleObject
|
||||
DECLARE_CONOBJECT(afxZodiacTerrainRenderer);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ZODIAC_TERRAIN_RENDERER_H_
|
||||
959
Engine/source/afx/arcaneFX.cpp
Normal file
959
Engine/source/afx/arcaneFX.cpp
Normal file
|
|
@ -0,0 +1,959 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "scene/sceneObject.h"
|
||||
#include "scene/sceneManager.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "T3D/gameBase/gameProcess.h"
|
||||
#include "T3D/player.h"
|
||||
#include "math/mathUtils.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxSelectron.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#define N_LIGHTING_MODELS 6
|
||||
//
|
||||
// "SG - Original Advanced (Lighting Pack)"
|
||||
// "SG - Original Stock (Lighting Pack)"
|
||||
// "SG - Inverse Square (Lighting Pack)"
|
||||
// "SG - Inverse Square Fast Falloff (Lighting Pack)"
|
||||
// "SG - Near Linear (Lighting Pack)"
|
||||
// "SG - Near Linear Fast Falloff (Lighting Pack)"
|
||||
static StringTableEntry lm_old_names[N_LIGHTING_MODELS];
|
||||
//
|
||||
// "Original Advanced"
|
||||
// "Original Stock"
|
||||
// "Inverse Square"
|
||||
// "Inverse Square Fast Falloff"
|
||||
// "Near Linear"
|
||||
// "Near Linear Fast Falloff"
|
||||
static StringTableEntry lm_new_names[N_LIGHTING_MODELS];
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class ClientZoneInEvent : public NetEvent
|
||||
{
|
||||
typedef NetEvent Parent;
|
||||
public:
|
||||
ClientZoneInEvent() { mGuaranteeType = Guaranteed; }
|
||||
~ClientZoneInEvent() { }
|
||||
|
||||
virtual void pack(NetConnection*, BitStream*bstream) { }
|
||||
virtual void write(NetConnection*, BitStream *bstream) { }
|
||||
virtual void unpack(NetConnection* /*ps*/, BitStream *bstream) { }
|
||||
|
||||
virtual void process(NetConnection* conn)
|
||||
{
|
||||
GameConnection* game_conn = dynamic_cast<GameConnection*>(conn);
|
||||
if (game_conn && !game_conn->isZonedIn())
|
||||
{
|
||||
arcaneFX::syncToNewConnection(game_conn);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CONOBJECT(ClientZoneInEvent);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
IMPLEMENT_CO_SERVEREVENT_V1(ClientZoneInEvent);
|
||||
|
||||
ConsoleDocClass( ClientZoneInEvent,
|
||||
"@brief Event posted when player is fully loaded into the game and ready for interaction.\n\n"
|
||||
"@internal");
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
Vector<afxChoreographer*> arcaneFX::active_choreographers;
|
||||
Vector<afxChoreographer*> arcaneFX::client_choreographers;
|
||||
Vector<afxSelectronData*> arcaneFX::selectrons;
|
||||
Vector<SceneObject*> arcaneFX::scoped_objs;
|
||||
|
||||
StringTableEntry arcaneFX::NULLSTRING = 0;
|
||||
U32 arcaneFX::sTargetSelectionMask = 0;
|
||||
U32 arcaneFX::sFreeTargetSelectionMask = 0;
|
||||
bool arcaneFX::sIsFreeTargeting = false;
|
||||
Point3F arcaneFX::sFreeTargetPos = Point3F(0.0f, 0.0f, 0.0f);
|
||||
bool arcaneFX::sFreeTargetPosValid = false;
|
||||
F32 arcaneFX::sTargetSelectionRange = 200.0f;
|
||||
U32 arcaneFX::sTargetSelectionTimeoutMS = 500;
|
||||
bool arcaneFX::sClickToTargetSelf = false;
|
||||
U32 arcaneFX::sMissileCollisionMask = 0;
|
||||
StringTableEntry arcaneFX::sParameterFieldPrefix = 0;
|
||||
F32 arcaneFX::sTerrainZodiacZBias = -0.00025f;
|
||||
F32 arcaneFX::sInteriorZodiacZBias = -0.0001f;
|
||||
F32 arcaneFX::sPolysoupZodiacZBias = -0.0001f;
|
||||
U32 arcaneFX::master_choreographer_id = 1;
|
||||
U16 arcaneFX::master_scope_id = 1;
|
||||
bool arcaneFX::is_shutdown = true;
|
||||
|
||||
bool arcaneFX::sUsePlayerCentricListener = false;
|
||||
|
||||
void arcaneFX::init()
|
||||
{
|
||||
NULLSTRING = StringTable->insert("");
|
||||
sParameterFieldPrefix = StringTable->insert("_");
|
||||
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
arcaneFX::sTerrainZodiacZBias = -0.00025f;
|
||||
arcaneFX::sInteriorZodiacZBias = -0.00025f;
|
||||
arcaneFX::sPolysoupZodiacZBias = -0.00025f;
|
||||
#endif
|
||||
|
||||
Con::addVariable( "pref::AFX::targetSelectionMask", TypeS32, &sTargetSelectionMask);
|
||||
Con::addVariable( "pref::AFX::freeTargetSelectionMask", TypeS32, &sFreeTargetSelectionMask);
|
||||
Con::addVariable( "pref::AFX::targetSelectionRange", TypeF32, &sTargetSelectionRange);
|
||||
Con::addVariable( "pref::AFX::targetSelectionTimeoutMS", TypeS32, &sTargetSelectionTimeoutMS);
|
||||
Con::addVariable( "pref::AFX::missileCollisionMask", TypeS32, &sMissileCollisionMask);
|
||||
Con::addVariable( "pref::AFX::clickToTargetSelf", TypeBool, &sClickToTargetSelf);
|
||||
Con::addVariable( "Pref::Server::AFX::parameterFieldPrefix", TypeString, &sParameterFieldPrefix);
|
||||
|
||||
Con::addVariable( "pref::AFX::terrainZodiacZBias", TypeF32, &sTerrainZodiacZBias);
|
||||
Con::addVariable( "pref::AFX::interiorZodiacZBias", TypeF32, &sInteriorZodiacZBias);
|
||||
Con::addVariable( "pref::AFX::polysoupZodiacZBias", TypeF32, &sPolysoupZodiacZBias);
|
||||
|
||||
Con::setIntVariable( "$AFX::TARGETING_OFF", TARGETING_OFF);
|
||||
Con::setIntVariable( "$AFX::TARGETING_STANDARD", TARGETING_STANDARD);
|
||||
Con::setIntVariable( "$AFX::TARGETING_FREE", TARGETING_FREE);
|
||||
Con::setIntVariable( "$AFX::TARGET_CHECK_POLL", TARGET_CHECK_POLL);
|
||||
Con::setIntVariable( "$AFX::TARGET_CHECK_ON_MOUSE_MOVE", TARGET_CHECK_ON_MOUSE_MOVE);
|
||||
|
||||
Con::setIntVariable( "$AFX::IMPACTED_SOMETHING", afxEffectDefs::IMPACTED_SOMETHING);
|
||||
Con::setIntVariable( "$AFX::IMPACTED_TARGET", afxEffectDefs::IMPACTED_TARGET);
|
||||
Con::setIntVariable( "$AFX::IMPACTED_PRIMARY", afxEffectDefs::IMPACTED_PRIMARY);
|
||||
Con::setIntVariable( "$AFX::IMPACT_IN_WATER", afxEffectDefs::IMPACT_IN_WATER);
|
||||
Con::setIntVariable( "$AFX::CASTER_IN_WATER", afxEffectDefs::CASTER_IN_WATER);
|
||||
|
||||
Con::setIntVariable( "$AFX::SERVER_ONLY", afxEffectDefs::SERVER_ONLY);
|
||||
Con::setIntVariable( "$AFX::SCOPE_ALWAYS", afxEffectDefs::SCOPE_ALWAYS);
|
||||
Con::setIntVariable( "$AFX::GHOSTABLE", afxEffectDefs::GHOSTABLE);
|
||||
Con::setIntVariable( "$AFX::CLIENT_ONLY", afxEffectDefs::CLIENT_ONLY);
|
||||
Con::setIntVariable( "$AFX::SERVER_AND_CLIENT", afxEffectDefs::SERVER_AND_CLIENT);
|
||||
|
||||
Con::setIntVariable( "$AFX::DELAY", afxEffectDefs::TIMING_DELAY);
|
||||
Con::setIntVariable( "$AFX::LIFETIME", afxEffectDefs::TIMING_LIFETIME);
|
||||
Con::setIntVariable( "$AFX::FADE_IN_TIME", afxEffectDefs::TIMING_FADE_IN);
|
||||
Con::setIntVariable( "$AFX::FADE_OUT_TIME", afxEffectDefs::TIMING_FADE_OUT);
|
||||
|
||||
Con::setFloatVariable( "$AFX::INFINITE_TIME", -1.0f);
|
||||
Con::setIntVariable( "$AFX::INFINITE_REPEATS", -1);
|
||||
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_0", Player::PLAYER_MOVE_TRIGGER_0);
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_1", Player::PLAYER_MOVE_TRIGGER_1);
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_2", Player::PLAYER_MOVE_TRIGGER_2);
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_3", Player::PLAYER_MOVE_TRIGGER_3);
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_4", Player::PLAYER_MOVE_TRIGGER_4);
|
||||
Con::setIntVariable( "$AFX::PLAYER_MOVE_TRIGGER_5", Player::PLAYER_MOVE_TRIGGER_5);
|
||||
|
||||
Con::setIntVariable( "$AFX::PLAYER_FIRE_S_TRIGGER", Player::PLAYER_FIRE_S_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_FIRE_ALT_S_TRIGGER", Player::PLAYER_FIRE_ALT_S_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_JUMP_S_TRIGGER", Player::PLAYER_JUMP_S_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_LANDING_S_TRIGGER", Player::PLAYER_LANDING_S_TRIGGER);
|
||||
|
||||
Con::setIntVariable( "$AFX::PLAYER_LF_FOOT_C_TRIGGER", Player::PLAYER_LF_FOOT_C_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_RT_FOOT_C_TRIGGER", Player::PLAYER_RT_FOOT_C_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_LANDING_C_TRIGGER", Player::PLAYER_LANDING_C_TRIGGER);
|
||||
Con::setIntVariable( "$AFX::PLAYER_IDLE_C_TRIGGER", Player::PLAYER_IDLE_C_TRIGGER);
|
||||
|
||||
Con::setIntVariable( "$AFX::ILLUM_TERRAIN", 0);
|
||||
Con::setIntVariable( "$AFX::ILLUM_ATLAS", 0);
|
||||
Con::setIntVariable( "$AFX::ILLUM_DIF", 0);
|
||||
Con::setIntVariable( "$AFX::ILLUM_DTS", 0);
|
||||
Con::setIntVariable( "$AFX::ILLUM_ALL", 0);
|
||||
|
||||
Con::setIntVariable("$TypeMasks::TerrainLikeObjectType", TerrainLikeObjectType);
|
||||
Con::setIntVariable("$TypeMasks::InteriorLikeObjectType", InteriorLikeObjectType);
|
||||
Con::setIntVariable("$TypeMasks::PolysoupObjectType", InteriorLikeObjectType); // deprecated
|
||||
|
||||
Con::addVariable("$pref::Audio::usePlayerCentricListener", TypeBool, &sUsePlayerCentricListener);
|
||||
|
||||
afxResidueMgr* residue_mgr = new afxResidueMgr;
|
||||
afxResidueMgr::setMaster(residue_mgr);
|
||||
|
||||
master_scope_id = 1;
|
||||
master_choreographer_id = 1;
|
||||
is_shutdown = false;
|
||||
|
||||
if (lm_old_names[0] == 0)
|
||||
{
|
||||
lm_old_names[0] = StringTable->insert("SG - Original Advanced (Lighting Pack)");
|
||||
lm_old_names[1] = StringTable->insert("SG - Original Stock (Lighting Pack)");
|
||||
lm_old_names[2] = StringTable->insert("SG - Inverse Square (Lighting Pack)");
|
||||
lm_old_names[3] = StringTable->insert("SG - Inverse Square Fast Falloff (Lighting Pack)");
|
||||
lm_old_names[4] = StringTable->insert("SG - Near Linear (Lighting Pack)");
|
||||
lm_old_names[5] = StringTable->insert("SG - Near Linear Fast Falloff (Lighting Pack)");
|
||||
//
|
||||
lm_new_names[0] = StringTable->insert("Original Advanced");
|
||||
lm_new_names[1] = StringTable->insert("Original Stock");
|
||||
lm_new_names[2] = StringTable->insert("Inverse Square");
|
||||
lm_new_names[3] = StringTable->insert("Inverse Square Fast Falloff");
|
||||
lm_new_names[4] = StringTable->insert("Near Linear");
|
||||
lm_new_names[5] = StringTable->insert("Near Linear Fast Falloff");
|
||||
}
|
||||
}
|
||||
|
||||
void arcaneFX::shutdown()
|
||||
{
|
||||
is_shutdown = true;
|
||||
|
||||
for (S32 i = 0; i < scoped_objs.size(); i++)
|
||||
if (scoped_objs[i])
|
||||
scoped_objs[i]->setScopeRegistered(false);
|
||||
scoped_objs.clear();
|
||||
|
||||
for (S32 i = 0; i < client_choreographers.size(); i++)
|
||||
if (client_choreographers[i])
|
||||
client_choreographers[i]->clearChoreographerId();
|
||||
client_choreographers.clear();
|
||||
|
||||
for (S32 i = 0; i < selectrons.size(); i++)
|
||||
if (selectrons[i])
|
||||
selectrons[i]->registered = false;
|
||||
selectrons.clear();
|
||||
|
||||
afxResidueMgr* residue_mgr = afxResidueMgr::getMaster();
|
||||
delete residue_mgr;
|
||||
afxResidueMgr::setMaster(NULL);
|
||||
}
|
||||
|
||||
MODULE_BEGIN( arcaneFX )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
arcaneFX::init();
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
arcaneFX::shutdown();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void arcaneFX::advanceTime(U32 delta)
|
||||
{
|
||||
GameConnection* conn = GameConnection::getConnectionToServer();
|
||||
if (conn && !conn->isZonedIn() && conn->getCameraObject() != 0)
|
||||
{
|
||||
conn->setZonedIn();
|
||||
conn->postNetEvent(new ClientZoneInEvent());
|
||||
}
|
||||
|
||||
afxZodiacMgr::frameReset();
|
||||
afxResidueMgr::getMaster()->residueAdvanceTime();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
U32 arcaneFX::registerChoreographer(afxChoreographer* ch)
|
||||
{
|
||||
if (!ch)
|
||||
return 0;
|
||||
|
||||
active_choreographers.push_back(ch);
|
||||
|
||||
//Con::printf("registerChoreographer() -- size=%d %s", active_choreographers.size(),
|
||||
// (ch->isServerObject()) ? "server" : "client");
|
||||
|
||||
return master_choreographer_id++;
|
||||
}
|
||||
|
||||
void arcaneFX::unregisterChoreographer(afxChoreographer* ch)
|
||||
{
|
||||
if (!ch)
|
||||
return;
|
||||
|
||||
for (U32 i = 0; i < active_choreographers.size(); i++)
|
||||
{
|
||||
if (ch == active_choreographers[i])
|
||||
{
|
||||
active_choreographers.erase_fast(i);
|
||||
//Con::printf("unregisterChoreographer() -- size=%d %s", active_choreographers.size(),
|
||||
// (ch->isServerObject()) ? "server" : "client");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::errorf("arcaneFX::unregisterChoreographer() -- failed to find choreographer in list.");
|
||||
}
|
||||
|
||||
void arcaneFX::registerClientChoreographer(afxChoreographer* ch)
|
||||
{
|
||||
if (!ch || ch->getChoreographerId() == 0)
|
||||
return;
|
||||
|
||||
client_choreographers.push_back(ch);
|
||||
}
|
||||
|
||||
void arcaneFX::unregisterClientChoreographer(afxChoreographer* ch)
|
||||
{
|
||||
if (!ch || ch->getChoreographerId() == 0)
|
||||
return;
|
||||
|
||||
for (U32 i = 0; i < client_choreographers.size(); i++)
|
||||
{
|
||||
if (ch == client_choreographers[i])
|
||||
{
|
||||
client_choreographers.erase_fast(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::errorf("arcaneFX::unregisterClientChoreographer() -- failed to find choreographer in list.");
|
||||
}
|
||||
|
||||
afxChoreographer* arcaneFX::findClientChoreographer(U32 id)
|
||||
{
|
||||
for (U32 i = 0; i < client_choreographers.size(); i++)
|
||||
{
|
||||
if (id == client_choreographers[i]->getChoreographerId())
|
||||
return client_choreographers[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void arcaneFX::registerSelectronData(afxSelectronData* selectron)
|
||||
{
|
||||
if (!selectron)
|
||||
return;
|
||||
|
||||
selectrons.push_back(selectron);
|
||||
}
|
||||
|
||||
void arcaneFX::unregisterSelectronData(afxSelectronData* selectron)
|
||||
{
|
||||
if (!selectron)
|
||||
return;
|
||||
|
||||
for (U32 i = 0; i < selectrons.size(); i++)
|
||||
{
|
||||
if (selectron == selectrons[i])
|
||||
{
|
||||
selectrons.erase_fast(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::errorf("arcaneFX::unregisterSelectronData() -- failed to find selectron in list.");
|
||||
}
|
||||
|
||||
afxSelectronData* arcaneFX::findSelectronData(U32 mask, U8 style)
|
||||
{
|
||||
for (U32 i = 0; i < selectrons.size(); i++)
|
||||
if (selectrons[i]->matches(mask, style))
|
||||
return selectrons[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U16 arcaneFX::generateScopeId()
|
||||
{
|
||||
U16 ret_id = master_scope_id++;
|
||||
if (master_scope_id >= BIT(GameBase::SCOPE_ID_BITS))
|
||||
master_scope_id = 1;
|
||||
return ret_id;
|
||||
}
|
||||
|
||||
void arcaneFX::registerScopedObject(SceneObject* object)
|
||||
{
|
||||
scoped_objs.push_back(object);
|
||||
object->setScopeRegistered(true);
|
||||
|
||||
for (S32 i = 0; i < client_choreographers.size(); i++)
|
||||
if (client_choreographers[i])
|
||||
client_choreographers[i]->restoreScopedObject(object);
|
||||
}
|
||||
|
||||
SceneObject* arcaneFX::findScopedObject(U16 scope_id)
|
||||
{
|
||||
if (scoped_objs.size() > 0)
|
||||
{
|
||||
for (S32 i = scoped_objs.size()-1; i >= 0; i--)
|
||||
if (scoped_objs[i] && scoped_objs[i]->getScopeId() == scope_id)
|
||||
return scoped_objs[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arcaneFX::unregisterScopedObject(SceneObject* object)
|
||||
{
|
||||
if (scoped_objs.size() > 0)
|
||||
{
|
||||
for (S32 i = scoped_objs.size()-1; i >= 0; i--)
|
||||
if (scoped_objs[i] == object)
|
||||
{
|
||||
scoped_objs.erase_fast(i);
|
||||
if (object)
|
||||
object->setScopeRegistered(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arcaneFX::syncToNewConnection(GameConnection* conn)
|
||||
{
|
||||
if (conn)
|
||||
conn->setZonedIn();
|
||||
|
||||
for (U32 i = 0; i < active_choreographers.size(); i++)
|
||||
{
|
||||
if (active_choreographers[i])
|
||||
active_choreographers[i]->sync_with_clients();
|
||||
}
|
||||
}
|
||||
|
||||
void arcaneFX::endMissionNotify()
|
||||
{
|
||||
for (S32 i = 0; i < scoped_objs.size(); i++)
|
||||
if (scoped_objs[i])
|
||||
scoped_objs[i]->setScopeRegistered(false);
|
||||
scoped_objs.clear();
|
||||
|
||||
for (S32 i = 0; i < client_choreographers.size(); i++)
|
||||
if (client_choreographers[i])
|
||||
client_choreographers[i]->clearChoreographerId();
|
||||
client_choreographers.clear();
|
||||
|
||||
for (S32 i = 0; i < selectrons.size(); i++)
|
||||
if (selectrons[i])
|
||||
selectrons[i]->registered = false;
|
||||
selectrons.clear();
|
||||
|
||||
if (afxResidueMgr::getMaster())
|
||||
afxResidueMgr::getMaster()->cleanup();
|
||||
afxZodiacMgr::missionCleanup();
|
||||
}
|
||||
|
||||
S32 arcaneFX::rolloverRayCast(Point3F start, Point3F end, U32 mask)
|
||||
{
|
||||
sIsFreeTargeting = false;
|
||||
#if !defined(AFX_CAP_ROLLOVER_RAYCASTS)
|
||||
return -1;
|
||||
#else
|
||||
GameConnection* conn = GameConnection::getConnectionToServer();
|
||||
SceneObject* ctrl_obj = NULL;
|
||||
|
||||
if (!arcaneFX::sClickToTargetSelf && conn != NULL)
|
||||
ctrl_obj = conn->getControlObject();
|
||||
|
||||
if (ctrl_obj)
|
||||
ctrl_obj->disableCollision();
|
||||
|
||||
SceneObject* rollover_obj = (conn) ? conn->getRolloverObj() : 0;
|
||||
SceneObject* picked_obj = 0;
|
||||
|
||||
RayInfo hit_info;
|
||||
if (gClientContainer.castRay(start, end, mask, &hit_info))
|
||||
picked_obj = dynamic_cast<SceneObject*>(hit_info.object);
|
||||
|
||||
if (ctrl_obj)
|
||||
ctrl_obj->enableCollision();
|
||||
|
||||
if (picked_obj != rollover_obj)
|
||||
{
|
||||
if (rollover_obj)
|
||||
rollover_obj->setSelectionFlags(rollover_obj->getSelectionFlags() & ~SceneObject::PRE_SELECTED);
|
||||
if (picked_obj)
|
||||
picked_obj->setSelectionFlags(picked_obj->getSelectionFlags() | SceneObject::PRE_SELECTED);
|
||||
rollover_obj = picked_obj;
|
||||
|
||||
if (conn)
|
||||
conn->setRolloverObj(rollover_obj);
|
||||
}
|
||||
|
||||
return (picked_obj) ? picked_obj->getId() : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool arcaneFX::freeTargetingRayCast(Point3F start, Point3F end, U32 mask)
|
||||
{
|
||||
sIsFreeTargeting = true;
|
||||
|
||||
RayInfo hit_info;
|
||||
if (!gClientContainer.castRay(start, end, mask, &hit_info))
|
||||
{
|
||||
sFreeTargetPosValid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
sFreeTargetPosValid = true;
|
||||
sFreeTargetPos = hit_info.point;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
StringTableEntry arcaneFX::convertLightingModelName(StringTableEntry lm_name)
|
||||
{
|
||||
for (U32 i = 0; i < N_LIGHTING_MODELS; i++)
|
||||
{
|
||||
if (lm_name == lm_old_names[i])
|
||||
return lm_new_names[i];
|
||||
}
|
||||
|
||||
return lm_name;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Console Functions
|
||||
|
||||
DefineEngineFunction(afxEndMissionNotify, void, (),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
arcaneFX::endMissionNotify();
|
||||
}
|
||||
|
||||
DefineEngineFunction(afxGetVersion, const char*, (),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return AFX_VERSION_STRING;
|
||||
}
|
||||
|
||||
DefineEngineFunction(afxGetEngine, const char*, (),,
|
||||
"...\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return "T3D";
|
||||
}
|
||||
|
||||
#if defined(AFX_CAP_ROLLOVER_RAYCASTS)
|
||||
DefineEngineFunction(rolloverRayCast, S32, (Point3F start, Point3F end, U32 mask),,
|
||||
"Performs a raycast from points start to end and returns the ID of nearest "
|
||||
"intersecting object with a type found in the specified mask. "
|
||||
"Returns -1 if no object is found.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return arcaneFX::rolloverRayCast(start, end, mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
DefineEngineFunction(getRandomF, F32, (float a, float b), (F32_MAX, F32_MAX),
|
||||
"Get a random float number between a and b.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (b == F32_MAX)
|
||||
{
|
||||
if (a == F32_MAX)
|
||||
return gRandGen.randF();
|
||||
|
||||
return gRandGen.randF(0.0f, a);
|
||||
}
|
||||
|
||||
return (a + (b-a)*gRandGen.randF());
|
||||
}
|
||||
|
||||
DefineEngineFunction(getRandomDir, Point3F, (Point3F axis, float thetaMin, float thetaMax, float phiMin, float phiMax),
|
||||
(Point3F(0.0f,0.0f,0.0f), 0.0f, 180.0f, 0.0f, 360.0f),
|
||||
"Get a random direction vector.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return MathUtils::randomDir(axis, thetaMin, thetaMax, phiMin, phiMax);
|
||||
}
|
||||
|
||||
ConsoleFunction( MatrixInverseMulVector, const char*, 3, 3, "(MatrixF xfrm, Point3F vector)"
|
||||
"@brief Multiply the vector by the affine inverse of the transform.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
Point3F pos1(0.0f,0.0f,0.0f);
|
||||
AngAxisF aa1(Point3F(0.0f,0.0f,0.0f),0.0f);
|
||||
dSscanf(argv[1], "%g %g %g %g %g %g %g", &pos1.x, &pos1.y, &pos1.z, &aa1.axis.x, &aa1.axis.y, &aa1.axis.z, &aa1.angle);
|
||||
|
||||
MatrixF temp1(true);
|
||||
aa1.setMatrix(&temp1);
|
||||
temp1.setColumn(3, pos1);
|
||||
|
||||
Point3F vec1(0.0f,0.0f,0.0f);
|
||||
dSscanf(argv[2], "%g %g %g", &vec1.x, &vec1.y, &vec1.z);
|
||||
|
||||
temp1.affineInverse();
|
||||
|
||||
Point3F result;
|
||||
temp1.mulV(vec1, &result);
|
||||
|
||||
char* ret = Con::getReturnBuffer(256);
|
||||
dSprintf(ret, 255, "%g %g %g", result.x, result.y, result.z);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ConsoleFunction(moveTransformAbs, const char*, 3, 3, "(MatrixF xfrm, Point3F pos)"
|
||||
"@brief Move the transform to the new absolute position.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
Point3F pos1(0.0f,0.0f,0.0f);
|
||||
AngAxisF aa1(Point3F(0.0f,0.0f,0.0f),0.0f);
|
||||
dSscanf(argv[1], "%g %g %g %g %g %g %g", &pos1.x, &pos1.y, &pos1.z, &aa1.axis.x, &aa1.axis.y, &aa1.axis.z, &aa1.angle);
|
||||
|
||||
Point3F pos2(0.0f,0.0f,0.0f);
|
||||
dSscanf(argv[2], "%g %g %g", &pos2.x, &pos2.y, &pos2.z);
|
||||
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 255, "%g %g %g %g %g %g %g",
|
||||
pos2.x, pos2.y, pos2.z,
|
||||
aa1.axis.x, aa1.axis.y, aa1.axis.z,
|
||||
aa1.angle);
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
ConsoleFunction(moveTransformRel, const char*, 3, 3, "(MatrixF xfrm, Point3F pos)"
|
||||
"@brief Move the transform to the new relative position.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
Point3F pos1(0.0f,0.0f,0.0f);
|
||||
AngAxisF aa1(Point3F(0.0f,0.0f,0.0f),0.0f);
|
||||
dSscanf(argv[1], "%g %g %g %g %g %g %g", &pos1.x, &pos1.y, &pos1.z, &aa1.axis.x, &aa1.axis.y, &aa1.axis.z, &aa1.angle);
|
||||
|
||||
Point3F pos2(0.0f,0.0f,0.0f);
|
||||
dSscanf(argv[2], "%g %g %g", &pos2.x, &pos2.y, &pos2.z);
|
||||
|
||||
pos2 += pos1;
|
||||
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 255, "%g %g %g %g %g %g %g",
|
||||
pos2.x, pos2.y, pos2.z,
|
||||
aa1.axis.x, aa1.axis.y, aa1.axis.z,
|
||||
aa1.angle);
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getFreeTargetPosition, Point3F, (),,
|
||||
"@brief Returns the current location of the free target.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (!arcaneFX::sFreeTargetPosValid)
|
||||
return Point3F(0.0f, 0.0f, 0.0f);
|
||||
return arcaneFX::sFreeTargetPos;
|
||||
}
|
||||
|
||||
DefineEngineMethod(SceneObject, getSpeed, F32, (),,
|
||||
"Returns the velocity of a scene-object.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return object->getVelocity().len();
|
||||
}
|
||||
|
||||
static S32 mark_modkey = -1;
|
||||
|
||||
DefineEngineFunction(markDataBlocks, void, (),,
|
||||
"@brief Called before a series of datablocks are reloaded to "
|
||||
"help distinguish reloaded datablocks from already loaded ones.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
mark_modkey = SimDataBlock::getNextModifiedKey();
|
||||
}
|
||||
|
||||
DefineEngineFunction(touchDataBlocks, void, (),,
|
||||
"@brief Called after a series of datablocks are reloaded to "
|
||||
"trigger some important actions on the reloaded datablocks.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (mark_modkey < 0)
|
||||
return;
|
||||
|
||||
SimDataBlockGroup* g = Sim::getDataBlockGroup();
|
||||
|
||||
U32 groupCount = g->size();
|
||||
for (S32 i = groupCount-1; i >= 0; i--)
|
||||
{
|
||||
SimDataBlock* simdb = (SimDataBlock*)(*g)[i];
|
||||
if (simdb->getModifiedKey() > mark_modkey)
|
||||
{
|
||||
simdb->unregisterObject();
|
||||
simdb->registerObject();
|
||||
}
|
||||
}
|
||||
|
||||
mark_modkey = -1;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Syntax Error Checking
|
||||
// (for checking eval() and compile() calls)
|
||||
|
||||
DefineEngineFunction(wasSyntaxError, bool, (),,
|
||||
"@brief Returns true if script compiler had a syntax error. Useful "
|
||||
"for detecting syntax errors after reloading a script.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return Compiler::gSyntaxError;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Network Object Identification
|
||||
|
||||
// These useful console methods come from the following code resource:
|
||||
//
|
||||
// How to Identify Objects from Client to Server or Server to Client by Nathan Davies
|
||||
// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4852
|
||||
//
|
||||
|
||||
DefineEngineMethod(NetConnection, GetGhostIndex, S32, (NetObject* obj),,
|
||||
"Returns the ghost-index for an object.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (obj)
|
||||
return object->getGhostIndex(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(NetConnection, ResolveGhost, S32, (int ghostIndex),,
|
||||
"Resolves a ghost-index into an object ID.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
if (ghostIndex != -1)
|
||||
{
|
||||
NetObject* pObject = NULL;
|
||||
if( object->isGhostingTo())
|
||||
pObject = object->resolveGhost(ghostIndex);
|
||||
else if( object->isGhostingFrom())
|
||||
pObject = object->resolveObjectFromGhostIndex(ghostIndex);
|
||||
if (pObject)
|
||||
return pObject->getId();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TypeByteRange
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IMPLEMENT_STRUCT( ByteRange, ByteRange,,
|
||||
"" )
|
||||
END_IMPLEMENT_STRUCT;
|
||||
|
||||
ConsoleType( ByteRange, TypeByteRange, ByteRange, "")
|
||||
ConsoleType( ByteRange, TypeByteRange2, ByteRange, "")
|
||||
|
||||
ConsoleGetType( TypeByteRange )
|
||||
{
|
||||
ByteRange* pt = (ByteRange *) dptr;
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%u %u", pt->low, pt->high);
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeByteRange )
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
ByteRange* range = (ByteRange*) dptr;
|
||||
U32 lo, hi;
|
||||
S32 args = dSscanf(argv[0], "%u %u", &lo, &hi);
|
||||
range->low = (args > 0) ? lo : 0;
|
||||
range->high = (args > 1) ? hi : 255;
|
||||
}
|
||||
else
|
||||
Con::printf("ByteRange must be set as \"low\" or \"low high\"");
|
||||
}
|
||||
|
||||
ConsoleGetType( TypeByteRange2 )
|
||||
{
|
||||
ByteRange* pt = (ByteRange *) dptr;
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%u %u", pt->low, pt->high);
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeByteRange2 )
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
ByteRange* range = (ByteRange*) dptr;
|
||||
U32 lo, hi;
|
||||
S32 args = dSscanf(argv[0], "%u %u", &lo, &hi);
|
||||
range->low = (args > 0) ? lo : 0;
|
||||
range->high = (args > 1) ? hi : lo;
|
||||
}
|
||||
else
|
||||
Con::printf("ByteRange must be set as \"low\" or \"low high\"");
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
static void HSVtoRGB(F32 h, F32 s, F32 v, F32& r, F32& g, F32& b)
|
||||
{
|
||||
h = mFmod(h, 360.0f);
|
||||
|
||||
if (v == 0.0f)
|
||||
r = g = b = 0.0f;
|
||||
else if (s == 0.0f)
|
||||
r = g = b = v;
|
||||
else
|
||||
{
|
||||
F32 hf = h/60.0f;
|
||||
S32 i = (S32) mFloor(hf);
|
||||
F32 f = hf - i;
|
||||
|
||||
F32 pv = v*(1.0f - s);
|
||||
F32 qv = v*(1.0f - s*f);
|
||||
F32 tv = v*(1.0f - s*(1.0f - f));
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
r = v; g = tv; b = pv;
|
||||
break;
|
||||
case 1:
|
||||
r = qv; g = v; b = pv;
|
||||
break;
|
||||
case 2:
|
||||
r = pv; g = v; b = tv;
|
||||
break;
|
||||
case 3:
|
||||
r = pv; g = qv; b = v;
|
||||
break;
|
||||
case 4:
|
||||
r = tv; g = pv; b = v;
|
||||
break;
|
||||
case 5:
|
||||
r = v; g = pv; b = qv;
|
||||
break;
|
||||
default:
|
||||
r = g = b = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineFunction(getColorFromHSV, const char*, (float hue, float sat, float val, float alpha), (0.0, 0.0, 1.0, 1.0),
|
||||
"Coverts an HSV formatted color into an RBG color.\n\n"
|
||||
"@param hue The hue of the color (0-360).\n"
|
||||
"@param sat The saturation of the color (0-1).\n"
|
||||
"@param val The value of the color (0-1).\n"
|
||||
"@param alpha The alpha of the color (0-1).\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
LinearColorF rgb;
|
||||
HSVtoRGB(hue, sat, val, rgb.red, rgb.green, rgb.blue);
|
||||
rgb.alpha = alpha;
|
||||
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%g %g %g %g", rgb.red, rgb.green, rgb.blue, rgb.alpha);
|
||||
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
DefineEngineFunction(ColorScale, const char*, ( LinearColorF color, float scalar ),,
|
||||
"Returns color scaled by scalar (color*scalar).\n\n"
|
||||
"@param color The color to be scaled.\n"
|
||||
"@param scalar The amount to scale the color.\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
color *= scalar;
|
||||
|
||||
char* returnBuffer = Con::getReturnBuffer(256);
|
||||
dSprintf(returnBuffer, 256, "%g %g %g %g", color.red, color.green, color.blue, color.alpha);
|
||||
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getMinF, F32, (float a, float b),,
|
||||
"Returns the lesser of the two arguments.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return getMin(a, b);
|
||||
}
|
||||
|
||||
DefineEngineFunction(getMaxF, F32, (float a, float b),,
|
||||
"Returns the greater of the two arguments.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return getMax(a, b);
|
||||
}
|
||||
|
||||
ConsoleFunction(echoThru, const char*, 2, 0, "(string passthru, string text...)"
|
||||
"Like echo(), but first argument is returned.\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
U32 len = 0;
|
||||
S32 i;
|
||||
for(i = 2; i < argc; i++)
|
||||
len += dStrlen(argv[i]);
|
||||
|
||||
char *ret = Con::getReturnBuffer(len + 1);
|
||||
ret[0] = 0;
|
||||
for(i = 2; i < argc; i++)
|
||||
dStrcat(ret, argv[i]);
|
||||
|
||||
Con::printf("%s -- [%s]", ret, argv[1].getStringValue());
|
||||
ret[0] = 0;
|
||||
|
||||
return argv[1];
|
||||
}
|
||||
|
||||
ConsoleFunction(warnThru, const char*, 2, 0, "(string passthru, string text...)"
|
||||
"Like warn(), but first argument is returned.\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
U32 len = 0;
|
||||
S32 i;
|
||||
for(i = 2; i < argc; i++)
|
||||
len += dStrlen(argv[i]);
|
||||
|
||||
char *ret = Con::getReturnBuffer(len + 1);
|
||||
ret[0] = 0;
|
||||
for(i = 2; i < argc; i++)
|
||||
dStrcat(ret, argv[i]);
|
||||
|
||||
Con::warnf("%s -- [%s]", ret, argv[1].getStringValue());
|
||||
ret[0] = 0;
|
||||
|
||||
return argv[1];
|
||||
}
|
||||
|
||||
ConsoleFunction(errorThru, const char*, 2, 0, "(string passthru, string text...)"
|
||||
"Like error(), but first argument is returned.\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
U32 len = 0;
|
||||
S32 i;
|
||||
for(i = 2; i < argc; i++)
|
||||
len += dStrlen(argv[i]);
|
||||
|
||||
char *ret = Con::getReturnBuffer(len + 1);
|
||||
ret[0] = 0;
|
||||
for(i = 2; i < argc; i++)
|
||||
dStrcat(ret, argv[i]);
|
||||
|
||||
Con::errorf("%s -- [%s]", ret, argv[1].getStringValue());
|
||||
ret[0] = 0;
|
||||
|
||||
return argv[1];
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
214
Engine/source/afx/arcaneFX.h
Normal file
214
Engine/source/afx/arcaneFX.h
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _ARCANE_FX_H_
|
||||
#define _ARCANE_FX_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
|
||||
#define AFX_VERSION_STRING "2.0"
|
||||
#define AFX_VERSION 2.0
|
||||
|
||||
// #define AFX_CUSTOMIZED_BRANCH
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
#if defined(AFX_CUSTOMIZED_BRANCH)
|
||||
|
||||
#elif (TORQUE_GAME_ENGINE == 1100 || TORQUE_GAME_ENGINE >= 3000)
|
||||
|
||||
#define AFX_CAP_SCOPE_TRACKING
|
||||
#define AFX_CAP_ROLLOVER_RAYCASTS
|
||||
//#define AFX_CAP_AFXMODEL_TYPE
|
||||
//#define BROKEN_POINT_IN_WATER
|
||||
#define BROKEN_DAMAGEFLASH_WHITEOUT_BLACKOUT
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
#else
|
||||
|
||||
// This version of AFX source only supports T3D 1.1
|
||||
|
||||
#endif
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#ifndef _CONSOLETYPES_H_
|
||||
#include "console/consoleTypes.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ENGINEAPI_H_
|
||||
#include "console/engineAPI.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SIMBASE_H_
|
||||
#include "console/simBase.h"
|
||||
#endif
|
||||
|
||||
#ifndef _BITSTREAM_H_
|
||||
#include "core/stream/bitStream.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GAMEBASE_H_
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#endif
|
||||
|
||||
#if defined(DGL_GRAPHICS_LAYER)
|
||||
#ifndef _DGL_H_
|
||||
#include "dgl/dgl.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class afxChoreographer;
|
||||
class afxSelectronData;
|
||||
class GameConnection;
|
||||
class SceneObject;
|
||||
|
||||
class arcaneFX
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
TARGETING_OFF,
|
||||
TARGETING_STANDARD,
|
||||
TARGETING_FREE
|
||||
};
|
||||
enum {
|
||||
TARGET_CHECK_POLL,
|
||||
TARGET_CHECK_ON_MOUSE_MOVE
|
||||
};
|
||||
|
||||
private:
|
||||
static Vector<afxChoreographer*> active_choreographers;
|
||||
static Vector<afxChoreographer*> client_choreographers;
|
||||
static Vector<afxSelectronData*> selectrons;
|
||||
static Vector<SceneObject*> scoped_objs;
|
||||
static bool is_shutdown;
|
||||
|
||||
public:
|
||||
static StringTableEntry NULLSTRING;
|
||||
static U32 sTargetSelectionMask;
|
||||
static U32 sFreeTargetSelectionMask;
|
||||
static bool sIsFreeTargeting;
|
||||
static Point3F sFreeTargetPos;
|
||||
static bool sFreeTargetPosValid;
|
||||
static F32 sTargetSelectionRange;
|
||||
static U32 sTargetSelectionTimeoutMS;
|
||||
static bool sClickToTargetSelf;
|
||||
static U32 sMissileCollisionMask;
|
||||
static StringTableEntry sParameterFieldPrefix;
|
||||
static F32 sTerrainZodiacZBias;
|
||||
static F32 sInteriorZodiacZBias;
|
||||
static F32 sPolysoupZodiacZBias;
|
||||
static U32 master_choreographer_id;
|
||||
static U16 master_scope_id;
|
||||
|
||||
public:
|
||||
static void init();
|
||||
static void shutdown();
|
||||
static void advanceTime(U32 delta);
|
||||
|
||||
static U32 registerChoreographer(afxChoreographer*);
|
||||
static void unregisterChoreographer(afxChoreographer*);
|
||||
static void registerClientChoreographer(afxChoreographer*);
|
||||
static void unregisterClientChoreographer(afxChoreographer*);
|
||||
static afxChoreographer* findClientChoreographer(U32 id);
|
||||
|
||||
static void registerSelectronData(afxSelectronData*);
|
||||
static void unregisterSelectronData(afxSelectronData*);
|
||||
static afxSelectronData* findSelectronData(U32 obj_type_mask, U8 code);
|
||||
|
||||
static U16 generateScopeId();
|
||||
static void registerScopedObject(SceneObject*);
|
||||
static SceneObject* findScopedObject(U16 scope_id);
|
||||
static void unregisterScopedObject(SceneObject*);
|
||||
|
||||
static void syncToNewConnection(GameConnection* conn);
|
||||
static void endMissionNotify();
|
||||
static S32 rolloverRayCast(Point3F start, Point3F end, U32 mask);
|
||||
static bool freeTargetingRayCast(Point3F start, Point3F end, U32 mask);
|
||||
|
||||
static bool isShutdown() { return is_shutdown; }
|
||||
static StringTableEntry convertLightingModelName(StringTableEntry lm_name);
|
||||
|
||||
private:
|
||||
static bool sUsePlayerCentricListener;
|
||||
public:
|
||||
static bool usePlayerCentricListener() { return sUsePlayerCentricListener; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class ByteRange
|
||||
{
|
||||
public:
|
||||
U8 low;
|
||||
U8 high;
|
||||
|
||||
public:
|
||||
/*C*/ ByteRange() { low = 0; high = 255; }
|
||||
/*C*/ ByteRange(U8 l, U8 h=255) { low = l; high = h; }
|
||||
|
||||
void set(U8 l, U8 h=255) { low = l; high = h; }
|
||||
bool outOfRange(U8 v) { return (v < low || v > high); }
|
||||
bool inRange(U8 v) { return !outOfRange(v); }
|
||||
S32 getSpan() const { return high - low; }
|
||||
};
|
||||
|
||||
DefineConsoleType(TypeByteRange, ByteRange)
|
||||
DefineConsoleType(TypeByteRange2, ByteRange)
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
inline void writeDatablockID(BitStream* s, SimObject* simobj, bool packed=false)
|
||||
{
|
||||
if (s->writeFlag(simobj))
|
||||
s->writeRangedU32(packed ? SimObjectId((uintptr_t)simobj) : simobj->getId(),
|
||||
DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
inline S32 readDatablockID(BitStream* s)
|
||||
{
|
||||
return (!s->readFlag()) ? 0 : ((S32)s->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast));
|
||||
}
|
||||
|
||||
inline void registerForCleanup(SimObject* obj)
|
||||
{
|
||||
SimGroup* cleanup_grp = dynamic_cast<SimGroup*>(Sim::findObject("MissionCleanup"));
|
||||
if (cleanup_grp)
|
||||
cleanup_grp->addObject(obj);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#define ST_NULLSTRING (arcaneFX::NULLSTRING)
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _ARCANE_FX_H_
|
||||
|
||||
217
Engine/source/afx/ce/afxAnimClip.cpp
Normal file
217
Engine/source/afx/ce/afxAnimClip.cpp
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxAnimClip.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxAnimClipData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxAnimClipData);
|
||||
|
||||
ConsoleDocClass( afxAnimClipData,
|
||||
"@brief A datablock that specifies an Animation Clip effect.\n\n"
|
||||
|
||||
"An Animation Clip forces a target ShapeBase-derived object, such as Player or AIPlayer, to perform a particular "
|
||||
"animation sequence. Animation Clip does not supply any new animation data, but simply selects, by name, a "
|
||||
"sequence that is already defined in the target. Animation Clip can also target afxModel effects within the same "
|
||||
"choreographer."
|
||||
"\n\n"
|
||||
|
||||
"The target of an Animation Clip is the constraint source object specified by the posConstraint field of the enclosing "
|
||||
"effect wrapper. The target must be a ShapeBase-derived object, or an afxModel and it must contain an animation "
|
||||
"sequence with the same name as the clipName field."
|
||||
"\n\n"
|
||||
|
||||
"Animation Clip controls the rate of animation playback and can even play a sequence in reverse. When an Animation "
|
||||
"Clip selects a blended animation sequence, it is mixed with the current animation instead of replacing it. Animation "
|
||||
"Clips can be used to activate multiple, overlapping blend sequences."
|
||||
"\n\n"
|
||||
|
||||
"Normally when an Animation Clip is applied to a user-controlled Player, any interactive user actions will override the "
|
||||
"animation selected by the clip, but Animation Clips can be configured to temporarily block out some user actions for "
|
||||
"the duration of the clip."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxAnimClipData::afxAnimClipData()
|
||||
{
|
||||
clip_name = ST_NULLSTRING;
|
||||
rate = 1.0f;
|
||||
pos_offset = 0.0;
|
||||
trans = 0.12f;
|
||||
flags = 0;
|
||||
|
||||
ignore_disabled = false;
|
||||
ignore_enabled = false;
|
||||
is_death_anim = false;
|
||||
lock_anim = false;
|
||||
ignore_first_person = false;
|
||||
ignore_third_person = false;
|
||||
}
|
||||
|
||||
afxAnimClipData::afxAnimClipData(const afxAnimClipData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
clip_name = other.clip_name;
|
||||
rate = other.rate;
|
||||
pos_offset = other.pos_offset;
|
||||
trans = other.trans;
|
||||
flags = other.flags;
|
||||
|
||||
expand_flags();
|
||||
}
|
||||
|
||||
void afxAnimClipData::onStaticModified(const char* slot, const char* newValue)
|
||||
{
|
||||
Parent::onStaticModified(slot, newValue);
|
||||
merge_flags();
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxAnimClipData)
|
||||
|
||||
void afxAnimClipData::initPersistFields()
|
||||
{
|
||||
addField("clipName", TYPEID< StringTableEntry >(), myOffset(clip_name),
|
||||
"The name of an animation sequence to be played by a ShapeBase-derived object to which this effect is "
|
||||
"constrained. Also works on afxModel effects.\n"
|
||||
"default: \"\"\n");
|
||||
addField("rate", TYPEID< F32 >(), myOffset(rate),
|
||||
"The desired playback speed for the sequence. A value of 1.0 indicates forward playback at a normal rate. Negative "
|
||||
"values cause the sequence to play backwards.\n"
|
||||
"default: 1.0\n");
|
||||
addField("posOffset", TYPEID< F32 >(), myOffset(pos_offset),
|
||||
"Sets a starting offset for the selected animation clip. It directly specifies an animation thread position in the 0.0 to "
|
||||
"1.0 range as a fraction of the clip's duration.\n"
|
||||
"default: 1.0\n");
|
||||
addField("transitionTime", TYPEID< F32 >(), myOffset(trans),
|
||||
"The duration in which the active animation overlaps and blends into the sequence selected by the animation clip.\n"
|
||||
"default: 0.12\n");
|
||||
addField("ignoreCorpse", TYPEID< bool >(), myOffset(ignore_disabled),
|
||||
"Specifies if the animation clip should not be applied to corpses or anything else with a disabled damage state.\n"
|
||||
"default: false\n");
|
||||
addField("ignoreLiving", TYPEID< bool >(), myOffset(ignore_enabled),
|
||||
"Specifies if the animation clip should not be applied to living objects or anything else with an enabled damage "
|
||||
"state.\n"
|
||||
"default: false\n");
|
||||
addField("treatAsDeathAnim", TYPEID< bool >(), myOffset(is_death_anim),
|
||||
"Indicates if the animation clip is a death animation. If the target object dies during the effect, this will prevent "
|
||||
"the object from playing another standard death animation after this clip finishes.\n"
|
||||
"default: false\n");
|
||||
addField("lockAnimation", TYPEID< bool >(), myOffset(lock_anim),
|
||||
"Indicates if user control of a Player should be temporarily blocked during the clip. (See afxAnimLockData.)\n"
|
||||
"default: false\n");
|
||||
addField("ignoreFirstPerson", TYPEID< bool >(), myOffset(ignore_first_person),
|
||||
"If true, the clip will not be played on targets that are the control object and the camera is in first person mode.\n"
|
||||
"default: false\n");
|
||||
addField("ignoreThirdPerson", TYPEID< bool >(), myOffset(ignore_third_person),
|
||||
"If true, the clip will not be played on targets that are the control object and the camera is in third person mode.\n"
|
||||
"default: false\n");
|
||||
|
||||
// synonyms
|
||||
addField("ignoreDisabled", TYPEID< bool >(), myOffset(ignore_disabled),
|
||||
"A synonym for ignoreLiving.");
|
||||
addField("ignoreEnabled", TYPEID< bool >(), myOffset(ignore_enabled),
|
||||
"A synonym for ignoreCorpse.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxAnimClipData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxAnimClipData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
merge_flags();
|
||||
|
||||
stream->writeString(clip_name);
|
||||
stream->write(rate);
|
||||
stream->write(pos_offset);
|
||||
stream->write(trans);
|
||||
stream->write(flags);
|
||||
}
|
||||
|
||||
void afxAnimClipData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
clip_name = stream->readSTString();
|
||||
stream->read(&rate);
|
||||
stream->read(&pos_offset);
|
||||
stream->read(&trans);
|
||||
stream->read(&flags);
|
||||
|
||||
expand_flags();
|
||||
}
|
||||
|
||||
bool afxAnimClipData::writeField(StringTableEntry fieldname, const char* value)
|
||||
{
|
||||
if (!Parent::writeField(fieldname, value))
|
||||
return false;
|
||||
|
||||
// don't write the synonyms
|
||||
if( fieldname == StringTable->insert("ignoreDisabled") )
|
||||
return false;
|
||||
if( fieldname == StringTable->insert("ignoreEnabled") )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxAnimClipData::expand_flags()
|
||||
{
|
||||
ignore_disabled = ((flags & IGNORE_DISABLED) != 0);
|
||||
ignore_enabled = ((flags & IGNORE_ENABLED) != 0);
|
||||
lock_anim = ((flags & BLOCK_USER_CONTROL) != 0);
|
||||
is_death_anim = ((flags & IS_DEATH_ANIM) != 0);
|
||||
ignore_first_person = ((flags & IGNORE_FIRST_PERSON) != 0);
|
||||
ignore_third_person = ((flags & IGNORE_THIRD_PERSON) != 0);
|
||||
}
|
||||
|
||||
void afxAnimClipData::merge_flags()
|
||||
{
|
||||
flags = (((ignore_disabled) ? IGNORE_DISABLED : 0) |
|
||||
((ignore_enabled) ? IGNORE_ENABLED : 0) |
|
||||
((lock_anim) ? BLOCK_USER_CONTROL : 0) |
|
||||
((ignore_first_person) ? IGNORE_FIRST_PERSON : 0) |
|
||||
((ignore_third_person) ? IGNORE_THIRD_PERSON : 0) |
|
||||
((is_death_anim) ? IS_DEATH_ANIM : 0));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
81
Engine/source/afx/ce/afxAnimClip.h
Normal file
81
Engine/source/afx/ce/afxAnimClip.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ANIM_CLIP_H_
|
||||
#define _AFX_ANIM_CLIP_H_
|
||||
|
||||
class afxAnimClipData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
enum
|
||||
{
|
||||
IGNORE_DISABLED = BIT(0),
|
||||
IGNORE_ENABLED = BIT(1),
|
||||
IS_DEATH_ANIM = BIT(2),
|
||||
BLOCK_USER_CONTROL = BIT(3),
|
||||
IGNORE_FIRST_PERSON = BIT(4),
|
||||
IGNORE_THIRD_PERSON = BIT(5)
|
||||
};
|
||||
|
||||
public:
|
||||
StringTableEntry clip_name;
|
||||
F32 rate;
|
||||
F32 pos_offset;
|
||||
F32 trans;
|
||||
U8 flags;
|
||||
|
||||
bool ignore_disabled;
|
||||
bool ignore_enabled;
|
||||
bool is_death_anim;
|
||||
bool lock_anim;
|
||||
bool ignore_first_person;
|
||||
bool ignore_third_person;
|
||||
|
||||
void expand_flags();
|
||||
void merge_flags();
|
||||
|
||||
public:
|
||||
/*C*/ afxAnimClipData();
|
||||
/*C*/ afxAnimClipData(const afxAnimClipData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
virtual bool writeField(StringTableEntry fieldname, const char* value);
|
||||
|
||||
virtual void onStaticModified(const char* slotName, const char* newValue = NULL);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxAnimClipData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ANIM_CLIP_H_
|
||||
95
Engine/source/afx/ce/afxAnimLock.cpp
Normal file
95
Engine/source/afx/ce/afxAnimLock.cpp
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxAnimLock.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxAnimLockData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxAnimLockData);
|
||||
|
||||
ConsoleDocClass( afxAnimLockData,
|
||||
"@brief A datablock that specifies an Animation Lock effect.\n\n"
|
||||
|
||||
"Animation Lock is used to temporarily lock out user-controlled Player actions, usually while an Animation Clip is "
|
||||
"concurrently playing. Animation Clips can already do this, but must lock out user actions for the entire clip length. "
|
||||
"Sometimes you only want to block user actions for a short section of a longer playing animation, such as the part where "
|
||||
"the Player is thrown into the air from an impact. With Animation Lock, you can set a specific timespan for when user "
|
||||
"actions are blocked, independent of any Animation Clip timing."
|
||||
"\n\n"
|
||||
|
||||
"The target of an Animation Lock is the constraint source object specified by the posConstraint field of the enclosing effect "
|
||||
"wrapper. The target must be a Player, a subclass of Player, or an afxModel."
|
||||
"\n\n"
|
||||
|
||||
"The timing of the Animation Lock is determined by the timing fields of the enclosing effect wrapper."
|
||||
"\n\n"
|
||||
|
||||
"Locking behavior timing is set by fields of the enclosing effect wrapper, so afxAnimLockData does not require any fields. "
|
||||
"However, TorqueScript syntax disallows the declaration of an empty datablock. Therefore, it is recommended that you set "
|
||||
"a dynamic field named 'priority' to zero in the body of the datablock as a workaround to this limitation."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxAnimLockData::afxAnimLockData()
|
||||
{
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxAnimLockData)
|
||||
|
||||
void afxAnimLockData::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxAnimLockData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxAnimLockData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
}
|
||||
|
||||
void afxAnimLockData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
48
Engine/source/afx/ce/afxAnimLock.h
Normal file
48
Engine/source/afx/ce/afxAnimLock.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_ANIM_LOCK_H_
|
||||
#define _AFX_ANIM_LOCK_H_
|
||||
|
||||
class afxAnimLockData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
/*C*/ afxAnimLockData();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxAnimLockData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_ANIM_LOCK_H_
|
||||
121
Engine/source/afx/ce/afxAreaDamage.cpp
Normal file
121
Engine/source/afx/ce/afxAreaDamage.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/ce/afxAreaDamage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxAreaDamageData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxAreaDamageData);
|
||||
|
||||
ConsoleDocClass( afxAreaDamageData,
|
||||
"@brief A datablock that specifies an Area Damage effect.\n\n"
|
||||
|
||||
"An Area Damage effect is useful for assigning area damage with unusual timing that must be synchronized with other "
|
||||
"effects. Negative damage amounts can be used for healing effects."
|
||||
"\n\n"
|
||||
|
||||
"The primary difference between afxAreaDamageData and afxDamageData, which is also capable of inflicting area damage, "
|
||||
"is that afxAreaDamageData effects calculate the area damage in C++ code rather than calling out to the script function "
|
||||
"radiusDamage(). In cases where area damage needs to be inflicted repeatedly or in areas crowded with many targets, "
|
||||
"afxAreaDamageData is likely to get better performance."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxAreaDamageData::afxAreaDamageData()
|
||||
{
|
||||
flavor = ST_NULLSTRING;
|
||||
amount = 0;
|
||||
radius = 0;
|
||||
impulse = 0;
|
||||
notify_damage_src = false;
|
||||
exclude_cons_obj = false;
|
||||
}
|
||||
|
||||
afxAreaDamageData::afxAreaDamageData(const afxAreaDamageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
flavor = other.flavor;
|
||||
amount = other.amount;
|
||||
radius = other.radius;
|
||||
impulse = other.impulse;
|
||||
notify_damage_src = other.notify_damage_src;
|
||||
exclude_cons_obj = other.exclude_cons_obj;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxAreaDamageData)
|
||||
|
||||
void afxAreaDamageData::initPersistFields()
|
||||
{
|
||||
addField("flavor", TypeString, myOffset(flavor),
|
||||
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
|
||||
"method. It is used to classify a type of damage such as 'melee', 'magical', or "
|
||||
"'fire'.");
|
||||
addField("damage", TypeF32, myOffset(amount),
|
||||
"An amount of area damage to inflict on a target. Objects within half the radius "
|
||||
"receive full damage which then diminishes out to the full distance of the specified "
|
||||
"radius.");
|
||||
addField("radius", TypeF32, myOffset(radius),
|
||||
"Radius centered at the effect position in which damage will be applied.");
|
||||
addField("impulse", TypeF32, myOffset(impulse),
|
||||
"Specifies an amount of force to apply to damaged objects. Objects within half the "
|
||||
"radius receive full impulse which then diminishes out to the full distance of the "
|
||||
"specified radius.");
|
||||
addField("notifyDamageSource", TypeBool, myOffset(notify_damage_src),
|
||||
"When true, the onInflictedAreaDamage() method of the damaged object will be called "
|
||||
"to notify it of the damage. This is useful for starting some effects or action that "
|
||||
"responds to the damage.");
|
||||
addField("excludeConstraintObject", TypeBool, myOffset(exclude_cons_obj),
|
||||
"When true, the object specified as the effect's primary position constraint will not "
|
||||
"receive any damage.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxAreaDamageData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxAreaDamageData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
}
|
||||
|
||||
void afxAreaDamageData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
62
Engine/source/afx/ce/afxAreaDamage.h
Normal file
62
Engine/source/afx/ce/afxAreaDamage.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_AREA_DAMAGE_H_
|
||||
#define _AFX_AREA_DAMAGE_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class afxAreaDamageData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry flavor;
|
||||
|
||||
F32 amount;
|
||||
F32 radius;
|
||||
F32 impulse;
|
||||
bool notify_damage_src;
|
||||
bool exclude_cons_obj;
|
||||
|
||||
public:
|
||||
/*C*/ afxAreaDamageData();
|
||||
/*C*/ afxAreaDamageData(const afxAreaDamageData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxAreaDamageData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_AREA_DAMAGE_H_
|
||||
246
Engine/source/afx/ce/afxAudioBank.cpp
Normal file
246
Engine/source/afx/ce/afxAudioBank.cpp
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
|
||||
#include "afx/ce/afxAudioBank.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxAudioBank);
|
||||
|
||||
ConsoleDocClass( afxAudioBank,
|
||||
"@brief A datablock that specifies an Audio Bank effect.\n\n"
|
||||
|
||||
"afxAudioBank is very similar to the stock Torque SFXProfile datablock but it allows specification of up to 32 different sound "
|
||||
"files. The sound that actually plays is determined by the playIndex field."
|
||||
"\n\n"
|
||||
|
||||
"afxAudioBank is most useful when used in combination with field substitutions, whereby a substitution statement "
|
||||
"assigned to playIndex selects a different sound (perhaps randomly) each time the effect is used."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxAudioBank::afxAudioBank()
|
||||
{
|
||||
mPath = ST_NULLSTRING;
|
||||
mDescriptionObjectID = 0;
|
||||
mDescriptionObject = NULL;
|
||||
mPreload = false;
|
||||
play_index = -1;
|
||||
|
||||
for (S32 i = 0; i < 32; i++)
|
||||
mFilenames[i] = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxAudioBank::afxAudioBank(const afxAudioBank& other, bool temp_clone) : SimDataBlock(other, temp_clone)
|
||||
{
|
||||
mPath = other.mPath;
|
||||
mDescriptionObject = other.mDescriptionObject;
|
||||
mDescriptionObjectID = other.mDescriptionObjectID; // -- for pack/unpack of mDescriptionObject ptr
|
||||
mPreload = other.mPreload;
|
||||
play_index = other.play_index;
|
||||
|
||||
for (S32 i = 0; i < 32; i++)
|
||||
mFilenames[i] = other.mFilenames[i];
|
||||
}
|
||||
|
||||
afxAudioBank::~afxAudioBank()
|
||||
{
|
||||
if (!isTempClone())
|
||||
return;
|
||||
|
||||
if (mDescriptionObject && mDescriptionObject->isTempClone())
|
||||
{
|
||||
delete mDescriptionObject;
|
||||
mDescriptionObject = 0;
|
||||
}
|
||||
}
|
||||
|
||||
afxAudioBank* afxAudioBank::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
|
||||
{
|
||||
if (!owner)
|
||||
return this;
|
||||
|
||||
afxAudioBank* sub_profile_db = this;
|
||||
|
||||
SFXDescription* desc_db;
|
||||
if (mDescriptionObject && mDescriptionObject->getSubstitutionCount() > 0)
|
||||
{
|
||||
SFXDescription* orig_db = mDescriptionObject;
|
||||
desc_db = new SFXDescription(*orig_db, true);
|
||||
orig_db->performSubstitutions(desc_db, owner, index);
|
||||
}
|
||||
else
|
||||
desc_db = 0;
|
||||
|
||||
if (this->getSubstitutionCount() > 0 || desc_db)
|
||||
{
|
||||
sub_profile_db = new afxAudioBank(*this, true);
|
||||
performSubstitutions(sub_profile_db, owner, index);
|
||||
if (desc_db)
|
||||
sub_profile_db->mDescriptionObject = desc_db;
|
||||
}
|
||||
|
||||
return sub_profile_db;
|
||||
}
|
||||
|
||||
void afxAudioBank::onPerformSubstitutions()
|
||||
{
|
||||
}
|
||||
|
||||
void afxAudioBank::initPersistFields()
|
||||
{
|
||||
addField("path", TypeFilename, Offset(mPath, afxAudioBank),
|
||||
"A filesystem path to the folder containing the sound files specified by the "
|
||||
"filenames[] field. All sound files used in a single AudioBank must be located in "
|
||||
"the same folder.");
|
||||
addField("filenames", TypeString, Offset(mFilenames, afxAudioBank), 32,
|
||||
"Up to 32 names of sound files found in the path folder. The sound that is actually "
|
||||
"played by an Audio Bank effect is determined by the playIndex field.");
|
||||
addField("description", TYPEID<SFXDescription>(), Offset(mDescriptionObject, afxAudioBank),
|
||||
"SFXDescription datablock to use with this set of sounds.");
|
||||
addField("preload", TypeBool, Offset(mPreload, afxAudioBank),
|
||||
"If set to true, file is pre-loaded, otherwise it is loaded on-demand.");
|
||||
addField("playIndex", TypeS32, Offset(play_index, afxAudioBank),
|
||||
"An array index that selects a sound to play from the filenames[] field. Values "
|
||||
"outside of the range of assigned filename[] entries will not play any sound.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxAudioBank::preload(bool server, String &errorStr)
|
||||
{
|
||||
if(!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxAudioBank::onAdd()
|
||||
{
|
||||
if (!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
if (!mDescriptionObject && mDescriptionObjectID)
|
||||
Sim::findObject(mDescriptionObjectID , mDescriptionObject);
|
||||
|
||||
// if this is client side, make sure that description is as well
|
||||
if(mDescriptionObject)
|
||||
{ // client side dataBlock id's are not in the dataBlock id range
|
||||
if (getId() >= DataBlockObjectIdFirst && getId() <= DataBlockObjectIdLast)
|
||||
{
|
||||
SimObjectId pid = mDescriptionObject->getId();
|
||||
if (pid < DataBlockObjectIdFirst || pid > DataBlockObjectIdLast)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,"afxAudioBank: data dataBlock not networkable (use datablock to create).");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
void afxAudioBank::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
if (stream->writeFlag(mDescriptionObject))
|
||||
stream->writeRangedU32(mDescriptionObject->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
|
||||
/*
|
||||
char buffer[256];
|
||||
if(!mFilename)
|
||||
buffer[0] = 0;
|
||||
else
|
||||
dStrcpy(buffer, mFilename);
|
||||
stream->writeString(buffer);
|
||||
*/
|
||||
|
||||
stream->writeString(mPath);
|
||||
|
||||
for (S32 i = 0; i < 32; i++)
|
||||
{
|
||||
stream->writeString(mFilenames[i]);
|
||||
if (mFilenames[i] == ST_NULLSTRING)
|
||||
break;
|
||||
}
|
||||
|
||||
stream->writeFlag(mPreload);
|
||||
|
||||
if (stream->writeFlag(play_index >= 0 && play_index < 32))
|
||||
stream->writeInt(play_index, 5);
|
||||
}
|
||||
|
||||
void afxAudioBank::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
if (stream->readFlag()) // AudioDescription
|
||||
{
|
||||
SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
mDescriptionObjectID = id;
|
||||
Sim::findObject(id, mDescriptionObject);
|
||||
}
|
||||
|
||||
// Filename
|
||||
/*
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
mFilename = StringTable->insert(buffer);
|
||||
*/
|
||||
|
||||
char buffer[256];
|
||||
|
||||
stream->readString(buffer);
|
||||
mPath = StringTable->insert(buffer);
|
||||
|
||||
for (S32 i = 0; i < 32; i++)
|
||||
{
|
||||
stream->readString(buffer);
|
||||
mFilenames[i] = StringTable->insert(buffer);
|
||||
if (mFilenames[i] == ST_NULLSTRING)
|
||||
break;
|
||||
}
|
||||
|
||||
mPreload = stream->readFlag(); // Preload
|
||||
|
||||
if (stream->readFlag())
|
||||
play_index = stream->readInt(5);
|
||||
else
|
||||
play_index = -1;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
67
Engine/source/afx/ce/afxAudioBank.h
Normal file
67
Engine/source/afx/ce/afxAudioBank.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_AUDIO_BANK_H_
|
||||
#define _AFX_AUDIO_BANK_H_
|
||||
|
||||
class SFXDescription;
|
||||
|
||||
class afxAudioBank: public SimDataBlock
|
||||
{
|
||||
private:
|
||||
typedef SimDataBlock Parent;
|
||||
|
||||
public:
|
||||
SFXDescription* mDescriptionObject;
|
||||
U32 mDescriptionObjectID;
|
||||
StringTableEntry mPath;
|
||||
StringTableEntry mFilenames[32];
|
||||
bool mPreload;
|
||||
S32 play_index;
|
||||
|
||||
public:
|
||||
/*C*/ afxAudioBank();
|
||||
/*C*/ afxAudioBank(const afxAudioBank&, bool = false);
|
||||
/*D*/ ~afxAudioBank();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream* stream);
|
||||
virtual void unpackData(BitStream* stream);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
afxAudioBank* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||
virtual void onPerformSubstitutions();
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
DECLARE_CONOBJECT(afxAudioBank);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_AUDIO_BANK_H_
|
||||
294
Engine/source/afx/ce/afxBillboard.cpp
Normal file
294
Engine/source/afx/ce/afxBillboard.cpp
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "gfx/gfxAPI.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxBillboard.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxBillboardData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxBillboardData);
|
||||
|
||||
ConsoleDocClass( afxBillboardData,
|
||||
"@brief A datablock that specifies a Billboard effect.\n\n"
|
||||
|
||||
"A Billboard effect is a textured quadrangle which is always aligned to face towards the camera. It is much like a single "
|
||||
"static particle and is rendered in a similar fashion."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxBillboardData::afxBillboardData()
|
||||
{
|
||||
color.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
txr_name = ST_NULLSTRING;
|
||||
dimensions.set(1.0f, 1.0f);
|
||||
texCoords[0].set(0.0f, 0.0f);
|
||||
texCoords[1].set(0.0f, 1.0f);
|
||||
texCoords[2].set(1.0f, 1.0f);
|
||||
texCoords[3].set(1.0f, 0.0f);
|
||||
blendStyle = BlendUndefined;
|
||||
srcBlendFactor = BLEND_UNDEFINED;
|
||||
dstBlendFactor = BLEND_UNDEFINED;
|
||||
texFunc = TexFuncModulate;
|
||||
}
|
||||
|
||||
afxBillboardData::afxBillboardData(const afxBillboardData& other, bool temp_clone)
|
||||
: GameBaseData(other, temp_clone)
|
||||
{
|
||||
color = other.color;
|
||||
txr_name = other.txr_name;
|
||||
txr = other.txr;
|
||||
dimensions = other.dimensions;
|
||||
texCoords[0] = other.texCoords[0];
|
||||
texCoords[1] = other.texCoords[1];
|
||||
texCoords[2] = other.texCoords[2];
|
||||
texCoords[3] = other.texCoords[3];
|
||||
blendStyle = other.blendStyle;
|
||||
srcBlendFactor = other.srcBlendFactor;
|
||||
dstBlendFactor = other.dstBlendFactor;
|
||||
texFunc = other.texFunc;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxBillboardData)
|
||||
|
||||
extern EnumTable srcBlendFactorTable;
|
||||
extern EnumTable dstBlendFactorTable;
|
||||
|
||||
ImplementEnumType( afxBillboard_BlendStyle, "Possible blending types.\n" "@ingroup afxBillboard\n\n" )
|
||||
{ afxBillboardData::BlendNormal, "NORMAL", "..." },
|
||||
{ afxBillboardData::BlendAdditive, "ADDITIVE", "..." },
|
||||
{ afxBillboardData::BlendSubtractive, "SUBTRACTIVE", "..." },
|
||||
{ afxBillboardData::BlendPremultAlpha, "PREMULTALPHA", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( afxBillboard_TexFuncType, "Possible texture function types.\n" "@ingroup afxBillboard\n\n" )
|
||||
{ afxBillboardData::TexFuncReplace, "replace", "..." },
|
||||
{ afxBillboardData::TexFuncModulate, "modulate", "..." },
|
||||
{ afxBillboardData::TexFuncAdd, "add", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
void afxBillboardData::initPersistFields()
|
||||
{
|
||||
addField("color", TypeColorF, myOffset(color),
|
||||
"The color assigned to the quadrangle geometry. The way it combines with the given "
|
||||
"texture varies according to the setting of the textureFunction field.");
|
||||
addField("texture", TypeFilename, myOffset(txr_name),
|
||||
"An image to use as the billboard's texture.");
|
||||
addField("dimensions", TypePoint2F, myOffset(dimensions),
|
||||
"A value-pair that specifies the horizontal and vertical dimensions of the billboard "
|
||||
"in scene units.");
|
||||
addField("textureCoords", TypePoint2F, myOffset(texCoords), 4,
|
||||
"An array of four value-pairs that specify the UV texture coordinates for the four "
|
||||
"corners of the billboard's quadrangle.");
|
||||
|
||||
addField("blendStyle", TYPEID<afxBillboardData::BlendStyle>(), myOffset(blendStyle),
|
||||
"Selects a common blend factor preset. When set to 'user', srcBlendFactor and "
|
||||
"dstBlendFactor can be used to set additional blend factor combinations.\n"
|
||||
"Possible values: normal, additive, subtractive, premultalpha, or user.");
|
||||
addField("srcBlendFactor", TYPEID<GFXBlend>(), myOffset(srcBlendFactor),
|
||||
"Specifies source blend factor when blendStyle is set to 'user'.\n"
|
||||
"Possible values: GFXBlendZero, GFXBlendOne, GFXBlendDestColor, GFXBlendInvDestColor, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha, GFXBlendDestAlpha, GFXBlendInvDestAlpha, or GFXBlendSrcAlphaSat");
|
||||
addField("dstBlendFactor", TYPEID<GFXBlend>(), myOffset(dstBlendFactor),
|
||||
"Specifies destination blend factor when blendStyle is set to 'user'.\n"
|
||||
"Possible values: GFXBlendZero, GFXBlendOne, GFXBlendSrcColor, GFXBlendInvSrcColor, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha, GFXBlendDestAlpha, or GFXBlendInvDestAlpha");
|
||||
|
||||
addField("textureFunction", TYPEID<afxBillboardData::TexFuncType>(), myOffset(texFunc),
|
||||
"Selects a texture function that determines how the texture pixels are combined "
|
||||
"with the shaded color of the billboard's quadrangle geometry.\n"
|
||||
"Possible values: replace, modulate, or add.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxBillboardData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(color);
|
||||
stream->writeString(txr_name);
|
||||
mathWrite(*stream, dimensions);
|
||||
mathWrite(*stream, texCoords[0]);
|
||||
mathWrite(*stream, texCoords[1]);
|
||||
mathWrite(*stream, texCoords[2]);
|
||||
mathWrite(*stream, texCoords[3]);
|
||||
|
||||
stream->writeInt(srcBlendFactor, 4);
|
||||
stream->writeInt(dstBlendFactor, 4);
|
||||
stream->writeInt(texFunc, 4);
|
||||
}
|
||||
|
||||
void afxBillboardData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&color);
|
||||
txr_name = stream->readSTString();
|
||||
txr = GFXTexHandle();
|
||||
mathRead(*stream, &dimensions);
|
||||
mathRead(*stream, &texCoords[0]);
|
||||
mathRead(*stream, &texCoords[1]);
|
||||
mathRead(*stream, &texCoords[2]);
|
||||
mathRead(*stream, &texCoords[3]);
|
||||
|
||||
srcBlendFactor = (GFXBlend) stream->readInt(4);
|
||||
dstBlendFactor = (GFXBlend) stream->readInt(4);
|
||||
texFunc = stream->readInt(4);
|
||||
}
|
||||
|
||||
bool afxBillboardData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
if (!server)
|
||||
{
|
||||
if (txr_name && txr_name[0] != '\0')
|
||||
{
|
||||
txr.set(txr_name, &GFXStaticTextureSRGBProfile, "Billboard Texture");
|
||||
}
|
||||
}
|
||||
|
||||
// if blend-style is set to User, check for defined blend-factors
|
||||
if (blendStyle == BlendUser && (srcBlendFactor == BLEND_UNDEFINED || dstBlendFactor == BLEND_UNDEFINED))
|
||||
{
|
||||
blendStyle = BlendUndefined;
|
||||
Con::warnf(ConsoleLogEntry::General, "afxBillboardData(%s) incomplete blend factor specification.", getName());
|
||||
}
|
||||
|
||||
// silently switch Undefined blend-style to User if blend factors are both defined
|
||||
if (blendStyle == BlendUndefined && srcBlendFactor != BLEND_UNDEFINED && dstBlendFactor != BLEND_UNDEFINED)
|
||||
{
|
||||
blendStyle = BlendUser;
|
||||
}
|
||||
|
||||
// set pre-defined blend-factors
|
||||
switch (blendStyle)
|
||||
{
|
||||
case BlendNormal:
|
||||
srcBlendFactor = GFXBlendSrcAlpha;
|
||||
dstBlendFactor = GFXBlendInvSrcAlpha;
|
||||
break;
|
||||
case BlendSubtractive:
|
||||
srcBlendFactor = GFXBlendZero;
|
||||
dstBlendFactor = GFXBlendInvSrcColor;
|
||||
break;
|
||||
case BlendPremultAlpha:
|
||||
srcBlendFactor = GFXBlendOne;
|
||||
dstBlendFactor = GFXBlendInvSrcAlpha;
|
||||
break;
|
||||
case BlendUser:
|
||||
break;
|
||||
case BlendAdditive:
|
||||
srcBlendFactor = GFXBlendSrcAlpha;
|
||||
dstBlendFactor = GFXBlendOne;
|
||||
break;
|
||||
case BlendUndefined:
|
||||
default:
|
||||
blendStyle = BlendNormal;
|
||||
srcBlendFactor = GFXBlendSrcAlpha;
|
||||
dstBlendFactor = GFXBlendInvSrcAlpha;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxBillboard
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxBillboard);
|
||||
|
||||
ConsoleDocClass( afxBillboard,
|
||||
"@brief A Billboard effect as defined by an afxBillboardData datablock.\n\n"
|
||||
|
||||
"A Billboard effect is a textured quadrangle which is always aligned to "
|
||||
"face towards the camera. It is much like a single static particle and is rendered "
|
||||
"in a similar fashion.\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxBillboard::afxBillboard()
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(IsGhost);
|
||||
|
||||
mDataBlock = 0;
|
||||
fade_amt = 1.0f;
|
||||
is_visible = true;
|
||||
sort_priority = 0;
|
||||
live_color.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
afxBillboard::~afxBillboard()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxBillboard::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<afxBillboardData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
live_color = mDataBlock->color;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxBillboard::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
F32 width = mDataBlock->dimensions.x * 0.5f;
|
||||
F32 height = mDataBlock->dimensions.y * 0.5f;
|
||||
mObjBox = Box3F(Point3F(-width, -0.01f, -height), Point3F(width, 0.01f, height));
|
||||
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxBillboard::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
131
Engine/source/afx/ce/afxBillboard.h
Normal file
131
Engine/source/afx/ce/afxBillboard.h
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_BILLBOARD_H_
|
||||
#define _AFX_BILLBOARD_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
#define BLEND_UNDEFINED GFXBlend_COUNT
|
||||
|
||||
class afxBillboardData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
// This enum specifies common blend settings with predefined values
|
||||
// for src/dst blend factors.
|
||||
enum BlendStyle {
|
||||
BlendUndefined,
|
||||
BlendNormal,
|
||||
BlendAdditive,
|
||||
BlendSubtractive,
|
||||
BlendPremultAlpha,
|
||||
BlendUser,
|
||||
};
|
||||
|
||||
enum TexFuncType {
|
||||
TexFuncReplace,
|
||||
TexFuncModulate,
|
||||
TexFuncAdd,
|
||||
};
|
||||
|
||||
public:
|
||||
StringTableEntry txr_name;
|
||||
GFXTexHandle txr;
|
||||
|
||||
LinearColorF color;
|
||||
Point2F texCoords[4];
|
||||
Point2F dimensions;
|
||||
S32 blendStyle;
|
||||
GFXBlend srcBlendFactor;
|
||||
GFXBlend dstBlendFactor;
|
||||
S32 texFunc;
|
||||
|
||||
public:
|
||||
/*C*/ afxBillboardData();
|
||||
/*C*/ afxBillboardData(const afxBillboardData&, bool = false);
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxBillboardData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
typedef afxBillboardData::BlendStyle afxBillboard_BlendStyle;
|
||||
DefineEnumType( afxBillboard_BlendStyle );
|
||||
|
||||
typedef afxBillboardData::TexFuncType afxBillboard_TexFuncType;
|
||||
DefineEnumType( afxBillboard_TexFuncType );
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxBillboard
|
||||
|
||||
class afxBillboard : public GameBase, public afxEffectDefs
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
friend class afxEA_Billboard;
|
||||
|
||||
private:
|
||||
afxBillboardData* mDataBlock;
|
||||
|
||||
F32 fade_amt;
|
||||
bool is_visible;
|
||||
S8 sort_priority;
|
||||
LinearColorF live_color;
|
||||
|
||||
GFXStateBlockRef normal_sb;
|
||||
GFXStateBlockRef reflected_sb;
|
||||
|
||||
public:
|
||||
/*C*/ afxBillboard();
|
||||
/*D*/ ~afxBillboard();
|
||||
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
void setFadeAmount(F32 amt) { fade_amt = amt; }
|
||||
void setSortPriority(S8 priority) { sort_priority = priority; }
|
||||
void setVisibility(bool flag) { is_visible = flag; }
|
||||
|
||||
virtual void prepRenderImage(SceneRenderState*);
|
||||
|
||||
void _renderBillboard(ObjectRenderInst*, SceneRenderState*, BaseMatInstance*);
|
||||
|
||||
DECLARE_CONOBJECT(afxBillboard);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_BILLBOARD_H_
|
||||
145
Engine/source/afx/ce/afxBillboard_T3D.cpp
Normal file
145
Engine/source/afx/ce/afxBillboard_T3D.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxBillboard.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxBillboard::prepRenderImage(SceneRenderState* state)
|
||||
{
|
||||
if (!is_visible)
|
||||
return;
|
||||
|
||||
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
|
||||
ri->renderDelegate.bind(this, &afxBillboard::_renderBillboard);
|
||||
ri->type = RenderPassManager::RIT_ObjectTranslucent;
|
||||
ri->translucentSort = true;
|
||||
ri->defaultKey = (U32)(dsize_t)mDataBlock;
|
||||
ri->sortDistSq = getWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
|
||||
state->getRenderPass()->addInst(ri);
|
||||
}
|
||||
|
||||
void afxBillboard::_renderBillboard(ObjectRenderInst *ri, SceneRenderState* state, BaseMatInstance* overrideMat)
|
||||
{
|
||||
if (overrideMat)
|
||||
return;
|
||||
|
||||
// predraw
|
||||
if (normal_sb.isNull())
|
||||
{
|
||||
GFXStateBlockDesc desc;
|
||||
|
||||
// Culling -- it's a billboard, so no backfaces
|
||||
desc.setCullMode(GFXCullCW);
|
||||
|
||||
// Blending
|
||||
desc.setBlend(true, mDataBlock->srcBlendFactor, mDataBlock->dstBlendFactor);
|
||||
desc.alphaTestEnable = (desc.blendSrc == GFXBlendSrcAlpha &&
|
||||
(desc.blendDest == GFXBlendInvSrcAlpha || desc.blendDest == GFXBlendOne));
|
||||
desc.alphaTestRef = 1;
|
||||
desc.alphaTestFunc = GFXCmpGreaterEqual;
|
||||
|
||||
desc.setZReadWrite(true);
|
||||
desc.zFunc = GFXCmpLessEqual;
|
||||
desc.zWriteEnable = false;
|
||||
|
||||
desc.samplersDefined = true;
|
||||
switch (mDataBlock->texFunc)
|
||||
{
|
||||
case afxBillboardData::TexFuncReplace:
|
||||
desc.samplers[0].textureColorOp = GFXTOPDisable;
|
||||
break;
|
||||
case afxBillboardData::TexFuncModulate:
|
||||
desc.samplers[0].textureColorOp = GFXTOPModulate;
|
||||
break;
|
||||
case afxBillboardData::TexFuncAdd:
|
||||
desc.samplers[0].textureColorOp = GFXTOPAdd;
|
||||
break;
|
||||
}
|
||||
|
||||
desc.samplers[1].textureColorOp = GFXTOPDisable;
|
||||
|
||||
normal_sb = GFX->createStateBlock(desc);
|
||||
|
||||
desc.setCullMode(GFXCullCCW);
|
||||
reflected_sb = GFX->createStateBlock(desc);
|
||||
}
|
||||
|
||||
if (state->isReflectPass())
|
||||
GFX->setStateBlock(reflected_sb);
|
||||
else
|
||||
GFX->setStateBlock(normal_sb);
|
||||
|
||||
GFXTransformSaver saver;
|
||||
GFX->multWorld(getRenderTransform());
|
||||
|
||||
GFX->setTexture(0, mDataBlock->txr);
|
||||
|
||||
MatrixF worldmod = GFX->getWorldMatrix();
|
||||
MatrixF viewmod = GFX->getViewMatrix();
|
||||
|
||||
Point4F Position;
|
||||
MatrixF ModelView;
|
||||
ModelView.mul(viewmod, worldmod);
|
||||
ModelView.getColumn(3, &Position);
|
||||
ModelView.identity();
|
||||
ModelView.setColumn(3, Position);
|
||||
|
||||
GFX->setWorldMatrix(ModelView);
|
||||
MatrixF ident;
|
||||
ident.identity();
|
||||
GFX->setViewMatrix(ident);
|
||||
|
||||
F32 width = mDataBlock->dimensions.x * 0.5f * mObjScale.x;
|
||||
F32 height = mDataBlock->dimensions.y * 0.5f * mObjScale.z;
|
||||
|
||||
Point3F points[4];
|
||||
points[0].set( width, 0.0f, -height);
|
||||
points[1].set(-width, 0.0f, -height);
|
||||
points[2].set(-width, 0.0f, height);
|
||||
points[3].set( width, 0.0f, height);
|
||||
|
||||
PrimBuild::begin(GFXTriangleStrip, 4);
|
||||
{
|
||||
PrimBuild::color4f(live_color.red, live_color.green, live_color.blue, live_color.alpha*fade_amt);
|
||||
PrimBuild::texCoord2f(mDataBlock->texCoords[1].x, mDataBlock->texCoords[1].y);
|
||||
PrimBuild::vertex3fv(points[1]);
|
||||
PrimBuild::texCoord2f(mDataBlock->texCoords[2].x, mDataBlock->texCoords[2].y);
|
||||
PrimBuild::vertex3fv(points[0]);
|
||||
PrimBuild::texCoord2f(mDataBlock->texCoords[0].x, mDataBlock->texCoords[0].y);
|
||||
PrimBuild::vertex3fv(points[2]);
|
||||
PrimBuild::texCoord2f(mDataBlock->texCoords[3].x, mDataBlock->texCoords[3].y);
|
||||
PrimBuild::vertex3fv(points[3]);
|
||||
}
|
||||
PrimBuild::end();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
132
Engine/source/afx/ce/afxCameraPuppet.cpp
Normal file
132
Engine/source/afx/ce/afxCameraPuppet.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxCameraPuppet.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxCameraPuppetData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxCameraPuppetData);
|
||||
|
||||
ConsoleDocClass( afxCameraPuppetData,
|
||||
"@brief A datablock that specifies a Camera Puppet effect.\n\n"
|
||||
|
||||
"A Camera Puppet effect is used to control the position and orientation of the camera using the AFX constraint system. "
|
||||
"Camera Puppet effects are useful for creating small cut-scenes and can add a lot of visual drama to a spell or effectron "
|
||||
"effect."
|
||||
"\n\n"
|
||||
|
||||
"Effective use of Camera Puppet effects require a fairly advanced understanding of how Torque cameras work in a "
|
||||
"server-client context. Care must be taken to prevent client cameras from drifting too far out of sync from the server camera. "
|
||||
"Otherwise, obvious discontinuities in the motion will result when the Camera Puppet ends and control is restored to the "
|
||||
"server camera. Scoping problems can also result if a client camera is moved to a location that is inconsistent with the "
|
||||
"scene scoping done by the server camera."
|
||||
"\n\n"
|
||||
|
||||
"Often it is useful to manage camera controlling in an isolated effectron rather than directly incorporated into a magic-spell. "
|
||||
"This way the camera controlling effectron can target the specific client associated with the spellcaster. The spellcasting "
|
||||
"player observes the spell in a dramatic cut-scene-like fashion while other players continue to observe from their own "
|
||||
"viewing locations."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxCameraPuppetData::afxCameraPuppetData()
|
||||
{
|
||||
cam_spec = ST_NULLSTRING;
|
||||
networking = SERVER_AND_CLIENT;
|
||||
}
|
||||
|
||||
afxCameraPuppetData::afxCameraPuppetData(const afxCameraPuppetData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
cam_spec = other.cam_spec;
|
||||
networking = other.networking;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxCameraPuppetData)
|
||||
|
||||
void afxCameraPuppetData::initPersistFields()
|
||||
{
|
||||
addField("cameraSpec", TypeString, myOffset(cam_spec),
|
||||
"This field is like the effect-wrapper fields for specifying constraint sources, "
|
||||
"but here it specifies a target for the camera-puppet effect.");
|
||||
addField("networking", TypeS8, myOffset(networking),
|
||||
"Specifies the networking model used for the camerapuppet effect. The effect can "
|
||||
"puppet just the server camera, just the client camera, or both.\n"
|
||||
"Possible values: $AFX::SERVER_ONLY, $AFX::CLIENT_ONLY, or $AFX::SERVER_AND_CLIENT.");
|
||||
|
||||
// disallow some field substitutions
|
||||
disableFieldSubstitutions("cameraSpec");
|
||||
disableFieldSubstitutions("networking");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxCameraPuppetData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
cam_def.parseSpec(cam_spec, runs_on_s, runs_on_c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxCameraPuppetData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(cam_spec);
|
||||
stream->write(networking);
|
||||
}
|
||||
|
||||
void afxCameraPuppetData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
cam_spec = stream->readSTString();
|
||||
stream->read(&networking);
|
||||
}
|
||||
|
||||
void afxCameraPuppetData::gather_cons_defs(Vector<afxConstraintDef>& defs)
|
||||
{
|
||||
if (cam_def.isDefined())
|
||||
defs.push_back(cam_def);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
64
Engine/source/afx/ce/afxCameraPuppet.h
Normal file
64
Engine/source/afx/ce/afxCameraPuppet.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_CAMERA_PUPPET_H_
|
||||
#define _AFX_CAMERA_PUPPET_H_
|
||||
|
||||
#include "afx/ce/afxComponentEffect.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
class afxCameraPuppetData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry cam_spec;
|
||||
afxConstraintDef cam_def;
|
||||
|
||||
U8 networking;
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
|
||||
public:
|
||||
/*C*/ afxCameraPuppetData();
|
||||
/*C*/ afxCameraPuppetData(const afxCameraPuppetData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxCameraPuppetData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_CAMERA_PUPPET_H_
|
||||
118
Engine/source/afx/ce/afxCameraShake.cpp
Normal file
118
Engine/source/afx/ce/afxCameraShake.cpp
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxCameraShake.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxCameraShakeData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxCameraShakeData);
|
||||
|
||||
ConsoleDocClass( afxCameraShakeData,
|
||||
"@brief A datablock that specifies a Camera Shake effect.\n\n"
|
||||
|
||||
"Camera Shake internally utilizes the standard Torque CameraShake class to implement a shaken camera effect."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxCameraShakeData::afxCameraShakeData()
|
||||
{
|
||||
camShakeFreq.set( 10.0, 10.0, 10.0 );
|
||||
camShakeAmp.set( 1.0, 1.0, 1.0 );
|
||||
camShakeRadius = 10.0;
|
||||
camShakeFalloff = 10.0;
|
||||
}
|
||||
|
||||
afxCameraShakeData::afxCameraShakeData(const afxCameraShakeData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
camShakeFreq = other.camShakeFreq;
|
||||
camShakeAmp = other.camShakeAmp;
|
||||
camShakeRadius = other.camShakeRadius;
|
||||
camShakeFalloff = other.camShakeFalloff;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxCameraShakeData)
|
||||
|
||||
void afxCameraShakeData::initPersistFields()
|
||||
{
|
||||
addField("frequency", TypePoint3F, Offset(camShakeFreq, afxCameraShakeData),
|
||||
"The camera shake frequencies for all three axes: X, Y, Z.");
|
||||
addField("amplitude", TypePoint3F, Offset(camShakeAmp, afxCameraShakeData),
|
||||
"The camera shake amplitudes for all three axes: X, Y, Z.");
|
||||
addField("radius", TypeF32, Offset(camShakeRadius, afxCameraShakeData),
|
||||
"Radius about the effect position in which shaking will be applied.");
|
||||
addField("falloff", TypeF32, Offset(camShakeFalloff, afxCameraShakeData),
|
||||
"Magnitude by which shaking decreases over distance to radius.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxCameraShakeData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxCameraShakeData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(camShakeFreq.x);
|
||||
stream->write(camShakeFreq.y);
|
||||
stream->write(camShakeFreq.z);
|
||||
stream->write(camShakeAmp.x);
|
||||
stream->write(camShakeAmp.y);
|
||||
stream->write(camShakeAmp.z);
|
||||
stream->write(camShakeRadius);
|
||||
stream->write(camShakeFalloff);
|
||||
}
|
||||
|
||||
void afxCameraShakeData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&camShakeFreq.x);
|
||||
stream->read(&camShakeFreq.y);
|
||||
stream->read(&camShakeFreq.z);
|
||||
stream->read(&camShakeAmp.x);
|
||||
stream->read(&camShakeAmp.y);
|
||||
stream->read(&camShakeAmp.z);
|
||||
stream->read(&camShakeRadius);
|
||||
stream->read(&camShakeFalloff);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
57
Engine/source/afx/ce/afxCameraShake.h
Normal file
57
Engine/source/afx/ce/afxCameraShake.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_CAMERA_SHAKE_H_
|
||||
#define _AFX_CAMERA_SHAKE_H_
|
||||
|
||||
class afxCameraShakeData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
VectorF camShakeFreq;
|
||||
VectorF camShakeAmp;
|
||||
F32 camShakeRadius;
|
||||
F32 camShakeFalloff;
|
||||
|
||||
public:
|
||||
/*C*/ afxCameraShakeData();
|
||||
/*C*/ afxCameraShakeData(const afxCameraShakeData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxCameraShakeData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_CAMERA_SHAKE_H_
|
||||
103
Engine/source/afx/ce/afxCollisionEvent.cpp
Normal file
103
Engine/source/afx/ce/afxCollisionEvent.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxCollisionEvent.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxCollisionEventData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxCollisionEventData);
|
||||
|
||||
ConsoleDocClass( afxCollisionEventData,
|
||||
"@brief A datablock that specifies a Collision Event effect.\n\n"
|
||||
|
||||
"MORE NEEDED HERE.\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxCollisionEventData::afxCollisionEventData()
|
||||
{
|
||||
method_name = ST_NULLSTRING;
|
||||
script_data = ST_NULLSTRING;
|
||||
gen_trigger = false;
|
||||
trigger_bit = 0;
|
||||
}
|
||||
|
||||
afxCollisionEventData::afxCollisionEventData(const afxCollisionEventData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
method_name = other.method_name;
|
||||
script_data = other.script_data;
|
||||
gen_trigger = other.gen_trigger;
|
||||
trigger_bit = other.trigger_bit;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxCollisionEventData)
|
||||
|
||||
void afxCollisionEventData::initPersistFields()
|
||||
{
|
||||
addField("methodName", TypeString, myOffset(method_name),
|
||||
"...");
|
||||
addField("scriptData", TypeString, myOffset(script_data),
|
||||
"...");
|
||||
addField("generateTrigger", TypeBool, myOffset(gen_trigger),
|
||||
"...");
|
||||
addField("triggerBit", TypeS8, myOffset(trigger_bit),
|
||||
"...");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxCollisionEventData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(method_name);
|
||||
stream->writeString(script_data);
|
||||
if (stream->writeFlag(gen_trigger))
|
||||
stream->write(trigger_bit);
|
||||
}
|
||||
|
||||
void afxCollisionEventData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
method_name = stream->readSTString();
|
||||
script_data = stream->readSTString();
|
||||
gen_trigger = stream->readFlag();
|
||||
if (gen_trigger)
|
||||
stream->read(&trigger_bit);
|
||||
else
|
||||
trigger_bit = 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
59
Engine/source/afx/ce/afxCollisionEvent.h
Normal file
59
Engine/source/afx/ce/afxCollisionEvent.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_COLLISION_EVENT_H_
|
||||
#define _AFX_COLLISION_EVENT_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxCollisionEventData
|
||||
|
||||
struct afxCollisionEventData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry method_name;
|
||||
StringTableEntry script_data;
|
||||
bool gen_trigger;
|
||||
U8 trigger_bit;
|
||||
|
||||
public:
|
||||
/*C*/ afxCollisionEventData();
|
||||
/*C*/ afxCollisionEventData(const afxCollisionEventData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxCollisionEventData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_COLLISION_EVENT_H_
|
||||
41
Engine/source/afx/ce/afxComponentEffect.h
Normal file
41
Engine/source/afx/ce/afxComponentEffect.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_COMPONENT_EFFECT_H_
|
||||
#define _AFX_COMPONENT_EFFECT_H_
|
||||
|
||||
#include "core/util/tVector.h"
|
||||
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
class afxComponentEffectData
|
||||
{
|
||||
public:
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs) { };
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_COMPONENT_EFFECT_H_
|
||||
93
Engine/source/afx/ce/afxConsoleMessage.cpp
Normal file
93
Engine/source/afx/ce/afxConsoleMessage.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxConsoleMessage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxConsoleMessageData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxConsoleMessageData);
|
||||
|
||||
ConsoleDocClass( afxConsoleMessageData,
|
||||
"@brief A datablock that specifies a Console Message effect.\n\n"
|
||||
|
||||
"Console Message effects are useful for debugging purposes when you want to make sure that an effect with a certain kind "
|
||||
"of timing is actually getting executed and for evaluating some kinds of field substitutions."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxConsoleMessageData::afxConsoleMessageData()
|
||||
{
|
||||
message_str = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxConsoleMessageData::afxConsoleMessageData(const afxConsoleMessageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
message_str = other.message_str;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxConsoleMessageData)
|
||||
|
||||
void afxConsoleMessageData::initPersistFields()
|
||||
{
|
||||
addField("message", TypeString, myOffset(message_str),
|
||||
"A text message to be displayed when the effect is executed.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxConsoleMessageData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxConsoleMessageData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(message_str);
|
||||
}
|
||||
|
||||
void afxConsoleMessageData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
message_str = stream->readSTString();
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
54
Engine/source/afx/ce/afxConsoleMessage.h
Normal file
54
Engine/source/afx/ce/afxConsoleMessage.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_CONSOLE_MESSAGE_H_
|
||||
#define _AFX_CONSOLE_MESSAGE_H_
|
||||
|
||||
class afxConsoleMessageData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry message_str;
|
||||
|
||||
public:
|
||||
/*C*/ afxConsoleMessageData();
|
||||
/*C*/ afxConsoleMessageData(const afxConsoleMessageData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxConsoleMessageData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_CONSOLE_MESSAGE_H_
|
||||
140
Engine/source/afx/ce/afxDamage.cpp
Normal file
140
Engine/source/afx/ce/afxDamage.cpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxDamage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxDamageData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxDamageData);
|
||||
|
||||
ConsoleDocClass( afxDamageData,
|
||||
"@brief A datablock that specifies a Damage effect.\n\n"
|
||||
|
||||
"A Damage effect is useful for assigning damage with unusual timing that must be synchronized with other effects. They "
|
||||
"can be used to deal direct damage, radius damage, and damage over time. Negative damage amounts can be used for "
|
||||
"healing effects."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxDamageData::afxDamageData()
|
||||
{
|
||||
label = ST_NULLSTRING;
|
||||
flavor = ST_NULLSTRING;
|
||||
amount = 0;
|
||||
repeats = 1;
|
||||
ad_amount = 0;
|
||||
radius = 0;
|
||||
impulse = 0;
|
||||
}
|
||||
|
||||
afxDamageData::afxDamageData(const afxDamageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
label = other.label;
|
||||
flavor = other.flavor;
|
||||
amount = other.amount;
|
||||
repeats = other.repeats;
|
||||
ad_amount = other.ad_amount;
|
||||
radius = other.radius;
|
||||
impulse = other.impulse;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxDamageData)
|
||||
|
||||
void afxDamageData::initPersistFields()
|
||||
{
|
||||
addField("label", TypeString, myOffset(label),
|
||||
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
|
||||
"method. It can be used to identify which damage effect the damage came from in "
|
||||
"cases where more than one damage effect is used in a single spell.");
|
||||
addField("flavor", TypeString, myOffset(flavor),
|
||||
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
|
||||
"method. It is used to classify a type of damage such as 'melee', 'magical', or "
|
||||
"'fire'.");
|
||||
addField("directDamage", TypeF32, myOffset(amount),
|
||||
"An amount of direct damage to inflict on a target.");
|
||||
addField("directDamageRepeats", TypeS8, myOffset(repeats),
|
||||
"The number of times to inflict the damage specified by directDamage. Values "
|
||||
"greater than 1 inflict damage over time, with the amount of directDamage "
|
||||
"repeatedly dealt at evenly spaced intervals over the lifetime of the effect.");
|
||||
addField("areaDamage", TypeF32, myOffset(ad_amount),
|
||||
"An amount of area damage to inflict on a target. Objects within half the radius "
|
||||
"receive full damage which then diminishes out to the full distance of "
|
||||
"areaDamageRadius.");
|
||||
addField("areaDamageRadius", TypeF32, myOffset(radius),
|
||||
"Radius centered at the effect position in which damage will be applied.");
|
||||
addField("areaDamageImpulse", TypeF32, myOffset(impulse),
|
||||
"Specifies an amount of force to apply to damaged objects. Objects within half the "
|
||||
"radius receive full impulse which then diminishes out to the full distance of "
|
||||
"areaDamageRadius.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxDamageData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxDamageData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(label);
|
||||
stream->writeString(flavor);
|
||||
stream->write(amount);
|
||||
stream->write(repeats);
|
||||
stream->write(ad_amount);
|
||||
stream->write(radius);
|
||||
stream->write(impulse);
|
||||
}
|
||||
|
||||
void afxDamageData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
label = stream->readSTString();
|
||||
flavor = stream->readSTString();
|
||||
stream->read(&amount);
|
||||
stream->read(&repeats);
|
||||
stream->read(&ad_amount);
|
||||
stream->read(&radius);
|
||||
stream->read(&impulse);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
63
Engine/source/afx/ce/afxDamage.h
Normal file
63
Engine/source/afx/ce/afxDamage.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_DAMAGE_H_
|
||||
#define _AFX_DAMAGE_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class afxDamageData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry label;
|
||||
StringTableEntry flavor;
|
||||
|
||||
F32 amount;
|
||||
U8 repeats;
|
||||
F32 ad_amount;
|
||||
F32 radius;
|
||||
F32 impulse;
|
||||
|
||||
public:
|
||||
/*C*/ afxDamageData();
|
||||
/*C*/ afxDamageData(const afxDamageData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxDamageData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_DAMAGE_H_
|
||||
116
Engine/source/afx/ce/afxFootSwitch.cpp
Normal file
116
Engine/source/afx/ce/afxFootSwitch.cpp
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxFootSwitch.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxFootSwitchData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxFootSwitchData);
|
||||
|
||||
ConsoleDocClass( afxFootSwitchData,
|
||||
"@brief A datablock that specifies a Foot Switch effect.\n\n"
|
||||
|
||||
"A Foot Switch effect is used to disable some or all of the standard built-in footstep effects generated by Player objects."
|
||||
"\n\n"
|
||||
|
||||
"Stock Player objects generate footprint decals, footstep sounds, and puffs of particle dust in response to special "
|
||||
"animation triggers embedded in the Player's dts model. With the help of Phase Effects, AFX can substitute alternatives for "
|
||||
"these built-in effects. When this is done, it is often preferable to turn off some or all of the built-in footstep effects."
|
||||
"\n\n"
|
||||
|
||||
"Foot Switch effects are only meaningful when the primary position constraint is a Player or Player-derived object."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxFootSwitchData::afxFootSwitchData()
|
||||
{
|
||||
override_all = false;
|
||||
override_decals = false;
|
||||
override_sounds = false;
|
||||
override_dust = false;
|
||||
}
|
||||
|
||||
afxFootSwitchData::afxFootSwitchData(const afxFootSwitchData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
override_all = other.override_all;
|
||||
override_decals = other.override_decals;
|
||||
override_sounds = other.override_sounds;
|
||||
override_dust = other.override_dust;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxFootSwitchData)
|
||||
|
||||
void afxFootSwitchData::initPersistFields()
|
||||
{
|
||||
addField("overrideAll", TypeBool, myOffset(override_all),
|
||||
"When true, all of a Player's footstep effects are turned off for the duration of "
|
||||
"the foot-switch effect.");
|
||||
addField("overrideDecals", TypeBool, myOffset(override_decals),
|
||||
"Specifically selects whether the Player's footprint decals are enabled.");
|
||||
addField("overrideSounds", TypeBool, myOffset(override_sounds),
|
||||
"Specifically selects whether the Player's footstep sounds are enabled.");
|
||||
addField("overrideDust", TypeBool, myOffset(override_dust),
|
||||
"Specifically selects whether the Player's footstep puffs of dust are enabled.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxFootSwitchData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
if (!stream->writeFlag(override_all))
|
||||
{
|
||||
stream->writeFlag(override_decals);
|
||||
stream->writeFlag(override_sounds);
|
||||
stream->writeFlag(override_dust);
|
||||
}
|
||||
}
|
||||
|
||||
void afxFootSwitchData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
override_all = stream->readFlag();
|
||||
if (!override_all)
|
||||
{
|
||||
override_decals = stream->readFlag();
|
||||
override_sounds = stream->readFlag();
|
||||
override_dust = stream->readFlag();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
56
Engine/source/afx/ce/afxFootSwitch.h
Normal file
56
Engine/source/afx/ce/afxFootSwitch.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_FOOT_SWITCH_H_
|
||||
#define _AFX_FOOT_SWITCH_H_
|
||||
|
||||
class afxFootSwitchData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
bool override_all;
|
||||
bool override_decals;
|
||||
bool override_sounds;
|
||||
bool override_dust;
|
||||
|
||||
public:
|
||||
/*C*/ afxFootSwitchData();
|
||||
/*C*/ afxFootSwitchData(const afxFootSwitchData&, bool = false);
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxFootSwitchData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_FOOT_SWITCH_H_
|
||||
109
Engine/source/afx/ce/afxGuiController.cpp
Normal file
109
Engine/source/afx/ce/afxGuiController.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxGuiController.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxGuiControllerData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxGuiControllerData);
|
||||
|
||||
ConsoleDocClass( afxGuiControllerData,
|
||||
"@brief A datablock that specifies a Gui Controller effect.\n\n"
|
||||
|
||||
"A Gui Controller enables effect manipulation of pre-existing gui controls. With a Gui Controller effect, a regular gui control "
|
||||
"is located by name, made visible during the lifetime of the effect, and potentially repositioned by projecting 3D constraint "
|
||||
"positions into 2D screen space. In addition, when used with a progress-bar control, (GuiProgressCtrl, afxSpellCastBar, "
|
||||
"afxStatusBar), the progress-bar will continuously reflect the elapsed progress of the effect over its lifetime."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxGuiControllerData::afxGuiControllerData()
|
||||
{
|
||||
control_name = ST_NULLSTRING;
|
||||
preserve_pos = false;
|
||||
ctrl_client_only = false;
|
||||
}
|
||||
|
||||
afxGuiControllerData::afxGuiControllerData(const afxGuiControllerData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
control_name = other.control_name;
|
||||
preserve_pos = other.preserve_pos;
|
||||
ctrl_client_only = other.ctrl_client_only;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxGuiControllerData)
|
||||
|
||||
void afxGuiControllerData::initPersistFields()
|
||||
{
|
||||
addField("controlName", TypeString, myOffset(control_name),
|
||||
"Specifies the name of an existing gui-control.");
|
||||
addField("preservePosition", TypeBool, myOffset(preserve_pos),
|
||||
"When true, the gui-control will retain its initial position, otherwise the "
|
||||
"gui-control position will be continuously updated using a projection of the "
|
||||
"3D constraint position into 2D screen coordinates.");
|
||||
addField("controllingClientOnly", TypeBool, myOffset(ctrl_client_only),
|
||||
"If true, the effect will only be applied to a gui-control on the client that "
|
||||
"matches the controlling-client of the primary position constraint object.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxGuiControllerData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxGuiControllerData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(control_name);
|
||||
stream->writeFlag(preserve_pos);
|
||||
stream->writeFlag(ctrl_client_only);
|
||||
}
|
||||
|
||||
void afxGuiControllerData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
control_name = stream->readSTString();
|
||||
preserve_pos = stream->readFlag();
|
||||
ctrl_client_only = stream->readFlag();
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
58
Engine/source/afx/ce/afxGuiController.h
Normal file
58
Engine/source/afx/ce/afxGuiController.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_GUI_CONTROLLER_H_
|
||||
#define _AFX_GUI_CONTROLLER_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class afxGuiControllerData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry control_name;
|
||||
bool preserve_pos;
|
||||
bool ctrl_client_only;
|
||||
|
||||
public:
|
||||
/*C*/ afxGuiControllerData();
|
||||
/*C*/ afxGuiControllerData(const afxGuiControllerData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxGuiControllerData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_GUI_CONTROLLER_H_
|
||||
103
Engine/source/afx/ce/afxGuiText.cpp
Normal file
103
Engine/source/afx/ce/afxGuiText.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxGuiText.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxGuiTextData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxGuiTextData);
|
||||
|
||||
ConsoleDocClass( afxGuiTextData,
|
||||
"@brief A datablock that specifies a Gui Text effect.\n\n"
|
||||
|
||||
"A Gui Text effect, with the help of an existing afxGuiTextHud, can be used to display 2D text effects on the Gui Canvas. "
|
||||
"Essentially, using Gui Text effects with an afxGuiTextHud is like using the stock GuiShapeNameHud, but with the ability "
|
||||
"to make additional text elements come and go as effects constrained to the projection of 3D positions onto the 2D screen."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxGuiTextData::afxGuiTextData()
|
||||
{
|
||||
text_str = ST_NULLSTRING;
|
||||
text_clr.set(1,1,1,1);
|
||||
}
|
||||
|
||||
afxGuiTextData::afxGuiTextData(const afxGuiTextData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
text_str = other.text_str;
|
||||
text_clr = other.text_clr;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxGuiTextData)
|
||||
|
||||
void afxGuiTextData::initPersistFields()
|
||||
{
|
||||
addField("text", TypeString, myOffset(text_str),
|
||||
"The literal text to display on the afxGuiTextHud. The center of the text will be "
|
||||
"placed at the projection of the 3D constraint position into 2D screen space.\n"
|
||||
"If the text field is set to the special string, '#shapeName', the shape name of the "
|
||||
"primary position constraint object will be used. (This is only meaningful if the "
|
||||
"constraint source is a ShapeBase-derived object.)");
|
||||
addField("color", TypeColorF, myOffset(text_clr),
|
||||
"A color value for the text label.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxGuiTextData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxGuiTextData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(text_str);
|
||||
stream->write(text_clr);
|
||||
}
|
||||
|
||||
void afxGuiTextData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
text_str = stream->readSTString();
|
||||
stream->read(&text_clr);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
57
Engine/source/afx/ce/afxGuiText.h
Normal file
57
Engine/source/afx/ce/afxGuiText.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_GUI_TEXT_H_
|
||||
#define _AFX_GUI_TEXT_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class afxGuiTextData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry text_str;
|
||||
LinearColorF text_clr;
|
||||
|
||||
public:
|
||||
/*C*/ afxGuiTextData();
|
||||
/*C*/ afxGuiTextData(const afxGuiTextData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxGuiTextData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_GUI_TEXT_H_
|
||||
41
Engine/source/afx/ce/afxLight.cpp
Normal file
41
Engine/source/afx/ce/afxLight.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/ce/afxLight.h"
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxLightData);
|
||||
|
||||
ConsoleDocClass( afxLightData,
|
||||
"@brief afxLightData is a legacy datablock which is not supported for T3D.\n\n"
|
||||
|
||||
"In T3D, instead of afxLightData, use afxT3DPointLightData or afxT3DSpotLightData.\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
38
Engine/source/afx/ce/afxLight.h
Normal file
38
Engine/source/afx/ce/afxLight.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_LIGHT_H_
|
||||
#define _AFX_LIGHT_H_
|
||||
|
||||
struct afxLightData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
DECLARE_CONOBJECT(afxLightData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_LIGHT_H_
|
||||
243
Engine/source/afx/ce/afxLightBase_T3D.cpp
Normal file
243
Engine/source/afx/ce/afxLightBase_T3D.cpp
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "T3D/lightAnimData.h"
|
||||
|
||||
#include "afx/ce/afxLightBase_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxT3DLightBaseData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxT3DLightBaseData);
|
||||
|
||||
ConsoleDocClass( afxT3DLightBaseData,
|
||||
"@brief A datablock baseclass for afxT3DPointLightData and afxT3DSpotLightData.\n\n"
|
||||
|
||||
"Not intended to be used directly, afxT3DLightBaseData exists to provide base member variables and generic functionality "
|
||||
"for the derived classes afxT3DPointLightData and afxT3DSpotLightData."
|
||||
"\n\n"
|
||||
|
||||
"@see afxT3DPointLightData\n\n"
|
||||
"@see afxT3DSpotLightData\n\n"
|
||||
"@see PointLight\n\n"
|
||||
"@see SpotLight\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxT3DLightBaseData::afxT3DLightBaseData()
|
||||
: mIsEnabled( true ),
|
||||
mColor( LinearColorF::WHITE ),
|
||||
mBrightness( 1.0f ),
|
||||
mCastShadows( false ),
|
||||
mPriority( 1.0f ),
|
||||
mAnimationData( NULL ),
|
||||
mFlareData( NULL ),
|
||||
mFlareScale( 1.0f )
|
||||
{
|
||||
|
||||
mLocalRenderViz = false;
|
||||
|
||||
// marked true if datablock ids need to
|
||||
// be converted into pointers
|
||||
do_id_convert = false;
|
||||
}
|
||||
|
||||
afxT3DLightBaseData::afxT3DLightBaseData(const afxT3DLightBaseData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
mIsEnabled = other.mIsEnabled;
|
||||
mColor = other.mColor;
|
||||
mBrightness = other.mBrightness;
|
||||
mCastShadows = other.mCastShadows;
|
||||
mPriority = other.mPriority;
|
||||
mAnimationData = other.mAnimationData;
|
||||
mAnimState = other.mAnimState;
|
||||
mFlareData = other.mFlareData;
|
||||
mFlareScale = other.mFlareScale;
|
||||
|
||||
mLocalRenderViz = other.mLocalRenderViz;
|
||||
|
||||
do_id_convert = other.do_id_convert;
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: keep this as consistent as possible with LightBase::initPersistFields()
|
||||
//
|
||||
void afxT3DLightBaseData::initPersistFields()
|
||||
{
|
||||
// We only add the basic lighting options that all lighting
|
||||
// systems would use... the specific lighting system options
|
||||
// are injected at runtime by the lighting system itself.
|
||||
|
||||
addGroup( "Light" );
|
||||
|
||||
addField( "isEnabled", TypeBool, Offset( mIsEnabled, afxT3DLightBaseData ),
|
||||
"Enables/Disables the object rendering and functionality in the scene.");
|
||||
addField( "color", TypeColorF, Offset( mColor, afxT3DLightBaseData ),
|
||||
"Changes the base color hue of the light.");
|
||||
addField( "brightness", TypeF32, Offset( mBrightness, afxT3DLightBaseData ),
|
||||
"Adjusts the lights power, 0 being off completely.");
|
||||
addField( "castShadows", TypeBool, Offset( mCastShadows, afxT3DLightBaseData ),
|
||||
"Enables/disables shadow casts by this light.");
|
||||
addField( "priority", TypeF32, Offset( mPriority, afxT3DLightBaseData ),
|
||||
"Used for sorting of lights by the light manager. Priority determines if a light "
|
||||
"has a stronger effect than, those with a lower value");
|
||||
addField( "localRenderViz", TypeBool, Offset( mLocalRenderViz, afxT3DLightBaseData ),
|
||||
"Enables/disables a semi-transparent geometry to help visualize the light's "
|
||||
"range and placement.");
|
||||
|
||||
endGroup( "Light" );
|
||||
|
||||
addGroup( "Light Animation" );
|
||||
|
||||
addField( "animate", TypeBool, Offset( mAnimState.active, afxT3DLightBaseData ),
|
||||
"Toggles animation for the light on and off");
|
||||
addField( "animationType", TYPEID<LightAnimData>(), Offset( mAnimationData, afxT3DLightBaseData ),
|
||||
"Datablock containing light animation information (LightAnimData)");
|
||||
addField( "animationPeriod", TypeF32, Offset( mAnimState.animationPeriod, afxT3DLightBaseData ),
|
||||
"The length of time in seconds for a single playback of the light animation");
|
||||
addField( "animationPhase", TypeF32, Offset( mAnimState.animationPhase, afxT3DLightBaseData ),
|
||||
"The phase used to offset the animation start time to vary the animation of "
|
||||
"nearby lights.");
|
||||
|
||||
endGroup( "Light Animation" );
|
||||
|
||||
addGroup( "Misc" );
|
||||
|
||||
addField( "flareType", TYPEID<LightFlareData>(), Offset( mFlareData, afxT3DLightBaseData ),
|
||||
"Datablock containing light flare information (LightFlareData)");
|
||||
addField( "flareScale", TypeF32, Offset( mFlareScale, afxT3DLightBaseData ),
|
||||
"Globally scales all features of the light flare");
|
||||
|
||||
endGroup( "Misc" );
|
||||
|
||||
/*
|
||||
// Now inject any light manager specific fields.
|
||||
LightManager::initLightFields();
|
||||
*/
|
||||
|
||||
// We do the parent fields at the end so that
|
||||
// they show up that way in the inspector.
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxT3DLightBaseData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxT3DLightBaseData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
// note: BitStream's overloaded write() for LinearColorF will convert
|
||||
// to ColorI for transfer and then back to LinearColorF. This is fine
|
||||
// for most color usage but for lighting colors we want to preserve
|
||||
// "pushed" color values which may be greater than 1.0 so the color
|
||||
// is instead sent as individual color primaries.
|
||||
stream->write( mColor.red );
|
||||
stream->write( mColor.green );
|
||||
stream->write( mColor.blue );
|
||||
|
||||
stream->write( mBrightness );
|
||||
stream->writeFlag( mCastShadows );
|
||||
stream->write( mAnimState.animationPeriod );
|
||||
stream->write( mAnimState.animationPhase );
|
||||
stream->write( mFlareScale );
|
||||
|
||||
writeDatablockID(stream, mAnimationData, packed);
|
||||
writeDatablockID(stream, mFlareData, packed);
|
||||
}
|
||||
|
||||
void afxT3DLightBaseData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read( &mColor.red );
|
||||
stream->read( &mColor.green );
|
||||
stream->read( &mColor.blue );
|
||||
mColor.alpha = 1.0f;
|
||||
|
||||
stream->read( &mBrightness );
|
||||
mCastShadows = stream->readFlag();
|
||||
stream->read( &mAnimState.animationPeriod );
|
||||
stream->read( &mAnimState.animationPhase );
|
||||
stream->read( &mFlareScale );
|
||||
|
||||
mAnimationData = (LightAnimData*) readDatablockID(stream);
|
||||
mFlareData = (LightFlareData*) readDatablockID(stream);
|
||||
|
||||
do_id_convert = true;
|
||||
}
|
||||
|
||||
bool afxT3DLightBaseData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server)
|
||||
{
|
||||
if (do_id_convert)
|
||||
{
|
||||
SimObjectId anim_id = SimObjectId((uintptr_t)mAnimationData);
|
||||
if (anim_id != 0)
|
||||
{
|
||||
// try to convert id to pointer
|
||||
if (!Sim::findObject(anim_id, mAnimationData))
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"afxT3DLightBaseData::preload() -- bad datablockId: 0x%x (animationType)",
|
||||
anim_id);
|
||||
}
|
||||
}
|
||||
SimObjectId flare_id = SimObjectId((uintptr_t)mFlareData);
|
||||
if (flare_id != 0)
|
||||
{
|
||||
// try to convert id to pointer
|
||||
if (!Sim::findObject(flare_id, mFlareData))
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"afxT3DLightBaseData::preload() -- bad datablockId: 0x%x (flareType)",
|
||||
flare_id);
|
||||
}
|
||||
}
|
||||
do_id_convert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
73
Engine/source/afx/ce/afxLightBase_T3D.h
Normal file
73
Engine/source/afx/ce/afxLightBase_T3D.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_T3D_LIGHT_BASE_H_
|
||||
#define _AFX_T3D_LIGHT_BASE_H_
|
||||
|
||||
#include "T3D/lightBase.h"
|
||||
|
||||
class LightAnimData;
|
||||
class LightFlareData;
|
||||
|
||||
class afxT3DLightBaseData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
bool mIsEnabled;
|
||||
LinearColorF mColor;
|
||||
F32 mBrightness;
|
||||
bool mCastShadows;
|
||||
F32 mPriority;
|
||||
|
||||
LightAnimData* mAnimationData;
|
||||
LightAnimState mAnimState;
|
||||
|
||||
bool mLocalRenderViz;
|
||||
|
||||
LightFlareData* mFlareData;
|
||||
F32 mFlareScale;
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
/*C*/ afxT3DLightBaseData();
|
||||
/*C*/ afxT3DLightBaseData(const afxT3DLightBaseData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxT3DLightBaseData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_T3D_LIGHT_BASE_H_
|
||||
127
Engine/source/afx/ce/afxMachineGun.cpp
Normal file
127
Engine/source/afx/ce/afxMachineGun.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "lighting/lightInfo.h"
|
||||
#include "T3D/projectile.h"
|
||||
|
||||
#include "afx/ce/afxMachineGun.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMachineGunData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxMachineGunData);
|
||||
|
||||
ConsoleDocClass( afxMachineGunData,
|
||||
"@brief A datablock that specifies a Machine Gun effect.\n\n"
|
||||
|
||||
"Machine Gun is a simple but useful effect for rapidly shooting standard Torque Projectile objects. For performance "
|
||||
"reasons, keep in mind that each bullet is a separate Projectile object, which is not a very lightweight object."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxMachineGunData::afxMachineGunData()
|
||||
{
|
||||
projectile_data = 0;
|
||||
rounds_per_minute = 60;
|
||||
}
|
||||
|
||||
afxMachineGunData::afxMachineGunData(const afxMachineGunData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
projectile_data = other.projectile_data;
|
||||
rounds_per_minute = other.rounds_per_minute;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxMachineGunData)
|
||||
|
||||
void afxMachineGunData::initPersistFields()
|
||||
{
|
||||
addField("projectile", TYPEID<ProjectileData>(), myOffset(projectile_data),
|
||||
"A ProjectileData datablock describing the projectile to be launched.");
|
||||
addField("roundsPerMinute", TypeS32, myOffset(rounds_per_minute),
|
||||
"Specifies the number of projectiles fired over a minute of time. A value of 1200 "
|
||||
"will create 20 projectiles per second.\n"
|
||||
"Sample values for real machine guns:\n"
|
||||
" AK-47 = 600, M16 = 750-900, UZI = 600");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// disallow some field substitutions
|
||||
disableFieldSubstitutions("projectile");
|
||||
}
|
||||
|
||||
bool afxMachineGunData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
if (projectile_data)
|
||||
{
|
||||
if (getId() >= DataBlockObjectIdFirst && getId() <= DataBlockObjectIdLast)
|
||||
{
|
||||
SimObjectId pid = projectile_data->getId();
|
||||
if (pid < DataBlockObjectIdFirst || pid > DataBlockObjectIdLast)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,"afxMachineGunData: bad ProjectileData datablock.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxMachineGunData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
if (stream->writeFlag(projectile_data))
|
||||
stream->writeRangedU32(projectile_data->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
|
||||
stream->write(rounds_per_minute);
|
||||
}
|
||||
|
||||
void afxMachineGunData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
Sim::findObject(id, projectile_data);
|
||||
}
|
||||
|
||||
stream->read(&rounds_per_minute);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
59
Engine/source/afx/ce/afxMachineGun.h
Normal file
59
Engine/source/afx/ce/afxMachineGun.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_MACHINE_GUN_H_
|
||||
#define _AFX_MACHINE_GUN_H_
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class ProjectileData;
|
||||
|
||||
class afxMachineGunData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
ProjectileData* projectile_data;
|
||||
S32 rounds_per_minute;
|
||||
|
||||
public:
|
||||
/*C*/ afxMachineGunData();
|
||||
/*C*/ afxMachineGunData(const afxMachineGunData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxMachineGunData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MACHINE_GUN_H_
|
||||
770
Engine/source/afx/ce/afxModel.cpp
Normal file
770
Engine/source/afx/ce/afxModel.cpp
Normal file
|
|
@ -0,0 +1,770 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/objectTypes.h"
|
||||
#include "T3D/gameBase/gameProcess.h"
|
||||
#include "core/resourceManager.h"
|
||||
#include "sim/netConnection.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "scene/sceneManager.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "ts/tsMaterialList.h"
|
||||
|
||||
#include "afx/ce/afxModel.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxModelData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxModelData);
|
||||
|
||||
ConsoleDocClass( afxModelData,
|
||||
"@brief A datablock that specifies a Model effect.\n\n"
|
||||
|
||||
"A Model effect is a lightweight client-only geometry object useful for effect-driven props."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxModelData::afxModelData()
|
||||
{
|
||||
shapeName = ST_NULLSTRING;
|
||||
sequence = ST_NULLSTRING;
|
||||
seq_rate = 1.0f;
|
||||
seq_offset = 0.0f;
|
||||
alpha_mult = 1.0f;
|
||||
use_vertex_alpha = false;
|
||||
force_on_material_flags = 0;
|
||||
force_off_material_flags = 0;
|
||||
texture_filtering = true;
|
||||
fog_mult = 1.0f;
|
||||
remap_txr_tags = ST_NULLSTRING;
|
||||
remap_buffer = 0;
|
||||
|
||||
overrideLightingOptions = false;
|
||||
receiveSunLight = true;
|
||||
receiveLMLighting = true;
|
||||
useAdaptiveSelfIllumination = false;
|
||||
useCustomAmbientLighting = false;
|
||||
customAmbientForSelfIllumination = false;
|
||||
customAmbientLighting = LinearColorF(0.0f, 0.0f, 0.0f);
|
||||
shadowEnable = false;
|
||||
|
||||
shadowSize = 128;
|
||||
shadowMaxVisibleDistance = 80.0f;
|
||||
shadowProjectionDistance = 10.0f;
|
||||
shadowSphereAdjust = 1.0;
|
||||
}
|
||||
|
||||
afxModelData::afxModelData(const afxModelData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
shapeName = other.shapeName;
|
||||
shape = other.shape; // --
|
||||
sequence = other.sequence;
|
||||
seq_rate = other.seq_rate;
|
||||
seq_offset = other.seq_offset;
|
||||
alpha_mult = other.alpha_mult;
|
||||
use_vertex_alpha = other.use_vertex_alpha;
|
||||
force_on_material_flags = other.force_on_material_flags;
|
||||
force_off_material_flags = other.force_off_material_flags;
|
||||
texture_filtering = other.texture_filtering;
|
||||
fog_mult = other.fog_mult;
|
||||
remap_txr_tags = other.remap_txr_tags;
|
||||
remap_buffer = other.remap_buffer;
|
||||
overrideLightingOptions = other.overrideLightingOptions;
|
||||
receiveSunLight = other.receiveSunLight;
|
||||
receiveLMLighting = other.receiveLMLighting;
|
||||
useAdaptiveSelfIllumination = other.useAdaptiveSelfIllumination;
|
||||
useCustomAmbientLighting = other.useCustomAmbientLighting;
|
||||
customAmbientForSelfIllumination = other.customAmbientForSelfIllumination;
|
||||
customAmbientLighting = other.customAmbientLighting;
|
||||
shadowEnable = other.shadowEnable;
|
||||
}
|
||||
|
||||
afxModelData::~afxModelData()
|
||||
{
|
||||
if (remap_buffer)
|
||||
dFree(remap_buffer);
|
||||
}
|
||||
|
||||
bool afxModelData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (Parent::preload(server, errorStr) == false)
|
||||
return false;
|
||||
|
||||
// don't need to do this stuff on the server
|
||||
if (server)
|
||||
return true;
|
||||
|
||||
if (shapeName != ST_NULLSTRING && !shape)
|
||||
{
|
||||
shape = ResourceManager::get().load(shapeName);
|
||||
if (!shape)
|
||||
{
|
||||
errorStr = String::ToString("afxModelData::load: Failed to load shape \"%s\"", shapeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// just parse up the string and collect the remappings in txr_tag_remappings.
|
||||
if (remap_txr_tags != ST_NULLSTRING)
|
||||
{
|
||||
txr_tag_remappings.clear();
|
||||
if (remap_buffer)
|
||||
dFree(remap_buffer);
|
||||
|
||||
remap_buffer = dStrdup(remap_txr_tags);
|
||||
|
||||
char* remap_token = dStrtok(remap_buffer, " \t");
|
||||
while (remap_token != NULL)
|
||||
{
|
||||
char* colon = dStrchr(remap_token, ':');
|
||||
if (colon)
|
||||
{
|
||||
*colon = '\0';
|
||||
txr_tag_remappings.increment();
|
||||
txr_tag_remappings.last().old_tag = remap_token;
|
||||
txr_tag_remappings.last().new_tag = colon+1;
|
||||
}
|
||||
remap_token = dStrtok(NULL, " \t");
|
||||
}
|
||||
}
|
||||
|
||||
// this little hack messes things up when remapping texture tags
|
||||
if (txr_tag_remappings.size() == 0)
|
||||
{
|
||||
// this little hack forces the textures to preload
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(shape);
|
||||
delete pDummy;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxModelData)
|
||||
|
||||
void afxModelData::initPersistFields()
|
||||
{
|
||||
addField("shapeFile", TypeFilename, myOffset(shapeName),
|
||||
"The name of a .dts format file to use for the model.");
|
||||
addField("sequence", TypeFilename, myOffset(sequence),
|
||||
"The name of an animation sequence to play in the model.");
|
||||
addField("sequenceRate", TypeF32, myOffset(seq_rate),
|
||||
"The rate of playback for the sequence.");
|
||||
addField("sequenceOffset", TypeF32, myOffset(seq_offset),
|
||||
"An offset in seconds indicating a starting point for the animation sequence "
|
||||
"specified by the sequence field. A rate of 1.0 (rather than sequenceRate) is used "
|
||||
"to convert from seconds to the thread offset.");
|
||||
addField("alphaMult", TypeF32, myOffset(alpha_mult),
|
||||
"An alpha multiplier used to set maximum opacity of the model.");
|
||||
|
||||
addField("fogMult", TypeF32, myOffset(fog_mult),
|
||||
"");
|
||||
addField("remapTextureTags", TypeString, myOffset(remap_txr_tags),
|
||||
"Rename one or more texture tags in the model. Texture tags are what link a "
|
||||
"model's textures to materials.\n"
|
||||
"Field should be a string containing space-separated remapping tokens. A remapping "
|
||||
"token is two names separated by a colon, ':'. The first name should be a texture-tag "
|
||||
"that exists in the model, while the second is a new name to replace it. The string "
|
||||
"can have any number of remapping tokens as long as the total string length does not "
|
||||
"exceed 255.");
|
||||
addField("shadowEnable", TypeBool, myOffset(shadowEnable),
|
||||
"Sets whether the model casts a shadow.");
|
||||
|
||||
addField("useVertexAlpha", TypeBool, myOffset(use_vertex_alpha),
|
||||
"deprecated");
|
||||
addField("forceOnMaterialFlags", TypeS32, myOffset(force_on_material_flags),
|
||||
"deprecated");
|
||||
addField("forceOffMaterialFlags", TypeS32, myOffset(force_off_material_flags),
|
||||
"deprecated");
|
||||
addField("textureFiltering", TypeBool, myOffset(texture_filtering),
|
||||
"deprecated");
|
||||
addField("overrideLightingOptions", TypeBool, myOffset(overrideLightingOptions),
|
||||
"deprecated");
|
||||
addField("receiveSunLight", TypeBool, myOffset(receiveSunLight),
|
||||
"");
|
||||
addField("receiveLMLighting", TypeBool, myOffset(receiveLMLighting),
|
||||
"deprecated");
|
||||
addField("useAdaptiveSelfIllumination", TypeBool, myOffset(useAdaptiveSelfIllumination),
|
||||
"deprecated");
|
||||
addField("useCustomAmbientLighting", TypeBool, myOffset(useCustomAmbientLighting),
|
||||
"deprecated");
|
||||
addField("customAmbientSelfIllumination", TypeBool, myOffset(customAmbientForSelfIllumination),
|
||||
"deprecated");
|
||||
addField("customAmbientLighting", TypeColorF, myOffset(customAmbientLighting),
|
||||
"deprecated");
|
||||
addField("shadowSize", TypeS32, myOffset(shadowSize),
|
||||
"deprecated");
|
||||
addField("shadowMaxVisibleDistance", TypeF32, myOffset(shadowMaxVisibleDistance),
|
||||
"deprecated");
|
||||
addField("shadowProjectionDistance", TypeF32, myOffset(shadowProjectionDistance),
|
||||
"deprecated");
|
||||
addField("shadowSphereAdjust", TypeF32, myOffset(shadowSphereAdjust),
|
||||
"deprecated");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// Material Flags
|
||||
Con::setIntVariable("$MaterialFlags::S_Wrap", TSMaterialList::S_Wrap);
|
||||
Con::setIntVariable("$MaterialFlags::T_Wrap", TSMaterialList::T_Wrap);
|
||||
Con::setIntVariable("$MaterialFlags::Translucent", TSMaterialList::Translucent);
|
||||
Con::setIntVariable("$MaterialFlags::Additive", TSMaterialList::Additive);
|
||||
Con::setIntVariable("$MaterialFlags::Subtractive", TSMaterialList::Subtractive);
|
||||
Con::setIntVariable("$MaterialFlags::SelfIlluminating", TSMaterialList::SelfIlluminating);
|
||||
Con::setIntVariable("$MaterialFlags::NeverEnvMap", TSMaterialList::NeverEnvMap);
|
||||
Con::setIntVariable("$MaterialFlags::NoMipMap", TSMaterialList::NoMipMap);
|
||||
Con::setIntVariable("$MaterialFlags::MipMap_ZeroBorder", TSMaterialList::MipMap_ZeroBorder);
|
||||
Con::setIntVariable("$MaterialFlags::AuxiliaryMap", TSMaterialList::AuxiliaryMap);
|
||||
|
||||
#if defined(AFX_CAP_AFXMODEL_TYPE)
|
||||
Con::setIntVariable("$TypeMasks::afxModelObjectType", afxModelObjectType);
|
||||
#endif
|
||||
}
|
||||
|
||||
void afxModelData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(shapeName);
|
||||
stream->writeString(sequence);
|
||||
stream->write(seq_rate);
|
||||
stream->write(seq_offset);
|
||||
stream->write(alpha_mult);
|
||||
stream->write(use_vertex_alpha);
|
||||
stream->write(force_on_material_flags);
|
||||
stream->write(force_off_material_flags);
|
||||
stream->writeFlag(texture_filtering);
|
||||
stream->write(fog_mult);
|
||||
|
||||
stream->writeString(remap_txr_tags);
|
||||
|
||||
stream->writeFlag(overrideLightingOptions);
|
||||
stream->writeFlag(receiveSunLight);
|
||||
stream->writeFlag(useAdaptiveSelfIllumination);
|
||||
stream->writeFlag(useCustomAmbientLighting);
|
||||
stream->writeFlag(customAmbientForSelfIllumination);
|
||||
stream->write(customAmbientLighting);
|
||||
stream->writeFlag(receiveLMLighting);
|
||||
stream->writeFlag(shadowEnable);
|
||||
|
||||
stream->write(shadowSize);
|
||||
stream->write(shadowMaxVisibleDistance);
|
||||
stream->write(shadowProjectionDistance);
|
||||
stream->write(shadowSphereAdjust);
|
||||
}
|
||||
|
||||
void afxModelData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
shapeName = stream->readSTString();
|
||||
sequence = stream->readSTString();
|
||||
stream->read(&seq_rate);
|
||||
stream->read(&seq_offset);
|
||||
stream->read(&alpha_mult);
|
||||
stream->read(&use_vertex_alpha);
|
||||
stream->read(&force_on_material_flags);
|
||||
stream->read(&force_off_material_flags);
|
||||
texture_filtering = stream->readFlag();
|
||||
stream->read(&fog_mult);
|
||||
|
||||
remap_txr_tags = stream->readSTString();
|
||||
|
||||
overrideLightingOptions = stream->readFlag();
|
||||
receiveSunLight = stream->readFlag();
|
||||
useAdaptiveSelfIllumination = stream->readFlag();
|
||||
useCustomAmbientLighting = stream->readFlag();
|
||||
customAmbientForSelfIllumination = stream->readFlag();
|
||||
stream->read(&customAmbientLighting);
|
||||
receiveLMLighting = stream->readFlag();
|
||||
shadowEnable = stream->readFlag();
|
||||
|
||||
stream->read(&shadowSize);
|
||||
stream->read(&shadowMaxVisibleDistance);
|
||||
stream->read(&shadowProjectionDistance);
|
||||
stream->read(&shadowSphereAdjust);
|
||||
}
|
||||
|
||||
void afxModelData::onPerformSubstitutions()
|
||||
{
|
||||
if (shapeName != ST_NULLSTRING)
|
||||
{
|
||||
shape = ResourceManager::get().load(shapeName);
|
||||
if (!shape)
|
||||
{
|
||||
Con::errorf("afxModelData::onPerformSubstitutions: Failed to load shape \"%s\"", shapeName);
|
||||
return;
|
||||
}
|
||||
|
||||
// REMAP-TEXTURE-TAGS ISSUES?
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxModel
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxModel);
|
||||
|
||||
ConsoleDocClass( afxModel,
|
||||
"@brief A Model effect as defined by an afxModelData datablock.\n\n"
|
||||
|
||||
"A Model effect is a lightweight client-only geometry object useful for effect-driven "
|
||||
"props.\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxModel::afxModel()
|
||||
{
|
||||
mTypeMask |= DynamicShapeObjectType;
|
||||
#if defined(AFX_CAP_AFXMODEL_TYPE)
|
||||
mTypeMask |= afxModelObjectType;
|
||||
#endif
|
||||
|
||||
shape_inst = 0;
|
||||
|
||||
main_seq_thread = 0;
|
||||
main_seq_id = -1;
|
||||
seq_rate_factor = 1.0f;
|
||||
last_anim_tag = 0;
|
||||
|
||||
seq_animates_vis = false;
|
||||
fade_amt = 1.0f;
|
||||
is_visible = true;
|
||||
sort_priority = 0;
|
||||
|
||||
mNetFlags.set( IsGhost );
|
||||
}
|
||||
|
||||
afxModel::~afxModel()
|
||||
{
|
||||
delete shape_inst;
|
||||
}
|
||||
|
||||
void afxModel::setSequenceRateFactor(F32 factor)
|
||||
{
|
||||
seq_rate_factor = factor;
|
||||
if (shape_inst != NULL && main_seq_thread != NULL)
|
||||
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxModel::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<afxModelData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxModel::onAdd()
|
||||
{
|
||||
// first check if we have a server connection, if we don't then this is on the server
|
||||
// and we should exit, then check if the parent fails to add the object
|
||||
NetConnection* conn = NetConnection::getConnectionToServer();
|
||||
if (!conn || !Parent::onAdd())
|
||||
return false;
|
||||
|
||||
// setup our bounding box
|
||||
if (mDataBlock->shape)
|
||||
mObjBox = mDataBlock->shape->bounds;
|
||||
else
|
||||
mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
|
||||
|
||||
// setup the shape instance and sequence
|
||||
if (mDataBlock->shape)
|
||||
{
|
||||
if (/*isClientObject() && */mDataBlock->txr_tag_remappings.size() > 0)
|
||||
{
|
||||
// temporarily substitute material tags with alternates
|
||||
TSMaterialList* mat_list = mDataBlock->shape->materialList;
|
||||
if (mat_list)
|
||||
{
|
||||
for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++)
|
||||
{
|
||||
afxModelData::TextureTagRemapping* remap = &mDataBlock->txr_tag_remappings[i];
|
||||
Vector<String> & mat_names = (Vector<String>&) mat_list->getMaterialNameList();
|
||||
for (S32 j = 0; j < mat_names.size(); j++)
|
||||
{
|
||||
if (mat_names[j].compare(remap->old_tag, dStrlen(remap->old_tag), String::NoCase) == 0)
|
||||
{
|
||||
//Con::printf("REMAP TEXTURE TAG [%s] TO [%s]", remap->old_tag, remap->new_tag);
|
||||
mat_names[j] = String(remap->new_tag);
|
||||
mat_names[j].insert(0,'#');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shape_inst = new TSShapeInstance(mDataBlock->shape);
|
||||
|
||||
if (true) // isClientObject())
|
||||
{
|
||||
shape_inst->cloneMaterialList();
|
||||
|
||||
// restore the material tags to original form
|
||||
if (mDataBlock->txr_tag_remappings.size() > 0)
|
||||
{
|
||||
TSMaterialList* mat_list = mDataBlock->shape->materialList;
|
||||
if (mat_list)
|
||||
{
|
||||
for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++)
|
||||
{
|
||||
afxModelData::TextureTagRemapping* remap = &mDataBlock->txr_tag_remappings[i];
|
||||
Vector<String> & mat_names = (Vector<String>&) mat_list->getMaterialNameList();
|
||||
for (S32 j = 0; j < mat_names.size(); j++)
|
||||
{
|
||||
if (mat_names[j].compare(remap->new_tag, dStrlen(remap->new_tag)) == 0)
|
||||
{
|
||||
//Con::printf("UNREMAP TEXTURE TAG [%s] TO [%s]", remap->new_tag, remap->old_tag);
|
||||
mat_names[j] = String(remap->old_tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mDataBlock->sequence == ST_NULLSTRING)
|
||||
{
|
||||
main_seq_thread = 0;
|
||||
main_seq_id = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// here we start the default animation sequence
|
||||
TSShape* shape = shape_inst->getShape();
|
||||
main_seq_id = shape->findSequence(mDataBlock->sequence);
|
||||
if (main_seq_id != -1)
|
||||
{
|
||||
main_seq_thread = shape_inst->addThread();
|
||||
|
||||
F32 seq_pos = 0.0f;
|
||||
if (mDataBlock->seq_offset > 0.0f && mDataBlock->seq_offset < shape_inst->getDuration(main_seq_thread))
|
||||
seq_pos = mDataBlock->seq_offset / shape_inst->getDuration(main_seq_thread);
|
||||
|
||||
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
|
||||
shape_inst->setSequence(main_seq_thread, main_seq_id, seq_pos);
|
||||
seq_animates_vis = shape->sequences[main_seq_id].visMatters.testAll();
|
||||
}
|
||||
}
|
||||
|
||||
// deal with material changes
|
||||
if (shape_inst && (mDataBlock->force_on_material_flags | mDataBlock->force_off_material_flags))
|
||||
{
|
||||
shape_inst->cloneMaterialList();
|
||||
TSMaterialList* mats = shape_inst->getMaterialList();
|
||||
if (mDataBlock->force_on_material_flags != 0)
|
||||
{
|
||||
for (U32 i = 0; i < mats->size(); i++)
|
||||
mats->setFlags(i, mats->getFlags(i) | mDataBlock->force_on_material_flags);
|
||||
}
|
||||
|
||||
if (mDataBlock->force_off_material_flags != 0)
|
||||
{
|
||||
for (U32 i = 0; i < mats->size(); i++)
|
||||
mats->setFlags(i, mats->getFlags(i) & ~mDataBlock->force_off_material_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetWorldBox();
|
||||
|
||||
if (mDataBlock->shape)
|
||||
{
|
||||
// Scan out the collision hulls...
|
||||
static const String sCollisionStr( "collision-" );
|
||||
|
||||
for (U32 i = 0; i < mDataBlock->shape->details.size(); i++)
|
||||
{
|
||||
const String &name = mDataBlock->shape->names[mDataBlock->shape->details[i].nameIndex];
|
||||
|
||||
if (name.compare( sCollisionStr, sCollisionStr.length(), String::NoCase ) == 0)
|
||||
{
|
||||
mCollisionDetails.push_back(i);
|
||||
|
||||
// The way LOS works is that it will check to see if there is a LOS detail that matches
|
||||
// the the collision detail + 1 + MaxCollisionShapes (this variable name should change in
|
||||
// the future). If it can't find a matching LOS it will simply use the collision instead.
|
||||
// We check for any "unmatched" LOS's further down
|
||||
mLOSDetails.increment();
|
||||
|
||||
char buff[128];
|
||||
dSprintf(buff, sizeof(buff), "LOS-%d", i + 1 + 8/*MaxCollisionShapes*/);
|
||||
U32 los = mDataBlock->shape->findDetail(buff);
|
||||
if (los == -1)
|
||||
mLOSDetails.last() = i;
|
||||
else
|
||||
mLOSDetails.last() = los;
|
||||
}
|
||||
}
|
||||
|
||||
// Snag any "unmatched" LOS details
|
||||
static const String sLOSStr( "LOS-" );
|
||||
|
||||
for (U32 i = 0; i < mDataBlock->shape->details.size(); i++)
|
||||
{
|
||||
const String &name = mDataBlock->shape->names[mDataBlock->shape->details[i].nameIndex];
|
||||
|
||||
if (name.compare( sLOSStr, sLOSStr.length(), String::NoCase ) == 0)
|
||||
{
|
||||
// See if we already have this LOS
|
||||
bool found = false;
|
||||
for (U32 j = 0; j < mLOSDetails.size(); j++)
|
||||
{
|
||||
if (mLOSDetails[j] == i)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
mLOSDetails.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the hull accelerators (actually, just force the shape to compute them)
|
||||
for (U32 i = 0; i < mCollisionDetails.size(); i++)
|
||||
shape_inst->getShape()->getAccelerator(mCollisionDetails[i]);
|
||||
}
|
||||
|
||||
// tell engine the model exists
|
||||
gClientSceneGraph->addObjectToScene(this);
|
||||
removeFromProcessList();
|
||||
ClientProcessList::get()->addObject(this);
|
||||
conn->addObject(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxModel::onRemove()
|
||||
{
|
||||
mSceneManager->removeObjectFromScene(this);
|
||||
getContainer()->removeObject(this);
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxModel::advanceTime(F32 dt)
|
||||
{
|
||||
if (main_seq_thread)
|
||||
shape_inst->advanceTime(dt, main_seq_thread);
|
||||
|
||||
for (S32 i = 0; i < blend_clips.size(); i++)
|
||||
shape_inst->advanceTime(dt, blend_clips[i].thread);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxModel::prepRenderImage(SceneRenderState* state)
|
||||
{
|
||||
if (!is_visible || !shape_inst)
|
||||
return;
|
||||
|
||||
// calculate distance to camera
|
||||
Point3F cameraOffset;
|
||||
getRenderTransform().getColumn(3, &cameraOffset);
|
||||
cameraOffset -= state->getCameraPosition();
|
||||
F32 dist = cameraOffset.len();
|
||||
if (dist < 0.01f)
|
||||
dist = 0.01f;
|
||||
|
||||
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));
|
||||
shape_inst->setDetailFromDistance(state, dist*invScale);
|
||||
if ( shape_inst->getCurrentDetail() < 0 )
|
||||
return;
|
||||
|
||||
renderObject(state);
|
||||
}
|
||||
|
||||
bool afxModel::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
|
||||
{
|
||||
if (shape_inst)
|
||||
{
|
||||
RayInfo shortest;
|
||||
shortest.t = 1e8;
|
||||
|
||||
info->object = NULL;
|
||||
if (mLOSDetails.size() > 0)
|
||||
{
|
||||
for (U32 i = 0; i < mLOSDetails.size(); i++)
|
||||
{
|
||||
shape_inst->animate(mLOSDetails[i]);
|
||||
if (shape_inst->castRay(start, end, info, mLOSDetails[i]))
|
||||
{
|
||||
info->object = this;
|
||||
if (info->t < shortest.t)
|
||||
shortest = *info;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mCollisionDetails.size() > 0)
|
||||
{
|
||||
for (U32 i = 0; i < mCollisionDetails.size(); i++)
|
||||
{
|
||||
shape_inst->animate(mCollisionDetails[i]);
|
||||
if (shape_inst->castRay(start, end, info, mCollisionDetails[i]))
|
||||
{
|
||||
info->object = this;
|
||||
if (info->t < shortest.t)
|
||||
shortest = *info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info->object == this)
|
||||
{
|
||||
// Copy out the shortest time...
|
||||
*info = shortest;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 afxModel::unique_anim_tag_counter = 1;
|
||||
#define BAD_ANIM_ID 999999999
|
||||
|
||||
U32 afxModel::setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans)
|
||||
{
|
||||
if (!shape_inst)
|
||||
return 0;
|
||||
|
||||
TSShape* shape = shape_inst->getShape();
|
||||
|
||||
S32 seq_id = shape->findSequence(clip);
|
||||
if (seq_id == -1)
|
||||
{
|
||||
Con::errorf("afxModel::setAnimClip() -- failed to find a sequence matching the name, \"%s\".", clip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// JTF Note: test if this blend implementation is working
|
||||
if (shape->sequences[seq_id].isBlend())
|
||||
{
|
||||
BlendThread blend_clip;
|
||||
blend_clip.tag = ((unique_anim_tag_counter++) | 0x80000000);
|
||||
|
||||
blend_clip.thread = shape_inst->addThread();
|
||||
shape_inst->setSequence(blend_clip.thread, seq_id, pos);
|
||||
shape_inst->setTimeScale(blend_clip.thread, rate);
|
||||
|
||||
blend_clips.push_back(blend_clip);
|
||||
|
||||
return blend_clip.tag;
|
||||
}
|
||||
|
||||
if (!main_seq_thread)
|
||||
{
|
||||
main_seq_thread = shape_inst->addThread();
|
||||
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*rate);
|
||||
shape_inst->setSequence(main_seq_thread, seq_id, pos);
|
||||
seq_animates_vis = shape->sequences[seq_id].visMatters.testAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*rate);
|
||||
|
||||
F32 transTime = (trans < 0) ? 0.25 : trans;
|
||||
if (transTime > 0.0f)
|
||||
shape_inst->transitionToSequence(main_seq_thread, seq_id, pos, transTime, true);
|
||||
else
|
||||
shape_inst->setSequence(main_seq_thread, seq_id, pos);
|
||||
|
||||
seq_animates_vis = shape->sequences[seq_id].visMatters.testAll();
|
||||
}
|
||||
|
||||
last_anim_tag = unique_anim_tag_counter++;
|
||||
|
||||
return last_anim_tag;
|
||||
}
|
||||
|
||||
void afxModel::resetAnimation(U32 tag)
|
||||
{
|
||||
// check if this is a blended clip
|
||||
if ((tag & 0x80000000) != 0)
|
||||
{
|
||||
for (S32 i = 0; i < blend_clips.size(); i++)
|
||||
{
|
||||
if (blend_clips[i].tag == tag)
|
||||
{
|
||||
if (blend_clips[i].thread)
|
||||
{
|
||||
//Con::printf("DESTROY THREAD %d of %d tag=%d" , i, blend_clips.size(), tag & 0x7fffffff);
|
||||
shape_inst->destroyThread(blend_clips[i].thread);
|
||||
}
|
||||
blend_clips.erase_fast(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag != 0 && tag == last_anim_tag)
|
||||
{
|
||||
// restore original non-animated state
|
||||
if (main_seq_id == -1)
|
||||
{
|
||||
shape_inst->destroyThread(main_seq_thread);
|
||||
main_seq_thread = 0;
|
||||
}
|
||||
// restore original sequence
|
||||
else
|
||||
{
|
||||
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
|
||||
shape_inst->transitionToSequence(main_seq_thread, main_seq_id , 0.0f, 0.25f, true);
|
||||
}
|
||||
last_anim_tag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
F32 afxModel::getAnimClipDuration(const char* clip)
|
||||
{
|
||||
if (!shape_inst)
|
||||
return 0.0f;
|
||||
|
||||
TSShape* shape = shape_inst->getShape();
|
||||
S32 seq_id = shape->findSequence(clip);
|
||||
return (seq_id != -1) ? shape->sequences[seq_id].duration : 0.0f;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
166
Engine/source/afx/ce/afxModel.h
Normal file
166
Engine/source/afx/ce/afxModel.h
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_MODEL_H_
|
||||
#define _AFX_MODEL_H_
|
||||
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
|
||||
class ParticleEmitterData;
|
||||
class ParticleEmitter;
|
||||
class ExplosionData;
|
||||
class TSPartInstance;
|
||||
class TSShapeInstance;
|
||||
class TSShape;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxModel Data
|
||||
|
||||
struct afxModelData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
StringTableEntry shapeName;
|
||||
StringTableEntry sequence;
|
||||
F32 seq_rate;
|
||||
F32 seq_offset;
|
||||
F32 alpha_mult;
|
||||
bool use_vertex_alpha;
|
||||
U32 force_on_material_flags;
|
||||
U32 force_off_material_flags;
|
||||
bool texture_filtering;
|
||||
F32 fog_mult;
|
||||
|
||||
struct TextureTagRemapping
|
||||
{
|
||||
char* old_tag;
|
||||
char* new_tag;
|
||||
};
|
||||
char* remap_buffer;
|
||||
Vector<TextureTagRemapping> txr_tag_remappings;
|
||||
|
||||
StringTableEntry remap_txr_tags;
|
||||
|
||||
Resource<TSShape> shape;
|
||||
|
||||
bool overrideLightingOptions;
|
||||
bool receiveSunLight;
|
||||
bool receiveLMLighting;
|
||||
bool useAdaptiveSelfIllumination;
|
||||
bool useCustomAmbientLighting;
|
||||
bool customAmbientForSelfIllumination;
|
||||
LinearColorF customAmbientLighting;
|
||||
bool shadowEnable;
|
||||
|
||||
U32 shadowSize;
|
||||
F32 shadowMaxVisibleDistance;
|
||||
F32 shadowProjectionDistance;
|
||||
F32 shadowSphereAdjust;
|
||||
|
||||
public:
|
||||
/*C*/ afxModelData();
|
||||
/*C*/ afxModelData(const afxModelData&, bool = false);
|
||||
/*D*/ ~afxModelData();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
|
||||
virtual void onPerformSubstitutions();
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxModelData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxModel
|
||||
|
||||
class afxModel : public GameBase
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
private:
|
||||
afxModelData* mDataBlock;
|
||||
TSShapeInstance* shape_inst;
|
||||
TSThread* main_seq_thread;
|
||||
S32 main_seq_id;
|
||||
F32 seq_rate_factor;
|
||||
bool seq_animates_vis;
|
||||
U32 last_anim_tag;
|
||||
F32 fade_amt;
|
||||
bool is_visible;
|
||||
S8 sort_priority;
|
||||
|
||||
struct BlendThread
|
||||
{
|
||||
TSThread* thread;
|
||||
U32 tag;
|
||||
};
|
||||
Vector<BlendThread> blend_clips;
|
||||
static U32 unique_anim_tag_counter;
|
||||
|
||||
protected:
|
||||
Vector<S32> mCollisionDetails;
|
||||
Vector<S32> mLOSDetails;
|
||||
bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
|
||||
|
||||
virtual void advanceTime(F32 dt);
|
||||
|
||||
virtual void prepRenderImage(SceneRenderState*);
|
||||
|
||||
void renderObject(SceneRenderState*);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
public:
|
||||
/*C*/ afxModel();
|
||||
/*D*/ ~afxModel();
|
||||
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
|
||||
void setFadeAmount(F32 amt) { fade_amt = amt; }
|
||||
void setSequenceRateFactor(F32 factor);
|
||||
void setSortPriority(S8 priority) { sort_priority = priority; }
|
||||
|
||||
const char* getShapeFileName() const { return mDataBlock->shapeName; }
|
||||
void setVisibility(bool flag) { is_visible = flag; }
|
||||
TSShape* getTSShape() { return mDataBlock->shape; }
|
||||
TSShapeInstance* getTSShapeInstance() { return shape_inst; }
|
||||
|
||||
U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans);
|
||||
void resetAnimation(U32 tag);
|
||||
F32 getAnimClipDuration(const char* clip);
|
||||
|
||||
DECLARE_CONOBJECT(afxModel);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MODEL_H_
|
||||
71
Engine/source/afx/ce/afxModel_T3D.cpp
Normal file
71
Engine/source/afx/ce/afxModel_T3D.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "scene/sceneManager.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "lighting/lightQuery.h"
|
||||
|
||||
#include "afx/ce/afxModel.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxModel::renderObject(SceneRenderState* state)
|
||||
{
|
||||
MatrixF proj = GFX->getProjectionMatrix();
|
||||
RectI viewport = GFX->getViewport();
|
||||
|
||||
MatrixF world = GFX->getWorldMatrix();
|
||||
|
||||
GFX->pushWorldMatrix();
|
||||
|
||||
TSRenderState rdata;
|
||||
rdata.setSceneState( state );
|
||||
rdata.setFadeOverride(fade_amt*mDataBlock->alpha_mult);
|
||||
|
||||
// We might have some forward lit materials
|
||||
// so pass down a query to gather lights.
|
||||
LightQuery query;
|
||||
query.init( getWorldSphere() );
|
||||
rdata.setLightQuery( &query );
|
||||
|
||||
MatrixF mat = getRenderTransform();
|
||||
mat.scale( mObjScale );
|
||||
GFX->setWorldMatrix( mat );
|
||||
|
||||
shape_inst->animate();
|
||||
|
||||
shape_inst->render(rdata);
|
||||
|
||||
GFX->popWorldMatrix();
|
||||
|
||||
GFX->setProjectionMatrix( proj );
|
||||
GFX->setViewport( viewport );
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
278
Engine/source/afx/ce/afxMooring.cpp
Normal file
278
Engine/source/afx/ce/afxMooring.cpp
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxMooring.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMooringData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxMooringData);
|
||||
|
||||
ConsoleDocClass( afxMooringData,
|
||||
"@brief A datablock that specifies a Mooring effect.\n\n"
|
||||
|
||||
"A Mooring is an invisible effect object which can be positioned and oriented within a scene like other objects. Its main "
|
||||
"purpose is to serve as a common mount point for other effects within the same choreographer. Typically one uses AFX "
|
||||
"animation features to create movement for a Mooring and then other effects are bound to it using effect-to-effect "
|
||||
"constraints (#effect)."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxMooringData::afxMooringData()
|
||||
{
|
||||
track_pos_only = false;
|
||||
networking = SCOPE_ALWAYS;
|
||||
display_axis_marker = false;
|
||||
}
|
||||
|
||||
afxMooringData::afxMooringData(const afxMooringData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
track_pos_only = other.track_pos_only;
|
||||
networking = other.networking;
|
||||
display_axis_marker = other.display_axis_marker;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxMooringData)
|
||||
|
||||
void afxMooringData::initPersistFields()
|
||||
{
|
||||
addField("displayAxisMarker", TypeBool, myOffset(display_axis_marker),
|
||||
"Specifies whether to display an axis to help visualize the position and orientation "
|
||||
"of the mooring.");
|
||||
addField("trackPosOnly", TypeBool, myOffset(track_pos_only),
|
||||
"This field is only meaningful for networking settings of SCOPE_ALWAYS and GHOSTABLE. "
|
||||
"In these cases, client moorings are ghosting a mooring on the server, and "
|
||||
"trackPosOnly determines if the client moorings need to be updated with the server "
|
||||
"mooring's complete transform or just its position. If only the position needs to be "
|
||||
"tracked, setting trackPosOnly to true will reduce the network traffic.");
|
||||
addField("networking", TypeS8, myOffset(networking),
|
||||
"Specifies the networking model used for the mooring and should be one of: "
|
||||
"$AFX::SCOPE_ALWAYS, $AFX::GHOSTABLE, $AFX::SERVER_ONLY, or $AFX::CLIENT_ONLY");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxMooringData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxMooringData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
stream->write(display_axis_marker);
|
||||
stream->write(track_pos_only);
|
||||
stream->write(networking);
|
||||
}
|
||||
|
||||
void afxMooringData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
stream->read(&display_axis_marker);
|
||||
stream->read(&track_pos_only);
|
||||
stream->read(&networking);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMooring
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxMooring);
|
||||
|
||||
ConsoleDocClass( afxMooring,
|
||||
"@brief A Mooring effect as defined by an afxMooringData datablock.\n\n"
|
||||
|
||||
"A Mooring is an invisible effect object which can be positioned and oriented within "
|
||||
"a scene like other objects. Its main purpose is to serve as a common mount point for "
|
||||
"other effects within the same choreographer. Typically one uses AFX animation "
|
||||
"features to create movement for a Mooring and then other effects are bound to it "
|
||||
"using effect-to-effect constraints (#effect).\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxMooring::afxMooring()
|
||||
{
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
|
||||
chor_id = 0;
|
||||
hookup_with_chor = false;
|
||||
ghost_cons_name = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxMooring::afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name)
|
||||
{
|
||||
if (networking & SCOPE_ALWAYS)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
}
|
||||
else if (networking & GHOSTABLE)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(Ghostable);
|
||||
}
|
||||
else if (networking & SERVER_ONLY)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
}
|
||||
else // if (networking & CLIENT_ONLY)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(IsGhost);
|
||||
}
|
||||
|
||||
this->chor_id = chor_id;
|
||||
hookup_with_chor = false;
|
||||
this->ghost_cons_name = cons_name;
|
||||
}
|
||||
|
||||
afxMooring::~afxMooring()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxMooring::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<afxMooringData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxMooring::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if (hookup_with_chor)
|
||||
{
|
||||
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
|
||||
if (chor)
|
||||
{
|
||||
chor->setGhostConstraintObject(this, ghost_cons_name);
|
||||
hookup_with_chor = false;
|
||||
}
|
||||
}
|
||||
|
||||
Point3F pos = getRenderPosition();
|
||||
}
|
||||
|
||||
U32 afxMooring::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(conn, mask, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
stream->write(chor_id);
|
||||
stream->writeString(ghost_cons_name);
|
||||
}
|
||||
|
||||
if (stream->writeFlag(mask & PositionMask))
|
||||
{
|
||||
if (mDataBlock->track_pos_only)
|
||||
mathWrite(*stream, mObjToWorld.getPosition());
|
||||
else
|
||||
stream->writeAffineTransform(mObjToWorld);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxMooring::unpackUpdate(NetConnection * conn, BitStream * stream)
|
||||
{
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read(&chor_id);
|
||||
ghost_cons_name = stream->readSTString();
|
||||
|
||||
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
|
||||
hookup_with_chor = true;
|
||||
}
|
||||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
if (mDataBlock->track_pos_only)
|
||||
{
|
||||
Point3F pos;
|
||||
mathRead(*stream, &pos);
|
||||
setPosition(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
MatrixF mat;
|
||||
stream->readAffineTransform(&mat);
|
||||
setTransform(mat);
|
||||
setRenderTransform(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afxMooring::setTransform(const MatrixF& mat)
|
||||
{
|
||||
Parent::setTransform(mat);
|
||||
setMaskBits(PositionMask);
|
||||
}
|
||||
|
||||
bool afxMooring::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
mObjBox = Box3F(Point3F(-0.5, -0.5, -0.5), Point3F(0.5, 0.5, 0.5));
|
||||
|
||||
addToScene();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxMooring::onRemove()
|
||||
{
|
||||
removeFromScene();
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
102
Engine/source/afx/ce/afxMooring.h
Normal file
102
Engine/source/afx/ce/afxMooring.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_MOORING_H_
|
||||
#define _AFX_MOORING_H_
|
||||
|
||||
#include "renderInstance/renderPassManager.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
|
||||
class afxMooringData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
U8 networking;
|
||||
bool track_pos_only;
|
||||
bool display_axis_marker;
|
||||
|
||||
public:
|
||||
/*C*/ afxMooringData();
|
||||
/*C*/ afxMooringData(const afxMooringData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxMooringData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxMooring
|
||||
|
||||
class afxMooring : public GameBase, public afxEffectDefs
|
||||
{
|
||||
typedef GameBase Parent;
|
||||
|
||||
private:
|
||||
afxMooringData* mDataBlock;
|
||||
U32 chor_id;
|
||||
bool hookup_with_chor;
|
||||
StringTableEntry ghost_cons_name;
|
||||
|
||||
GFXStateBlockRef axis_sb;
|
||||
void _renderAxisLines(ObjectRenderInst*, SceneRenderState*, BaseMatInstance*);
|
||||
|
||||
protected:
|
||||
enum MaskBits
|
||||
{
|
||||
PositionMask = Parent::NextFreeMask,
|
||||
NextFreeMask = Parent::NextFreeMask << 1
|
||||
};
|
||||
|
||||
public:
|
||||
/*C*/ afxMooring();
|
||||
/*C*/ afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name);
|
||||
/*D*/ ~afxMooring();
|
||||
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
virtual void setTransform(const MatrixF&);
|
||||
|
||||
virtual void prepRenderImage(SceneRenderState*);
|
||||
|
||||
DECLARE_CONOBJECT(afxMooring);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MOORING_H_
|
||||
88
Engine/source/afx/ce/afxMooring_T3D.cpp
Normal file
88
Engine/source/afx/ce/afxMooring_T3D.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxMooring.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxMooring::prepRenderImage(SceneRenderState* state)
|
||||
{
|
||||
if (!mDataBlock->display_axis_marker)
|
||||
return;
|
||||
|
||||
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
|
||||
ri->renderDelegate.bind(this, &afxMooring::_renderAxisLines);
|
||||
ri->type = RenderPassManager::RIT_ObjectTranslucent;
|
||||
ri->translucentSort = true;
|
||||
ri->defaultKey = (U32)(dsize_t)mDataBlock;
|
||||
ri->sortDistSq = getWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
|
||||
state->getRenderPass()->addInst(ri);
|
||||
}
|
||||
|
||||
void afxMooring::_renderAxisLines(ObjectRenderInst *ri, SceneRenderState* state, BaseMatInstance* overrideMat)
|
||||
{
|
||||
if (overrideMat)
|
||||
return;
|
||||
|
||||
if (axis_sb.isNull())
|
||||
{
|
||||
GFXStateBlockDesc desc;
|
||||
|
||||
desc.blendDefined = true;
|
||||
desc.blendEnable = false;
|
||||
desc.cullDefined = true;
|
||||
desc.cullMode = GFXCullNone;
|
||||
desc.ffLighting = false;
|
||||
desc.zDefined = true;
|
||||
desc.zWriteEnable = false;
|
||||
|
||||
axis_sb = GFX->createStateBlock(desc);
|
||||
}
|
||||
|
||||
GFX->setStateBlock(axis_sb);
|
||||
|
||||
GFXTransformSaver saver;
|
||||
GFX->multWorld(getRenderTransform());
|
||||
|
||||
PrimBuild::begin(GFXLineList, 6);
|
||||
PrimBuild::color(LinearColorF(1.0, 0.0, 0.0));
|
||||
PrimBuild::vertex3f(-0.5, 0.0, 0.0);
|
||||
PrimBuild::vertex3f( 0.5, 0.0, 0.0);
|
||||
PrimBuild::color(LinearColorF(0.0, 1.0, 0.0));
|
||||
PrimBuild::vertex3f( 0.0, -0.5, 0.0);
|
||||
PrimBuild::vertex3f( 0.0, 0.5, 0.0);
|
||||
PrimBuild::color(LinearColorF(0.0, 0.0, 1.0));
|
||||
PrimBuild::vertex3f( 0.0, 0.0, -0.5);
|
||||
PrimBuild::vertex3f( 0.0, 0.0, 0.5);
|
||||
PrimBuild::end();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
40
Engine/source/afx/ce/afxMultiLight.cpp
Normal file
40
Engine/source/afx/ce/afxMultiLight.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/ce/afxMultiLight.h"
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxMultiLightData);
|
||||
|
||||
ConsoleDocClass( afxMultiLightData,
|
||||
"@brief afxMultiLightData is a legacy datablock which is not supported for T3D.\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
38
Engine/source/afx/ce/afxMultiLight.h
Normal file
38
Engine/source/afx/ce/afxMultiLight.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_MULTI_LIGHT_H_
|
||||
#define _AFX_MULTI_LIGHT_H_
|
||||
|
||||
struct afxMultiLightData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
DECLARE_CONOBJECT(afxMultiLightData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_MULTI_LIGHT_H_
|
||||
1617
Engine/source/afx/ce/afxParticleEmitter.cpp
Normal file
1617
Engine/source/afx/ce/afxParticleEmitter.cpp
Normal file
File diff suppressed because it is too large
Load diff
350
Engine/source/afx/ce/afxParticleEmitter.h
Normal file
350
Engine/source/afx/ce/afxParticleEmitter.h
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_EMITTER_PARTICLE_H_
|
||||
#define _AFX_EMITTER_PARTICLE_H_
|
||||
|
||||
#include "T3D/fx/particleEmitter.h"
|
||||
|
||||
class afxPathData;
|
||||
class afxPath3D;
|
||||
|
||||
class afxParticleEmitterData : public ParticleEmitterData
|
||||
{
|
||||
typedef ParticleEmitterData Parent;
|
||||
|
||||
public:
|
||||
// The afx enhanced particle emitter allows fading
|
||||
// of particle color, size, velocity, and/or offset.
|
||||
// Fading is controlled by a common value which is
|
||||
// set externally using setFadeAmount().
|
||||
//
|
||||
bool fade_velocity;
|
||||
bool fade_offset;
|
||||
Point3F pe_vector;
|
||||
// new -- consider vector in world space?
|
||||
bool pe_vector_is_world;
|
||||
|
||||
// new -- transform paths?
|
||||
StringTableEntry tpaths_string; //
|
||||
Vector<afxPathData*> tPathDataBlocks; // datablocks for paths
|
||||
Vector<U32> tPathDataBlockIds; // datablock IDs which correspond to the pathDataBlocks
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterData();
|
||||
/*C*/ afxParticleEmitterData(const afxParticleEmitterData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
bool onAdd();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxParticleEmitterData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// VECTOR
|
||||
|
||||
class afxParticleEmitterVectorData : public afxParticleEmitterData
|
||||
{
|
||||
typedef afxParticleEmitterData Parent;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterVectorData();
|
||||
/*C*/ afxParticleEmitterVectorData(const afxParticleEmitterVectorData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
bool onAdd();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxParticleEmitterVectorData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// CONE
|
||||
|
||||
class afxParticleEmitterConeData : public afxParticleEmitterData
|
||||
{
|
||||
typedef afxParticleEmitterData Parent;
|
||||
|
||||
public:
|
||||
F32 spread_min;
|
||||
F32 spread_max;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterConeData();
|
||||
/*C*/ afxParticleEmitterConeData(const afxParticleEmitterConeData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
bool onAdd();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxParticleEmitterConeData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// PATH
|
||||
|
||||
class afxParticleEmitterPathData : public afxParticleEmitterData
|
||||
{
|
||||
typedef afxParticleEmitterData Parent;
|
||||
|
||||
public:
|
||||
enum PathOriginType
|
||||
{
|
||||
PATHEMIT_ORIGIN,
|
||||
PATHEMIT_POINT,
|
||||
PATHEMIT_VECTOR,
|
||||
PATHEMIT_TANGENT
|
||||
};
|
||||
StringTableEntry epaths_string; //
|
||||
Vector<afxPathData*> epathDataBlocks; // datablocks for paths
|
||||
Vector<U32> epathDataBlockIds; // datablock IDs which correspond to the pathDataBlocks
|
||||
U32 path_origin_type;
|
||||
|
||||
bool ground_conform;
|
||||
bool ground_conform_terrain;
|
||||
bool ground_conform_interiors;
|
||||
F32 ground_conform_height;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterPathData();
|
||||
/*C*/ afxParticleEmitterPathData(const afxParticleEmitterPathData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
bool onAdd();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual void onPerformSubstitutions();
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxParticleEmitterPathData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
typedef afxParticleEmitterPathData::PathOriginType afxParticleEmitterPath_OriginType;
|
||||
DefineEnumType( afxParticleEmitterPath_OriginType );
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// DISC
|
||||
|
||||
class afxParticleEmitterDiscData : public afxParticleEmitterData
|
||||
{
|
||||
typedef afxParticleEmitterData Parent;
|
||||
|
||||
public:
|
||||
F32 pe_radius_min;
|
||||
F32 pe_radius_max;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterDiscData();
|
||||
/*C*/ afxParticleEmitterDiscData(const afxParticleEmitterDiscData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
bool onAdd();
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxParticleEmitterDiscData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxParticleEmitter : public ParticleEmitter
|
||||
{
|
||||
typedef ParticleEmitter Parent;
|
||||
|
||||
private:
|
||||
afxParticleEmitterData* mDataBlock;
|
||||
|
||||
protected:
|
||||
Point3F pe_vector, pe_vector_norm;
|
||||
|
||||
// these go with the "pathsTransform" field
|
||||
Vector<afxPath3D*> tpaths;
|
||||
Vector<F32> tpath_mults;
|
||||
U32 n_tpath_points;
|
||||
Point3F** tpath_points;
|
||||
|
||||
const SimObject* afx_owner;
|
||||
|
||||
void init_paths();
|
||||
void cleanup_paths();
|
||||
|
||||
Particle* alloc_particle();
|
||||
ParticleData* pick_particle_type();
|
||||
void afx_emitParticles(const Point3F& point, const bool useLastPosition, const Point3F& velocity, const U32 numMilliseconds);
|
||||
void afx_emitParticles(const Point3F& start, const Point3F& end, const Point3F& velocity, const U32 numMilliseconds);
|
||||
void preCompute(const MatrixF& mat);
|
||||
|
||||
virtual void sub_particleUpdate(Particle*);
|
||||
virtual void sub_preCompute(const MatrixF& mat)=0;
|
||||
virtual void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx)=0;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitter();
|
||||
/*D*/ ~afxParticleEmitter();
|
||||
|
||||
virtual void emitParticlesExt(const MatrixF& xfm, const Point3F& point, const Point3F& velocity, const U32 numMilliseconds);
|
||||
|
||||
afxParticleEmitterData* getDataBlock(){ return mDataBlock; }
|
||||
void setAFXOwner(const SimObject* owner) { afx_owner = owner; }
|
||||
bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// VECTOR
|
||||
|
||||
class afxParticleEmitterVector : public afxParticleEmitter
|
||||
{
|
||||
typedef afxParticleEmitter Parent;
|
||||
|
||||
private:
|
||||
afxParticleEmitterVectorData* mDataBlock;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterVector();
|
||||
/*D*/ ~afxParticleEmitterVector();
|
||||
|
||||
bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
|
||||
protected:
|
||||
void sub_preCompute(const MatrixF& mat);
|
||||
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offse, S32 part_idxt);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// CONE
|
||||
|
||||
class afxParticleEmitterCone : public afxParticleEmitter
|
||||
{
|
||||
typedef afxParticleEmitter Parent;
|
||||
|
||||
private:
|
||||
afxParticleEmitterData* mDataBlock;
|
||||
Point3F cone_v, cone_s0, cone_s1;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterCone();
|
||||
/*D*/ ~afxParticleEmitterCone();
|
||||
|
||||
bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
|
||||
protected:
|
||||
void sub_preCompute(const MatrixF& mat);
|
||||
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// PATH
|
||||
|
||||
class afxParticleEmitterPath : public afxParticleEmitter
|
||||
{
|
||||
typedef afxParticleEmitter Parent;
|
||||
|
||||
private:
|
||||
afxParticleEmitterPathData* mDataBlock;
|
||||
|
||||
Vector<afxPath3D*> epaths;
|
||||
Vector<F32> epath_mults;
|
||||
U32 n_epath_points;
|
||||
Point3F** epath_points;
|
||||
|
||||
void init_paths();
|
||||
void cleanup_paths();
|
||||
|
||||
void groundConformPoint(Point3F& point, const MatrixF& mat);
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterPath();
|
||||
/*D*/ ~afxParticleEmitterPath();
|
||||
|
||||
bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
|
||||
protected:
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
void sub_preCompute(const MatrixF& mat);
|
||||
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// DISC
|
||||
|
||||
class afxParticleEmitterDisc : public afxParticleEmitter
|
||||
{
|
||||
typedef afxParticleEmitter Parent;
|
||||
|
||||
private:
|
||||
afxParticleEmitterDiscData* mDataBlock;
|
||||
Point3F disc_v, disc_r;
|
||||
|
||||
public:
|
||||
/*C*/ afxParticleEmitterDisc();
|
||||
/*D*/ ~afxParticleEmitterDisc();
|
||||
|
||||
bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
|
||||
protected:
|
||||
void sub_preCompute(const MatrixF& mat);
|
||||
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_EMITTER_PARTICLE_H_
|
||||
312
Engine/source/afx/ce/afxPhraseEffect.cpp
Normal file
312
Engine/source/afx/ce/afxPhraseEffect.cpp
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxPhraseEffect.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhraseEffectData::ewValidator
|
||||
//
|
||||
// When an effect is added using "addEffect", this validator intercepts the value
|
||||
// and adds it to the dynamic effects list.
|
||||
//
|
||||
void afxPhraseEffectData::ewValidator::validateType(SimObject* object, void* typePtr)
|
||||
{
|
||||
afxPhraseEffectData* eff_data = dynamic_cast<afxPhraseEffectData*>(object);
|
||||
afxEffectBaseData** ew = (afxEffectBaseData**)(typePtr);
|
||||
|
||||
if (eff_data && ew)
|
||||
{
|
||||
eff_data->fx_list.push_back(*ew);
|
||||
*ew = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhraseEffectData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxPhraseEffectData);
|
||||
|
||||
ConsoleDocClass( afxPhraseEffectData,
|
||||
"@brief A datablock that specifies a Phrase Effect, a grouping of other effects.\n\n"
|
||||
|
||||
"A Phrase Effect is a grouping or phrase of effects that do nothing until certain trigger events occur. It's like having a whole "
|
||||
"Effectron organized as an individual effect."
|
||||
"\n\n"
|
||||
|
||||
"Phrase effects can respond to a number of different kinds of triggers:\n"
|
||||
" -- Player triggers such as footsteps, jumps, landings, and idle triggers.\n"
|
||||
" -- Arbitrary animation triggers on dts-based scene objects.\n"
|
||||
" -- Arbitrary trigger bits assigned to active choreographer objects."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxPhraseEffectData::afxPhraseEffectData()
|
||||
{
|
||||
duration = 0.0f;
|
||||
n_loops = 1;
|
||||
|
||||
// dummy entry holds effect-wrapper pointer while a special validator
|
||||
// grabs it and adds it to an appropriate effects list
|
||||
dummy_fx_entry = NULL;
|
||||
|
||||
// marked true if datablock ids need to
|
||||
// be converted into pointers
|
||||
do_id_convert = false;
|
||||
|
||||
trigger_mask = 0;
|
||||
match_type = MATCH_ANY;
|
||||
match_state = STATE_ON;
|
||||
phrase_type = PHRASE_TRIGGERED;
|
||||
|
||||
no_choreographer_trigs = false;
|
||||
no_cons_trigs = false;
|
||||
no_player_trigs = false;
|
||||
|
||||
on_trig_cmd = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxPhraseEffectData::afxPhraseEffectData(const afxPhraseEffectData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
duration = other.duration;
|
||||
n_loops = other.n_loops;
|
||||
dummy_fx_entry = other.dummy_fx_entry;
|
||||
do_id_convert = other.do_id_convert; // --
|
||||
trigger_mask = other.trigger_mask;
|
||||
match_type = other.match_type;
|
||||
match_state = other.match_state;
|
||||
phrase_type = other.phrase_type;
|
||||
no_choreographer_trigs = other.no_choreographer_trigs;
|
||||
no_cons_trigs = other.no_cons_trigs;
|
||||
no_player_trigs = other.no_player_trigs;
|
||||
on_trig_cmd = other.on_trig_cmd;
|
||||
|
||||
// fx_list; // -- ??
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::reloadReset()
|
||||
{
|
||||
fx_list.clear();
|
||||
}
|
||||
|
||||
ImplementEnumType( afxPhraseEffect_MatchType, "Possible phrase effect match types.\n" "@ingroup afxPhraseEffect\n\n" )
|
||||
{ afxPhraseEffectData::MATCH_ANY, "any", "..." },
|
||||
{ afxPhraseEffectData::MATCH_ALL, "all", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( afxPhraseEffect_StateType, "Possible phrase effect state types.\n" "@ingroup afxPhraseEffect\n\n" )
|
||||
{ afxPhraseEffectData::STATE_ON, "on", "..." },
|
||||
{ afxPhraseEffectData::STATE_OFF, "off", "..." },
|
||||
{ afxPhraseEffectData::STATE_ON_AND_OFF, "both", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( afxPhraseEffect_PhraseType, "Possible phrase effect types.\n" "@ingroup afxPhraseEffect\n\n" )
|
||||
{ afxPhraseEffectData::PHRASE_TRIGGERED, "triggered", "..." },
|
||||
{ afxPhraseEffectData::PHRASE_CONTINUOUS, "continuous", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
#define myOffset(field) Offset(field, afxPhraseEffectData)
|
||||
|
||||
void afxPhraseEffectData::initPersistFields()
|
||||
{
|
||||
addField("duration", TypeF32, myOffset(duration),
|
||||
"Specifies a duration for the phrase-effect. If set to infinity, the phrase-effect "
|
||||
"needs to have a phraseType of continuous. Set infinite duration using "
|
||||
"$AFX::INFINITE_TIME.");
|
||||
addField("numLoops", TypeS32, myOffset(n_loops),
|
||||
"Specifies the number of times the phrase-effect should loop. If set to infinity, "
|
||||
"the phrase-effect needs to have a phraseType of continuous. Set infinite looping "
|
||||
"using $AFX::INFINITE_REPEATS.");
|
||||
addField("triggerMask", TypeS32, myOffset(trigger_mask),
|
||||
"Sets which bits to consider in the current trigger-state which consists of 32 "
|
||||
"trigger-bits combined from (possibly overlapping) player trigger bits, constraint "
|
||||
"trigger bits, and choreographer trigger bits.");
|
||||
|
||||
addField("matchType", TYPEID<afxPhraseEffectData::MatchType>(), myOffset(match_type),
|
||||
"Selects what combination of bits in triggerMask lead to a trigger. When set to "
|
||||
"'any', any bit in triggerMask matching the current trigger-state will cause a "
|
||||
"trigger. If set to 'all', every bit in triggerMask must match the trigger-state. "
|
||||
"Possible values: any or all.");
|
||||
addField("matchState", TYPEID<afxPhraseEffectData::StateType>(), myOffset(match_state),
|
||||
"Selects which bit-state(s) of bits in the triggerMask to consider when comparing to "
|
||||
"the current trigger-state. Possible values: on, off, or both.");
|
||||
addField("phraseType", TYPEID<afxPhraseEffectData::PhraseType>(), myOffset(phrase_type),
|
||||
"Selects between triggered and continuous types of phrases. When set to 'triggered', "
|
||||
"the phrase-effect is triggered when the relevant trigger-bits change state. When set "
|
||||
"to 'continuous', the phrase-effect will stay active as long as the trigger-bits "
|
||||
"remain in a matching state. Possible values: triggered or continuous.");
|
||||
|
||||
addField("ignoreChoreographerTriggers", TypeBool, myOffset(no_choreographer_trigs),
|
||||
"When true, trigger-bits on the choreographer will be ignored.");
|
||||
addField("ignoreConstraintTriggers", TypeBool, myOffset(no_cons_trigs),
|
||||
"When true, animation triggers from dts-based constraint source objects will be "
|
||||
"ignored.");
|
||||
addField("ignorePlayerTriggers", TypeBool, myOffset(no_player_trigs),
|
||||
"When true, Player-specific triggers from Player-derived constraint source objects "
|
||||
"will be ignored.");
|
||||
|
||||
addField("onTriggerCommand", TypeString, myOffset(on_trig_cmd),
|
||||
"Like a field substitution statement without the leading '$$' token, this eval "
|
||||
"statement will be executed when a trigger occurs. Any '%%' and '##' tokens will be "
|
||||
"substituted.");
|
||||
|
||||
// effect lists
|
||||
// for each of these, dummy_fx_entry is set and then a validator adds it to the appropriate effects list
|
||||
static ewValidator emptyValidator(0);
|
||||
addFieldV("addEffect", TYPEID< afxEffectBaseData >(), myOffset(dummy_fx_entry), &emptyValidator,
|
||||
"A field macro which adds an effect wrapper datablock to a list of effects associated "
|
||||
"with the phrase-effect's single phrase. Unlike other fields, addEffect follows an "
|
||||
"unusual syntax. Order is important since the effects will resolve in the order they "
|
||||
"are added to each list.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// disallow some field substitutions
|
||||
disableFieldSubstitutions("addEffect");
|
||||
}
|
||||
|
||||
bool afxPhraseEffectData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::pack_fx(BitStream* stream, const afxEffectList& fx, bool packed)
|
||||
{
|
||||
stream->writeInt(fx.size(), EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < fx.size(); i++)
|
||||
writeDatablockID(stream, fx[i], packed);
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
||||
{
|
||||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(duration);
|
||||
stream->write(n_loops);
|
||||
stream->write(trigger_mask);
|
||||
stream->writeInt(match_type, 1);
|
||||
stream->writeInt(match_state, 2);
|
||||
stream->writeInt(phrase_type, 1);
|
||||
|
||||
stream->writeFlag(no_choreographer_trigs);
|
||||
stream->writeFlag(no_cons_trigs);
|
||||
stream->writeFlag(no_player_trigs);
|
||||
|
||||
stream->writeString(on_trig_cmd);
|
||||
|
||||
pack_fx(stream, fx_list, packed);
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&duration);
|
||||
stream->read(&n_loops);
|
||||
stream->read(&trigger_mask);
|
||||
match_type = stream->readInt(1);
|
||||
match_state = stream->readInt(2);
|
||||
phrase_type = stream->readInt(1);
|
||||
|
||||
no_choreographer_trigs = stream->readFlag();
|
||||
no_cons_trigs = stream->readFlag();
|
||||
no_player_trigs = stream->readFlag();
|
||||
|
||||
on_trig_cmd = stream->readSTString();
|
||||
|
||||
do_id_convert = true;
|
||||
unpack_fx(stream, fx_list);
|
||||
}
|
||||
|
||||
bool afxPhraseEffectData::preload(bool server, String &errorStr)
|
||||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server)
|
||||
{
|
||||
if (do_id_convert)
|
||||
{
|
||||
for (S32 i = 0; i < fx_list.size(); i++)
|
||||
{
|
||||
SimObjectId db_id = SimObjectId((uintptr_t)fx_list[i]);
|
||||
if (db_id != 0)
|
||||
{
|
||||
// try to convert id to pointer
|
||||
if (!Sim::findObject(db_id, fx_list[i]))
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::General,
|
||||
"afxPhraseEffectData::preload() -- bad datablockId: 0x%x",
|
||||
db_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
do_id_convert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::gather_cons_defs(Vector<afxConstraintDef>& defs)
|
||||
{
|
||||
afxConstraintDef::gather_cons_defs(defs, fx_list);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
DefineEngineMethod( afxPhraseEffectData, addEffect, void, ( afxEffectBaseData* effectData ),,
|
||||
"Add a child effect to a phrase effect datablock. Argument can be an afxEffectWrappperData or an afxEffectGroupData.\n" )
|
||||
{
|
||||
if (!effectData)
|
||||
{
|
||||
Con::errorf("afxPhraseEffectData::addEffect() -- failed to resolve effect datablock.");
|
||||
return;
|
||||
}
|
||||
|
||||
object->fx_list.push_back(effectData);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
120
Engine/source/afx/ce/afxPhraseEffect.h
Normal file
120
Engine/source/afx/ce/afxPhraseEffect.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PHRASE_EFFECT_H_
|
||||
#define _AFX_PHRASE_EFFECT_H_
|
||||
|
||||
#include "console/typeValidators.h"
|
||||
|
||||
#include "afx/ce/afxComponentEffect.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxPhrase.h"
|
||||
|
||||
class afxPhraseEffectData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
class ewValidator : public TypeValidator
|
||||
{
|
||||
U32 id;
|
||||
public:
|
||||
ewValidator(U32 id) { this->id = id; }
|
||||
void validateType(SimObject *object, void *typePtr);
|
||||
};
|
||||
|
||||
bool do_id_convert;
|
||||
|
||||
public:
|
||||
enum MatchType {
|
||||
MATCH_ANY = 0,
|
||||
MATCH_ALL = 1
|
||||
};
|
||||
enum StateType {
|
||||
STATE_ON = 1,
|
||||
STATE_OFF = 2,
|
||||
STATE_ON_AND_OFF = STATE_ON | STATE_OFF
|
||||
};
|
||||
enum PhraseType
|
||||
{
|
||||
PHRASE_TRIGGERED = 0,
|
||||
PHRASE_CONTINUOUS = 1
|
||||
};
|
||||
|
||||
public:
|
||||
afxEffectList fx_list;
|
||||
F32 duration;
|
||||
S32 n_loops;
|
||||
U32 trigger_mask;
|
||||
U32 match_type;
|
||||
U32 match_state;
|
||||
U32 phrase_type;
|
||||
|
||||
bool no_choreographer_trigs;
|
||||
bool no_cons_trigs;
|
||||
bool no_player_trigs;
|
||||
|
||||
StringTableEntry on_trig_cmd;
|
||||
|
||||
afxEffectBaseData* dummy_fx_entry;
|
||||
|
||||
private:
|
||||
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
|
||||
void unpack_fx(BitStream* stream, afxEffectList& fx);
|
||||
|
||||
public:
|
||||
/*C*/ afxPhraseEffectData();
|
||||
/*C*/ afxPhraseEffectData(const afxPhraseEffectData&, bool = false);
|
||||
|
||||
virtual void reloadReset();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool preload(bool server, String &errorStr);
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxPhraseEffectData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
typedef afxPhraseEffectData::MatchType afxPhraseEffect_MatchType;
|
||||
DefineEnumType( afxPhraseEffect_MatchType );
|
||||
|
||||
typedef afxPhraseEffectData::StateType afxPhraseEffect_StateType;
|
||||
DefineEnumType( afxPhraseEffect_StateType );
|
||||
|
||||
typedef afxPhraseEffectData::PhraseType afxPhraseEffect_PhraseType;
|
||||
DefineEnumType( afxPhraseEffect_PhraseType );
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PHRASE_EFFECT_H_
|
||||
114
Engine/source/afx/ce/afxPhysicalZone.cpp
Normal file
114
Engine/source/afx/ce/afxPhysicalZone.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/physicalZone.h"
|
||||
|
||||
#include "afx/ce/afxPhysicalZone.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhysicalZoneData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxPhysicalZoneData);
|
||||
|
||||
ConsoleDocClass( afxPhysicalZoneData,
|
||||
"@brief A datablock that specifies a PhysicalZone effect.\n\n"
|
||||
|
||||
"A Physical Zone is a Torque effect that applies physical forces to Players and other movable objects that enter a specific "
|
||||
"region of influence. AFX has enhanced Physical Zones by allowing orientation of vector forces and adding radial forces. "
|
||||
"AFX has also optimized Physical Zone networking so that they can be constrained to moving objects for a variety of "
|
||||
"effects including repelling and flying."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxPhysicalZoneData::afxPhysicalZoneData()
|
||||
{
|
||||
mVelocityMod = 1.0f;
|
||||
mGravityMod = 1.0f;
|
||||
mAppliedForce.zero();
|
||||
mPolyhedron = ST_NULLSTRING;
|
||||
force_type = PhysicalZone::VECTOR;
|
||||
orient_force = false;
|
||||
exclude_cons_obj = false;
|
||||
}
|
||||
|
||||
afxPhysicalZoneData::afxPhysicalZoneData(const afxPhysicalZoneData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
mVelocityMod = other.mVelocityMod;
|
||||
mGravityMod = other.mGravityMod;
|
||||
mAppliedForce = other.mAppliedForce;
|
||||
mPolyhedron = other.mPolyhedron;
|
||||
force_type = other.force_type;
|
||||
orient_force = other.orient_force;
|
||||
exclude_cons_obj = other.exclude_cons_obj;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxPhysicalZoneData)
|
||||
|
||||
void afxPhysicalZoneData::initPersistFields()
|
||||
{
|
||||
addField("velocityMod", TypeF32, myOffset(mVelocityMod),
|
||||
"A multiplier that biases the velocity of an object every tick it is within the "
|
||||
"zone.");
|
||||
addField("gravityMod", TypeF32, myOffset(mGravityMod),
|
||||
"A multiplier that biases the influence of gravity on objects within the zone.");
|
||||
addField("appliedForce", TypePoint3F, myOffset(mAppliedForce),
|
||||
"A three-valued vector representing a directional force applied to objects withing "
|
||||
"the zone.");
|
||||
addField("polyhedron", TypeString, myOffset(mPolyhedron),
|
||||
"Floating point values describing the outer bounds of the PhysicalZone's region of "
|
||||
"influence.");
|
||||
|
||||
addField("forceType", TYPEID<PhysicalZone::ForceType>(), myOffset(force_type),
|
||||
"This enumerated attribute defines the type of force used in the PhysicalZone. "
|
||||
"Possible values: vector, sphere, or cylinder.");
|
||||
|
||||
addField("orientForce", TypeBool, myOffset(orient_force),
|
||||
"Determines if the force can be oriented by the PhysicalZone's transform matrix.");
|
||||
addField("excludeConstraintObject", TypeBool, myOffset(exclude_cons_obj),
|
||||
"When true, an object used as the primary position constraint of a physical-zone "
|
||||
"effect will not be influenced by the forces of the zone.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxPhysicalZoneData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
}
|
||||
|
||||
void afxPhysicalZoneData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
65
Engine/source/afx/ce/afxPhysicalZone.h
Normal file
65
Engine/source/afx/ce/afxPhysicalZone.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PHYSICAL_ZONE_H_
|
||||
#define _AFX_PHYSICAL_ZONE_H_
|
||||
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#include "T3D/trigger.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPhysicalZoneData
|
||||
|
||||
class afxPhysicalZoneData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
F32 mVelocityMod;
|
||||
F32 mGravityMod;
|
||||
Point3F mAppliedForce;
|
||||
StringTableEntry mPolyhedron;
|
||||
S32 force_type;
|
||||
bool orient_force;
|
||||
bool exclude_cons_obj;
|
||||
|
||||
public:
|
||||
/*C*/ afxPhysicalZoneData();
|
||||
/*C*/ afxPhysicalZoneData(const afxPhysicalZoneData&, bool = false);
|
||||
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxPhysicalZoneData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PHYSICAL_ZONE_H_
|
||||
140
Engine/source/afx/ce/afxPlayerMovement.cpp
Normal file
140
Engine/source/afx/ce/afxPlayerMovement.cpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxPlayerMovement.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPlayerMovementData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxPlayerMovementData);
|
||||
|
||||
ConsoleDocClass( afxPlayerMovementData,
|
||||
"@brief A datablock that specifies a Player Movement effect.\n\n"
|
||||
|
||||
"Player Movement effects are used to directly alter the speed and/or movement direction of Player objects. The Player "
|
||||
"Movement effect is similar to the Player Puppet effect, but where puppet effects totally take over a Player's transformation "
|
||||
"using the AFX constraint system, Player Movement effects 'steer' the player using the same mechanisms that allow "
|
||||
"Player control from mouse and keyboard input. Another difference is that Player Movement effects only influence the "
|
||||
"server instance of a Player. Puppet effects can influence both the Player's server instance and its client ghosts."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
static Point3F default_movement(F32_MAX, F32_MAX, F32_MAX);
|
||||
|
||||
afxPlayerMovementData::afxPlayerMovementData()
|
||||
{
|
||||
speed_bias = 1.0f;
|
||||
movement = default_movement;
|
||||
movement_op = OP_MULTIPLY;
|
||||
}
|
||||
|
||||
afxPlayerMovementData::afxPlayerMovementData(const afxPlayerMovementData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
speed_bias = other.speed_bias;
|
||||
movement = other.movement;
|
||||
movement_op = other.movement_op;
|
||||
}
|
||||
|
||||
ImplementEnumType( afxPlayerMovement_OpType, "Possible player movement operation types.\n" "@ingroup afxPlayerMovemen\n\n" )
|
||||
{ afxPlayerMovementData::OP_ADD, "add", "..." },
|
||||
{ afxPlayerMovementData::OP_MULTIPLY, "multiply", "..." },
|
||||
{ afxPlayerMovementData::OP_REPLACE, "replace", "..." },
|
||||
{ afxPlayerMovementData::OP_MULTIPLY, "mult", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
#define myOffset(field) Offset(field, afxPlayerMovementData)
|
||||
|
||||
void afxPlayerMovementData::initPersistFields()
|
||||
{
|
||||
addField("speedBias", TypeF32, myOffset(speed_bias),
|
||||
"A floating-point multiplier that scales the constraint Player's movement speed.");
|
||||
addField("movement", TypePoint3F, myOffset(movement),
|
||||
"");
|
||||
addField("movementOp", TYPEID<afxPlayerMovementData::OpType>(), myOffset(movement_op),
|
||||
"Possible values: add, multiply, or replace.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxPlayerMovementData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxPlayerMovementData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(speed_bias);
|
||||
if (stream->writeFlag(movement != default_movement))
|
||||
{
|
||||
stream->write(movement.x);
|
||||
stream->write(movement.y);
|
||||
stream->write(movement.z);
|
||||
stream->writeInt(movement_op, OP_BITS);
|
||||
}
|
||||
}
|
||||
|
||||
void afxPlayerMovementData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&speed_bias);
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read(&movement.x);
|
||||
stream->read(&movement.y);
|
||||
stream->read(&movement.z);
|
||||
movement_op = stream->readInt(OP_BITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
movement = default_movement;
|
||||
movement_op = OP_MULTIPLY;
|
||||
}
|
||||
}
|
||||
|
||||
bool afxPlayerMovementData::hasMovementOverride()
|
||||
{
|
||||
return (movement != default_movement);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
73
Engine/source/afx/ce/afxPlayerMovement.h
Normal file
73
Engine/source/afx/ce/afxPlayerMovement.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PLAYER_MOVEMENT_H_
|
||||
#define _AFX_PLAYER_MOVEMENT_H_
|
||||
|
||||
#include "afx/ce/afxComponentEffect.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
class afxPlayerMovementData : public GameBaseData, public afxEffectDefs
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
public:
|
||||
enum OpType
|
||||
{
|
||||
OP_ADD = 0,
|
||||
OP_MULTIPLY,
|
||||
OP_REPLACE,
|
||||
OP_BITS = 2,
|
||||
};
|
||||
|
||||
public:
|
||||
F32 speed_bias;
|
||||
Point3F movement;
|
||||
U32 movement_op;
|
||||
|
||||
public:
|
||||
/*C*/ afxPlayerMovementData();
|
||||
/*C*/ afxPlayerMovementData(const afxPlayerMovementData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
bool hasMovementOverride();
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxPlayerMovementData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
typedef afxPlayerMovementData::OpType afxPlayerMovement_OpType;
|
||||
DefineEnumType( afxPlayerMovement_OpType );
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PLAYER_MOVEMENT_H_
|
||||
122
Engine/source/afx/ce/afxPlayerPuppet.cpp
Normal file
122
Engine/source/afx/ce/afxPlayerPuppet.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxPlayerPuppet.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxPlayerPuppetData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxPlayerPuppetData);
|
||||
|
||||
ConsoleDocClass( afxPlayerPuppetData,
|
||||
"@brief A datablock that specifies a Player Puppet effect.\n\n"
|
||||
|
||||
"Player Puppet effects are defined using the afxPlayerPuppetData datablock and are used to control the movement of "
|
||||
"Player objects with the AFX constraint system. The Player Puppet effect is similar to the Player Movement effect, but "
|
||||
"where movement effects 'steer' the player using the same mechanisms that allow Player control from mouse and keyboard "
|
||||
"input, Player Puppet effects totally take over a Player's transformation using the AFX constraint system."
|
||||
"\n\n"
|
||||
|
||||
"Player Puppet can be configured to directly move a Player's client ghosts as well as its server instance. When doing this, "
|
||||
"it is important to keep the general motion of the Player object and its ghosts somewhat consistent. Otherwise, obvious "
|
||||
"discontinuities in the motion will result when the Player Puppet ends and control is restored to the server Player."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxPlayerPuppetData::afxPlayerPuppetData()
|
||||
{
|
||||
obj_spec = ST_NULLSTRING;
|
||||
networking = SERVER_ONLY;
|
||||
}
|
||||
|
||||
afxPlayerPuppetData::afxPlayerPuppetData(const afxPlayerPuppetData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
obj_spec = other.obj_spec;
|
||||
networking = other.networking;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxPlayerPuppetData)
|
||||
|
||||
void afxPlayerPuppetData::initPersistFields()
|
||||
{
|
||||
addField("objectSpec", TypeString, myOffset(obj_spec),
|
||||
"...");
|
||||
addField("networking", TypeS8, myOffset(networking),
|
||||
"...");
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// disallow some field substitutions
|
||||
disableFieldSubstitutions("objectSpec");
|
||||
disableFieldSubstitutions("networking");
|
||||
}
|
||||
|
||||
bool afxPlayerPuppetData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
obj_def.parseSpec(obj_spec, runs_on_s, runs_on_c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxPlayerPuppetData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(obj_spec);
|
||||
stream->write(networking);
|
||||
}
|
||||
|
||||
void afxPlayerPuppetData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
obj_spec = stream->readSTString();
|
||||
stream->read(&networking);
|
||||
}
|
||||
|
||||
void afxPlayerPuppetData::gather_cons_defs(Vector<afxConstraintDef>& defs)
|
||||
{
|
||||
if (obj_def.isDefined())
|
||||
defs.push_back(obj_def);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
64
Engine/source/afx/ce/afxPlayerPuppet.h
Normal file
64
Engine/source/afx/ce/afxPlayerPuppet.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PLAYER_PUPPET_H_
|
||||
#define _AFX_PLAYER_PUPPET_H_
|
||||
|
||||
#include "afx/ce/afxComponentEffect.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
class afxPlayerPuppetData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry obj_spec;
|
||||
afxConstraintDef obj_def;
|
||||
|
||||
U8 networking;
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
|
||||
public:
|
||||
/*C*/ afxPlayerPuppetData();
|
||||
/*C*/ afxPlayerPuppetData(const afxPlayerPuppetData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxPlayerPuppetData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PLAYER_PUPPET_H_
|
||||
103
Engine/source/afx/ce/afxPointLight_T3D.cpp
Normal file
103
Engine/source/afx/ce/afxPointLight_T3D.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxPointLight_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxT3DPointLightData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxT3DPointLightData);
|
||||
|
||||
ConsoleDocClass( afxT3DPointLightData,
|
||||
"@brief A datablock that specifies a dynamic Point Light effect.\n\n"
|
||||
|
||||
"A Point Light effect that uses the T3D PointLight object. afxT3DPointLightData has the same fields found in PointLight but "
|
||||
"in a datablock structure."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxT3DPointLightData::afxT3DPointLightData()
|
||||
: mRadius( 5.0f )
|
||||
{
|
||||
}
|
||||
|
||||
afxT3DPointLightData::afxT3DPointLightData(const afxT3DPointLightData& other, bool temp_clone) : afxT3DLightBaseData(other, temp_clone)
|
||||
{
|
||||
mRadius = other.mRadius;
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: keep this as consistent as possible with PointLight::initPersistFields()
|
||||
//
|
||||
void afxT3DPointLightData::initPersistFields()
|
||||
{
|
||||
addGroup( "Light" );
|
||||
|
||||
addField( "radius", TypeF32, Offset( mRadius, afxT3DPointLightData ),
|
||||
"Controls the falloff of the light emission");
|
||||
|
||||
endGroup( "Light" );
|
||||
|
||||
// We do the parent fields at the end so that
|
||||
// they show up that way in the inspector.
|
||||
Parent::initPersistFields();
|
||||
|
||||
// Remove the scale field... it's already
|
||||
// defined by the light radius.
|
||||
removeField( "scale" );
|
||||
}
|
||||
|
||||
bool afxT3DPointLightData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxT3DPointLightData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write( mRadius );
|
||||
}
|
||||
|
||||
void afxT3DPointLightData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read( &mRadius );
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
56
Engine/source/afx/ce/afxPointLight_T3D.h
Normal file
56
Engine/source/afx/ce/afxPointLight_T3D.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_T3D_POINT_LIGHT_H_
|
||||
#define _AFX_T3D_POINT_LIGHT_H_
|
||||
|
||||
#include "afx/ce/afxLightBase_T3D.h"
|
||||
|
||||
class afxT3DPointLightData : public afxT3DLightBaseData
|
||||
{
|
||||
typedef afxT3DLightBaseData Parent;
|
||||
|
||||
public:
|
||||
F32 mRadius;
|
||||
|
||||
public:
|
||||
/*C*/ afxT3DPointLightData();
|
||||
/*C*/ afxT3DPointLightData(const afxT3DPointLightData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxT3DPointLightData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_T3D_POINT_LIGHT_H_
|
||||
371
Engine/source/afx/ce/afxProjectile.cpp
Normal file
371
Engine/source/afx/ce/afxProjectile.cpp
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/shapeBase.h"
|
||||
|
||||
#include "afx/ce/afxProjectile.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxProjectileData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxProjectileData);
|
||||
|
||||
ConsoleDocClass( afxProjectileData,
|
||||
"@brief A datablock that specifies a Projectile effect.\n\n"
|
||||
|
||||
"afxProjectileData inherits from ProjectileData and adds some AFX specific fields."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxProjectileData::afxProjectileData()
|
||||
{
|
||||
networking = GHOSTABLE;
|
||||
launch_pos_spec = ST_NULLSTRING;
|
||||
launch_dir_bias.zero();
|
||||
ignore_src_timeout = false;
|
||||
dynamicCollisionMask = 0;
|
||||
staticCollisionMask = 0;
|
||||
override_collision_masks = false;
|
||||
launch_dir_method = TowardPos2Constraint;
|
||||
}
|
||||
|
||||
afxProjectileData::afxProjectileData(const afxProjectileData& other, bool temp_clone) : ProjectileData(other, temp_clone)
|
||||
{
|
||||
networking = other.networking;
|
||||
launch_pos_spec = other.launch_pos_spec;
|
||||
launch_pos_def = other.launch_pos_def;
|
||||
launch_dir_bias = other.launch_dir_bias;
|
||||
ignore_src_timeout = other.ignore_src_timeout;
|
||||
dynamicCollisionMask = other.dynamicCollisionMask;
|
||||
staticCollisionMask = other.staticCollisionMask;
|
||||
override_collision_masks = other.override_collision_masks;
|
||||
launch_dir_method = other.launch_dir_method;
|
||||
}
|
||||
|
||||
ImplementEnumType( afxProjectile_LaunchDirType, "Possible projectile launch direction types.\n" "@ingroup afxProjectile\n\n" )
|
||||
{ afxProjectileData::TowardPos2Constraint, "towardPos2Constraint", "..." },
|
||||
{ afxProjectileData::OrientConstraint, "orientConstraint", "..." },
|
||||
{ afxProjectileData::LaunchDirField, "launchDirField", "..." },
|
||||
EndImplementEnumType;
|
||||
|
||||
#define myOffset(field) Offset(field, afxProjectileData)
|
||||
|
||||
void afxProjectileData::initPersistFields()
|
||||
{
|
||||
addField("networking", TypeS8, myOffset(networking),
|
||||
"...");
|
||||
addField("launchPosSpec", TypeString, myOffset(launch_pos_spec),
|
||||
"...");
|
||||
addField("launchDirBias", TypePoint3F, myOffset(launch_dir_bias),
|
||||
"...");
|
||||
addField("ignoreSourceTimeout", TypeBool, myOffset(ignore_src_timeout),
|
||||
"...");
|
||||
addField("dynamicCollisionMask", TypeS32, myOffset(dynamicCollisionMask),
|
||||
"...");
|
||||
addField("staticCollisionMask", TypeS32, myOffset(staticCollisionMask),
|
||||
"...");
|
||||
addField("overrideCollisionMasks", TypeBool, myOffset(override_collision_masks),
|
||||
"...");
|
||||
|
||||
addField("launchDirMethod", TYPEID<afxProjectileData::LaunchDirType>(), myOffset(launch_dir_method),
|
||||
"Possible values: towardPos2Constraint, orientConstraint, or launchDirField.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxProjectileData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
launch_pos_def.parseSpec(launch_pos_spec, runs_on_s, runs_on_c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxProjectileData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write(networking);
|
||||
stream->writeString(launch_pos_spec);
|
||||
if (stream->writeFlag(!launch_dir_bias.isZero()))
|
||||
{
|
||||
stream->write(launch_dir_bias.x);
|
||||
stream->write(launch_dir_bias.y);
|
||||
stream->write(launch_dir_bias.z);
|
||||
}
|
||||
stream->writeFlag(ignore_src_timeout);
|
||||
if (stream->writeFlag(override_collision_masks))
|
||||
{
|
||||
stream->write(dynamicCollisionMask);
|
||||
stream->write(staticCollisionMask);
|
||||
}
|
||||
|
||||
stream->writeInt(launch_dir_method, 2);
|
||||
}
|
||||
|
||||
void afxProjectileData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read(&networking);
|
||||
launch_pos_spec = stream->readSTString();
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read(&launch_dir_bias.x);
|
||||
stream->read(&launch_dir_bias.y);
|
||||
stream->read(&launch_dir_bias.z);
|
||||
}
|
||||
else
|
||||
launch_dir_bias.zero();
|
||||
ignore_src_timeout = stream->readFlag();
|
||||
if ((override_collision_masks = stream->readFlag()) == true)
|
||||
{
|
||||
stream->read(&dynamicCollisionMask);
|
||||
stream->read(&staticCollisionMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynamicCollisionMask = 0;
|
||||
staticCollisionMask = 0;
|
||||
}
|
||||
|
||||
launch_dir_method = (U32) stream->readInt(2);
|
||||
}
|
||||
|
||||
void afxProjectileData::gather_cons_defs(Vector<afxConstraintDef>& defs)
|
||||
{
|
||||
if (launch_pos_def.isDefined())
|
||||
defs.push_back(launch_pos_def);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxProjectile
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxProjectile);
|
||||
|
||||
ConsoleDocClass( afxProjectile,
|
||||
"@brief A Projectile effect as defined by an afxProjectileData datablock.\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxProjectile::afxProjectile()
|
||||
{
|
||||
chor_id = 0;
|
||||
hookup_with_chor = false;
|
||||
ghost_cons_name = ST_NULLSTRING;
|
||||
client_only = false;
|
||||
}
|
||||
|
||||
afxProjectile::afxProjectile(U32 networking, U32 chor_id, StringTableEntry cons_name)
|
||||
{
|
||||
if (networking & SCOPE_ALWAYS)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
client_only = false;
|
||||
}
|
||||
else if (networking & GHOSTABLE)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(Ghostable);
|
||||
client_only = false;
|
||||
}
|
||||
else if (networking & SERVER_ONLY)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
client_only = false;
|
||||
}
|
||||
else // if (networking & CLIENT_ONLY)
|
||||
{
|
||||
mNetFlags.clear();
|
||||
mNetFlags.set(IsGhost);
|
||||
client_only = true;
|
||||
}
|
||||
|
||||
this->chor_id = chor_id;
|
||||
hookup_with_chor = false;
|
||||
this->ghost_cons_name = cons_name;
|
||||
}
|
||||
|
||||
afxProjectile::~afxProjectile()
|
||||
{
|
||||
}
|
||||
|
||||
void afxProjectile::init(Point3F& pos, Point3F& vel, ShapeBase* src_obj)
|
||||
{
|
||||
mCurrPosition = pos;
|
||||
mCurrVelocity = vel;
|
||||
if (src_obj)
|
||||
{
|
||||
mSourceObject = src_obj;
|
||||
mSourceObjectId = src_obj->getId();
|
||||
mSourceObjectSlot = 0;
|
||||
}
|
||||
|
||||
setPosition(mCurrPosition);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxProjectile::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
return Parent::onNewDataBlock(dptr, reload);
|
||||
}
|
||||
|
||||
void afxProjectile::processTick(const Move* move)
|
||||
{
|
||||
// note: this deletion test must occur before calling to the parent's
|
||||
// processTick() because if this is a server projectile, the parent
|
||||
// might decide to delete it and then client_only will no longer be
|
||||
// valid after the return.
|
||||
bool do_delete = (client_only && mCurrTick >= mDataBlock->lifetime);
|
||||
|
||||
Parent::processTick(move);
|
||||
|
||||
if (do_delete)
|
||||
deleteObject();
|
||||
}
|
||||
|
||||
void afxProjectile::interpolateTick(F32 delta)
|
||||
{
|
||||
if (client_only)
|
||||
return;
|
||||
|
||||
Parent::interpolateTick(delta);
|
||||
}
|
||||
|
||||
void afxProjectile::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if (hookup_with_chor)
|
||||
{
|
||||
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
|
||||
if (chor)
|
||||
{
|
||||
chor->setGhostConstraintObject(this, ghost_cons_name);
|
||||
hookup_with_chor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool afxProjectile::onAdd()
|
||||
{
|
||||
if(!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
// add to client side mission cleanup
|
||||
SimGroup *cleanup = dynamic_cast<SimGroup *>( Sim::findObject( "ClientMissionCleanup") );
|
||||
if( cleanup != NULL )
|
||||
{
|
||||
cleanup->addObject( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertFatal( false, "Error, could not find ClientMissionCleanup group" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxProjectile::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
U32 afxProjectile::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(conn, mask, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
stream->write(chor_id);
|
||||
stream->writeString(ghost_cons_name);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxProjectile::unpackUpdate(NetConnection * conn, BitStream * stream)
|
||||
{
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read(&chor_id);
|
||||
ghost_cons_name = stream->readSTString();
|
||||
|
||||
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
|
||||
hookup_with_chor = true;
|
||||
}
|
||||
}
|
||||
|
||||
class afxProjectileDeleteEvent : public SimEvent
|
||||
{
|
||||
public:
|
||||
void process(SimObject *object)
|
||||
{
|
||||
object->deleteObject();
|
||||
}
|
||||
};
|
||||
|
||||
void afxProjectile::explode(const Point3F& p, const Point3F& n, const U32 collideType)
|
||||
{
|
||||
// Make sure we don't explode twice...
|
||||
if ( isHidden() )
|
||||
return;
|
||||
|
||||
Parent::explode(p, n, collideType);
|
||||
|
||||
if (isClientObject() && client_only)
|
||||
Sim::postEvent(this, new afxProjectileDeleteEvent, Sim::getCurrentTime() + DeleteWaitTime);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
117
Engine/source/afx/ce/afxProjectile.h
Normal file
117
Engine/source/afx/ce/afxProjectile.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_PROJECTILE_H_
|
||||
#define _AFX_PROJECTILE_H_
|
||||
|
||||
#include "lighting/lightInfo.h"
|
||||
#include "T3D/projectile.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxConstraint.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxProjectileData
|
||||
|
||||
class afxProjectileData : public ProjectileData, public afxEffectDefs
|
||||
{
|
||||
typedef ProjectileData Parent;
|
||||
|
||||
public:
|
||||
enum LaunchDirType {
|
||||
TowardPos2Constraint,
|
||||
OrientConstraint,
|
||||
LaunchDirField
|
||||
};
|
||||
|
||||
public:
|
||||
U8 networking;
|
||||
StringTableEntry launch_pos_spec;
|
||||
afxConstraintDef launch_pos_def;
|
||||
Point3F launch_dir_bias;
|
||||
bool ignore_src_timeout;
|
||||
U32 dynamicCollisionMask;
|
||||
U32 staticCollisionMask;
|
||||
bool override_collision_masks;
|
||||
U32 launch_dir_method;
|
||||
|
||||
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
|
||||
|
||||
public:
|
||||
/*C*/ afxProjectileData();
|
||||
/*C*/ afxProjectileData(const afxProjectileData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxProjectileData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
typedef afxProjectileData::LaunchDirType afxProjectile_LaunchDirType;
|
||||
DefineEnumType( afxProjectile_LaunchDirType );
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxProjectile
|
||||
|
||||
class afxProjectile : public Projectile, public afxEffectDefs
|
||||
{
|
||||
typedef Projectile Parent;
|
||||
|
||||
private:
|
||||
U32 chor_id;
|
||||
bool hookup_with_chor;
|
||||
StringTableEntry ghost_cons_name;
|
||||
bool client_only;
|
||||
|
||||
public:
|
||||
/*C*/ afxProjectile();
|
||||
/*C*/ afxProjectile(U32 networking, U32 chor_id, StringTableEntry cons_name);
|
||||
/*D*/ ~afxProjectile();
|
||||
|
||||
void init(Point3F& pos, Point3F& vel, ShapeBase* src_obj);
|
||||
|
||||
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
|
||||
virtual void processTick(const Move *move);
|
||||
virtual void interpolateTick(F32 delta);
|
||||
virtual void advanceTime(F32 dt);
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||
virtual void explode(const Point3F& p, const Point3F& n, const U32 collideType);
|
||||
|
||||
DECLARE_CONOBJECT(afxProjectile);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_PROJECTILE_H_
|
||||
94
Engine/source/afx/ce/afxScriptEvent.cpp
Normal file
94
Engine/source/afx/ce/afxScriptEvent.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxScriptEvent.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxScriptEventData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxScriptEventData);
|
||||
|
||||
ConsoleDocClass( afxScriptEventData,
|
||||
"@brief A datablock that specifies a Script Event effect.\n\n"
|
||||
|
||||
"Arbitrary script functions can be called as an AFX effect using afxScriptEventData. They are useful for implementing "
|
||||
"high-level scripted side-effects such as character resurrection or teleportation."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxScriptEventData::afxScriptEventData()
|
||||
{
|
||||
method_name = ST_NULLSTRING;
|
||||
script_data = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxScriptEventData::afxScriptEventData(const afxScriptEventData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
method_name = other.method_name;
|
||||
script_data = other.script_data;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxScriptEventData)
|
||||
|
||||
void afxScriptEventData::initPersistFields()
|
||||
{
|
||||
addField("methodName", TypeString, myOffset(method_name),
|
||||
"The name of a script method defined for the instance class of an effects "
|
||||
"choreographer. The arguments used to call this method are determined by the type "
|
||||
"of choreographer.");
|
||||
addField("scriptData", TypeString, myOffset(script_data),
|
||||
"An arbitrary blind data value which is passed in as an argument of the script event "
|
||||
"method. The value of scriptData can be used to differentiate uses when handling "
|
||||
"different script event effects with a single method.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxScriptEventData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(method_name);
|
||||
stream->writeString(script_data);
|
||||
}
|
||||
|
||||
void afxScriptEventData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
method_name = stream->readSTString();
|
||||
script_data = stream->readSTString();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
57
Engine/source/afx/ce/afxScriptEvent.h
Normal file
57
Engine/source/afx/ce/afxScriptEvent.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_SCRIPT_EVENT_H_
|
||||
#define _AFX_SCRIPT_EVENT_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxScriptEventData
|
||||
|
||||
struct afxScriptEventData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
|
||||
public:
|
||||
StringTableEntry method_name;
|
||||
StringTableEntry script_data;
|
||||
|
||||
public:
|
||||
/*C*/ afxScriptEventData();
|
||||
/*C*/ afxScriptEventData(const afxScriptEventData&, bool = false);
|
||||
|
||||
void packData(BitStream* stream);
|
||||
void unpackData(BitStream* stream);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxScriptEventData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_SCRIPT_EVENT_H_
|
||||
112
Engine/source/afx/ce/afxSpotLight_T3D.cpp
Normal file
112
Engine/source/afx/ce/afxSpotLight_T3D.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#include "afx/ce/afxSpotLight_T3D.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxT3DSpotLightData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxT3DSpotLightData);
|
||||
|
||||
ConsoleDocClass( afxT3DSpotLightData,
|
||||
"@brief A datablock that specifies a dynamic Spot Light effect.\n\n"
|
||||
|
||||
"A Spot Light effect that uses the T3D SpotLight object. afxT3DSpotLightData has the same fields found in SpotLight but in "
|
||||
"a datablock structure."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxT3DSpotLightData::afxT3DSpotLightData()
|
||||
: mRange( 10.0f ),
|
||||
mInnerConeAngle( 40.0f ),
|
||||
mOuterConeAngle( 45.0f )
|
||||
{
|
||||
}
|
||||
|
||||
afxT3DSpotLightData::afxT3DSpotLightData(const afxT3DSpotLightData& other, bool temp_clone) : afxT3DLightBaseData(other, temp_clone)
|
||||
{
|
||||
mRange = other.mRange;
|
||||
mInnerConeAngle = other.mInnerConeAngle;
|
||||
mOuterConeAngle = other.mOuterConeAngle;
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: keep this as consistent as possible with PointLight::initPersistFields()
|
||||
//
|
||||
void afxT3DSpotLightData::initPersistFields()
|
||||
{
|
||||
addGroup( "Light" );
|
||||
|
||||
addField( "range", TypeF32, Offset( mRange, afxT3DSpotLightData ),
|
||||
"...");
|
||||
addField( "innerAngle", TypeF32, Offset( mInnerConeAngle, afxT3DSpotLightData ),
|
||||
"...");
|
||||
addField( "outerAngle", TypeF32, Offset( mOuterConeAngle, afxT3DSpotLightData ),
|
||||
"...");
|
||||
|
||||
endGroup( "Light" );
|
||||
|
||||
// We do the parent fields at the end so that
|
||||
// they show up that way in the inspector.
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool afxT3DSpotLightData::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxT3DSpotLightData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->write( mRange );
|
||||
stream->write( mInnerConeAngle );
|
||||
stream->write( mOuterConeAngle );
|
||||
}
|
||||
|
||||
void afxT3DSpotLightData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
stream->read( &mRange );
|
||||
stream->read( &mInnerConeAngle );
|
||||
stream->read( &mOuterConeAngle );
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
58
Engine/source/afx/ce/afxSpotLight_T3D.h
Normal file
58
Engine/source/afx/ce/afxSpotLight_T3D.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 _AFX_T3D_SPOT_LIGHT_H_
|
||||
#define _AFX_T3D_SPOT_LIGHT_H_
|
||||
|
||||
#include "afx/ce/afxLightBase_T3D.h"
|
||||
|
||||
class afxT3DSpotLightData : public afxT3DLightBaseData
|
||||
{
|
||||
typedef afxT3DLightBaseData Parent;
|
||||
|
||||
public:
|
||||
F32 mRange;
|
||||
F32 mInnerConeAngle;
|
||||
F32 mOuterConeAngle;
|
||||
|
||||
public:
|
||||
/*C*/ afxT3DSpotLightData();
|
||||
/*C*/ afxT3DSpotLightData(const afxT3DSpotLightData&, bool = false);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void packData(BitStream*);
|
||||
virtual void unpackData(BitStream*);
|
||||
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(afxT3DSpotLightData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#endif // _AFX_T3D_SPOT_LIGHT_H_
|
||||
241
Engine/source/afx/ce/afxStaticShape.cpp
Normal file
241
Engine/source/afx/ce/afxStaticShape.cpp
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION 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 "afx/arcaneFX.h"
|
||||
|
||||
#include "ts/tsShapeInstance.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxStaticShape.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxStaticShapeData
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(afxStaticShapeData);
|
||||
|
||||
ConsoleDocClass( afxStaticShapeData,
|
||||
"@brief A datablock that specifies a StaticShape effect.\n\n"
|
||||
|
||||
"afxStaticShapeData inherits from StaticShapeData and adds some AFX specific fields. StaticShape effects should be "
|
||||
"specified using afxStaticShapeData rather than StaticShapeData datablocks."
|
||||
"\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
afxStaticShapeData::afxStaticShapeData()
|
||||
{
|
||||
sequence = ST_NULLSTRING;
|
||||
ignore_scene_amb = false;
|
||||
use_custom_scene_amb = false;
|
||||
custom_scene_amb.set(0.5f, 0.5f, 0.5f);
|
||||
do_spawn = false;
|
||||
}
|
||||
|
||||
afxStaticShapeData::afxStaticShapeData(const afxStaticShapeData& other, bool temp_clone) : StaticShapeData(other, temp_clone)
|
||||
{
|
||||
sequence = other.sequence;
|
||||
ignore_scene_amb = other.ignore_scene_amb;
|
||||
use_custom_scene_amb = other.use_custom_scene_amb;
|
||||
custom_scene_amb = other.custom_scene_amb;
|
||||
do_spawn = other.do_spawn;
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxStaticShapeData)
|
||||
|
||||
void afxStaticShapeData::initPersistFields()
|
||||
{
|
||||
addField("sequence", TypeFilename, myOffset(sequence),
|
||||
"An animation sequence in the StaticShape to play.");
|
||||
addField("ignoreSceneAmbient", TypeBool, myOffset(ignore_scene_amb),
|
||||
"...");
|
||||
addField("useCustomSceneAmbient", TypeBool, myOffset(use_custom_scene_amb),
|
||||
"...");
|
||||
addField("customSceneAmbient", TypeColorF, myOffset(custom_scene_amb),
|
||||
"...");
|
||||
addField("doSpawn", TypeBool, myOffset(do_spawn),
|
||||
"When true, the StaticShape effect will leave behind the StaticShape object as a "
|
||||
"permanent part of the scene.");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void afxStaticShapeData::packData(BitStream* stream)
|
||||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(sequence);
|
||||
stream->writeFlag(ignore_scene_amb);
|
||||
if (stream->writeFlag(use_custom_scene_amb))
|
||||
stream->write(custom_scene_amb);
|
||||
stream->writeFlag(do_spawn);
|
||||
}
|
||||
|
||||
void afxStaticShapeData::unpackData(BitStream* stream)
|
||||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
sequence = stream->readSTString();
|
||||
ignore_scene_amb = stream->readFlag();
|
||||
if ((use_custom_scene_amb = stream->readFlag()) == true)
|
||||
stream->read(&custom_scene_amb);
|
||||
do_spawn = stream->readFlag();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxStaticShape
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(afxStaticShape);
|
||||
|
||||
ConsoleDocClass( afxStaticShape,
|
||||
"@brief A StaticShape effect as defined by an afxStaticShapeData datablock.\n\n"
|
||||
|
||||
"@ingroup afxEffects\n"
|
||||
"@ingroup AFX\n"
|
||||
);
|
||||
|
||||
afxStaticShape::afxStaticShape()
|
||||
{
|
||||
afx_data = 0;
|
||||
is_visible = true;
|
||||
chor_id = 0;
|
||||
hookup_with_chor = false;
|
||||
ghost_cons_name = ST_NULLSTRING;
|
||||
}
|
||||
|
||||
afxStaticShape::~afxStaticShape()
|
||||
{
|
||||
}
|
||||
|
||||
void afxStaticShape::init(U32 chor_id, StringTableEntry cons_name)
|
||||
{
|
||||
this->chor_id = chor_id;
|
||||
ghost_cons_name = cons_name;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
bool afxStaticShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
||||
{
|
||||
mDataBlock = dynamic_cast<StaticShapeData*>(dptr);
|
||||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
afx_data = dynamic_cast<afxStaticShapeData*>(mDataBlock);
|
||||
|
||||
if (!mShapeInstance)
|
||||
return true;
|
||||
|
||||
const char* seq_name = 0;
|
||||
|
||||
// if datablock is afxStaticShapeData we get the sequence setting
|
||||
// directly from the datablock on the client-side only
|
||||
if (afx_data)
|
||||
{
|
||||
if (isClientObject())
|
||||
seq_name = afx_data->sequence;
|
||||
}
|
||||
// otherwise datablock is stock StaticShapeData and we look for
|
||||
// a sequence name on a dynamic field on the server.
|
||||
else
|
||||
{
|
||||
if (isServerObject())
|
||||
seq_name = mDataBlock->getDataField(StringTable->insert("sequence"),0);
|
||||
}
|
||||
|
||||
// if we have a sequence name, attempt to start a thread
|
||||
if (seq_name)
|
||||
{
|
||||
TSShape* shape = mShapeInstance->getShape();
|
||||
if (shape)
|
||||
{
|
||||
S32 seq = shape->findSequence(seq_name);
|
||||
if (seq != -1)
|
||||
setThreadSequence(0,seq);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxStaticShape::advanceTime(F32 dt)
|
||||
{
|
||||
Parent::advanceTime(dt);
|
||||
|
||||
if (hookup_with_chor)
|
||||
{
|
||||
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
|
||||
if (chor)
|
||||
{
|
||||
chor->setGhostConstraintObject(this, ghost_cons_name);
|
||||
hookup_with_chor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 afxStaticShape::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
|
||||
{
|
||||
U32 retMask = Parent::packUpdate(conn, mask, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
stream->write(chor_id);
|
||||
stream->writeString(ghost_cons_name);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxStaticShape::unpackUpdate(NetConnection * conn, BitStream * stream)
|
||||
{
|
||||
Parent::unpackUpdate(conn, stream);
|
||||
|
||||
// InitialUpdate
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read(&chor_id);
|
||||
ghost_cons_name = stream->readSTString();
|
||||
|
||||
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
|
||||
hookup_with_chor = true;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
void afxStaticShape::prepRenderImage(SceneRenderState* state)
|
||||
{
|
||||
if (is_visible)
|
||||
Parent::prepRenderImage(state);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue