mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 07:04:36 +00:00
Add all new AFX files
This commit is contained in:
parent
3d7c1bbbf7
commit
d7a8510756
218 changed files with 54970 additions and 0 deletions
200
Engine/source/afx/ea/afxEA_AnimClip.cpp
Normal file
200
Engine/source/afx/ea/afxEA_AnimClip.cpp
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxAnimClip.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_AnimClip
|
||||
|
||||
class afxEA_AnimClip : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxAnimClipData* clip_data;
|
||||
bool started;
|
||||
F32 anim_lifetime;
|
||||
U32 anim_tag;
|
||||
U32 lock_tag;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_AnimClip();
|
||||
/*C*/ ~afxEA_AnimClip();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_AnimClip::afxEA_AnimClip()
|
||||
{
|
||||
clip_data = 0;
|
||||
started = false;
|
||||
anim_lifetime = 0;
|
||||
anim_tag = 0;
|
||||
lock_tag = 0;
|
||||
}
|
||||
|
||||
afxEA_AnimClip::~afxEA_AnimClip()
|
||||
{
|
||||
if (clip_data && clip_data->isTempClone())
|
||||
delete clip_data;
|
||||
clip_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_AnimClip::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
clip_data = dynamic_cast<afxAnimClipData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_AnimClip::ea_start()
|
||||
{
|
||||
if (!clip_data)
|
||||
{
|
||||
Con::errorf("afxEA_AnimClip::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
if (full_lifetime == INFINITE_LIFETIME && pos_constraint != 0)
|
||||
anim_lifetime = pos_constraint->getAnimClipDuration(clip_data->clip_name);
|
||||
else
|
||||
anim_lifetime = full_lifetime;
|
||||
|
||||
anim_tag = 0;
|
||||
lock_tag = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_AnimClip::ea_update(F32 dt)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
if (!started && pos_constraint != 0)
|
||||
{
|
||||
bool go_for_it = true;
|
||||
|
||||
if (pos_constraint->getDamageState() == ShapeBase::Enabled)
|
||||
go_for_it = !clip_data->ignore_enabled;
|
||||
else if (pos_constraint->getDamageState() == ShapeBase::Disabled)
|
||||
go_for_it = !clip_data->ignore_disabled;
|
||||
|
||||
if (go_for_it && (clip_data->ignore_first_person || clip_data->ignore_third_person))
|
||||
{
|
||||
ShapeBase* shape = dynamic_cast<ShapeBase*>(pos_constraint->getSceneObject());
|
||||
if (shape)
|
||||
{
|
||||
bool is_first_person = shape->isFirstPerson();
|
||||
if (clip_data->ignore_first_person && is_first_person)
|
||||
go_for_it = false;
|
||||
if (clip_data->ignore_third_person && !is_first_person)
|
||||
go_for_it = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (go_for_it)
|
||||
{
|
||||
F32 rate = clip_data->rate/prop_time_factor;
|
||||
F32 pos = mFmod(life_elapsed, anim_lifetime)/anim_lifetime;
|
||||
pos = mFmod(pos + clip_data->pos_offset, 1.0);
|
||||
if (clip_data->rate < 0)
|
||||
pos = 1.0f - pos;
|
||||
anim_tag = pos_constraint->setAnimClip(clip_data->clip_name, pos, rate, clip_data->trans,
|
||||
clip_data->is_death_anim);
|
||||
if (clip_data->lock_anim)
|
||||
lock_tag = pos_constraint->lockAnimation();
|
||||
}
|
||||
started = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_AnimClip::ea_finish(bool was_stopped)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
if (pos_constraint && anim_tag != 0)
|
||||
{
|
||||
pos_constraint->resetAnimation(anim_tag);
|
||||
}
|
||||
if (pos_constraint && lock_tag != 0)
|
||||
pos_constraint->unlockAnimation(lock_tag);
|
||||
|
||||
started = false;
|
||||
}
|
||||
|
||||
void afxEA_AnimClip::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (clip_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxAnimClipData* orig_db = clip_data;
|
||||
clip_data = new afxAnimClipData(*orig_db, true);
|
||||
orig_db->performSubstitutions(clip_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_AnimClipDesc
|
||||
|
||||
class afxEA_AnimClipDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_AnimClipDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_AnimClip; }
|
||||
};
|
||||
|
||||
afxEA_AnimClipDesc afxEA_AnimClipDesc::desc;
|
||||
|
||||
bool afxEA_AnimClipDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxAnimClipData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_AnimClipDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
108
Engine/source/afx/ea/afxEA_AnimLock.cpp
Normal file
108
Engine/source/afx/ea/afxEA_AnimLock.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxAnimLock.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_AnimLock
|
||||
|
||||
class afxEA_AnimLock : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
bool started;
|
||||
U32 lock_tag;
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_AnimLock();
|
||||
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_AnimLock::afxEA_AnimLock()
|
||||
{
|
||||
started = false;
|
||||
lock_tag = 0;
|
||||
}
|
||||
|
||||
bool afxEA_AnimLock::ea_update(F32 dt)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
if (!started && pos_constraint != 0)
|
||||
{
|
||||
lock_tag = pos_constraint->lockAnimation();
|
||||
started = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_AnimLock::ea_finish(bool was_stopped)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
if (pos_constraint && lock_tag != 0)
|
||||
{
|
||||
pos_constraint->unlockAnimation(lock_tag);
|
||||
}
|
||||
|
||||
started = false;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_AnimLockDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_AnimLockDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_AnimLock; }
|
||||
};
|
||||
|
||||
afxEA_AnimLockDesc afxEA_AnimLockDesc::desc;
|
||||
|
||||
bool afxEA_AnimLockDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxAnimLockData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_AnimLockDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
264
Engine/source/afx/ea/afxEA_AreaDamage.cpp
Normal file
264
Engine/source/afx/ea/afxEA_AreaDamage.cpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxAreaDamage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_AreaDamage
|
||||
|
||||
class afxEA_AreaDamage : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxAreaDamageData* damage_data;
|
||||
Point3F impact_pos;
|
||||
bool damage_is_done;
|
||||
SceneObject* cons_obj;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
void deal_area_damage();
|
||||
void apply_damage(ShapeBase*, F32 damage, const char* flavor, Point3F& pos);
|
||||
void apply_impulse(ShapeBase*, F32 impulse, Point3F& pos);
|
||||
void notify_damage_source(ShapeBase* damaged, F32 damage, const char* flavor, Point3F& pos);
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_AreaDamage();
|
||||
/*C*/ ~afxEA_AreaDamage();
|
||||
|
||||
virtual bool isDone();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_AreaDamage::afxEA_AreaDamage()
|
||||
{
|
||||
damage_data = 0;
|
||||
impact_pos.zero();
|
||||
damage_is_done = false;
|
||||
cons_obj = 0;
|
||||
}
|
||||
|
||||
afxEA_AreaDamage::~afxEA_AreaDamage()
|
||||
{
|
||||
if (damage_data && damage_data->isTempClone())
|
||||
delete damage_data;
|
||||
damage_data = 0;
|
||||
}
|
||||
|
||||
bool afxEA_AreaDamage::isDone()
|
||||
{
|
||||
return damage_is_done;
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
damage_data = dynamic_cast<afxAreaDamageData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_AreaDamage::ea_start()
|
||||
{
|
||||
if (!damage_data)
|
||||
{
|
||||
Con::errorf("afxEA_AreaDamage::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_AreaDamage::ea_update(F32 dt)
|
||||
{
|
||||
if (!damage_is_done)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (pos_cons)
|
||||
{
|
||||
pos_cons->getPosition(impact_pos);
|
||||
cons_obj = pos_cons->getSceneObject();
|
||||
}
|
||||
|
||||
deal_area_damage();
|
||||
|
||||
damage_is_done = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::ea_finish(bool was_stopped)
|
||||
{
|
||||
damage_is_done = false;
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (damage_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxAreaDamageData* orig_db = damage_data;
|
||||
damage_data = new afxAreaDamageData(*orig_db, true);
|
||||
orig_db->performSubstitutions(damage_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
// radiusDamage(%sourceObject, %position, %radius, %damage, %damageType, %impulse, %excluded)
|
||||
|
||||
void afxEA_AreaDamage::deal_area_damage()
|
||||
{
|
||||
// initContainerRadiusSearch -- afterwards Container::mSearchList contains objects within radius sorted by distance
|
||||
gServerContainer.initRadiusSearch(impact_pos, damage_data->radius, ShapeBaseObjectType);
|
||||
|
||||
F32 halfradius = damage_data->radius*0.5f;
|
||||
|
||||
const Vector<SimObjectPtr<SceneObject>*>& list = gServerContainer.getRadiusSearchList();
|
||||
for (S32 i = 0; i < list.size(); i++)
|
||||
{
|
||||
if (!list[i]->isNull())
|
||||
{
|
||||
ShapeBase* shape = dynamic_cast<ShapeBase*>((SceneObject*)(*list[i]));
|
||||
if (!shape || (shape->getTypeMask() & CameraObjectType))
|
||||
continue;
|
||||
|
||||
if (damage_data->exclude_cons_obj && cons_obj == *list[i])
|
||||
continue;
|
||||
|
||||
#if 0 // AFX_T3D_DISABLED -- calcExplosionCoverage() is a script function
|
||||
// so we currently assign a coverage value of 1.0.
|
||||
|
||||
U32 mask = InteriorObjectType | TerrainObjectType | VehicleObjectType;
|
||||
F32 coverage = calcExplosionCoverage(impact_pos, shape, mask);
|
||||
if (coverage == 0.0f)
|
||||
continue;
|
||||
#else
|
||||
F32 coverage = 1.0f;
|
||||
#endif
|
||||
|
||||
// calulate distance
|
||||
Point3F pos;
|
||||
shape->getWorldBox().getCenter(&pos);
|
||||
F32 dist = (pos - impact_pos).len();
|
||||
|
||||
F32 min_dist = shape->getWorldBox().len_x();
|
||||
if (shape->getWorldBox().len_y() < min_dist)
|
||||
min_dist = shape->getWorldBox().len_y();
|
||||
if (shape->getWorldBox().len_z() < min_dist)
|
||||
min_dist = shape->getWorldBox().len_z();
|
||||
|
||||
dist -= min_dist;
|
||||
if (dist < 0)
|
||||
dist = 0;
|
||||
|
||||
F32 dist_scale = (dist < halfradius) ? 1.0f : 1.0f - ((dist - halfradius)/halfradius);
|
||||
|
||||
F32 damage = damage_data->amount*coverage*dist_scale;
|
||||
apply_damage(shape, damage, damage_data->flavor, impact_pos);
|
||||
apply_impulse(shape, damage_data->impulse*dist_scale, impact_pos);
|
||||
|
||||
if (damage_data->notify_damage_src)
|
||||
notify_damage_source(shape, damage, damage_data->flavor, impact_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::notify_damage_source(ShapeBase* damaged, F32 damage, const char* flavor, Point3F& pos)
|
||||
{
|
||||
if (mIsZero(damage))
|
||||
return;
|
||||
|
||||
char *posArg = Con::getArgBuffer(64);
|
||||
dSprintf(posArg, 64, "%f %f %f", pos.x, pos.y, pos.z);
|
||||
|
||||
Con::executef(choreographer->getDataBlock(), "onInflictedAreaDamage",
|
||||
choreographer->getIdString(),
|
||||
damaged->getIdString(),
|
||||
Con::getFloatArg(damage),
|
||||
flavor,
|
||||
posArg);
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::apply_damage(ShapeBase* shape, F32 damage, const char* flavor, Point3F& pos)
|
||||
{
|
||||
if (mIsZero(damage))
|
||||
return;
|
||||
|
||||
char *posArg = Con::getArgBuffer(64);
|
||||
dSprintf(posArg, 64, "%f %f %f", pos.x, pos.y, pos.z);
|
||||
|
||||
Con::executef(shape, "damage",
|
||||
choreographer->getIdString(),
|
||||
posArg,
|
||||
Con::getFloatArg(damage),
|
||||
flavor);
|
||||
}
|
||||
|
||||
void afxEA_AreaDamage::apply_impulse(ShapeBase* shape, F32 impulse, Point3F& pos)
|
||||
{
|
||||
if (impulse <= 0.0f)
|
||||
return;
|
||||
|
||||
Point3F center; shape->getWorldBox().getCenter(¢er);
|
||||
VectorF impulse_vec = center - pos;
|
||||
impulse_vec.normalizeSafe();
|
||||
impulse_vec *= impulse;
|
||||
shape->applyImpulse(pos, impulse_vec);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_AreaDamageDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_AreaDamageDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const { return false; }
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_AreaDamage; }
|
||||
};
|
||||
|
||||
afxEA_AreaDamageDesc afxEA_AreaDamageDesc::desc;
|
||||
|
||||
bool afxEA_AreaDamageDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxAreaDamageData) == typeid(*db));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
178
Engine/source/afx/ea/afxEA_AudioBank.cpp
Normal file
178
Engine/source/afx/ea/afxEA_AudioBank.cpp
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "sfx/sfxSystem.h"
|
||||
#include "sfx/sfxSource.h"
|
||||
#include "sfx/sfxProfile.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxAudioBank.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_AudioBank
|
||||
|
||||
class afxEA_AudioBank : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
SFXSource* sound_handle;
|
||||
afxAudioBank* sound_bank;
|
||||
|
||||
S32 play_index;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_AudioBank();
|
||||
/*D*/ ~afxEA_AudioBank();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_AudioBank::afxEA_AudioBank()
|
||||
{
|
||||
sound_handle = 0;
|
||||
sound_bank = 0;
|
||||
play_index = -1;
|
||||
}
|
||||
|
||||
afxEA_AudioBank::~afxEA_AudioBank()
|
||||
{
|
||||
if (sound_bank && sound_bank->isTempClone())
|
||||
delete sound_bank;
|
||||
sound_bank = 0;
|
||||
sound_handle = 0;
|
||||
}
|
||||
|
||||
void afxEA_AudioBank::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
sound_bank = dynamic_cast<afxAudioBank*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_AudioBank::ea_start()
|
||||
{
|
||||
if (!sound_bank)
|
||||
{
|
||||
Con::errorf("afxEA_AudioBank::ea_start() -- missing or incompatible afxAudioBank.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (sound_bank->mPath == ST_NULLSTRING)
|
||||
return false;
|
||||
|
||||
play_index = sound_bank->play_index;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_AudioBank::ea_update(F32 dt)
|
||||
{
|
||||
if (!sound_handle)
|
||||
{
|
||||
if (play_index >= 0 && play_index < 32 && sound_bank->mFilenames[play_index] != ST_NULLSTRING)
|
||||
{
|
||||
SFXProfile* temp_prof = new SFXProfile(sound_bank->mDescriptionObject,
|
||||
avar("%s/%s", sound_bank->mPath, sound_bank->mFilenames[play_index]),
|
||||
true);
|
||||
if (!temp_prof->registerObject())
|
||||
{
|
||||
Con::errorf( "afxEA_AudioBank::ea_update() -- unable to create profile");
|
||||
delete temp_prof;
|
||||
}
|
||||
else
|
||||
{
|
||||
sound_handle = SFX->createSource(temp_prof);
|
||||
if (sound_handle)
|
||||
sound_handle->play();
|
||||
temp_prof->setAutoDelete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sound_handle)
|
||||
{
|
||||
sound_handle->setTransform(updated_xfm);
|
||||
sound_handle->setVolume(updated_scale.x*fade_value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_AudioBank::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (sound_handle)
|
||||
{
|
||||
sound_handle->stop();
|
||||
SFX_DELETE(sound_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_AudioBank::do_runtime_substitutions()
|
||||
{
|
||||
sound_bank = sound_bank->cloneAndPerformSubstitutions(choreographer, group_index);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_SoundBankDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_SoundBankDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
//virtual void prepEffect(afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_AudioBank; }
|
||||
};
|
||||
|
||||
afxEA_SoundBankDesc afxEA_SoundBankDesc::desc;
|
||||
|
||||
bool afxEA_SoundBankDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxAudioBank) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_SoundBankDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
SFXDescription* desc = ((SFXProfile*)ew->effect_data)->getDescription();
|
||||
return (desc && desc->mIsLooping) ? (timing.lifetime < 0) : false;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
199
Engine/source/afx/ea/afxEA_Billboard.cpp
Normal file
199
Engine/source/afx/ea/afxEA_Billboard.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
#include "afx/ce/afxBillboard.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Billboard -- This is the adapter for geometry primitives.
|
||||
|
||||
class afxEA_Billboard : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxBillboardData* bb_data;
|
||||
afxBillboard* bb;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Billboard();
|
||||
/*D*/ ~afxEA_Billboard();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual void getUpdatedBoxCenter(Point3F& pos);
|
||||
virtual void getBaseColor(LinearColorF& color) { if (bb_data) color = bb_data->color; }
|
||||
};
|
||||
|
||||
|
||||
afxEA_Billboard::afxEA_Billboard()
|
||||
{
|
||||
bb_data = 0;
|
||||
bb = 0;
|
||||
}
|
||||
|
||||
afxEA_Billboard::~afxEA_Billboard()
|
||||
{
|
||||
if (bb)
|
||||
bb->deleteObject();
|
||||
if (bb_data && bb_data->isTempClone())
|
||||
delete bb_data;
|
||||
bb_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_Billboard::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
bb_data = dynamic_cast<afxBillboardData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Billboard::ea_start()
|
||||
{
|
||||
if (!bb_data)
|
||||
{
|
||||
Con::errorf("afxEA_Billboard::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Billboard::ea_update(F32 dt)
|
||||
{
|
||||
if (!bb)
|
||||
{
|
||||
// create and register effect
|
||||
bb = new afxBillboard();
|
||||
bb->onNewDataBlock(bb_data, false);
|
||||
if (!bb->registerObject())
|
||||
{
|
||||
delete bb;
|
||||
bb = 0;
|
||||
Con::errorf("afxEA_Billboard::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(bb);
|
||||
|
||||
///bb->setSequenceRateFactor(datablock->rate_factor/prop_time_factor);
|
||||
bb->setSortPriority(datablock->sort_priority);
|
||||
}
|
||||
|
||||
if (bb)
|
||||
{
|
||||
bb->live_color = updated_color;
|
||||
if (do_fades)
|
||||
{
|
||||
bb->setFadeAmount(fade_value);
|
||||
}
|
||||
bb->setTransform(updated_xfm);
|
||||
bb->setScale(updated_scale);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Billboard::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (!bb)
|
||||
return;
|
||||
|
||||
bb->deleteObject();
|
||||
bb = 0;
|
||||
}
|
||||
|
||||
void afxEA_Billboard::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (bb)
|
||||
bb->setVisibility(in_scope);
|
||||
}
|
||||
|
||||
void afxEA_Billboard::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (bb == dynamic_cast<afxBillboard*>(obj))
|
||||
bb = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_Billboard::getUpdatedBoxCenter(Point3F& pos)
|
||||
{
|
||||
if (bb)
|
||||
pos = bb->getBoxCenter();
|
||||
}
|
||||
|
||||
void afxEA_Billboard::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (bb_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxBillboardData* orig_db = bb_data;
|
||||
bb_data = new afxBillboardData(*orig_db, true);
|
||||
orig_db->performSubstitutions(bb_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_BillboardDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_BillboardDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Billboard; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_BillboardDesc afxEA_BillboardDesc::desc;
|
||||
|
||||
bool afxEA_BillboardDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxBillboardData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_BillboardDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
199
Engine/source/afx/ea/afxEA_CameraPuppet.cpp
Normal file
199
Engine/source/afx/ea/afxEA_CameraPuppet.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxCamera.h"
|
||||
#include "afx/ce/afxCameraPuppet.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_CameraPuppet
|
||||
|
||||
class afxEA_CameraPuppet : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxCameraPuppetData* puppet_data;
|
||||
afxConstraint* cam_cons;
|
||||
bool was_1st_person;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_CameraPuppet();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual void getUnconstrainedPosition(Point3F& pos);
|
||||
virtual void getUnconstrainedTransform(MatrixF& xfm);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_CameraPuppet::afxEA_CameraPuppet()
|
||||
{
|
||||
puppet_data = 0;
|
||||
cam_cons = 0;
|
||||
was_1st_person = false;
|
||||
}
|
||||
|
||||
void afxEA_CameraPuppet::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
puppet_data = dynamic_cast<afxCameraPuppetData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_CameraPuppet::ea_start()
|
||||
{
|
||||
if (!puppet_data)
|
||||
{
|
||||
Con::errorf("afxEA_CameraPuppet::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
afxConstraintID obj_id = cons_mgr->getConstraintId(puppet_data->cam_def);
|
||||
cam_cons = cons_mgr->getConstraint(obj_id);
|
||||
|
||||
SceneObject* obj = (cam_cons) ? cam_cons->getSceneObject() : 0;
|
||||
if (obj && obj->isClientObject())
|
||||
{
|
||||
GameConnection* conn = GameConnection::getConnectionToServer();
|
||||
if (conn)
|
||||
{
|
||||
was_1st_person = conn->isFirstPerson();
|
||||
if (was_1st_person)
|
||||
conn->setFirstPerson(false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_CameraPuppet::ea_update(F32 dt)
|
||||
{
|
||||
SceneObject* obj = (cam_cons) ? cam_cons->getSceneObject() : 0;
|
||||
|
||||
if (obj && in_scope)
|
||||
{
|
||||
obj->setTransform(updated_xfm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_CameraPuppet::ea_finish(bool was_stopped)
|
||||
{
|
||||
afxCamera* afx_cam = dynamic_cast<afxCamera*>((cam_cons) ? cam_cons->getSceneObject() : 0);
|
||||
if (afx_cam && afx_cam->isClientObject())
|
||||
afx_cam->setThirdPersonSnapClient();
|
||||
|
||||
if (was_1st_person)
|
||||
{
|
||||
GameConnection* conn = GameConnection::getConnectionToServer();
|
||||
if (conn)
|
||||
conn->setFirstPerson(true);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_CameraPuppet::getUnconstrainedPosition(Point3F& pos)
|
||||
{
|
||||
SceneObject* obj = (cam_cons) ? cam_cons->getSceneObject() : 0;
|
||||
if (obj)
|
||||
pos = obj->getRenderPosition();
|
||||
else
|
||||
pos.zero();
|
||||
}
|
||||
|
||||
void afxEA_CameraPuppet::getUnconstrainedTransform(MatrixF& xfm)
|
||||
{
|
||||
SceneObject* obj = (cam_cons) ? cam_cons->getSceneObject() : 0;
|
||||
if (obj)
|
||||
xfm = obj->getRenderTransform();
|
||||
else
|
||||
xfm.identity();
|
||||
}
|
||||
|
||||
void afxEA_CameraPuppet::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (puppet_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxCameraPuppetData* orig_db = puppet_data;
|
||||
puppet_data = new afxCameraPuppetData(*orig_db, true);
|
||||
orig_db->performSubstitutions(puppet_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_CameraPuppetDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_CameraPuppetDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const;
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_CameraPuppet; }
|
||||
};
|
||||
|
||||
afxEA_CameraPuppetDesc afxEA_CameraPuppetDesc::desc;
|
||||
|
||||
bool afxEA_CameraPuppetDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxCameraPuppetData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_CameraPuppetDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
bool afxEA_CameraPuppetDesc::runsOnServer(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxCameraPuppetData*)ew->effect_data)->networking;
|
||||
return ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
}
|
||||
|
||||
bool afxEA_CameraPuppetDesc::runsOnClient(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxCameraPuppetData*)ew->effect_data)->networking;
|
||||
return ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
196
Engine/source/afx/ea/afxEA_CameraShake.cpp
Normal file
196
Engine/source/afx/ea/afxEA_CameraShake.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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/fx/cameraFXMgr.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxCameraShake.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_CameraShake
|
||||
|
||||
class afxEA_CameraShake : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxCameraShakeData* shake_data;
|
||||
CameraShake* camera_shake;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_CameraShake();
|
||||
/*D*/ ~afxEA_CameraShake();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_CameraShake::afxEA_CameraShake()
|
||||
{
|
||||
shake_data = 0;
|
||||
camera_shake = 0;
|
||||
}
|
||||
|
||||
afxEA_CameraShake::~afxEA_CameraShake()
|
||||
{
|
||||
delete camera_shake;
|
||||
if (shake_data && shake_data->isTempClone())
|
||||
delete shake_data;
|
||||
shake_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_CameraShake::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
shake_data = dynamic_cast<afxCameraShakeData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_CameraShake::ea_start()
|
||||
{
|
||||
if (!shake_data)
|
||||
{
|
||||
Con::errorf("afxEA_CameraShake::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
afxConstraint* aim_constraint = getAimConstraint();
|
||||
|
||||
if (aim_constraint && pos_constraint)
|
||||
{
|
||||
if (full_lifetime <= 0 || full_lifetime == INFINITE_LIFETIME)
|
||||
{
|
||||
Con::errorf("afxEA_CameraShake::ea_start() -- effect requires a finite lifetime.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SceneObject* shaken = aim_constraint->getSceneObject();
|
||||
if (shaken)
|
||||
{
|
||||
Point3F pos; pos_constraint->getPosition(pos);
|
||||
VectorF diff = shaken->getPosition() - pos;
|
||||
F32 dist = diff.len();
|
||||
if (dist < shake_data->camShakeRadius)
|
||||
{
|
||||
camera_shake = new CameraShake;
|
||||
camera_shake->setDuration(full_lifetime);
|
||||
camera_shake->setFrequency(shake_data->camShakeFreq);
|
||||
|
||||
F32 falloff = dist/shake_data->camShakeRadius;
|
||||
falloff = 1 + falloff*10.0;
|
||||
falloff = 1.0 / (falloff*falloff);
|
||||
|
||||
VectorF shakeAmp = shake_data->camShakeAmp*falloff;
|
||||
camera_shake->setAmplitude(shakeAmp);
|
||||
camera_shake->setFalloff(shake_data->camShakeFalloff);
|
||||
camera_shake->init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_CameraShake::ea_update(F32 dt)
|
||||
{
|
||||
afxConstraint* aim_constraint = getAimConstraint();
|
||||
if (camera_shake && aim_constraint)
|
||||
{
|
||||
camera_shake->update(dt);
|
||||
|
||||
SceneObject* shaken = aim_constraint->getSceneObject();
|
||||
if (shaken)
|
||||
{
|
||||
MatrixF fxTrans = camera_shake->getTrans();
|
||||
MatrixF curTrans = shaken->getRenderTransform();
|
||||
curTrans.mul(fxTrans);
|
||||
|
||||
Point3F cameraPosWorld;
|
||||
curTrans.getColumn(3,&cameraPosWorld);
|
||||
shaken->setPosition(cameraPosWorld);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_CameraShake::ea_finish(bool was_stopped)
|
||||
{
|
||||
delete camera_shake;
|
||||
camera_shake = 0;
|
||||
}
|
||||
|
||||
void afxEA_CameraShake::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (shake_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxCameraShakeData* orig_db = shake_data;
|
||||
shake_data = new afxCameraShakeData(*orig_db, true);
|
||||
orig_db->performSubstitutions(shake_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_CameraShakeDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_CameraShakeDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_CameraShake; }
|
||||
};
|
||||
|
||||
afxEA_CameraShakeDesc afxEA_CameraShakeDesc::desc;
|
||||
|
||||
bool afxEA_CameraShakeDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxCameraShakeData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_CameraShakeDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
225
Engine/source/afx/ea/afxEA_CollisionEvent.cpp
Normal file
225
Engine/source/afx/ea/afxEA_CollisionEvent.cpp
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxCollisionEvent.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_CollisionEvent
|
||||
|
||||
class afxEA_CollisionEvent : public afxEffectWrapper, ShapeBase::CollisionEventCallback
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxCollisionEventData* script_data;
|
||||
ShapeBase* shape;
|
||||
U32 trigger_mask;
|
||||
bool triggered;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
void set_shape(ShapeBase*);
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_CollisionEvent();
|
||||
/*D*/ ~afxEA_CollisionEvent();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual void collisionNotify(SceneObject* obj0, SceneObject* obj1, const VectorF& vel);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_CollisionEvent::afxEA_CollisionEvent()
|
||||
{
|
||||
script_data = 0;
|
||||
shape = 0;
|
||||
trigger_mask = 0;
|
||||
triggered = false;
|
||||
}
|
||||
|
||||
afxEA_CollisionEvent::~afxEA_CollisionEvent()
|
||||
{
|
||||
if (shape)
|
||||
clearNotify(shape);
|
||||
if (script_data && script_data->isTempClone())
|
||||
delete script_data;
|
||||
script_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
script_data = dynamic_cast<afxCollisionEventData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_CollisionEvent::ea_start()
|
||||
{
|
||||
if (!script_data)
|
||||
{
|
||||
Con::errorf("afxEA_CollisionEvent::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (script_data->gen_trigger && script_data->trigger_bit < 32)
|
||||
trigger_mask = 1 << script_data->trigger_bit;
|
||||
else
|
||||
trigger_mask = 0;
|
||||
|
||||
triggered = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_CollisionEvent::ea_update(F32 dt)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
set_shape((pos_constraint) ? dynamic_cast<ShapeBase*>(pos_constraint->getSceneObject()) : 0);
|
||||
|
||||
if (choreographer && trigger_mask != 0)
|
||||
{
|
||||
if (triggered)
|
||||
{
|
||||
choreographer->setTriggerMask(trigger_mask | choreographer->getTriggerMask());
|
||||
triggered = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
choreographer->setTriggerMask(~trigger_mask & choreographer->getTriggerMask());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::ea_finish(bool was_stopped)
|
||||
{
|
||||
set_shape(0);
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (script_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxCollisionEventData* orig_db = script_data;
|
||||
script_data = new afxCollisionEventData(*orig_db, true);
|
||||
orig_db->performSubstitutions(script_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::set_shape(ShapeBase* new_shape)
|
||||
{
|
||||
if (shape == new_shape)
|
||||
return;
|
||||
|
||||
if (shape)
|
||||
{
|
||||
shape->unregisterCollisionCallback(this);
|
||||
clearNotify(shape);
|
||||
}
|
||||
|
||||
shape = new_shape;
|
||||
|
||||
if (shape)
|
||||
{
|
||||
deleteNotify(shape);
|
||||
shape->registerCollisionCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::collisionNotify(SceneObject* obj0, SceneObject* obj1, const VectorF& vel)
|
||||
{
|
||||
if (obj0 != shape || !choreographer || !choreographer->getDataBlock())
|
||||
return;
|
||||
|
||||
if (script_data->method_name != ST_NULLSTRING)
|
||||
{
|
||||
char *arg_buf = Con::getArgBuffer(64);
|
||||
dSprintf(arg_buf, 256, "%g %g %g", vel.x, vel.y, vel.z);
|
||||
|
||||
// CALL SCRIPT afxChoreographerData::method(%spell, %obj0, %obj1, %velocity)
|
||||
Con::executef(choreographer->getDataBlock(), script_data->method_name,
|
||||
choreographer->getIdString(),
|
||||
(obj0) ? obj0->getIdString() : "",
|
||||
(obj1) ? obj1->getIdString() : "",
|
||||
arg_buf,
|
||||
script_data->script_data);
|
||||
}
|
||||
|
||||
if (!triggered && trigger_mask != 0)
|
||||
triggered = true;
|
||||
}
|
||||
|
||||
void afxEA_CollisionEvent::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (obj == shape)
|
||||
{
|
||||
shape->unregisterCollisionCallback(this);
|
||||
shape = 0;
|
||||
}
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_CollisionEventDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_CollisionEventDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_CollisionEvent; }
|
||||
};
|
||||
|
||||
afxEA_CollisionEventDesc afxEA_CollisionEventDesc::desc;
|
||||
|
||||
bool afxEA_CollisionEventDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxCollisionEventData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_CollisionEventDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
128
Engine/source/afx/ea/afxEA_ConsoleMessage.cpp
Normal file
128
Engine/source/afx/ea/afxEA_ConsoleMessage.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxConsoleMessage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_ConsoleMessage
|
||||
|
||||
class afxEA_ConsoleMessage : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxConsoleMessageData* message_data;
|
||||
bool displayed;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_ConsoleMessage();
|
||||
|
||||
virtual bool isDone() { return displayed; }
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_ConsoleMessage::afxEA_ConsoleMessage()
|
||||
{
|
||||
message_data = 0;
|
||||
displayed = false;
|
||||
}
|
||||
|
||||
void afxEA_ConsoleMessage::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
message_data = dynamic_cast<afxConsoleMessageData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_ConsoleMessage::ea_start()
|
||||
{
|
||||
if (!message_data)
|
||||
{
|
||||
Con::errorf("afxEA_ConsoleMessage::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_ConsoleMessage::ea_update(F32 dt)
|
||||
{
|
||||
if (!displayed)
|
||||
{
|
||||
if (message_data->message_str != ST_NULLSTRING)
|
||||
Con::printf("ConsoleMessage: \"%s\"", message_data->message_str);
|
||||
displayed = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_ConsoleMessage::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (message_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxConsoleMessageData* orig_db = message_data;
|
||||
message_data = new afxConsoleMessageData(*orig_db, true);
|
||||
orig_db->performSubstitutions(message_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ConsoleMessageDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ConsoleMessageDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const { return false; }
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_ConsoleMessage; }
|
||||
};
|
||||
|
||||
afxEA_ConsoleMessageDesc afxEA_ConsoleMessageDesc::desc;
|
||||
|
||||
bool afxEA_ConsoleMessageDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxConsoleMessageData) == typeid(*db));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
201
Engine/source/afx/ea/afxEA_Damage.cpp
Normal file
201
Engine/source/afx/ea/afxEA_Damage.cpp
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxDamage.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Damage
|
||||
|
||||
class afxEA_Damage : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxDamageData* damage_data;
|
||||
bool started;
|
||||
U8 repeat_cnt;
|
||||
U32 dot_delta_ms;
|
||||
U32 next_dot_time;
|
||||
Point3F impact_pos;
|
||||
SimObjectId impacted_obj_id;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Damage();
|
||||
/*C*/ ~afxEA_Damage();
|
||||
|
||||
virtual bool isDone();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Damage::afxEA_Damage()
|
||||
{
|
||||
damage_data = 0;
|
||||
started = false;
|
||||
repeat_cnt = 0;
|
||||
dot_delta_ms = 0;
|
||||
next_dot_time = 0;
|
||||
impact_pos.zero();
|
||||
impacted_obj_id = 0;
|
||||
}
|
||||
|
||||
afxEA_Damage::~afxEA_Damage()
|
||||
{
|
||||
if (damage_data && damage_data->isTempClone())
|
||||
delete damage_data;
|
||||
damage_data = 0;
|
||||
}
|
||||
|
||||
bool afxEA_Damage::isDone()
|
||||
{
|
||||
return (damage_data) ? (repeat_cnt >= damage_data->repeats) : true;
|
||||
}
|
||||
|
||||
void afxEA_Damage::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
damage_data = dynamic_cast<afxDamageData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Damage::ea_start()
|
||||
{
|
||||
if (!damage_data)
|
||||
{
|
||||
Con::errorf("afxEA_Damage::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (damage_data->repeats > 1)
|
||||
{
|
||||
dot_delta_ms = full_lifetime/(damage_data->repeats - 1);
|
||||
next_dot_time = dot_delta_ms;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Damage::ea_update(F32 dt)
|
||||
{
|
||||
if (!started)
|
||||
{
|
||||
started = true;
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (pos_cons)
|
||||
pos_cons->getPosition(impact_pos);
|
||||
|
||||
afxConstraint* aim_cons = getAimConstraint();
|
||||
if (aim_cons && aim_cons->getSceneObject())
|
||||
impacted_obj_id = aim_cons->getSceneObject()->getId();
|
||||
|
||||
if (choreographer)
|
||||
choreographer->inflictDamage(damage_data->label, damage_data->flavor, impacted_obj_id, damage_data->amount,
|
||||
repeat_cnt, damage_data->ad_amount, damage_data->radius, impact_pos,
|
||||
damage_data->impulse);
|
||||
repeat_cnt++;
|
||||
}
|
||||
else if (repeat_cnt < damage_data->repeats)
|
||||
{
|
||||
if (next_dot_time <= life_elapsed)
|
||||
{
|
||||
// CONSTRAINT REMAPPING <<
|
||||
afxConstraint* aim_cons = getAimConstraint();
|
||||
if (aim_cons && aim_cons->getSceneObject())
|
||||
impacted_obj_id = aim_cons->getSceneObject()->getId();
|
||||
// CONSTRAINT REMAPPING >>
|
||||
|
||||
if (choreographer)
|
||||
choreographer->inflictDamage(damage_data->label, damage_data->flavor, impacted_obj_id, damage_data->amount,
|
||||
repeat_cnt, 0, 0, impact_pos, 0);
|
||||
next_dot_time += dot_delta_ms;
|
||||
repeat_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Damage::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (started && (repeat_cnt < damage_data->repeats))
|
||||
{
|
||||
if (next_dot_time <= life_elapsed)
|
||||
{
|
||||
if (choreographer)
|
||||
choreographer->inflictDamage(damage_data->label, damage_data->flavor, impacted_obj_id, damage_data->amount,
|
||||
repeat_cnt, 0, 0, impact_pos, 0);
|
||||
}
|
||||
}
|
||||
|
||||
started = false;
|
||||
}
|
||||
|
||||
void afxEA_Damage::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (damage_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxDamageData* orig_db = damage_data;
|
||||
damage_data = new afxDamageData(*orig_db, true);
|
||||
orig_db->performSubstitutions(damage_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_DamageDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_DamageDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const { return false; }
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Damage; }
|
||||
};
|
||||
|
||||
afxEA_DamageDesc afxEA_DamageDesc::desc;
|
||||
|
||||
bool afxEA_DamageDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxDamageData) == typeid(*db));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
199
Engine/source/afx/ea/afxEA_Debris.cpp
Normal file
199
Engine/source/afx/ea/afxEA_Debris.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/debris.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Debris
|
||||
|
||||
class afxEA_Debris : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
DebrisData* debris_data;
|
||||
Debris* debris;
|
||||
bool exploded;
|
||||
bool debris_done;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Debris();
|
||||
/*D*/ ~afxEA_Debris();
|
||||
|
||||
virtual bool isDone();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Debris::afxEA_Debris()
|
||||
{
|
||||
debris_data = 0;
|
||||
debris = 0;
|
||||
exploded = false;
|
||||
debris_done = false;
|
||||
}
|
||||
|
||||
afxEA_Debris::~afxEA_Debris()
|
||||
{
|
||||
if (debris)
|
||||
clearNotify(debris);
|
||||
}
|
||||
|
||||
bool afxEA_Debris::isDone()
|
||||
{
|
||||
return (datablock->use_as_cons_obj) ? debris_done : exploded;
|
||||
}
|
||||
|
||||
void afxEA_Debris::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
debris_data = dynamic_cast<DebrisData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Debris::ea_start()
|
||||
{
|
||||
if (!debris_data)
|
||||
{
|
||||
Con::errorf("afxEA_Debris::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
debris = new Debris();
|
||||
debris->onNewDataBlock(debris_data, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Debris::ea_update(F32 dt)
|
||||
{
|
||||
if (exploded && debris)
|
||||
{
|
||||
if (in_scope)
|
||||
{
|
||||
updated_xfm = debris->getRenderTransform();
|
||||
updated_xfm.getColumn(3, &updated_pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!exploded && debris)
|
||||
{
|
||||
if (in_scope)
|
||||
{
|
||||
Point3F dir_vec(0,1,0);
|
||||
updated_xfm.mulV(dir_vec);
|
||||
|
||||
debris->init(updated_pos, dir_vec);
|
||||
if (!debris->registerObject())
|
||||
{
|
||||
delete debris;
|
||||
debris = 0;
|
||||
Con::errorf("afxEA_Debris::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(debris);
|
||||
}
|
||||
exploded = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Debris::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (debris)
|
||||
{
|
||||
clearNotify(debris);
|
||||
debris = 0;
|
||||
}
|
||||
exploded = false;
|
||||
}
|
||||
|
||||
void afxEA_Debris::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
// debris deleted?
|
||||
Debris* del_debris = dynamic_cast<Debris*>(obj);
|
||||
if (del_debris == debris)
|
||||
{
|
||||
debris = NULL;
|
||||
debris_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_Debris::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (debris_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
DebrisData* orig_db = debris_data;
|
||||
debris_data = new DebrisData(*orig_db, true);
|
||||
orig_db->performSubstitutions(debris_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_DebrisDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_DebrisDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Debris; }
|
||||
};
|
||||
|
||||
afxEA_DebrisDesc afxEA_DebrisDesc::desc;
|
||||
|
||||
bool afxEA_DebrisDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(DebrisData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_DebrisDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (ew->use_as_cons_obj && timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
145
Engine/source/afx/ea/afxEA_Explosion.cpp
Normal file
145
Engine/source/afx/ea/afxEA_Explosion.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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/fx/explosion.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Explosion
|
||||
|
||||
class afxEA_Explosion : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
ExplosionData* explosion_data;
|
||||
Explosion* explosion;
|
||||
bool exploded;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Explosion();
|
||||
|
||||
virtual bool isDone() { return exploded; }
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Explosion::afxEA_Explosion()
|
||||
{
|
||||
explosion_data = 0;
|
||||
explosion = 0;
|
||||
exploded = false;
|
||||
}
|
||||
|
||||
void afxEA_Explosion::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
explosion_data = dynamic_cast<ExplosionData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Explosion::ea_start()
|
||||
{
|
||||
if (!explosion_data)
|
||||
{
|
||||
Con::errorf("afxEA_Explosion::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
explosion = new Explosion();
|
||||
explosion->setSubstitutionData(choreographer, group_index);
|
||||
explosion->setDataBlock(explosion_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Explosion::ea_update(F32 dt)
|
||||
{
|
||||
if (!exploded && explosion)
|
||||
{
|
||||
if (in_scope)
|
||||
{
|
||||
Point3F norm(0,0,1); updated_xfm.mulV(norm);
|
||||
explosion->setInitialState(updated_pos, norm);
|
||||
if (!explosion->registerObject())
|
||||
{
|
||||
delete explosion;
|
||||
explosion = 0;
|
||||
Con::errorf("afxEA_Explosion::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exploded = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Explosion::ea_finish(bool was_stopped)
|
||||
{
|
||||
explosion = 0;
|
||||
exploded = false;
|
||||
}
|
||||
|
||||
void afxEA_Explosion::do_runtime_substitutions()
|
||||
{
|
||||
explosion_data = explosion_data->cloneAndPerformSubstitutions(choreographer, group_index);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ExplosionDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ExplosionDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const { return false; }
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Explosion; }
|
||||
};
|
||||
|
||||
afxEA_ExplosionDesc afxEA_ExplosionDesc::desc;
|
||||
|
||||
bool afxEA_ExplosionDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(ExplosionData) == typeid(*db));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
180
Engine/source/afx/ea/afxEA_FootSwitch.cpp
Normal file
180
Engine/source/afx/ea/afxEA_FootSwitch.cpp
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/player.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxFootSwitch.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_FootSwitch
|
||||
|
||||
class afxEA_FootSwitch : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxFootSwitchData* footfall_data;
|
||||
Player* player;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_FootSwitch();
|
||||
|
||||
void set_overrides(Player*);
|
||||
void clear_overrides(Player*);
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_FootSwitch::afxEA_FootSwitch()
|
||||
{
|
||||
footfall_data = 0;
|
||||
player = 0;
|
||||
}
|
||||
|
||||
inline void afxEA_FootSwitch::set_overrides(Player* player)
|
||||
{
|
||||
if (footfall_data->override_all)
|
||||
player->overrideFootfallFX();
|
||||
else
|
||||
player->overrideFootfallFX(footfall_data->override_decals,
|
||||
footfall_data->override_sounds,
|
||||
footfall_data->override_dust);
|
||||
}
|
||||
|
||||
inline void afxEA_FootSwitch::clear_overrides(Player* player)
|
||||
{
|
||||
if (footfall_data->override_all)
|
||||
player->restoreFootfallFX();
|
||||
else
|
||||
player->restoreFootfallFX(footfall_data->override_decals,
|
||||
footfall_data->override_sounds,
|
||||
footfall_data->override_dust);
|
||||
}
|
||||
|
||||
void afxEA_FootSwitch::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
footfall_data = dynamic_cast<afxFootSwitchData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_FootSwitch::ea_start()
|
||||
{
|
||||
if (!footfall_data)
|
||||
{
|
||||
Con::errorf("afxEA_FootSwitch::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
player = (pos_cons) ? dynamic_cast<Player*>(pos_cons->getSceneObject()) : 0;
|
||||
if (player)
|
||||
set_overrides(player);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_FootSwitch::ea_update(F32 dt)
|
||||
{
|
||||
if (!player)
|
||||
return true;
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
Player* temp_player = (pos_cons) ? dynamic_cast<Player*>(pos_cons->getSceneObject()) : 0;
|
||||
if (temp_player && temp_player != player)
|
||||
{
|
||||
player = temp_player;
|
||||
if (player)
|
||||
set_overrides(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_FootSwitch::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
Player* temp_player = (pos_cons) ? dynamic_cast<Player*>(pos_cons->getSceneObject()) : 0;
|
||||
if (temp_player == player)
|
||||
clear_overrides(player);
|
||||
}
|
||||
|
||||
void afxEA_FootSwitch::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (footfall_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxFootSwitchData* orig_db = footfall_data;
|
||||
footfall_data = new afxFootSwitchData(*orig_db, true);
|
||||
orig_db->performSubstitutions(footfall_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_FootfallSwitchDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_FootfallSwitchDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_FootSwitch; }
|
||||
};
|
||||
|
||||
afxEA_FootfallSwitchDesc afxEA_FootfallSwitchDesc::desc;
|
||||
|
||||
bool afxEA_FootfallSwitchDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxFootSwitchData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_FootfallSwitchDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
216
Engine/source/afx/ea/afxEA_GuiController.cpp
Normal file
216
Engine/source/afx/ea/afxEA_GuiController.cpp
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.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "gui/core/guiControl.h"
|
||||
#include "gui/3d/guiTSControl.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "gui/game/guiProgressCtrl.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxGuiController.h"
|
||||
#include "afx/ui/afxProgressBase.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_GuiController
|
||||
|
||||
class afxEA_GuiController : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxGuiControllerData* controller_data;
|
||||
GuiControl* gui_control;
|
||||
GuiTSCtrl* ts_ctrl;
|
||||
afxProgressBase* progress_base;
|
||||
GuiProgressCtrl* progress_ctrl;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_GuiController();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_GuiController::afxEA_GuiController()
|
||||
{
|
||||
controller_data = 0;
|
||||
gui_control = 0;
|
||||
ts_ctrl = 0;
|
||||
progress_base = 0;
|
||||
progress_ctrl = 0;
|
||||
}
|
||||
|
||||
void afxEA_GuiController::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
controller_data = dynamic_cast<afxGuiControllerData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_GuiController::ea_start()
|
||||
{
|
||||
if (!controller_data)
|
||||
{
|
||||
Con::errorf("afxEA_GuiController::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (controller_data->ctrl_client_only)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (!pos_cons)
|
||||
return false; // not an error condition
|
||||
GameBase* gamebase_obj = dynamic_cast<GameBase*>(pos_cons->getSceneObject());
|
||||
if (!gamebase_obj || !gamebase_obj->getControllingClient())
|
||||
return false; // not an error condition
|
||||
}
|
||||
|
||||
if (controller_data->control_name == ST_NULLSTRING || controller_data->control_name[0] == '\0')
|
||||
{
|
||||
Con::errorf("afxEA_GuiController::ea_start() -- empty control name.");
|
||||
return false;
|
||||
}
|
||||
|
||||
gui_control = dynamic_cast<GuiControl*>(Sim::findObject(controller_data->control_name));
|
||||
if (!gui_control)
|
||||
{
|
||||
Con::errorf("afxEA_GuiController::ea_start() -- failed to find control \"%s\".", controller_data->control_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
gui_control->setVisible(true);
|
||||
|
||||
progress_base = dynamic_cast<afxProgressBase*>(gui_control);
|
||||
if (progress_base)
|
||||
{
|
||||
progress_base->setProgress(0.0f);
|
||||
progress_ctrl = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
progress_ctrl = (GuiProgressCtrl*)gui_control;
|
||||
if (progress_ctrl)
|
||||
{
|
||||
progress_ctrl->setScriptValue(0);
|
||||
progress_base = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ts_ctrl = 0;
|
||||
for (GuiControl* ctrl = gui_control->getParent(); ctrl != 0; ctrl->getParent())
|
||||
{
|
||||
if (dynamic_cast<GuiTSCtrl*>(ctrl))
|
||||
{
|
||||
ts_ctrl = (GuiTSCtrl*) ctrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_GuiController::ea_update(F32 dt)
|
||||
{
|
||||
if (ts_ctrl && !controller_data->preserve_pos)
|
||||
{
|
||||
Point3F screen_pos;
|
||||
if (ts_ctrl->project(updated_pos, &screen_pos))
|
||||
{
|
||||
const Point2I ext = gui_control->getExtent();
|
||||
Point2I newpos(screen_pos.x - ext.x/2, screen_pos.y - ext.y/2);
|
||||
gui_control->setPosition(newpos);
|
||||
}
|
||||
}
|
||||
|
||||
if (progress_base)
|
||||
progress_base->setProgress((ew_timing.lifetime > 0.0) ? life_elapsed/ew_timing.lifetime : 0.0f);
|
||||
else if (progress_ctrl)
|
||||
progress_ctrl->setScriptValue((ew_timing.lifetime > 0.0) ? avar("%g", life_elapsed/ew_timing.lifetime) : 0);
|
||||
|
||||
if (do_fades)
|
||||
gui_control->setFadeAmount(fade_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_GuiController::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (progress_base)
|
||||
progress_base->setProgress(1.0f);
|
||||
else if (progress_ctrl)
|
||||
progress_ctrl->setScriptValue("1");
|
||||
gui_control->setVisible(false);
|
||||
}
|
||||
|
||||
void afxEA_GuiController::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (controller_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxGuiControllerData* orig_db = controller_data;
|
||||
controller_data = new afxGuiControllerData(*orig_db, true);
|
||||
orig_db->performSubstitutions(controller_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_GuiControllerDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_GuiControllerDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_GuiController; }
|
||||
};
|
||||
|
||||
afxEA_GuiControllerDesc afxEA_GuiControllerDesc::desc;
|
||||
|
||||
bool afxEA_GuiControllerDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxGuiControllerData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_GuiControllerDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
180
Engine/source/afx/ea/afxEA_GuiText.cpp
Normal file
180
Engine/source/afx/ea/afxEA_GuiText.cpp
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxGuiText.h"
|
||||
#include "afx/ui/afxGuiTextHud.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_GuiText
|
||||
|
||||
class afxEA_GuiText : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
enum {
|
||||
UNDEFINED,
|
||||
USER_TEXT,
|
||||
SHAPE_NAME
|
||||
};
|
||||
|
||||
afxGuiTextData* text_data;
|
||||
S32 text_src;
|
||||
LinearColorF text_clr;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_GuiText();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_GuiText::afxEA_GuiText()
|
||||
{
|
||||
text_data = 0;
|
||||
text_src = UNDEFINED;
|
||||
text_clr.set(1,1,1,1);
|
||||
}
|
||||
|
||||
void afxEA_GuiText::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
text_data = dynamic_cast<afxGuiTextData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_GuiText::ea_start()
|
||||
{
|
||||
if (!text_data)
|
||||
{
|
||||
Con::errorf("afxEA_GuiText::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (text_data->text_str == ST_NULLSTRING || text_data->text_str[0] == '\0')
|
||||
{
|
||||
Con::errorf("afxEA_GuiText::ea_start() -- empty text string.");
|
||||
return false;
|
||||
}
|
||||
|
||||
text_clr = text_data->text_clr;
|
||||
|
||||
if (dStricmp("#shapeName", text_data->text_str) == 0)
|
||||
text_src = SHAPE_NAME;
|
||||
else
|
||||
text_src = USER_TEXT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_GuiText::ea_update(F32 dt)
|
||||
{
|
||||
switch (text_src)
|
||||
{
|
||||
case USER_TEXT:
|
||||
{
|
||||
LinearColorF temp_clr = text_clr;
|
||||
if (do_fades)
|
||||
temp_clr.alpha = fade_value;
|
||||
afxGuiTextHud::addTextItem(updated_pos, text_data->text_str, temp_clr);
|
||||
}
|
||||
break;
|
||||
case SHAPE_NAME:
|
||||
{
|
||||
const char* name = 0;
|
||||
SceneObject* cons_obj = 0;
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (pos_cons)
|
||||
{
|
||||
ShapeBase* shape = dynamic_cast<ShapeBase*>(pos_cons->getSceneObject());
|
||||
if (shape)
|
||||
{
|
||||
name = shape->getShapeName();
|
||||
cons_obj = shape;
|
||||
}
|
||||
}
|
||||
if (name && name[0] != '\0')
|
||||
{
|
||||
LinearColorF temp_clr = text_clr;
|
||||
if (do_fades)
|
||||
temp_clr.alpha = fade_value;
|
||||
afxGuiTextHud::addTextItem(updated_pos, name, temp_clr, cons_obj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_GuiText::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (text_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxGuiTextData* orig_db = text_data;
|
||||
text_data = new afxGuiTextData(*orig_db, true);
|
||||
orig_db->performSubstitutions(text_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_GuiTextDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_GuiTextDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_GuiText; }
|
||||
};
|
||||
|
||||
afxEA_GuiTextDesc afxEA_GuiTextDesc::desc;
|
||||
|
||||
bool afxEA_GuiTextDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxGuiTextData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_GuiTextDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
62
Engine/source/afx/ea/afxEA_Light.cpp
Normal file
62
Engine/source/afx/ea/afxEA_Light.cpp
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.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/ce/afxLight.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_LightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_LightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return 0; }
|
||||
};
|
||||
|
||||
afxEA_LightDesc afxEA_LightDesc::desc;
|
||||
|
||||
bool afxEA_LightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxLightData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_LightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
207
Engine/source/afx/ea/afxEA_MachineGun.cpp
Normal file
207
Engine/source/afx/ea/afxEA_MachineGun.cpp
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxProjectile.h"
|
||||
#include "afx/ce/afxMachineGun.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_MachineGun
|
||||
|
||||
class afxEA_MachineGun : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxMachineGunData* gun_data;
|
||||
ProjectileData* bullet_data;
|
||||
|
||||
bool shooting;
|
||||
F32 start_time;
|
||||
F32 shot_gap;
|
||||
S32 shot_count;
|
||||
|
||||
void launch_projectile();
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_MachineGun();
|
||||
/*D*/ ~afxEA_MachineGun();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_MachineGun::afxEA_MachineGun()
|
||||
{
|
||||
gun_data = 0;
|
||||
bullet_data = 0;
|
||||
shooting = false;
|
||||
start_time = 0.0f;
|
||||
shot_count = 0;
|
||||
shot_gap = 0.2f;
|
||||
}
|
||||
|
||||
afxEA_MachineGun::~afxEA_MachineGun()
|
||||
{
|
||||
if (gun_data && gun_data->isTempClone())
|
||||
delete gun_data;
|
||||
gun_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_MachineGun::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
gun_data = dynamic_cast<afxMachineGunData*>(db);
|
||||
if (gun_data)
|
||||
bullet_data = gun_data->projectile_data;
|
||||
}
|
||||
|
||||
bool afxEA_MachineGun::ea_start()
|
||||
{
|
||||
if (!gun_data)
|
||||
{
|
||||
Con::errorf("afxEA_MachineGun::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
if (!bullet_data)
|
||||
{
|
||||
Con::errorf("afxEA_MachineGun::ea_start() -- missing or incompatible ProjectileData.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (gun_data->rounds_per_minute > 0)
|
||||
shot_gap = 60.0f/gun_data->rounds_per_minute;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_MachineGun::ea_update(F32 dt)
|
||||
{
|
||||
if (!shooting)
|
||||
{
|
||||
start_time = elapsed;
|
||||
shooting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 next_shot = start_time + (shot_count+1)*shot_gap;
|
||||
while (next_shot < elapsed)
|
||||
{
|
||||
if (in_scope)
|
||||
launch_projectile();
|
||||
next_shot += shot_gap;
|
||||
shot_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_MachineGun::ea_finish(bool was_stopped)
|
||||
{
|
||||
}
|
||||
|
||||
void afxEA_MachineGun::launch_projectile()
|
||||
{
|
||||
afxProjectile* projectile = new afxProjectile();
|
||||
|
||||
ProjectileData* next_bullet = bullet_data;
|
||||
|
||||
if (bullet_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
next_bullet = new ProjectileData(*bullet_data, true);
|
||||
bullet_data->performSubstitutions(next_bullet, choreographer, group_index);
|
||||
}
|
||||
|
||||
projectile->onNewDataBlock(next_bullet, false);
|
||||
|
||||
F32 muzzle_vel = next_bullet->muzzleVelocity;
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
ShapeBase* src_obj = (pos_cons) ? (dynamic_cast<ShapeBase*>(pos_cons->getSceneObject())) : 0;
|
||||
|
||||
Point3F dir_vec = updated_aim - updated_pos;
|
||||
dir_vec.normalizeSafe();
|
||||
dir_vec *= muzzle_vel;
|
||||
projectile->init(updated_pos, dir_vec, src_obj);
|
||||
if (!projectile->registerObject())
|
||||
{
|
||||
delete projectile;
|
||||
projectile = 0;
|
||||
Con::errorf("afxEA_MachineGun::launch_projectile() -- projectile failed to register.");
|
||||
}
|
||||
if (projectile)
|
||||
projectile->setDataField(StringTable->insert("afxOwner"), 0, choreographer->getIdString());
|
||||
}
|
||||
|
||||
void afxEA_MachineGun::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (gun_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxMachineGunData* orig_db = gun_data;
|
||||
gun_data = new afxMachineGunData(*orig_db, true);
|
||||
orig_db->performSubstitutions(gun_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_MachineGunDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_MachineGunDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_MachineGun; }
|
||||
};
|
||||
|
||||
afxEA_MachineGunDesc afxEA_MachineGunDesc::desc;
|
||||
|
||||
bool afxEA_MachineGunDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxMachineGunData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_MachineGunDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
255
Engine/source/afx/ea/afxEA_Model.cpp
Normal file
255
Engine/source/afx/ea/afxEA_Model.cpp
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "ts/tsShapeInstance.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
#include "afx/ce/afxModel.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Model -- This is the adapter for afxModel, a lightweight animated model effect.
|
||||
|
||||
class afxEA_Model : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxModelData* model_data;
|
||||
afxModel* model;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Model();
|
||||
/*D*/ ~afxEA_Model();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
|
||||
virtual void getUpdatedBoxCenter(Point3F& pos);
|
||||
|
||||
virtual TSShape* getTSShape();
|
||||
virtual TSShapeInstance* getTSShapeInstance();
|
||||
virtual SceneObject* ea_get_scene_object() const;
|
||||
virtual U32 ea_get_triggers() const;
|
||||
|
||||
virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans);
|
||||
virtual void resetAnimation(U32 tag);
|
||||
virtual F32 getAnimClipDuration(const char* clip);
|
||||
};
|
||||
|
||||
|
||||
afxEA_Model::afxEA_Model()
|
||||
{
|
||||
model_data = 0;
|
||||
model = 0;
|
||||
}
|
||||
|
||||
afxEA_Model::~afxEA_Model()
|
||||
{
|
||||
if (model)
|
||||
model->deleteObject();
|
||||
if (model_data && model_data->isTempClone())
|
||||
delete model_data;
|
||||
model_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_Model::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
model_data = dynamic_cast<afxModelData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Model::ea_start()
|
||||
{
|
||||
if (!model_data)
|
||||
{
|
||||
Con::errorf("afxEA_Model::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Model::ea_update(F32 dt)
|
||||
{
|
||||
if (!model)
|
||||
{
|
||||
// create and register effect
|
||||
model = new afxModel();
|
||||
model->onNewDataBlock(model_data, false);
|
||||
if (!model->registerObject())
|
||||
{
|
||||
delete model;
|
||||
model = 0;
|
||||
Con::errorf("afxEA_Model::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(model);
|
||||
|
||||
model->setSequenceRateFactor(datablock->rate_factor/prop_time_factor);
|
||||
model->setSortPriority(datablock->sort_priority);
|
||||
}
|
||||
|
||||
if (model)
|
||||
{
|
||||
if (do_fades)
|
||||
{
|
||||
model->setFadeAmount(fade_value);
|
||||
}
|
||||
model->setTransform(updated_xfm);
|
||||
model->setScale(updated_scale);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Model::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (!model)
|
||||
return;
|
||||
|
||||
if (in_scope && ew_timing.residue_lifetime > 0)
|
||||
{
|
||||
clearNotify(model);
|
||||
afxResidueMgr::add(ew_timing.residue_lifetime, ew_timing.residue_fadetime, model);
|
||||
model = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
model->deleteObject();
|
||||
model = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_Model::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (model)
|
||||
model->setVisibility(in_scope);
|
||||
}
|
||||
|
||||
void afxEA_Model::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (model == dynamic_cast<afxModel*>(obj))
|
||||
model = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_Model::getUpdatedBoxCenter(Point3F& pos)
|
||||
{
|
||||
if (model)
|
||||
pos = model->getBoxCenter();
|
||||
}
|
||||
|
||||
TSShape* afxEA_Model::getTSShape()
|
||||
{
|
||||
return (model) ? model->getTSShape() : 0;
|
||||
}
|
||||
|
||||
TSShapeInstance* afxEA_Model::getTSShapeInstance()
|
||||
{
|
||||
return (model) ? model->getTSShapeInstance() : 0;
|
||||
}
|
||||
|
||||
SceneObject* afxEA_Model::ea_get_scene_object() const
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
U32 afxEA_Model::ea_get_triggers() const
|
||||
{
|
||||
TSShapeInstance* shape_inst = model->getTSShapeInstance();
|
||||
return (shape_inst) ? shape_inst->getTriggerStateMask() : 0;
|
||||
}
|
||||
|
||||
void afxEA_Model::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (model_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxModelData* orig_db = model_data;
|
||||
model_data = new afxModelData(*orig_db, true);
|
||||
orig_db->performSubstitutions(model_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
U32 afxEA_Model::setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans)
|
||||
{
|
||||
return (model) ? model->setAnimClip(clip, pos, rate, trans) : 0;
|
||||
}
|
||||
|
||||
void afxEA_Model::resetAnimation(U32 tag)
|
||||
{
|
||||
if (model)
|
||||
model->resetAnimation(tag);
|
||||
}
|
||||
|
||||
F32 afxEA_Model::getAnimClipDuration(const char* clip)
|
||||
{
|
||||
return (model) ? model->getAnimClipDuration(clip) : 0;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ModelDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ModelDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Model; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_ModelDesc afxEA_ModelDesc::desc;
|
||||
|
||||
bool afxEA_ModelDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxModelData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_ModelDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
188
Engine/source/afx/ea/afxEA_Mooring.cpp
Normal file
188
Engine/source/afx/ea/afxEA_Mooring.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxMooring.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Mooring
|
||||
|
||||
class afxEA_Mooring : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxMooringData* mooring_data;
|
||||
afxMooring* obj;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Mooring();
|
||||
/*D*/ ~afxEA_Mooring();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Mooring::afxEA_Mooring()
|
||||
{
|
||||
mooring_data = 0;
|
||||
obj = 0;
|
||||
}
|
||||
|
||||
afxEA_Mooring::~afxEA_Mooring()
|
||||
{
|
||||
if (obj)
|
||||
obj->deleteObject();
|
||||
if (mooring_data && mooring_data->isTempClone())
|
||||
delete mooring_data;
|
||||
mooring_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_Mooring::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
mooring_data = dynamic_cast<afxMooringData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_Mooring::ea_start()
|
||||
{
|
||||
if (!mooring_data)
|
||||
{
|
||||
Con::errorf("afxEA_Mooring::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Mooring::ea_update(F32 dt)
|
||||
{
|
||||
if (!obj)
|
||||
{
|
||||
if (datablock->use_ghost_as_cons_obj && datablock->effect_name != ST_NULLSTRING)
|
||||
{
|
||||
obj = new afxMooring(mooring_data->networking,
|
||||
choreographer->getChoreographerId(),
|
||||
datablock->effect_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = new afxMooring(mooring_data->networking, 0, ST_NULLSTRING);
|
||||
}
|
||||
|
||||
obj->onNewDataBlock(mooring_data, false);
|
||||
if (!obj->registerObject())
|
||||
{
|
||||
delete obj;
|
||||
obj = 0;
|
||||
Con::errorf("afxEA_Mooring::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(obj);
|
||||
}
|
||||
|
||||
if (obj)
|
||||
{
|
||||
obj->setTransform(updated_xfm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Mooring::ea_finish(bool was_stopped)
|
||||
{
|
||||
}
|
||||
|
||||
void afxEA_Mooring::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (this->obj == obj)
|
||||
obj = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_Mooring::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (mooring_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxMooringData* orig_db = mooring_data;
|
||||
mooring_data = new afxMooringData(*orig_db, true);
|
||||
orig_db->performSubstitutions(mooring_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_MooringDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_MooringDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const;
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Mooring; }
|
||||
};
|
||||
|
||||
afxEA_MooringDesc afxEA_MooringDesc::desc;
|
||||
|
||||
bool afxEA_MooringDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxMooringData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_MooringDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
bool afxEA_MooringDesc::runsOnServer(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxMooringData*)ew->effect_data)->networking;
|
||||
return ((networking & CLIENT_ONLY) == 0);
|
||||
}
|
||||
|
||||
bool afxEA_MooringDesc::runsOnClient(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxMooringData*)ew->effect_data)->networking;
|
||||
return ((networking & CLIENT_ONLY) != 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
62
Engine/source/afx/ea/afxEA_MultiLight.cpp
Normal file
62
Engine/source/afx/ea/afxEA_MultiLight.cpp
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.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/ce/afxLight.h"
|
||||
#include "afx/ce/afxMultiLight.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_MultiLightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_MultiLightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return 0; }
|
||||
};
|
||||
|
||||
afxEA_MultiLightDesc afxEA_MultiLightDesc::desc;
|
||||
|
||||
bool afxEA_MultiLightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxMultiLightData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_MultiLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
337
Engine/source/afx/ea/afxEA_ParticleEmitter.cpp
Normal file
337
Engine/source/afx/ea/afxEA_ParticleEmitter.cpp
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#if defined(STOCK_TGE_PARTICLES)
|
||||
#include "game/fx/particleEngine.h"
|
||||
#else
|
||||
#include "afx/ce/afxParticleEmitter.h"
|
||||
#endif
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ea/afxEA_ParticleEmitter.h"
|
||||
#include "afx/util/afxParticlePool.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_ParticleEmitter
|
||||
|
||||
afxEA_ParticleEmitter::afxEA_ParticleEmitter()
|
||||
{
|
||||
emitter_data = 0;
|
||||
emitter = 0;
|
||||
do_bbox_update = false;
|
||||
}
|
||||
|
||||
afxEA_ParticleEmitter::~afxEA_ParticleEmitter()
|
||||
{
|
||||
if (emitter)
|
||||
{
|
||||
clearNotify(emitter);
|
||||
emitter->deleteWhenEmpty();
|
||||
emitter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_ParticleEmitter::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
emitter_data = dynamic_cast<ParticleEmitterData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_ParticleEmitter::ea_start()
|
||||
{
|
||||
if (!emitter_data)
|
||||
{
|
||||
Con::errorf("afxEA_ParticleEmitter::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
#if defined(STOCK_TGE_PARTICLES)
|
||||
emitter = new ParticleEmitter();
|
||||
emitter->onNewDataBlock(emitter_data);
|
||||
#else
|
||||
afxParticleEmitterData* afx_emitter_db = dynamic_cast<afxParticleEmitterData*>(emitter_data);
|
||||
if (afx_emitter_db)
|
||||
{
|
||||
if (dynamic_cast<afxParticleEmitterVectorData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterVector* pe = new afxParticleEmitterVector();
|
||||
pe->onNewDataBlock(afx_emitter_db, false);
|
||||
pe->setAFXOwner(choreographer);
|
||||
emitter = pe;
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterConeData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterCone* pe = new afxParticleEmitterCone();
|
||||
pe->onNewDataBlock(afx_emitter_db, false);
|
||||
pe->setAFXOwner(choreographer);
|
||||
emitter = pe;
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterPathData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterPath* pe = new afxParticleEmitterPath();
|
||||
pe->onNewDataBlock(afx_emitter_db, false);
|
||||
pe->setAFXOwner(choreographer);
|
||||
emitter = pe;
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterDiscData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterDisc* pe = new afxParticleEmitterDisc();
|
||||
pe->onNewDataBlock(afx_emitter_db, false);
|
||||
pe->setAFXOwner(choreographer);
|
||||
emitter = pe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter = new ParticleEmitter();
|
||||
emitter->onNewDataBlock(emitter_data, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AFX_CAP_PARTICLE_POOLS)
|
||||
// here we find or create any required particle-pools
|
||||
if (emitter_data->pool_datablock)
|
||||
{
|
||||
afxParticlePool* pool = choreographer->findParticlePool(emitter_data->pool_datablock, emitter_data->pool_index);
|
||||
if (!pool)
|
||||
{
|
||||
afxParticlePoolData* pool_data = emitter_data->pool_datablock;
|
||||
if (pool_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxParticlePoolData* orig_db = pool_data;
|
||||
pool_data = new afxParticlePoolData(*orig_db, true);
|
||||
orig_db->performSubstitutions(pool_data, choreographer, group_index);
|
||||
}
|
||||
|
||||
pool = new afxParticlePool();
|
||||
pool->onNewDataBlock(pool_data, false);
|
||||
pool->setKeyBlock(emitter_data->pool_datablock, emitter_data->pool_index);
|
||||
if (!pool->registerObject())
|
||||
{
|
||||
Con::errorf("afxEA_ParticleEmitter::ea_start() -- Failed to register Particle Pool.");
|
||||
delete pool;
|
||||
pool = 0;
|
||||
}
|
||||
if (pool)
|
||||
{
|
||||
pool->setChoreographer(choreographer);
|
||||
choreographer->registerParticlePool(pool);
|
||||
}
|
||||
}
|
||||
if (pool)
|
||||
emitter->setPool(pool);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!emitter->registerObject())
|
||||
{
|
||||
delete emitter;
|
||||
emitter = NULL;
|
||||
Con::errorf("afxEA_ParticleEmitter::ea_start() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datablock->forced_bbox.isValidBox())
|
||||
{
|
||||
do_bbox_update = true;
|
||||
}
|
||||
|
||||
emitter->setSortPriority(datablock->sort_priority);
|
||||
deleteNotify(emitter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_ParticleEmitter::ea_update(F32 dt)
|
||||
{
|
||||
if (emitter && in_scope)
|
||||
{
|
||||
if (do_bbox_update)
|
||||
{
|
||||
Box3F bbox = emitter->getObjBox();
|
||||
|
||||
bbox.minExtents = updated_pos + datablock->forced_bbox.minExtents;
|
||||
bbox.maxExtents = updated_pos + datablock->forced_bbox.maxExtents;
|
||||
|
||||
emitter->setForcedObjBox(bbox);
|
||||
emitter->setTransform(emitter->getTransform());
|
||||
|
||||
if (!datablock->update_forced_bbox)
|
||||
do_bbox_update = false;
|
||||
}
|
||||
|
||||
if (do_fades)
|
||||
emitter->setFadeAmount(fade_value);
|
||||
|
||||
emitter->emitParticlesExt(updated_xfm, updated_pos, Point3F(0.0,0.0,0.0), (U32)(dt*1000));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_ParticleEmitter::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (arcaneFX::isShutdown())
|
||||
return;
|
||||
|
||||
if (emitter)
|
||||
{
|
||||
// make sure particles are fully faded.
|
||||
// note - fully faded particles are not always
|
||||
// invisible, so they are still kept alive and
|
||||
// deleted via deleteWhenEmpty().
|
||||
if (ew_timing.fade_out_time > 0.0f)
|
||||
emitter->setFadeAmount(0.0f);
|
||||
if (dynamic_cast<afxParticleEmitter*>(emitter))
|
||||
((afxParticleEmitter*)emitter)->setAFXOwner(0);
|
||||
clearNotify(emitter);
|
||||
emitter->deleteWhenEmpty();
|
||||
emitter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_ParticleEmitter::do_runtime_substitutions()
|
||||
{
|
||||
bool clone_particles = false;
|
||||
for (S32 i = 0; i < emitter_data->particleDataBlocks.size(); i++)
|
||||
{
|
||||
if (emitter_data->particleDataBlocks[i] && (emitter_data->particleDataBlocks[i]->getSubstitutionCount() > 0))
|
||||
{
|
||||
clone_particles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (clone_particles || (emitter_data->getSubstitutionCount() > 0))
|
||||
{
|
||||
afxParticleEmitterData* afx_emitter_db = dynamic_cast<afxParticleEmitterData*>(emitter_data);
|
||||
if (afx_emitter_db)
|
||||
{
|
||||
if (dynamic_cast<afxParticleEmitterVectorData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterVectorData* orig_db = (afxParticleEmitterVectorData*)emitter_data;
|
||||
emitter_data = new afxParticleEmitterVectorData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data, choreographer, group_index);
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterConeData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterConeData* orig_db = (afxParticleEmitterConeData*)emitter_data;
|
||||
emitter_data = new afxParticleEmitterConeData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data, choreographer, group_index);
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterPathData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterPathData* orig_db = (afxParticleEmitterPathData*)emitter_data;
|
||||
emitter_data = new afxParticleEmitterPathData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data, choreographer, group_index);
|
||||
}
|
||||
else if (dynamic_cast<afxParticleEmitterDiscData*>(emitter_data))
|
||||
{
|
||||
afxParticleEmitterDiscData* orig_db = (afxParticleEmitterDiscData*)emitter_data;
|
||||
emitter_data = new afxParticleEmitterDiscData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParticleEmitterData* orig_db = emitter_data;
|
||||
emitter_data = new ParticleEmitterData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data, choreographer, group_index);
|
||||
}
|
||||
|
||||
if (clone_particles)
|
||||
{
|
||||
for (S32 i = 0; i < emitter_data->particleDataBlocks.size(); i++)
|
||||
{
|
||||
if (emitter_data->particleDataBlocks[i] && (emitter_data->particleDataBlocks[i]->getSubstitutionCount() > 0))
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
ParticleData* orig_db = emitter_data->particleDataBlocks[i];
|
||||
emitter_data->particleDataBlocks[i] = new ParticleData(*orig_db, true);
|
||||
orig_db->performSubstitutions(emitter_data->particleDataBlocks[i], choreographer, group_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_ParticleEmitter::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (emitter == dynamic_cast<ParticleEmitter*>(obj))
|
||||
emitter = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ParticleEmitterDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ParticleEmitterDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_ParticleEmitter; }
|
||||
};
|
||||
|
||||
afxEA_ParticleEmitterDesc afxEA_ParticleEmitterDesc::desc;
|
||||
|
||||
bool afxEA_ParticleEmitterDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
#if defined(STOCK_TGE_PARTICLES)
|
||||
return (typeid(ParticleEmitterData) == typeid(*db));
|
||||
#else
|
||||
if (typeid(ParticleEmitterData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxParticleEmitterVectorData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxParticleEmitterConeData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxParticleEmitterPathData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxParticleEmitterDiscData) == typeid(*db))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool afxEA_ParticleEmitterDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
67
Engine/source/afx/ea/afxEA_ParticleEmitter.h
Normal file
67
Engine/source/afx/ea/afxEA_ParticleEmitter.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_EA_PARTICLE_EMITTER_H_
|
||||
#define _AFX_EA_PARTICLE_EMITTER_H_
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_ParticleEmitter
|
||||
|
||||
class ParticleEmitter;
|
||||
class ParticleEmitterData;
|
||||
|
||||
class afxEA_ParticleEmitter : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
bool do_bbox_update;
|
||||
ParticleEmitterData* emitter_data;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
ParticleEmitter* emitter;
|
||||
|
||||
/*C*/ afxEA_ParticleEmitter();
|
||||
/*D*/ ~afxEA_ParticleEmitter();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
|
||||
#endif // _AFX_EA_PARTICLE_EMITTER_H_
|
||||
385
Engine/source/afx/ea/afxEA_PhraseEffect.cpp
Normal file
385
Engine/source/afx/ea/afxEA_PhraseEffect.cpp
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "console/compiler.h"
|
||||
#include "T3D/player.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxPhrase.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxPhraseEffect.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_PhraseEffect
|
||||
|
||||
class afxEA_PhraseEffect : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxPhraseEffectData* phrase_fx_data;
|
||||
Vector<afxPhrase*>* active_phrases;
|
||||
U32 last_trigger_mask;
|
||||
|
||||
Vector<afxPhrase*> _phrases_a;
|
||||
Vector<afxPhrase*> _phrases_b;
|
||||
|
||||
void grab_constraint_triggers(U32& trigger_mask);
|
||||
void grab_player_triggers(U32& trigger_mask);
|
||||
|
||||
void do_runtime_substitutions();
|
||||
void trigger_new_phrase();
|
||||
void update_active_phrases(F32 dt);
|
||||
void cleanup_finished_phrases();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_PhraseEffect();
|
||||
/*D*/ ~afxEA_PhraseEffect();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_PhraseEffect::afxEA_PhraseEffect()
|
||||
{
|
||||
phrase_fx_data = 0;
|
||||
active_phrases = &_phrases_a;
|
||||
}
|
||||
|
||||
afxEA_PhraseEffect::~afxEA_PhraseEffect()
|
||||
{
|
||||
if (phrase_fx_data && phrase_fx_data->isTempClone())
|
||||
delete phrase_fx_data;
|
||||
phrase_fx_data = 0;
|
||||
|
||||
for (S32 i = 0; i < _phrases_a.size(); i++)
|
||||
{
|
||||
if (_phrases_a[i])
|
||||
delete _phrases_a[i];
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < _phrases_b.size(); i++)
|
||||
{
|
||||
if (_phrases_b[i])
|
||||
delete _phrases_b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
phrase_fx_data = dynamic_cast<afxPhraseEffectData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_PhraseEffect::ea_start()
|
||||
{
|
||||
if (!phrase_fx_data)
|
||||
{
|
||||
Con::errorf("afxEA_PhraseEffect::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//last_trigger_mask = choreographer->getTriggerMask();
|
||||
last_trigger_mask = 0xffffffff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::grab_constraint_triggers(U32& trigger_mask)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (pos_cons)
|
||||
trigger_mask |= pos_cons->getTriggers();
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::grab_player_triggers(U32& trigger_mask)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
Player* player = (pos_cons) ? dynamic_cast<Player*>(pos_cons->getSceneObject()) : 0;
|
||||
if (player)
|
||||
{
|
||||
if (player->isClientObject())
|
||||
trigger_mask |= player->getClientEventTriggers();
|
||||
else
|
||||
trigger_mask |= player->getServerEventTriggers();
|
||||
}
|
||||
}
|
||||
|
||||
bool afxEA_PhraseEffect::ea_update(F32 dt)
|
||||
{
|
||||
if (fade_value >= 1.0f)
|
||||
{
|
||||
//
|
||||
// Choreographer Triggers:
|
||||
// These triggers can come from the choreographer owning this effect.
|
||||
// They must be set explicitly by calls to afxChoreographer
|
||||
// console-methods, setTriggerBit(), or clearTriggerBit().
|
||||
//
|
||||
U32 trigger_mask = (phrase_fx_data->no_choreographer_trigs) ? 0 : choreographer->getTriggerMask();
|
||||
|
||||
//
|
||||
// Constraint Triggers:
|
||||
// These triggers can come from the position contraint if it is:
|
||||
// -- a TSStatic or ShapeBase derived object with dts triggers.
|
||||
// -- a trigger producing effect such as afxModel.
|
||||
//
|
||||
if (!phrase_fx_data->no_cons_trigs)
|
||||
grab_constraint_triggers(trigger_mask);
|
||||
|
||||
//
|
||||
// Player Triggers:
|
||||
// These triggers can come from the position contraint if it is
|
||||
// a Player or Player-derived object.
|
||||
//
|
||||
if (!phrase_fx_data->no_player_trigs)
|
||||
grab_player_triggers(trigger_mask);
|
||||
|
||||
// any change in the triggers?
|
||||
if (trigger_mask != last_trigger_mask)
|
||||
{
|
||||
if (phrase_fx_data->phrase_type == afxPhraseEffectData::PHRASE_CONTINUOUS)
|
||||
{
|
||||
bool last_state, new_state;
|
||||
if (phrase_fx_data->match_type == afxPhraseEffectData::MATCH_ANY)
|
||||
{
|
||||
last_state = ((last_trigger_mask & phrase_fx_data->trigger_mask) != 0);
|
||||
new_state = ((trigger_mask & phrase_fx_data->trigger_mask) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_state = ((last_trigger_mask & phrase_fx_data->trigger_mask) == phrase_fx_data->trigger_mask);
|
||||
new_state = ((trigger_mask & phrase_fx_data->trigger_mask) == phrase_fx_data->trigger_mask);
|
||||
}
|
||||
if (new_state != last_state)
|
||||
{
|
||||
bool state_on = phrase_fx_data->match_state & afxPhraseEffectData::STATE_ON;
|
||||
if (new_state == state_on) // start trigger
|
||||
{
|
||||
trigger_new_phrase();
|
||||
}
|
||||
else // stop trigger
|
||||
{
|
||||
for (S32 i = 0; i < active_phrases->size(); i++)
|
||||
{
|
||||
(*active_phrases)[i]->stop(life_elapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // if (phrase_fx_data->phrase_type == afxPhraseEffectData::PHRASE_TRIGGERED)
|
||||
{
|
||||
bool did_trigger = false;
|
||||
U32 changed_bits = (last_trigger_mask ^ trigger_mask);
|
||||
|
||||
if ((phrase_fx_data->match_state & afxPhraseEffectData::STATE_ON) != 0)
|
||||
{
|
||||
// check for trigger bits that just switched to on state
|
||||
U32 changed_on_bits = (changed_bits & trigger_mask);
|
||||
if (phrase_fx_data->match_type == afxPhraseEffectData::MATCH_ANY)
|
||||
did_trigger = ((changed_on_bits & phrase_fx_data->trigger_mask) != 0);
|
||||
else
|
||||
did_trigger = ((changed_on_bits & phrase_fx_data->trigger_mask) == phrase_fx_data->trigger_mask);
|
||||
}
|
||||
|
||||
if (!did_trigger && ((phrase_fx_data->match_state & afxPhraseEffectData::STATE_OFF) != 0))
|
||||
{
|
||||
// check for trigger bits that just switched to off state
|
||||
U32 changed_off_bits = (changed_bits & last_trigger_mask);
|
||||
if (phrase_fx_data->match_type == afxPhraseEffectData::MATCH_ANY)
|
||||
did_trigger = ((changed_off_bits & phrase_fx_data->trigger_mask) != 0);
|
||||
else
|
||||
did_trigger = ((changed_off_bits & phrase_fx_data->trigger_mask) == phrase_fx_data->trigger_mask);
|
||||
}
|
||||
|
||||
if (did_trigger)
|
||||
trigger_new_phrase();
|
||||
}
|
||||
|
||||
last_trigger_mask = trigger_mask;
|
||||
}
|
||||
}
|
||||
|
||||
update_active_phrases(dt);
|
||||
|
||||
cleanup_finished_phrases();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::ea_finish(bool was_stopped)
|
||||
{
|
||||
for (S32 i = 0; i < active_phrases->size(); i++)
|
||||
{
|
||||
(*active_phrases)[i]->stop(life_elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (phrase_fx_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxPhraseEffectData* orig_db = phrase_fx_data;
|
||||
phrase_fx_data = new afxPhraseEffectData(*orig_db, true);
|
||||
orig_db->performSubstitutions(phrase_fx_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::trigger_new_phrase()
|
||||
{
|
||||
//afxPhrase* phrase = new afxPhrase(choreographer->isServerObject(), /*willStop=*/false);
|
||||
bool will_stop = phrase_fx_data->phrase_type == afxPhraseEffectData::PHRASE_CONTINUOUS;
|
||||
afxPhrase* phrase = new afxPhrase(choreographer->isServerObject(), will_stop);
|
||||
phrase->init(phrase_fx_data->fx_list, datablock->ewd_timing.lifetime, choreographer, time_factor, phrase_fx_data->n_loops, group_index);
|
||||
phrase->start(0, 0);
|
||||
if (phrase->isEmpty())
|
||||
{
|
||||
delete phrase;
|
||||
return;
|
||||
}
|
||||
|
||||
if (phrase_fx_data->on_trig_cmd != ST_NULLSTRING)
|
||||
{
|
||||
char obj_str[32];
|
||||
dStrcpy(obj_str, Con::getIntArg(choreographer->getId()));
|
||||
|
||||
char index_str[32];
|
||||
dStrcpy(index_str, Con::getIntArg(group_index));
|
||||
|
||||
char buffer[1024];
|
||||
char* b = buffer;
|
||||
const char* v = phrase_fx_data->on_trig_cmd;
|
||||
while (*v != '\0')
|
||||
{
|
||||
if (v[0] == '%' && v[1] == '%')
|
||||
{
|
||||
const char* s = obj_str;
|
||||
while (*s != '\0')
|
||||
{
|
||||
b[0] = s[0];
|
||||
b++;
|
||||
s++;
|
||||
}
|
||||
v += 2;
|
||||
}
|
||||
else if (v[0] == '#' && v[1] == '#')
|
||||
{
|
||||
const char* s = index_str;
|
||||
while (*s != '\0')
|
||||
{
|
||||
b[0] = s[0];
|
||||
b++;
|
||||
s++;
|
||||
}
|
||||
v += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = v[0];
|
||||
b++;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
b[0] = '\0';
|
||||
|
||||
Compiler::gSyntaxError = false;
|
||||
//Con::errorf("EVAL [%s]", avar("%s;", buffer));
|
||||
Con::evaluate(avar("%s;", buffer), false, 0);
|
||||
if (Compiler::gSyntaxError)
|
||||
{
|
||||
Con::errorf("onTriggerCommand \"%s\" -- syntax error", phrase_fx_data->on_trig_cmd);
|
||||
Compiler::gSyntaxError = false;
|
||||
}
|
||||
}
|
||||
|
||||
active_phrases->push_back(phrase);
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::update_active_phrases(F32 dt)
|
||||
{
|
||||
for (S32 i = 0; i < active_phrases->size(); i++)
|
||||
{
|
||||
afxPhrase* phrase = (*active_phrases)[i];
|
||||
if (phrase->expired(life_elapsed))
|
||||
phrase->recycle(life_elapsed);
|
||||
phrase->update(dt, life_elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhraseEffect::cleanup_finished_phrases()
|
||||
{
|
||||
Vector<afxPhrase*>* surviving_phrases = (active_phrases == &_phrases_a) ? &_phrases_b : &_phrases_a;
|
||||
|
||||
surviving_phrases->clear();
|
||||
for (S32 i = 0; i < active_phrases->size(); i++)
|
||||
{
|
||||
afxPhrase* phrase = (*active_phrases)[i];
|
||||
if (!phrase->isEmpty())
|
||||
surviving_phrases->push_back(phrase);
|
||||
else
|
||||
delete phrase;
|
||||
}
|
||||
|
||||
active_phrases->clear();
|
||||
active_phrases = surviving_phrases;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_PhraseEffectDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_PhraseEffectDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_PhraseEffect; }
|
||||
};
|
||||
|
||||
afxEA_PhraseEffectDesc afxEA_PhraseEffectDesc::desc;
|
||||
|
||||
bool afxEA_PhraseEffectDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxPhraseEffectData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_PhraseEffectDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
226
Engine/source/afx/ea/afxEA_PhysicalZone.cpp
Normal file
226
Engine/source/afx/ea/afxEA_PhysicalZone.cpp
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/physicalZone.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxPhysicalZone.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_PhysicalZone
|
||||
|
||||
class afxEA_PhysicalZone : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxPhysicalZoneData* zone_data;
|
||||
PhysicalZone* physical_zone;
|
||||
SceneObject* cons_obj;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
void set_cons_object(SceneObject*);
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_PhysicalZone();
|
||||
/*D*/ ~afxEA_PhysicalZone();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_PhysicalZone::afxEA_PhysicalZone()
|
||||
{
|
||||
zone_data = 0;
|
||||
physical_zone = 0;
|
||||
cons_obj = 0;
|
||||
}
|
||||
|
||||
afxEA_PhysicalZone::~afxEA_PhysicalZone()
|
||||
{
|
||||
if (physical_zone)
|
||||
physical_zone->deleteObject();
|
||||
if (zone_data && zone_data->isTempClone())
|
||||
delete zone_data;
|
||||
zone_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
zone_data = dynamic_cast<afxPhysicalZoneData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_PhysicalZone::ea_start()
|
||||
{
|
||||
if (!zone_data)
|
||||
{
|
||||
Con::errorf("afxEA_PhysicalZone::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_PhysicalZone::ea_update(F32 dt)
|
||||
{
|
||||
if (!physical_zone)
|
||||
{
|
||||
// create and register effect
|
||||
physical_zone = new PhysicalZone();
|
||||
physical_zone->mVelocityMod = zone_data->mVelocityMod;
|
||||
physical_zone->mGravityMod = zone_data->mGravityMod;
|
||||
physical_zone->mAppliedForce = zone_data->mAppliedForce;
|
||||
physical_zone->force_type = zone_data->force_type;
|
||||
physical_zone->orient_force = zone_data->orient_force;
|
||||
physical_zone->setField("polyhedron", zone_data->mPolyhedron);
|
||||
|
||||
if (!physical_zone->registerObject())
|
||||
{
|
||||
delete physical_zone;
|
||||
physical_zone = 0;
|
||||
Con::errorf("afxEA_PhysicalZone::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(physical_zone);
|
||||
physical_zone->activate();
|
||||
}
|
||||
|
||||
if (physical_zone)
|
||||
{
|
||||
if (zone_data->exclude_cons_obj)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
set_cons_object((pos_constraint) ? pos_constraint->getSceneObject() : 0);
|
||||
}
|
||||
|
||||
if (do_fades)
|
||||
physical_zone->setFadeAmount(fade_value);
|
||||
physical_zone->setTransform(updated_xfm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (physical_zone)
|
||||
{
|
||||
set_cons_object(0);
|
||||
physical_zone->deleteObject();
|
||||
physical_zone = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (physical_zone)
|
||||
{
|
||||
if (in_scope && !physical_zone->isActive())
|
||||
physical_zone->activate();
|
||||
else if (!in_scope && physical_zone->isActive())
|
||||
physical_zone->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (physical_zone == dynamic_cast<PhysicalZone*>(obj))
|
||||
physical_zone = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (zone_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxPhysicalZoneData* orig_db = zone_data;
|
||||
zone_data = new afxPhysicalZoneData(*orig_db, true);
|
||||
orig_db->performSubstitutions(zone_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PhysicalZone::set_cons_object(SceneObject* new_obj)
|
||||
{
|
||||
if (cons_obj == new_obj)
|
||||
return;
|
||||
|
||||
if (cons_obj)
|
||||
{
|
||||
physical_zone->unregisterExcludedObject(cons_obj);
|
||||
//clearNotify(shape);
|
||||
}
|
||||
|
||||
cons_obj = new_obj;
|
||||
|
||||
if (cons_obj)
|
||||
{
|
||||
//deleteNotify(shape);
|
||||
physical_zone->registerExcludedObject(cons_obj);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_PhysicalZoneDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_PhysicalZoneDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_PhysicalZone; }
|
||||
};
|
||||
|
||||
afxEA_PhysicalZoneDesc afxEA_PhysicalZoneDesc::desc;
|
||||
|
||||
bool afxEA_PhysicalZoneDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxPhysicalZoneData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_PhysicalZoneDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
170
Engine/source/afx/ea/afxEA_PlayerMovement.cpp
Normal file
170
Engine/source/afx/ea/afxEA_PlayerMovement.cpp
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/player.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxPlayerMovement.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_PlayerMovement
|
||||
|
||||
class afxEA_PlayerMovement : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxPlayerMovementData* movement_data;
|
||||
U32 tag;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_PlayerMovement();
|
||||
/*C*/ ~afxEA_PlayerMovement();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_PlayerMovement::afxEA_PlayerMovement()
|
||||
{
|
||||
movement_data = 0;
|
||||
tag = 0;
|
||||
}
|
||||
|
||||
afxEA_PlayerMovement::~afxEA_PlayerMovement()
|
||||
{
|
||||
if (movement_data && movement_data->isTempClone())
|
||||
delete movement_data;
|
||||
movement_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_PlayerMovement::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
movement_data = dynamic_cast<afxPlayerMovementData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_PlayerMovement::ea_start()
|
||||
{
|
||||
if (!movement_data)
|
||||
{
|
||||
Con::errorf("afxEA_PlayerMovement::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
tag = 0;
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (!pos_cons)
|
||||
{
|
||||
Con::warnf("afxEA_PlayerMovement::ea_start() -- missing position constraint.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Player* player = dynamic_cast<Player*>(pos_cons->getSceneObject());
|
||||
if (!player)
|
||||
{
|
||||
Con::warnf("afxEA_PlayerMovement::ea_start() -- position constraint is not a Player.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup player overrides
|
||||
if (movement_data->hasMovementOverride())
|
||||
tag = player->setMovementOverride(movement_data->speed_bias, &movement_data->movement, movement_data->movement_op);
|
||||
else
|
||||
tag = player->setMovementOverride(movement_data->speed_bias);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_PlayerMovement::ea_update(F32 dt)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_PlayerMovement::ea_finish(bool was_stopped)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
if (!pos_cons)
|
||||
return;
|
||||
|
||||
Player* player = dynamic_cast<Player*>(pos_cons->getSceneObject());
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
// restore player overrides
|
||||
player->restoreMovement(tag);
|
||||
}
|
||||
|
||||
void afxEA_PlayerMovement::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (movement_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxPlayerMovementData* orig_db = movement_data;
|
||||
movement_data = new afxPlayerMovementData(*orig_db, true);
|
||||
orig_db->performSubstitutions(movement_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_PlayerMovementDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_PlayerMovementDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_PlayerMovement; }
|
||||
};
|
||||
|
||||
afxEA_PlayerMovementDesc afxEA_PlayerMovementDesc::desc;
|
||||
|
||||
bool afxEA_PlayerMovementDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxPlayerMovementData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_PlayerMovementDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
184
Engine/source/afx/ea/afxEA_PlayerPuppet.cpp
Normal file
184
Engine/source/afx/ea/afxEA_PlayerPuppet.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/player.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ce/afxPlayerPuppet.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_PlayerPuppet
|
||||
|
||||
class afxEA_PlayerPuppet : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxPlayerPuppetData* mover_data;
|
||||
afxConstraint* obj_cons;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_PlayerPuppet();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual void getUnconstrainedPosition(Point3F& pos);
|
||||
virtual void getUnconstrainedTransform(MatrixF& xfm);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_PlayerPuppet::afxEA_PlayerPuppet()
|
||||
{
|
||||
mover_data = 0;
|
||||
obj_cons = 0;
|
||||
}
|
||||
|
||||
void afxEA_PlayerPuppet::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
mover_data = dynamic_cast<afxPlayerPuppetData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_PlayerPuppet::ea_start()
|
||||
{
|
||||
if (!mover_data)
|
||||
{
|
||||
Con::errorf("afxEA_PlayerPuppet::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
afxConstraintID obj_id = cons_mgr->getConstraintId(mover_data->obj_def);
|
||||
obj_cons = cons_mgr->getConstraint(obj_id);
|
||||
|
||||
Player* player = dynamic_cast<Player*>((obj_cons) ? obj_cons->getSceneObject() : 0);
|
||||
if (player)
|
||||
player->ignore_updates = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_PlayerPuppet::ea_update(F32 dt)
|
||||
{
|
||||
SceneObject* obj = (obj_cons) ? obj_cons->getSceneObject() : 0;
|
||||
|
||||
if (obj && in_scope)
|
||||
{
|
||||
obj->setTransform(updated_xfm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_PlayerPuppet::ea_finish(bool was_stopped)
|
||||
{
|
||||
Player* player = dynamic_cast<Player*>((obj_cons) ? obj_cons->getSceneObject() : 0);
|
||||
if (player)
|
||||
{
|
||||
player->resetContactTimer();
|
||||
player->ignore_updates = false;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_PlayerPuppet::getUnconstrainedPosition(Point3F& pos)
|
||||
{
|
||||
SceneObject* obj = (obj_cons) ? obj_cons->getSceneObject() : 0;
|
||||
if (obj)
|
||||
pos = obj->getRenderPosition();
|
||||
else
|
||||
pos.zero();
|
||||
}
|
||||
|
||||
void afxEA_PlayerPuppet::getUnconstrainedTransform(MatrixF& xfm)
|
||||
{
|
||||
SceneObject* obj = (obj_cons) ? obj_cons->getSceneObject() : 0;
|
||||
if (obj)
|
||||
xfm = obj->getRenderTransform();
|
||||
else
|
||||
xfm.identity();
|
||||
}
|
||||
|
||||
void afxEA_PlayerPuppet::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (mover_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxPlayerPuppetData* orig_db = mover_data;
|
||||
mover_data = new afxPlayerPuppetData(*orig_db, true);
|
||||
orig_db->performSubstitutions(mover_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_PlayerPuppetDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_PlayerPuppetDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const;
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_PlayerPuppet; }
|
||||
};
|
||||
|
||||
afxEA_PlayerPuppetDesc afxEA_PlayerPuppetDesc::desc;
|
||||
|
||||
bool afxEA_PlayerPuppetDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxPlayerPuppetData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_PlayerPuppetDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
bool afxEA_PlayerPuppetDesc::runsOnServer(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxPlayerPuppetData*)ew->effect_data)->networking;
|
||||
return ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
}
|
||||
|
||||
bool afxEA_PlayerPuppetDesc::runsOnClient(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
U8 networking = ((const afxPlayerPuppetData*)ew->effect_data)->networking;
|
||||
return ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
289
Engine/source/afx/ea/afxEA_PointLight_T3D.cpp
Normal file
289
Engine/source/afx/ea/afxEA_PointLight_T3D.cpp
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/pointLight.h"
|
||||
|
||||
#include "afx/ce/afxPointLight_T3D.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_T3DPointLight
|
||||
|
||||
class PointLightProxy;
|
||||
|
||||
class afxEA_T3DPointLight : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxT3DPointLightData* light_data;
|
||||
PointLightProxy* light;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_T3DPointLight();
|
||||
/*D*/ ~afxEA_T3DPointLight();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual void getBaseColor(LinearColorF& color);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class PointLightProxy : public PointLight
|
||||
{
|
||||
F32 fade_amt;
|
||||
|
||||
public:
|
||||
PointLightProxy() { fade_amt = 1.0f; }
|
||||
|
||||
void force_ghost()
|
||||
{
|
||||
mNetFlags.clear(Ghostable | ScopeAlways);
|
||||
mNetFlags.set(IsGhost);
|
||||
}
|
||||
|
||||
void setFadeAmount(F32 fade_amt)
|
||||
{
|
||||
this->fade_amt = fade_amt;
|
||||
mLight->setBrightness(mBrightness*fade_amt);
|
||||
}
|
||||
|
||||
void updateTransform(const MatrixF& xfm)
|
||||
{
|
||||
mLight->setTransform(xfm);
|
||||
LightBase::setTransform(xfm);
|
||||
}
|
||||
|
||||
void initWithDataBlock(const afxT3DPointLightData* db)
|
||||
{
|
||||
mRadius = db->mRadius;
|
||||
|
||||
mColor = db->mColor;
|
||||
mBrightness = db->mBrightness;
|
||||
mCastShadows = db->mCastShadows;
|
||||
mPriority = db->mPriority;
|
||||
mFlareData = db->mFlareData;
|
||||
mAnimationData = db->mAnimationData;
|
||||
mAnimState.active = (mAnimationData != 0);
|
||||
|
||||
mLocalRenderViz = db->mLocalRenderViz;
|
||||
|
||||
mLight->setType( LightInfo::Point );
|
||||
mLight->setBrightness( db->mBrightness );
|
||||
mLight->setRange( db->mRadius );
|
||||
mLight->setColor( db->mColor );
|
||||
mLight->setCastShadows( db->mCastShadows );
|
||||
mLight->setPriority( db->mPriority );
|
||||
|
||||
// Update the bounds and scale to fit our light.
|
||||
mObjBox.minExtents.set( -1, -1, -1 );
|
||||
mObjBox.maxExtents.set( 1, 1, 1 );
|
||||
mObjScale.set( db->mRadius, db->mRadius, db->mRadius );
|
||||
|
||||
//_conformLights();
|
||||
}
|
||||
|
||||
void setLiveColor(const LinearColorF& live_color)
|
||||
{
|
||||
mLight->setColor(live_color);
|
||||
}
|
||||
|
||||
void submitLights(LightManager* lm, bool staticLighting)
|
||||
{
|
||||
if (mAnimState.active && mAnimationData && fade_amt < 1.0f)
|
||||
{
|
||||
F32 mBrightness_save = mBrightness;
|
||||
mBrightness *= fade_amt;
|
||||
PointLight::submitLights(lm, staticLighting);
|
||||
mBrightness = mBrightness_save;
|
||||
return;
|
||||
}
|
||||
|
||||
PointLight::submitLights(lm, staticLighting);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_T3DPointLight::afxEA_T3DPointLight()
|
||||
{
|
||||
light_data = 0;
|
||||
light = 0;
|
||||
}
|
||||
|
||||
afxEA_T3DPointLight::~afxEA_T3DPointLight()
|
||||
{
|
||||
if (light)
|
||||
light->deleteObject();
|
||||
if (light_data && light_data->isTempClone())
|
||||
delete light_data;
|
||||
light_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
light_data = dynamic_cast<afxT3DPointLightData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_T3DPointLight::ea_start()
|
||||
{
|
||||
if (!light_data)
|
||||
{
|
||||
Con::errorf("afxEA_T3DPointLight::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
// create and register effect
|
||||
light = new PointLightProxy();
|
||||
light->force_ghost();
|
||||
if (!light->registerObject())
|
||||
{
|
||||
delete light;
|
||||
light = 0;
|
||||
Con::errorf("afxEA_T3DPointLight::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(light);
|
||||
|
||||
light->initWithDataBlock(light_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_T3DPointLight::ea_update(F32 dt)
|
||||
{
|
||||
if (light)
|
||||
{
|
||||
#if 0 // AFX_T3D_DISABLED
|
||||
// With sgLightObject lights, the following code block would hook
|
||||
// the constraint object up to the light in case the light was
|
||||
// configured to exclude it from flare occusions. The code remains
|
||||
// here in case we need to implement the same feature for T3D light.
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
SceneObject* cons_obj = (pos_cons) ? pos_cons->getSceneObject() : 0;
|
||||
light->setConstraintObject(cons_obj);
|
||||
#endif
|
||||
|
||||
light->setLiveColor(updated_color);
|
||||
|
||||
if (do_fades)
|
||||
light->setFadeAmount(fade_value*updated_scale.x);
|
||||
|
||||
light->updateTransform(updated_xfm);
|
||||
|
||||
// scale should not be updated this way. It messes up the culling.
|
||||
//light->setScale(updated_scale);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (light)
|
||||
{
|
||||
light->deleteObject();
|
||||
light = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (light)
|
||||
light->setLightEnabled(in_scope);
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (light == dynamic_cast<PointLight*>(obj))
|
||||
light = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::getBaseColor(LinearColorF& color)
|
||||
{
|
||||
if (light_data)
|
||||
color = light_data->mColor;
|
||||
}
|
||||
|
||||
void afxEA_T3DPointLight::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (light_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxT3DPointLightData* orig_db = light_data;
|
||||
light_data = new afxT3DPointLightData(*orig_db, true);
|
||||
orig_db->performSubstitutions(light_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_T3DPointLightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_T3DPointLightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_T3DPointLight; }
|
||||
};
|
||||
|
||||
afxEA_T3DPointLightDesc afxEA_T3DPointLightDesc::desc;
|
||||
|
||||
bool afxEA_T3DPointLightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxT3DPointLightData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_T3DPointLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
315
Engine/source/afx/ea/afxEA_Projectile.cpp
Normal file
315
Engine/source/afx/ea/afxEA_Projectile.cpp
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "lighting/lightInfo.h"
|
||||
#include "T3D/projectile.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxProjectile.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Projectile
|
||||
|
||||
class afxEA_Projectile : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
ProjectileData* projectile_data;
|
||||
afxProjectileData* afx_projectile_data;
|
||||
afxProjectile* projectile;
|
||||
bool launched;
|
||||
bool impacted;
|
||||
bool projectile_done;
|
||||
afxConstraint* launch_cons;
|
||||
Point3F launch_dir_bias;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Projectile();
|
||||
/*D*/ ~afxEA_Projectile();
|
||||
|
||||
virtual bool isDone();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Projectile::afxEA_Projectile()
|
||||
{
|
||||
projectile_data = 0;
|
||||
afx_projectile_data = 0;
|
||||
projectile = 0;
|
||||
launched = false;
|
||||
impacted = false;
|
||||
projectile_done = false;
|
||||
launch_cons = 0;
|
||||
launch_dir_bias.zero();
|
||||
}
|
||||
|
||||
afxEA_Projectile::~afxEA_Projectile()
|
||||
{
|
||||
if (projectile)
|
||||
clearNotify(projectile);
|
||||
//if (projectile_data && projectile_data->isTempClone())
|
||||
// delete projectile_data;
|
||||
projectile_data = 0;
|
||||
afx_projectile_data = 0;
|
||||
}
|
||||
|
||||
bool afxEA_Projectile::isDone()
|
||||
{
|
||||
return (datablock->use_as_cons_obj || datablock->use_ghost_as_cons_obj) ? projectile_done : impacted;
|
||||
}
|
||||
|
||||
void afxEA_Projectile::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
projectile_data = dynamic_cast<ProjectileData*>(db);
|
||||
afx_projectile_data = dynamic_cast<afxProjectileData*>(projectile_data);
|
||||
}
|
||||
|
||||
bool afxEA_Projectile::ea_start()
|
||||
{
|
||||
if (!projectile_data)
|
||||
{
|
||||
Con::errorf("afxEA_Projectile::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (!afx_projectile_data)
|
||||
{
|
||||
projectile = new afxProjectile();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (datablock->use_ghost_as_cons_obj && datablock->effect_name != ST_NULLSTRING)
|
||||
projectile = new afxProjectile(afx_projectile_data->networking, choreographer->getChoreographerId(), datablock->effect_name);
|
||||
else
|
||||
projectile = new afxProjectile(afx_projectile_data->networking, 0, ST_NULLSTRING);
|
||||
projectile->ignoreSourceTimeout = afx_projectile_data->ignore_src_timeout;
|
||||
if (afx_projectile_data->override_collision_masks)
|
||||
{
|
||||
projectile->dynamicCollisionMask = afx_projectile_data->dynamicCollisionMask;
|
||||
projectile->staticCollisionMask = afx_projectile_data->staticCollisionMask;
|
||||
}
|
||||
afxConstraintID launch_pos_id = cons_mgr->getConstraintId(afx_projectile_data->launch_pos_def);
|
||||
launch_cons = cons_mgr->getConstraint(launch_pos_id);
|
||||
launch_dir_bias = afx_projectile_data->launch_dir_bias;
|
||||
}
|
||||
|
||||
projectile->onNewDataBlock(projectile_data, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Projectile::ea_update(F32 dt)
|
||||
{
|
||||
if (!launched && projectile)
|
||||
{
|
||||
if (in_scope)
|
||||
{
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
ShapeBase* src_obj = (pos_cons) ? (dynamic_cast<ShapeBase*>(pos_cons->getSceneObject())) : 0;
|
||||
|
||||
F32 muzzle_vel = projectile_data->muzzleVelocity;
|
||||
|
||||
Point3F dir_vec;
|
||||
if (afx_projectile_data)
|
||||
{
|
||||
switch (afx_projectile_data->launch_dir_method)
|
||||
{
|
||||
case afxProjectileData::OrientConstraint:
|
||||
dir_vec.set(0,0,1);
|
||||
updated_xfm.mulV(dir_vec);
|
||||
break;
|
||||
case afxProjectileData::LaunchDirField:
|
||||
dir_vec.set(0,0,1);
|
||||
break;
|
||||
case afxProjectileData::TowardPos2Constraint:
|
||||
default:
|
||||
dir_vec = updated_aim - updated_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
dir_vec = updated_aim - updated_pos;
|
||||
|
||||
dir_vec.normalizeSafe();
|
||||
if (!launch_dir_bias.isZero())
|
||||
{
|
||||
dir_vec += launch_dir_bias;
|
||||
dir_vec.normalizeSafe();
|
||||
}
|
||||
dir_vec *= muzzle_vel;
|
||||
|
||||
Point3F launch_pos;
|
||||
if (launch_cons && launch_cons->getPosition(launch_pos))
|
||||
{
|
||||
ShapeBase* launch_obj = (launch_cons) ? (dynamic_cast<ShapeBase*>(launch_cons->getSceneObject())) : 0;
|
||||
projectile->init(launch_pos, dir_vec, (launch_obj) ? launch_obj : src_obj);
|
||||
}
|
||||
else
|
||||
projectile->init(updated_pos, dir_vec, src_obj);
|
||||
|
||||
if (!projectile->registerObject())
|
||||
{
|
||||
delete projectile;
|
||||
projectile = 0;
|
||||
Con::errorf("afxEA_Projectile::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
|
||||
deleteNotify(projectile);
|
||||
|
||||
if (projectile)
|
||||
projectile->setDataField(StringTable->insert("afxOwner"), 0, choreographer->getIdString());
|
||||
|
||||
}
|
||||
launched = true;
|
||||
}
|
||||
|
||||
if (launched && projectile)
|
||||
{
|
||||
if (in_scope)
|
||||
{
|
||||
updated_xfm = projectile->getRenderTransform();
|
||||
updated_xfm.getColumn(3, &updated_pos);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Projectile::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (projectile)
|
||||
{
|
||||
clearNotify(projectile);
|
||||
projectile = 0;
|
||||
}
|
||||
launched = false;
|
||||
impacted = false;
|
||||
}
|
||||
|
||||
void afxEA_Projectile::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
// projectile deleted?
|
||||
Projectile* del_projectile = dynamic_cast<Projectile*>(obj);
|
||||
if (del_projectile == projectile)
|
||||
{
|
||||
projectile = NULL;
|
||||
projectile_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_Projectile::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (projectile_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
if (typeid(afxProjectileData) == typeid(*projectile_data))
|
||||
{
|
||||
afxProjectileData* orig_db = (afxProjectileData*)projectile_data;
|
||||
afx_projectile_data = new afxProjectileData(*orig_db, true);
|
||||
projectile_data = afx_projectile_data;
|
||||
orig_db->performSubstitutions(projectile_data, choreographer, group_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
ProjectileData* orig_db = projectile_data;
|
||||
afx_projectile_data = 0;
|
||||
projectile_data = new ProjectileData(*orig_db, true);
|
||||
orig_db->performSubstitutions(projectile_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ProjectileDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ProjectileDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const;
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Projectile; }
|
||||
};
|
||||
|
||||
afxEA_ProjectileDesc afxEA_ProjectileDesc::desc;
|
||||
|
||||
bool afxEA_ProjectileDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
if (typeid(ProjectileData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxProjectileData) == typeid(*db))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool afxEA_ProjectileDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return ((ew->use_as_cons_obj || ew->use_ghost_as_cons_obj) && timing.lifetime < 0);
|
||||
}
|
||||
|
||||
bool afxEA_ProjectileDesc::runsOnServer(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
afxProjectileData* afx_projectile_data = dynamic_cast<afxProjectileData*>(ew->effect_data);
|
||||
if (!afx_projectile_data)
|
||||
return true;
|
||||
|
||||
U8 networking = ((const afxProjectileData*)ew->effect_data)->networking;
|
||||
return ((networking & CLIENT_ONLY) == 0);
|
||||
}
|
||||
|
||||
bool afxEA_ProjectileDesc::runsOnClient(const afxEffectWrapperData* ew) const
|
||||
{
|
||||
afxProjectileData* afx_projectile_data = dynamic_cast<afxProjectileData*>(ew->effect_data);
|
||||
if (!afx_projectile_data)
|
||||
return false;
|
||||
|
||||
U8 networking = ((const afxProjectileData*)ew->effect_data)->networking;
|
||||
return ((networking & CLIENT_ONLY) != 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
145
Engine/source/afx/ea/afxEA_ScriptEvent.cpp
Normal file
145
Engine/source/afx/ea/afxEA_ScriptEvent.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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxScriptEvent.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_ScriptEvent
|
||||
|
||||
class afxEA_ScriptEvent : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxScriptEventData* script_data;
|
||||
bool ran_script;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_ScriptEvent();
|
||||
/*D*/ ~afxEA_ScriptEvent();
|
||||
|
||||
virtual bool isDone() { return ran_script; }
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_ScriptEvent::afxEA_ScriptEvent()
|
||||
{
|
||||
script_data = 0;
|
||||
ran_script = false;
|
||||
}
|
||||
|
||||
afxEA_ScriptEvent::~afxEA_ScriptEvent()
|
||||
{
|
||||
if (script_data && script_data->isTempClone())
|
||||
delete script_data;
|
||||
script_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_ScriptEvent::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
script_data = dynamic_cast<afxScriptEventData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_ScriptEvent::ea_start()
|
||||
{
|
||||
if (!script_data)
|
||||
{
|
||||
Con::errorf("afxEA_ScriptEvent::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
ran_script = (script_data->method_name == ST_NULLSTRING);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_ScriptEvent::ea_update(F32 dt)
|
||||
{
|
||||
if (!ran_script && choreographer != NULL)
|
||||
{
|
||||
afxConstraint* pos_constraint = getPosConstraint();
|
||||
choreographer->executeScriptEvent(script_data->method_name, pos_constraint, updated_xfm,
|
||||
script_data->script_data);
|
||||
ran_script = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_ScriptEvent::ea_finish(bool was_stopped)
|
||||
{
|
||||
ran_script = false;
|
||||
}
|
||||
|
||||
void afxEA_ScriptEvent::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (script_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxScriptEventData* orig_db = script_data;
|
||||
script_data = new afxScriptEventData(*orig_db, true);
|
||||
orig_db->performSubstitutions(script_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ScriptEventDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ScriptEventDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const { return false; }
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool isPositional(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_ScriptEvent; }
|
||||
};
|
||||
|
||||
afxEA_ScriptEventDesc afxEA_ScriptEventDesc::desc;
|
||||
|
||||
bool afxEA_ScriptEventDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxScriptEventData) == typeid(*db));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
214
Engine/source/afx/ea/afxEA_Sound.cpp
Normal file
214
Engine/source/afx/ea/afxEA_Sound.cpp
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.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
#include <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "sfx/sfxSystem.h"
|
||||
#include "sfx/sfxSource.h"
|
||||
#include "sfx/sfxProfile.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Sound
|
||||
|
||||
class afxEA_Sound : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
SFXProfile* sound_prof;
|
||||
SFXDescription* sound_desc;
|
||||
SFXSource* sound_handle;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Sound();
|
||||
/*D*/ ~afxEA_Sound();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_Sound::afxEA_Sound()
|
||||
{
|
||||
sound_prof = 0;
|
||||
sound_desc = 0;
|
||||
sound_handle = 0;
|
||||
}
|
||||
|
||||
afxEA_Sound::~afxEA_Sound()
|
||||
{
|
||||
if (sound_prof && sound_prof->isTempClone())
|
||||
delete sound_prof;
|
||||
sound_prof = 0;
|
||||
sound_desc = 0;
|
||||
sound_handle = 0;
|
||||
}
|
||||
|
||||
void afxEA_Sound::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
sound_prof = dynamic_cast<SFXProfile*>(db);
|
||||
if (sound_prof)
|
||||
sound_desc = sound_prof->getDescription();
|
||||
}
|
||||
|
||||
bool afxEA_Sound::ea_start()
|
||||
{
|
||||
if (!sound_prof)
|
||||
{
|
||||
Con::errorf("afxEA_Sound::ea_start() -- missing or incompatible AudioProfile.");
|
||||
return false;
|
||||
}
|
||||
if (!sound_desc)
|
||||
{
|
||||
Con::errorf("afxEA_Sound::ea_start() -- missing or incompatible AudioDescriptor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Sound::ea_update(F32 dt)
|
||||
{
|
||||
if (!sound_handle)
|
||||
{
|
||||
sound_handle = SFX->createSource(sound_prof, &updated_xfm, 0);
|
||||
if (sound_handle)
|
||||
sound_handle->play();
|
||||
}
|
||||
|
||||
if (sound_handle)
|
||||
{
|
||||
sound_handle->setTransform(updated_xfm);
|
||||
sound_handle->setVolume((in_scope) ? updated_scale.x*fade_value : 0.0f);
|
||||
deleteNotify(sound_handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Sound::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (sound_handle)
|
||||
{
|
||||
sound_handle->stop();
|
||||
SFX_DELETE(sound_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_Sound::do_runtime_substitutions()
|
||||
{
|
||||
sound_prof = sound_prof->cloneAndPerformSubstitutions(choreographer, group_index);
|
||||
sound_desc = sound_prof->getDescription();
|
||||
}
|
||||
|
||||
void afxEA_Sound::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (sound_handle == dynamic_cast<SFXSource*>(obj))
|
||||
sound_handle = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_SoundDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_SoundDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
virtual void prepEffect(afxEffectWrapperData*) const;
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Sound; }
|
||||
};
|
||||
|
||||
afxEA_SoundDesc afxEA_SoundDesc::desc;
|
||||
|
||||
bool afxEA_SoundDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
// dynamic cast used here so that both SFXProfile and AudioProfile match
|
||||
return (dynamic_cast<const SFXProfile*>(db) != 0);
|
||||
}
|
||||
|
||||
bool afxEA_SoundDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
SFXDescription* desc = ((SFXProfile*)ew->effect_data)->getDescription();
|
||||
return (desc && desc->mIsLooping) ? (timing.lifetime < 0) : false;
|
||||
}
|
||||
|
||||
void afxEA_SoundDesc::prepEffect(afxEffectWrapperData* ew) const
|
||||
{
|
||||
if (ew->ewd_timing.lifetime < 0)
|
||||
{
|
||||
SFXProfile* snd = (SFXProfile*) ew->effect_data;
|
||||
SFXDescription* desc = snd->getDescription();
|
||||
if (desc && !desc->mIsLooping)
|
||||
{
|
||||
static bool test_for_audio = true;
|
||||
static bool can_get_audio_len = false;
|
||||
|
||||
if (test_for_audio)
|
||||
{
|
||||
can_get_audio_len = true;
|
||||
test_for_audio = false;
|
||||
}
|
||||
|
||||
if (can_get_audio_len)
|
||||
{
|
||||
SFXResource* sfx_rsrc = snd->getResource();
|
||||
if (sfx_rsrc)
|
||||
{
|
||||
ew->ewd_timing.lifetime = 0.001f*sfx_rsrc->getDuration();
|
||||
//Con::printf("SFX (%s) duration=%g", snd->mFilename, timing.lifetime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ew->ewd_timing.lifetime = 0;
|
||||
Con::printf("afxEA_SoundDesc::prepEffect() -- cannot get audio length from sound file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
293
Engine/source/afx/ea/afxEA_SpotLight_T3D.cpp
Normal file
293
Engine/source/afx/ea/afxEA_SpotLight_T3D.cpp
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "T3D/spotLight.h"
|
||||
|
||||
#include "afx/ce/afxSpotLight_T3D.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_T3DSpotLight
|
||||
|
||||
class SpotLightProxy;
|
||||
|
||||
class afxEA_T3DSpotLight : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxT3DSpotLightData* light_data;
|
||||
SpotLightProxy* light;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_T3DSpotLight();
|
||||
/*D*/ ~afxEA_T3DSpotLight();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual void getBaseColor(LinearColorF& color);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class SpotLightProxy : public SpotLight
|
||||
{
|
||||
F32 fade_amt;
|
||||
|
||||
public:
|
||||
SpotLightProxy() { fade_amt = 1.0f; }
|
||||
|
||||
void force_ghost()
|
||||
{
|
||||
mNetFlags.clear(Ghostable | ScopeAlways);
|
||||
mNetFlags.set(IsGhost);
|
||||
}
|
||||
|
||||
void setFadeAmount(F32 fade_amt)
|
||||
{
|
||||
this->fade_amt = fade_amt;
|
||||
mLight->setBrightness(mBrightness*fade_amt);
|
||||
}
|
||||
|
||||
void updateTransform(const MatrixF& xfm)
|
||||
{
|
||||
mLight->setTransform(xfm);
|
||||
LightBase::setTransform(xfm);
|
||||
}
|
||||
|
||||
void initWithDataBlock(const afxT3DSpotLightData* db)
|
||||
{
|
||||
mRange = getMax(db->mRange, 0.05f);
|
||||
mInnerConeAngle = db->mInnerConeAngle;
|
||||
mOuterConeAngle = db->mOuterConeAngle;
|
||||
|
||||
mColor = db->mColor;
|
||||
mBrightness = db->mBrightness;
|
||||
mCastShadows = db->mCastShadows;
|
||||
mPriority = db->mPriority;
|
||||
mFlareData = db->mFlareData;
|
||||
mAnimationData = db->mAnimationData;
|
||||
mAnimState.active = (mAnimationData != 0);
|
||||
|
||||
mLocalRenderViz = db->mLocalRenderViz;
|
||||
|
||||
mLight->setType( LightInfo::Spot );
|
||||
mLight->setBrightness( db->mBrightness );
|
||||
mLight->setRange( db->mRange );
|
||||
mLight->setColor( db->mColor );
|
||||
mLight->setCastShadows( db->mCastShadows );
|
||||
mLight->setPriority( db->mPriority );
|
||||
mLight->setInnerConeAngle( db->mInnerConeAngle );
|
||||
mLight->setOuterConeAngle( db->mOuterConeAngle );
|
||||
|
||||
// Update the bounds and scale to fit our light.
|
||||
F32 radius = mRange * mSin( mDegToRad( mOuterConeAngle ) * 0.5f );
|
||||
mObjBox.minExtents.set( -1, -1, -1 );
|
||||
mObjBox.maxExtents.set( 1, 1, 1 );
|
||||
mObjScale.set( radius, mRange, radius );
|
||||
|
||||
//_conformLights();
|
||||
}
|
||||
|
||||
void setLiveColor(const LinearColorF& live_color)
|
||||
{
|
||||
mLight->setColor(live_color);
|
||||
}
|
||||
|
||||
void submitLights(LightManager* lm, bool staticLighting)
|
||||
{
|
||||
if (mAnimState.active && mAnimationData && fade_amt < 1.0f)
|
||||
{
|
||||
F32 mBrightness_save = mBrightness;
|
||||
mBrightness *= fade_amt;
|
||||
SpotLight::submitLights(lm, staticLighting);
|
||||
mBrightness = mBrightness_save;
|
||||
return;
|
||||
}
|
||||
|
||||
SpotLight::submitLights(lm, staticLighting);
|
||||
}
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_T3DSpotLight::afxEA_T3DSpotLight()
|
||||
{
|
||||
light_data = 0;
|
||||
light = 0;
|
||||
}
|
||||
|
||||
afxEA_T3DSpotLight::~afxEA_T3DSpotLight()
|
||||
{
|
||||
if (light)
|
||||
light->deleteObject();
|
||||
if (light_data && light_data->isTempClone())
|
||||
delete light_data;
|
||||
light_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
light_data = dynamic_cast<afxT3DSpotLightData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_T3DSpotLight::ea_start()
|
||||
{
|
||||
if (!light_data)
|
||||
{
|
||||
Con::errorf("afxEA_T3DSpotLight::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
// create and register effect
|
||||
light = new SpotLightProxy();
|
||||
light->force_ghost();
|
||||
if (!light->registerObject())
|
||||
{
|
||||
delete light;
|
||||
light = 0;
|
||||
Con::errorf("afxEA_T3DSpotLight::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(light);
|
||||
|
||||
light->initWithDataBlock(light_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_T3DSpotLight::ea_update(F32 dt)
|
||||
{
|
||||
if (light)
|
||||
{
|
||||
#if 0 // AFX_T3D_DISABLED
|
||||
// With sgLightObject lights, the following code block would hook
|
||||
// the constraint object up to the light in case the light was
|
||||
// configured to exclude it from flare occusions. The code remains
|
||||
// here in case we need to implement the same feature for T3D light.
|
||||
|
||||
afxConstraint* pos_cons = getPosConstraint();
|
||||
SceneObject* cons_obj = (pos_cons) ? pos_cons->getSceneObject() : 0;
|
||||
light->setConstraintObject(cons_obj);
|
||||
#endif
|
||||
|
||||
light->setLiveColor(updated_color);
|
||||
|
||||
if (do_fades)
|
||||
light->setFadeAmount(fade_value);
|
||||
|
||||
light->updateTransform(updated_xfm);
|
||||
|
||||
// scale should not be updated this way. It messes up the culling.
|
||||
//light->setScale(updated_scale);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (light)
|
||||
{
|
||||
light->deleteObject();
|
||||
light = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (light)
|
||||
light->setLightEnabled(in_scope);
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (light == dynamic_cast<SpotLight*>(obj))
|
||||
light = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::getBaseColor(LinearColorF& color)
|
||||
{
|
||||
if (light_data)
|
||||
color = light_data->mColor;
|
||||
}
|
||||
|
||||
void afxEA_T3DSpotLight::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (light_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxT3DSpotLightData* orig_db = light_data;
|
||||
light_data = new afxT3DSpotLightData(*orig_db, true);
|
||||
orig_db->performSubstitutions(light_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_T3DSpotLightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_T3DSpotLightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_T3DSpotLight; }
|
||||
};
|
||||
|
||||
afxEA_T3DSpotLightDesc afxEA_T3DSpotLightDesc::desc;
|
||||
|
||||
bool afxEA_T3DSpotLightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxT3DSpotLightData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_T3DSpotLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
249
Engine/source/afx/ea/afxEA_StaticShape.cpp
Normal file
249
Engine/source/afx/ea/afxEA_StaticShape.cpp
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxStaticShape.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_StaticShape
|
||||
|
||||
class afxEA_StaticShape : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
StaticShapeData* shape_data;
|
||||
afxStaticShape* static_shape;
|
||||
bool fade_out_started;
|
||||
bool do_spawn;
|
||||
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_StaticShape();
|
||||
/*D*/ ~afxEA_StaticShape();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
|
||||
virtual void getUpdatedBoxCenter(Point3F& pos);
|
||||
virtual TSShape* getTSShape();
|
||||
virtual TSShapeInstance* getTSShapeInstance();
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_StaticShape::afxEA_StaticShape()
|
||||
{
|
||||
shape_data = 0;
|
||||
static_shape = 0;
|
||||
fade_out_started = false;
|
||||
do_spawn = true;
|
||||
}
|
||||
|
||||
afxEA_StaticShape::~afxEA_StaticShape()
|
||||
{
|
||||
if (static_shape)
|
||||
static_shape->deleteObject();
|
||||
if (shape_data && shape_data->isTempClone())
|
||||
delete shape_data;
|
||||
shape_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
shape_data = dynamic_cast<StaticShapeData*>(db);
|
||||
afxStaticShapeData* afx_shape_data = dynamic_cast<afxStaticShapeData*>(shape_data);
|
||||
do_spawn = (afx_shape_data) ? afx_shape_data->do_spawn : false;
|
||||
}
|
||||
|
||||
bool afxEA_StaticShape::ea_start()
|
||||
{
|
||||
if (!shape_data)
|
||||
{
|
||||
Con::errorf("afxEA_StaticShape::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
// fades are handled using startFade() calls.
|
||||
do_fades = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_StaticShape::ea_update(F32 dt)
|
||||
{
|
||||
if (!static_shape)
|
||||
{
|
||||
// create and register effect
|
||||
static_shape = new afxStaticShape();
|
||||
if (datablock->use_ghost_as_cons_obj && datablock->effect_name != ST_NULLSTRING)
|
||||
static_shape->init(choreographer->getChoreographerId(), datablock->effect_name);
|
||||
|
||||
static_shape->onNewDataBlock(shape_data, false);
|
||||
if (!static_shape->registerObject())
|
||||
{
|
||||
delete static_shape;
|
||||
static_shape = 0;
|
||||
Con::errorf("afxEA_StaticShape::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(static_shape);
|
||||
registerForCleanup(static_shape);
|
||||
|
||||
if (ew_timing.fade_in_time > 0.0f)
|
||||
static_shape->startFade(ew_timing.fade_in_time, 0, false);
|
||||
}
|
||||
|
||||
if (static_shape)
|
||||
{
|
||||
if (!fade_out_started && elapsed > fade_out_start)
|
||||
{
|
||||
if (!do_spawn)
|
||||
{
|
||||
if (ew_timing.fade_out_time > 0.0f)
|
||||
static_shape->startFade(ew_timing.fade_out_time, 0, true);
|
||||
}
|
||||
fade_out_started = true;
|
||||
}
|
||||
|
||||
if (in_scope)
|
||||
{
|
||||
static_shape->setTransform(updated_xfm);
|
||||
static_shape->setScale(updated_scale);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (!static_shape)
|
||||
return;
|
||||
|
||||
if (do_spawn)
|
||||
{
|
||||
Con::executef(shape_data, "onSpawn", static_shape->getIdString(), datablock->effect_name);
|
||||
clearNotify(static_shape);
|
||||
}
|
||||
else
|
||||
static_shape->deleteObject();
|
||||
|
||||
static_shape = 0;
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (static_shape)
|
||||
static_shape->setVisibility(do_spawn || in_scope);
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (static_shape == dynamic_cast<afxStaticShape*>(obj))
|
||||
static_shape = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::getUpdatedBoxCenter(Point3F& pos)
|
||||
{
|
||||
if (static_shape)
|
||||
pos = static_shape->getBoxCenter();
|
||||
}
|
||||
|
||||
|
||||
TSShape* afxEA_StaticShape::getTSShape()
|
||||
{
|
||||
return (static_shape) ? ((TSShape*)static_shape->getShape()) : 0;
|
||||
}
|
||||
|
||||
TSShapeInstance* afxEA_StaticShape::getTSShapeInstance()
|
||||
{
|
||||
return (static_shape) ? static_shape->getShapeInstance() : 0;
|
||||
}
|
||||
|
||||
void afxEA_StaticShape::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (shape_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
if (typeid(afxStaticShapeData) == typeid(*shape_data))
|
||||
{
|
||||
afxStaticShapeData* orig_db = (afxStaticShapeData*)shape_data;
|
||||
shape_data = new afxStaticShapeData(*orig_db, true);
|
||||
orig_db->performSubstitutions(shape_data, choreographer, group_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
StaticShapeData* orig_db = shape_data;
|
||||
shape_data = new StaticShapeData(*orig_db, true);
|
||||
orig_db->performSubstitutions(shape_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_StaticShapeDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_StaticShapeDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return true; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return false; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_StaticShape; }
|
||||
};
|
||||
|
||||
afxEA_StaticShapeDesc afxEA_StaticShapeDesc::desc;
|
||||
|
||||
bool afxEA_StaticShapeDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
if (typeid(StaticShapeData) == typeid(*db))
|
||||
return true;
|
||||
if (typeid(afxStaticShapeData) == typeid(*db))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool afxEA_StaticShapeDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
79
Engine/source/afx/ea/afxEA_TLKLight.cpp
Normal file
79
Engine/source/afx/ea/afxEA_TLKLight.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
||||
struct sgLightObjectData : public GameBaseData
|
||||
{
|
||||
typedef GameBaseData Parent;
|
||||
DECLARE_CONOBJECT(sgLightObjectData);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(sgLightObjectData);
|
||||
|
||||
ConsoleDocClass( sgLightObjectData,
|
||||
"@brief Allows legacy sgLightObjectData datablocks to appear in scripts.\n\n"
|
||||
|
||||
"@ingroup afxMisc\n"
|
||||
"@ingroup AFX\n"
|
||||
"@ingroup Datablocks\n"
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_TLKLightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_TLKLightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return 0; }
|
||||
};
|
||||
|
||||
afxEA_TLKLightDesc afxEA_TLKLightDesc::desc;
|
||||
|
||||
//class sgUniversalStaticLightData;
|
||||
|
||||
bool afxEA_TLKLightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(sgLightObjectData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_TLKLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
61
Engine/source/afx/ea/afxEA_VolumeLight.cpp
Normal file
61
Engine/source/afx/ea/afxEA_VolumeLight.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/ea/afxEA_ParticleEmitter.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/ce/afxVolumeLight.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_VolumeLightDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_VolumeLightDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return 0; }
|
||||
};
|
||||
|
||||
afxEA_VolumeLightDesc afxEA_VolumeLightDesc::desc;
|
||||
|
||||
bool afxEA_VolumeLightDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxVolumeLightData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_VolumeLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
434
Engine/source/afx/ea/afxEA_Zodiac.cpp
Normal file
434
Engine/source/afx/ea/afxEA_Zodiac.cpp
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// 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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "math/mathUtils.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
#include "afx/util/afxEase.h"
|
||||
#include "afx/ce/afxZodiacMgr.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_Zodiac
|
||||
|
||||
class afxEA_Zodiac : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxZodiacData* zode_data;
|
||||
Point3F zode_pos;
|
||||
F32 zode_radius;
|
||||
Point2F zode_vrange;
|
||||
LinearColorF zode_color;
|
||||
F32 zode_angle;
|
||||
F32 zode_angle_offset;
|
||||
|
||||
F32 live_color_factor;
|
||||
LinearColorF live_color;
|
||||
bool became_residue;
|
||||
bool do_altitude_bias;
|
||||
F32 altitude_falloff_range;
|
||||
|
||||
F32 calc_facing_angle();
|
||||
F32 calc_terrain_alt_bias();
|
||||
F32 calc_interior_alt_bias();
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_Zodiac();
|
||||
/*C*/ ~afxEA_Zodiac();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
|
||||
virtual bool ea_is_enabled() { return true; }
|
||||
|
||||
virtual void getBaseColor(LinearColorF& color) { color = zode_data->color; }
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
//DECLARE_CONOBJECT(afxEA_Zodiac);
|
||||
DECLARE_CATEGORY("AFX");
|
||||
};
|
||||
|
||||
//IMPLEMENT_CONOBJECT(afxEA_Zodiac);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
F32 afxEA_Zodiac::calc_facing_angle()
|
||||
{
|
||||
// get direction player is facing
|
||||
VectorF shape_vec;
|
||||
MatrixF shape_xfm;
|
||||
|
||||
afxConstraint* orient_constraint = getOrientConstraint();
|
||||
if (orient_constraint)
|
||||
orient_constraint->getTransform(shape_xfm);
|
||||
else
|
||||
shape_xfm.identity();
|
||||
|
||||
shape_xfm.getColumn(1, &shape_vec);
|
||||
shape_vec.z = 0.0f;
|
||||
shape_vec.normalize();
|
||||
|
||||
F32 pitch, yaw;
|
||||
MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
|
||||
|
||||
return mRadToDeg(yaw);
|
||||
}
|
||||
|
||||
inline F32 afxEA_Zodiac::calc_terrain_alt_bias()
|
||||
{
|
||||
if (terrain_altitude >= zode_data->altitude_max)
|
||||
return 0.0f;
|
||||
return 1.0f - (terrain_altitude - zode_data->altitude_falloff)/altitude_falloff_range;
|
||||
}
|
||||
|
||||
inline F32 afxEA_Zodiac::calc_interior_alt_bias()
|
||||
{
|
||||
if (interior_altitude >= zode_data->altitude_max)
|
||||
return 0.0f;
|
||||
return 1.0f - (interior_altitude - zode_data->altitude_falloff)/altitude_falloff_range;
|
||||
}
|
||||
|
||||
afxEA_Zodiac::afxEA_Zodiac()
|
||||
{
|
||||
zode_data = 0;
|
||||
zode_pos.zero();
|
||||
zode_radius = 1;
|
||||
zode_vrange.set(1,1);
|
||||
zode_color.set(1,1,1,1);
|
||||
zode_angle = 0;
|
||||
zode_angle_offset = 0;
|
||||
live_color.set(1,1,1,1);
|
||||
live_color_factor = 0.0f;
|
||||
do_altitude_bias = false;
|
||||
altitude_falloff_range = 0.0f;
|
||||
became_residue = false;
|
||||
}
|
||||
|
||||
afxEA_Zodiac::~afxEA_Zodiac()
|
||||
{
|
||||
if (!became_residue && zode_data && zode_data->isTempClone())
|
||||
delete zode_data;
|
||||
zode_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_Zodiac::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
zode_data = dynamic_cast<afxZodiacData*>(db);
|
||||
if (zode_data)
|
||||
{
|
||||
do_altitude_bias = (zode_data->altitude_max > 0.0f && (zode_data->altitude_shrinks || zode_data->altitude_fades));
|
||||
altitude_falloff_range = zode_data->altitude_max - zode_data->altitude_falloff;
|
||||
}
|
||||
}
|
||||
|
||||
bool afxEA_Zodiac::ea_start()
|
||||
{
|
||||
if (!zode_data)
|
||||
{
|
||||
Con::errorf("afxEA_Zodiac::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
zode_angle_offset = calc_facing_angle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_Zodiac::ea_update(F32 dt)
|
||||
{
|
||||
if (!in_scope)
|
||||
return true;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Zodiac Color
|
||||
|
||||
zode_color = updated_color;
|
||||
|
||||
if (live_color_factor > 0.0)
|
||||
{
|
||||
zode_color.interpolate(zode_color, live_color, live_color_factor);
|
||||
//Con::printf("LIVE-COLOR %g %g %g %g FACTOR is %g",
|
||||
// live_color.red, live_color.green, live_color.blue, live_color.alpha,
|
||||
// live_color_factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Con::printf("LIVE-COLOR-FACTOR is ZERO");
|
||||
}
|
||||
|
||||
if (do_fades)
|
||||
{
|
||||
if (fade_value < 0.01f)
|
||||
return true; // too transparent
|
||||
|
||||
if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
|
||||
zode_color *= fade_value*live_fade_factor;
|
||||
else
|
||||
zode_color.alpha *= fade_value*live_fade_factor;
|
||||
}
|
||||
|
||||
if (zode_color.alpha < 0.01f)
|
||||
return true;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Zodiac
|
||||
|
||||
// scale and grow zode
|
||||
zode_radius = zode_data->radius_xy*updated_scale.x + life_elapsed*zode_data->growth_rate;
|
||||
|
||||
// zode is growing
|
||||
if (life_elapsed < zode_data->grow_in_time)
|
||||
{
|
||||
F32 t = life_elapsed/zode_data->grow_in_time;
|
||||
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.2f, 0.8f);
|
||||
}
|
||||
// zode is shrinking
|
||||
else if (full_lifetime - life_elapsed < zode_data->shrink_out_time)
|
||||
{
|
||||
F32 t = (full_lifetime - life_elapsed)/zode_data->shrink_out_time;
|
||||
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.0f, 0.9f);
|
||||
}
|
||||
|
||||
zode_radius *= live_scale_factor;
|
||||
|
||||
if (zode_radius < 0.001f)
|
||||
return true; // too small
|
||||
|
||||
zode_vrange = zode_data->vert_range;
|
||||
if (zode_data->scale_vert_range)
|
||||
{
|
||||
F32 scale_factor = zode_radius/zode_data->radius_xy;
|
||||
zode_vrange *= scale_factor;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Zodiac Position
|
||||
|
||||
zode_pos = updated_pos;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
// Zodiac Rotation
|
||||
|
||||
if (zode_data->respect_ori_cons)
|
||||
{
|
||||
afxConstraint* orient_constraint = getOrientConstraint();
|
||||
if (orient_constraint)
|
||||
{
|
||||
VectorF shape_vec;
|
||||
updated_xfm.getColumn(1, &shape_vec);
|
||||
shape_vec.z = 0.0f;
|
||||
shape_vec.normalize();
|
||||
F32 pitch, yaw;
|
||||
MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
|
||||
zode_angle_offset = mRadToDeg(yaw);
|
||||
}
|
||||
}
|
||||
|
||||
zode_angle = zode_data->calcRotationAngle(life_elapsed, datablock->rate_factor/prop_time_factor);
|
||||
zode_angle = mFmod(zode_angle + zode_angle_offset, 360.0f);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
// post zodiac
|
||||
if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_TERRAIN) != 0)
|
||||
{
|
||||
if (do_altitude_bias && terrain_altitude > zode_data->altitude_falloff)
|
||||
{
|
||||
F32 alt_bias = calc_terrain_alt_bias();
|
||||
if (alt_bias > 0.0f)
|
||||
{
|
||||
F32 alt_rad = zode_radius;
|
||||
if (zode_data->altitude_shrinks)
|
||||
alt_rad *= alt_bias;
|
||||
LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
|
||||
if (zode_data->altitude_fades)
|
||||
alt_clr.alpha *= alt_bias;
|
||||
afxZodiacMgr::addTerrainZodiac(zode_pos, alt_rad, alt_clr, zode_angle, zode_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
afxZodiacMgr::addTerrainZodiac(zode_pos, zode_radius, zode_color, zode_angle, zode_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_INTERIORS) != 0)
|
||||
{
|
||||
if (do_altitude_bias && interior_altitude > zode_data->altitude_falloff)
|
||||
{
|
||||
F32 alt_bias = calc_interior_alt_bias();
|
||||
if (alt_bias > 0.0f)
|
||||
{
|
||||
F32 alt_rad = zode_radius;
|
||||
if (zode_data->altitude_shrinks)
|
||||
alt_rad *= alt_bias;
|
||||
LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
|
||||
if (zode_data->altitude_fades)
|
||||
alt_clr.alpha *= alt_bias;
|
||||
afxZodiacMgr::addInteriorZodiac(zode_pos, alt_rad, zode_vrange, alt_clr, zode_angle, zode_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
afxZodiacMgr::addInteriorZodiac(zode_pos, zode_radius, zode_vrange, zode_color, zode_angle, zode_data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_Zodiac::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (in_scope && ew_timing.residue_lifetime > 0)
|
||||
{
|
||||
if (do_fades)
|
||||
{
|
||||
if (fade_value < 0.01f)
|
||||
return;
|
||||
zode_color.alpha *= fade_value;
|
||||
}
|
||||
if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_TERRAIN) != 0)
|
||||
{
|
||||
if (do_altitude_bias && terrain_altitude > zode_data->altitude_falloff)
|
||||
{
|
||||
F32 alt_bias = calc_terrain_alt_bias();
|
||||
if (alt_bias > 0.0f)
|
||||
{
|
||||
F32 alt_rad = zode_radius;
|
||||
if (zode_data->altitude_shrinks)
|
||||
alt_rad *= alt_bias;
|
||||
LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
|
||||
if (zode_data->altitude_fades)
|
||||
zode_color.alpha *= alt_bias;
|
||||
became_residue = true;
|
||||
afxResidueMgr::add_terrain_zodiac(ew_timing.residue_lifetime, ew_timing.residue_fadetime, zode_data, zode_pos, alt_rad,
|
||||
alt_clr, zode_angle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
became_residue = true;
|
||||
afxResidueMgr::add_terrain_zodiac(ew_timing.residue_lifetime, ew_timing.residue_fadetime, zode_data, zode_pos, zode_radius,
|
||||
zode_color, zode_angle);
|
||||
}
|
||||
}
|
||||
if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_INTERIORS) != 0)
|
||||
{
|
||||
if (do_altitude_bias && interior_altitude > zode_data->altitude_falloff)
|
||||
{
|
||||
F32 alt_bias = calc_interior_alt_bias();
|
||||
if (alt_bias > 0.0f)
|
||||
{
|
||||
F32 alt_rad = zode_radius;
|
||||
if (zode_data->altitude_shrinks)
|
||||
alt_rad *= alt_bias;
|
||||
LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
|
||||
if (zode_data->altitude_fades)
|
||||
zode_color.alpha *= alt_bias;
|
||||
|
||||
afxZodiacData* temp_zode = zode_data;
|
||||
if (became_residue)
|
||||
temp_zode = new afxZodiacData(*zode_data, true);
|
||||
became_residue = true;
|
||||
afxResidueMgr::add_interior_zodiac(ew_timing.residue_lifetime, ew_timing.residue_fadetime, temp_zode, zode_pos, alt_rad,
|
||||
zode_vrange, alt_clr, zode_angle);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
afxZodiacData* temp_zode = zode_data;
|
||||
if (became_residue)
|
||||
temp_zode = new afxZodiacData(*zode_data, true);
|
||||
became_residue = true;
|
||||
afxResidueMgr::add_interior_zodiac(ew_timing.residue_lifetime, ew_timing.residue_fadetime, temp_zode, zode_pos, zode_radius,
|
||||
zode_vrange, zode_color, zode_angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afxEA_Zodiac::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (zode_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxZodiacData* orig_db = zode_data;
|
||||
zode_data = new afxZodiacData(*orig_db, true);
|
||||
orig_db->performSubstitutions(zode_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
#undef myOffset
|
||||
#define myOffset(field) Offset(field, afxEA_Zodiac)
|
||||
|
||||
void afxEA_Zodiac::initPersistFields()
|
||||
{
|
||||
addField("liveColor", TypeColorF, myOffset(live_color),
|
||||
"...");
|
||||
addField("liveColorFactor", TypeF32, myOffset(live_color_factor),
|
||||
"...");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ZodiacDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ZodiacDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_Zodiac; }
|
||||
};
|
||||
|
||||
afxEA_ZodiacDesc afxEA_ZodiacDesc::desc;
|
||||
|
||||
bool afxEA_ZodiacDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxZodiacData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_ZodiacDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
344
Engine/source/afx/ea/afxEA_ZodiacPlane.cpp
Normal file
344
Engine/source/afx/ea/afxEA_ZodiacPlane.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 <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "math/mathUtils.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxEffectWrapper.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/util/afxEase.h"
|
||||
#include "afx/afxResidueMgr.h"
|
||||
#include "afx/ce/afxZodiacPlane.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// afxEA_ZodiacPlane
|
||||
|
||||
class afxEA_ZodiacPlane : public afxEffectWrapper
|
||||
{
|
||||
typedef afxEffectWrapper Parent;
|
||||
|
||||
afxZodiacPlaneData* zode_data;
|
||||
afxZodiacPlane* pzode;
|
||||
|
||||
F32 zode_angle_offset;
|
||||
AngAxisF aa_rot;
|
||||
|
||||
F32 live_color_factor;
|
||||
LinearColorF live_color;
|
||||
|
||||
F32 calc_facing_angle();
|
||||
void do_runtime_substitutions();
|
||||
|
||||
public:
|
||||
/*C*/ afxEA_ZodiacPlane();
|
||||
/*D*/ ~afxEA_ZodiacPlane();
|
||||
|
||||
virtual void ea_set_datablock(SimDataBlock*);
|
||||
virtual bool ea_start();
|
||||
virtual bool ea_update(F32 dt);
|
||||
virtual void ea_finish(bool was_stopped);
|
||||
virtual void ea_set_scope_status(bool flag);
|
||||
virtual void onDeleteNotify(SimObject*);
|
||||
virtual void getUpdatedBoxCenter(Point3F& pos);
|
||||
virtual void getBaseColor(LinearColorF& color) { color = zode_data->color; }
|
||||
};
|
||||
|
||||
F32 afxEA_ZodiacPlane::calc_facing_angle()
|
||||
{
|
||||
// get direction player is facing
|
||||
VectorF shape_vec;
|
||||
MatrixF shape_xfm;
|
||||
|
||||
afxConstraint* orient_constraint = getOrientConstraint();
|
||||
if (orient_constraint)
|
||||
orient_constraint->getTransform(shape_xfm);
|
||||
else
|
||||
shape_xfm.identity();
|
||||
|
||||
shape_xfm.getColumn(1, &shape_vec);
|
||||
shape_vec.z = 0.0f;
|
||||
shape_vec.normalize();
|
||||
|
||||
F32 pitch, yaw;
|
||||
MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
|
||||
|
||||
return mRadToDeg(yaw);
|
||||
}
|
||||
|
||||
afxEA_ZodiacPlane::afxEA_ZodiacPlane()
|
||||
{
|
||||
zode_data = 0;
|
||||
pzode = 0;
|
||||
zode_angle_offset = 0;
|
||||
live_color.set(1,1,1,1);
|
||||
live_color_factor = 0.0f;
|
||||
}
|
||||
|
||||
afxEA_ZodiacPlane::~afxEA_ZodiacPlane()
|
||||
{
|
||||
if (pzode)
|
||||
pzode->deleteObject();
|
||||
if (zode_data && zode_data->isTempClone())
|
||||
delete zode_data;
|
||||
zode_data = 0;
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::ea_set_datablock(SimDataBlock* db)
|
||||
{
|
||||
zode_data = dynamic_cast<afxZodiacPlaneData*>(db);
|
||||
}
|
||||
|
||||
bool afxEA_ZodiacPlane::ea_start()
|
||||
{
|
||||
if (!zode_data)
|
||||
{
|
||||
Con::errorf("afxEA_ZodiacPlane::ea_start() -- missing or incompatible datablock.");
|
||||
return false;
|
||||
}
|
||||
|
||||
do_runtime_substitutions();
|
||||
|
||||
if (!zode_data->use_full_xfm)
|
||||
zode_angle_offset = calc_facing_angle();
|
||||
|
||||
switch (zode_data->face_dir)
|
||||
{
|
||||
case afxZodiacPlaneData::FACES_UP:
|
||||
aa_rot.set(Point3F(0.0f,0.0f,1.0f),0.0f);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_DOWN:
|
||||
aa_rot.set(Point3F(0.0f,0.0f,-1.0f),0.0f);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_FORWARD:
|
||||
aa_rot.set(Point3F(0.0f,1.0f,0.0f),0.0f);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_BACK:
|
||||
aa_rot.set(Point3F(0.0f,-1.0f,0.0f),0.0f);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_RIGHT:
|
||||
aa_rot.set(Point3F(1.0f,0.0f,0.0f),0.0f);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_LEFT:
|
||||
aa_rot.set(Point3F(-1.0f,0.0f,0.0f),0.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool afxEA_ZodiacPlane::ea_update(F32 dt)
|
||||
{
|
||||
if (!pzode)
|
||||
{
|
||||
// create and register effect
|
||||
pzode = new afxZodiacPlane();
|
||||
pzode->onNewDataBlock(zode_data, false);
|
||||
if (!pzode->registerObject())
|
||||
{
|
||||
delete pzode;
|
||||
pzode = 0;
|
||||
Con::errorf("afxEA_ZodiacPlane::ea_update() -- effect failed to register.");
|
||||
return false;
|
||||
}
|
||||
deleteNotify(pzode);
|
||||
|
||||
///pzode->setSequenceRateFactor(datablock->rate_factor/prop_time_factor);
|
||||
///pzode->setSortPriority(datablock->sort_priority);
|
||||
}
|
||||
|
||||
if (pzode)
|
||||
{
|
||||
//LinearColorF zode_color = zode_data->color;
|
||||
LinearColorF zode_color = updated_color;
|
||||
|
||||
if (live_color_factor > 0.0)
|
||||
zode_color.interpolate(zode_color, live_color, live_color_factor);
|
||||
|
||||
if (do_fades)
|
||||
{
|
||||
if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
|
||||
zode_color *= fade_value*live_fade_factor;
|
||||
else
|
||||
zode_color.alpha *= fade_value*live_fade_factor;
|
||||
}
|
||||
|
||||
// scale and grow zode
|
||||
//F32 zode_radius = zode_data->radius_xy*updated_scale.x + life_elapsed*zode_data->growth_rate;
|
||||
F32 zode_radius = zode_data->radius_xy + life_elapsed*zode_data->growth_rate;
|
||||
|
||||
// zode is growing
|
||||
if (life_elapsed < zode_data->grow_in_time)
|
||||
{
|
||||
F32 t = life_elapsed/zode_data->grow_in_time;
|
||||
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.2f, 0.8f);
|
||||
}
|
||||
// zode is shrinking
|
||||
else if (full_lifetime - life_elapsed < zode_data->shrink_out_time)
|
||||
{
|
||||
F32 t = (full_lifetime - life_elapsed)/zode_data->shrink_out_time;
|
||||
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.0f, 0.9f);
|
||||
}
|
||||
|
||||
zode_radius *= live_scale_factor;
|
||||
|
||||
if (zode_data->respect_ori_cons && !zode_data->use_full_xfm)
|
||||
{
|
||||
VectorF shape_vec;
|
||||
updated_xfm.getColumn(1, &shape_vec);
|
||||
shape_vec.normalize();
|
||||
|
||||
F32 ang;
|
||||
|
||||
switch (zode_data->face_dir)
|
||||
{
|
||||
case afxZodiacPlaneData::FACES_FORWARD:
|
||||
case afxZodiacPlaneData::FACES_BACK:
|
||||
ang = mAtan2(shape_vec.x, shape_vec.z);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_RIGHT:
|
||||
case afxZodiacPlaneData::FACES_LEFT:
|
||||
ang = mAtan2(shape_vec.y, shape_vec.z);
|
||||
break;
|
||||
case afxZodiacPlaneData::FACES_UP:
|
||||
case afxZodiacPlaneData::FACES_DOWN:
|
||||
default:
|
||||
ang = mAtan2(shape_vec.x, shape_vec.y);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ang < 0.0f)
|
||||
ang += M_2PI_F;
|
||||
|
||||
switch (zode_data->face_dir)
|
||||
{
|
||||
case afxZodiacPlaneData::FACES_DOWN:
|
||||
case afxZodiacPlaneData::FACES_BACK:
|
||||
case afxZodiacPlaneData::FACES_LEFT:
|
||||
ang = -ang;
|
||||
break;
|
||||
}
|
||||
|
||||
zode_angle_offset = mRadToDeg(ang);
|
||||
}
|
||||
|
||||
F32 zode_angle = zode_data->calcRotationAngle(life_elapsed, datablock->rate_factor/prop_time_factor);
|
||||
zode_angle = mFmod(zode_angle + zode_angle_offset, 360.0f);
|
||||
aa_rot.angle = mDegToRad(zode_angle);
|
||||
|
||||
MatrixF spin_xfm;
|
||||
aa_rot.setMatrix(&spin_xfm);
|
||||
|
||||
// set color, radius
|
||||
pzode->setColor(zode_color);
|
||||
pzode->setRadius(zode_radius);
|
||||
if (zode_data->use_full_xfm)
|
||||
{
|
||||
updated_xfm.mul(spin_xfm);
|
||||
pzode->setTransform(updated_xfm);
|
||||
}
|
||||
else
|
||||
pzode->setTransform(spin_xfm);
|
||||
pzode->setPosition(updated_pos);
|
||||
pzode->setScale(updated_scale);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::ea_finish(bool was_stopped)
|
||||
{
|
||||
if (!pzode)
|
||||
return;
|
||||
|
||||
pzode->deleteObject();
|
||||
pzode = 0;
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::ea_set_scope_status(bool in_scope)
|
||||
{
|
||||
if (pzode)
|
||||
pzode->setVisibility(in_scope);
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
if (pzode == dynamic_cast<afxZodiacPlane*>(obj))
|
||||
pzode = 0;
|
||||
|
||||
Parent::onDeleteNotify(obj);
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::getUpdatedBoxCenter(Point3F& pos)
|
||||
{
|
||||
if (pzode)
|
||||
pos = pzode->getBoxCenter();
|
||||
}
|
||||
|
||||
void afxEA_ZodiacPlane::do_runtime_substitutions()
|
||||
{
|
||||
// only clone the datablock if there are substitutions
|
||||
if (zode_data->getSubstitutionCount() > 0)
|
||||
{
|
||||
// clone the datablock and perform substitutions
|
||||
afxZodiacPlaneData* orig_db = zode_data;
|
||||
zode_data = new afxZodiacPlaneData(*orig_db, true);
|
||||
orig_db->performSubstitutions(zode_data, choreographer, group_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
class afxEA_ZodiacPlaneDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
||||
{
|
||||
static afxEA_ZodiacPlaneDesc desc;
|
||||
|
||||
public:
|
||||
virtual bool testEffectType(const SimDataBlock*) const;
|
||||
virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
|
||||
virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
|
||||
virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
|
||||
|
||||
virtual afxEffectWrapper* create() const { return new afxEA_ZodiacPlane; }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
afxEA_ZodiacPlaneDesc afxEA_ZodiacPlaneDesc::desc;
|
||||
|
||||
bool afxEA_ZodiacPlaneDesc::testEffectType(const SimDataBlock* db) const
|
||||
{
|
||||
return (typeid(afxZodiacPlaneData) == typeid(*db));
|
||||
}
|
||||
|
||||
bool afxEA_ZodiacPlaneDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
||||
{
|
||||
return (timing.lifetime < 0);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
Loading…
Add table
Add a link
Reference in a new issue