Add all new AFX files

This commit is contained in:
Marc Chapman 2017-07-26 09:35:44 +01:00
parent 3d7c1bbbf7
commit d7a8510756
218 changed files with 54970 additions and 0 deletions

View file

@ -0,0 +1,183 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
// Copyright (C) 2015 Faust Logic, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#include "afx/arcaneFX.h"
#include "afx/afxChoreographer.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxEffectWrapper.h"
#include "afx/forces/afxForce.h"
#include "afx/forces/afxForceSet.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxEA_Force
class afxEA_Force : public afxEffectWrapper
{
typedef afxEffectWrapper Parent;
afxForceData* force_data;
afxForce* force;
afxForceSetMgr* force_set_mgr;
void do_runtime_substitutions();
public:
/*C*/ afxEA_Force();
/*D*/ ~afxEA_Force();
virtual void ea_set_datablock(SimDataBlock*);
virtual bool ea_start();
virtual bool ea_update(F32 dt);
virtual void ea_finish(bool was_stopped);
};
//~~~~~~~~~~~~~~~~~~~~//
afxEA_Force::afxEA_Force()
{
force_data = 0;
force = 0;
force_set_mgr = 0;
}
afxEA_Force::~afxEA_Force()
{
if (force)
{
if (force_set_mgr)
force_set_mgr->unregisterForce(force_data->force_set_name, force);
delete force;
}
if (force_data && force_data->isTempClone())
{
delete force_data;
force_data = 0;
}
force_set_mgr = 0;
}
void afxEA_Force::ea_set_datablock(SimDataBlock* db)
{
force_data = dynamic_cast<afxForceData*>(db);
}
bool afxEA_Force::ea_start()
{
if (!force_data)
{
Con::errorf("afxEA_Force::ea_start() -- missing or incompatible datablock.");
return false;
}
do_runtime_substitutions();
force_set_mgr = choreographer->getForceSetMgr();
return true;
}
bool afxEA_Force::ea_update(F32 dt)
{
if (!force)
{
force = (force_data->force_desc) ? force_data->force_desc->create() : 0;
if (!force)
{
delete force;
force = 0;
Con::errorf(ConsoleLogEntry::General, "Force effect failed to instantiate. (%s)", datablock->getName());
return false;
}
force->onNewDataBlock(force_data, false);
if (force)
{
force_set_mgr->registerForce(force_data->force_set_name, force);
force->start();
}
}
if (force) // && in_scope)
{
if (do_fades)
force->setFadeAmount(fade_value);
force->update(dt);
}
return true;
}
void afxEA_Force::ea_finish(bool was_stopped)
{
if (!force)
return;
if (force_set_mgr)
force_set_mgr->unregisterForce(force_data->force_set_name, force);
delete force;
force = 0;
}
void afxEA_Force::do_runtime_substitutions()
{
force_data = force_data->cloneAndPerformSubstitutions(choreographer, group_index);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxEA_ForceDesc : public afxEffectAdapterDesc, public afxEffectDefs
{
static afxEA_ForceDesc 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_Force; }
};
afxEA_ForceDesc afxEA_ForceDesc::desc;
bool afxEA_ForceDesc::testEffectType(const SimDataBlock* db) const
{
if (dynamic_cast<const afxForceData*>(db) != 0)
return afxForceDesc::identifyForce((afxForceData*) db);
return false;
}
bool afxEA_ForceDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
{
return (timing.lifetime < 0);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,209 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/forces/afxForce.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_DragData : public afxForceData
{
typedef afxForceData Parent;
public:
F32 drag_coefficient;
F32 air_density;
F32 cross_sectional_area;
public:
/*C*/ afxF_DragData();
/*C*/ afxF_DragData(const afxF_DragData&, bool = false);
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
virtual afxForceData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
static void initPersistFields();
DECLARE_CONOBJECT(afxF_DragData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_Drag : public afxForce
{
typedef afxForce Parent;
private:
afxF_DragData* datablock;
F32 air_friction_constant;
public:
/*C*/ afxF_Drag();
virtual bool onNewDataBlock(afxForceData* dptr, bool reload);
virtual void start();
virtual Point3F evaluate(Point3F pos, Point3F v, F32 mass);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxDragData
IMPLEMENT_CO_DATABLOCK_V1(afxF_DragData);
ConsoleDocClass( afxF_DragData,
"@brief A datablock for specifiying AFX drag forces.\n\n"
"@ingroup afxExperimental\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxF_DragData::afxF_DragData()
{
air_density = 1.2250f;
cross_sectional_area = 0.75f; // this variable isn't exposed to the user to keep things simple
drag_coefficient = 1.0f;
}
afxF_DragData::afxF_DragData(const afxF_DragData& other, bool temp_clone) : afxForceData(other, temp_clone)
{
air_density = other.air_density;
cross_sectional_area = other.cross_sectional_area;
drag_coefficient = other.drag_coefficient;
}
#define myOffset(field) Offset(field, afxF_DragData)
void afxF_DragData::initPersistFields()
{
addField("drag", TypeF32, myOffset(drag_coefficient),
"...");
addField("airDensity", TypeF32, myOffset(air_density),
"...");
addField("crossSectionalArea", TypeF32, myOffset(cross_sectional_area),
"...");
Parent::initPersistFields();
}
void afxF_DragData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(drag_coefficient);
stream->write(air_density);
stream->write(cross_sectional_area);
}
void afxF_DragData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&drag_coefficient);
stream->read(&air_density);
stream->read(&cross_sectional_area);
}
afxForceData* afxF_DragData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
{
afxF_DragData* drag_data = this;
// only clone the datablock if there are substitutions
if (this->getSubstitutionCount() > 0)
{
// clone the datablock and perform substitutions
afxF_DragData* orig_db = this;
drag_data = new afxF_DragData(*orig_db, true);
orig_db->performSubstitutions(drag_data, owner, index);
}
return drag_data;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
afxF_Drag::afxF_Drag() : afxForce()
{
air_friction_constant = 1.0f;
}
bool afxF_Drag::onNewDataBlock(afxForceData* dptr, bool reload)
{
datablock = dynamic_cast<afxF_DragData*>(dptr);
if (!datablock || !Parent::onNewDataBlock(dptr, reload))
return false;
return true;
}
void afxF_Drag::start()
{
air_friction_constant = 0.5f * datablock->drag_coefficient
* datablock->air_density
* datablock->cross_sectional_area;
//Con::printf("Air Friction: %f", air_friction_constant);
}
Point3F afxF_Drag::evaluate(Point3F pos, Point3F velocity, F32 mass)
{
// This implements the standard drag equation for object's at high speeds.
// F-drag = 1/2pACv^2
// p = medium (air) density
// A = cross-sectional area of moving object (plane perpendicular to direction of motion)
// C = coefficient of drag
// -- Velocity here should actually be relative to the velocity of the fluid... (relative speed)
// (is it already?)
F32 drag = air_friction_constant*velocity.magnitudeSafe();
// Here, velocity is normalized just to get a direction vector.
// Drag is in the direction opposite velocity. Is this right?
velocity.normalizeSafe();
return (velocity*-drag*mass);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_DragDesc : public afxForceDesc
{
static afxF_DragDesc desc;
public:
virtual bool testForceType(const SimDataBlock*) const;
virtual afxForce* create() const { return new afxF_Drag; }
};
afxF_DragDesc afxF_DragDesc::desc;
bool afxF_DragDesc::testForceType(const SimDataBlock* db) const
{
return (typeid(afxF_DragData) == typeid(*db));
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,171 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/forces/afxForce.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_GravityData : public afxForceData
{
typedef afxForceData Parent;
public:
F32 gravity;
public:
/*C*/ afxF_GravityData();
/*C*/ afxF_GravityData(const afxF_GravityData&, bool = false);
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
virtual afxForceData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
static void initPersistFields();
DECLARE_CONOBJECT(afxF_GravityData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_Gravity : public afxForce
{
typedef afxForce Parent;
private:
afxF_GravityData* datablock;
public:
/*C*/ afxF_Gravity();
virtual bool onNewDataBlock(afxForceData* dptr, bool reload);
virtual Point3F evaluate(Point3F pos, Point3F v, F32 mass);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxForceData
IMPLEMENT_CO_DATABLOCK_V1(afxF_GravityData);
ConsoleDocClass( afxF_GravityData,
"@brief A datablock for specifiying AFX gravity forces.\n\n"
"@ingroup afxExperimental\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxF_GravityData::afxF_GravityData()
{
gravity = 9.807f;
}
afxF_GravityData::afxF_GravityData(const afxF_GravityData& other, bool temp_clone) : afxForceData(other, temp_clone)
{
gravity = other.gravity;
}
#define myOffset(field) Offset(field, afxF_GravityData)
void afxF_GravityData::initPersistFields()
{
addField("gravity", TypeF32, myOffset(gravity),
"...");
Parent::initPersistFields();
}
void afxF_GravityData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(gravity);
}
void afxF_GravityData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&gravity);
}
afxForceData* afxF_GravityData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
{
afxF_GravityData* grav_data = this;
// only clone the datablock if there are substitutions
if (this->getSubstitutionCount() > 0)
{
// clone the datablock and perform substitutions
afxF_GravityData* orig_db = this;
grav_data = new afxF_GravityData(*orig_db, true);
orig_db->performSubstitutions(grav_data, owner, index);
}
return grav_data;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
afxF_Gravity::afxF_Gravity() : afxForce()
{
}
bool afxF_Gravity::onNewDataBlock(afxForceData* dptr, bool reload)
{
datablock = dynamic_cast<afxF_GravityData*>(dptr);
if (!datablock || !Parent::onNewDataBlock(dptr, reload))
return false;
return true;
}
Point3F afxF_Gravity::evaluate(Point3F pos, Point3F v, F32 mass)
{
return Point3F(0,0,-datablock->gravity)*mass;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxF_GravityDesc : public afxForceDesc
{
static afxF_GravityDesc desc;
public:
virtual bool testForceType(const SimDataBlock*) const;
virtual afxForce* create() const { return new afxF_Gravity; }
};
afxF_GravityDesc afxF_GravityDesc::desc;
bool afxF_GravityDesc::testForceType(const SimDataBlock* db) const
{
return (typeid(afxF_GravityData) == typeid(*db));
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,148 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
// Copyright (C) 2015 Faust Logic, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#include "afx/arcaneFX.h"
#include "console/consoleTypes.h"
#include "core/stream/bitStream.h"
#include "scene/sceneRenderState.h"
#include "math/mathIO.h"
#include "afx/afxChoreographer.h"
#include "afx/forces/afxForce.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxForceData
afxForceData::afxForceData()
{
force_set_name = ST_NULLSTRING;
force_desc = 0;
}
afxForceData::afxForceData(const afxForceData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
force_set_name = other.force_set_name;
force_desc = other.force_desc;
}
#define myOffset(field) Offset(field, afxForceData)
void afxForceData::initPersistFields()
{
addField("forceSetName", TypeString, myOffset(force_set_name),
"...");
Parent::initPersistFields();
}
bool afxForceData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxForceData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(force_set_name);
}
void afxForceData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
force_set_name = stream->readSTString();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxForce
afxForce::afxForce()
{
datablock = 0;
fade_amt = 1.0f;
}
afxForce::~afxForce()
{
}
bool afxForce::onNewDataBlock(afxForceData* dptr, bool reload)
{
datablock = dptr;
return true;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
Vector<afxForceDesc*>* afxForceDesc::forces = 0;
afxForceDesc::afxForceDesc()
{
if (!forces)
forces = new Vector<afxForceDesc*>;
forces->push_back(this);
}
bool afxForceDesc::identifyForce(afxForceData* force_data)
{
if (!force_data)
{
Con::errorf("afxForceDesc::identifyForce() -- force datablock was not specified.");
return false;
}
if (!forces)
{
Con::errorf("afxForceDesc::identifyForce() -- force registration list has not been allocated.");
return false;
}
if (forces->size() == 0)
{
Con::errorf("afxForceDesc::identifyForce() -- no forces have been registered.");
return false;
}
for (S32 i = 0; i < forces->size(); i++)
{
if ((*forces)[i]->testForceType(force_data))
{
force_data->force_desc = (*forces)[i];
return true;
}
}
Con::errorf("afxForceDesc::identifyForce() -- force %s has an undefined type. -- %d",
force_data, forces->size());
return false;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,97 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_FORCE_H_
#define _AFX_FORCE_H_
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxForce Data
class afxForceDesc;
class afxForceData : public GameBaseData
{
typedef GameBaseData Parent;
public:
StringTableEntry force_set_name;
afxForceDesc* force_desc;
public:
/*C*/ afxForceData();
/*C*/ afxForceData(const afxForceData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
virtual bool allowSubstitutions() const { return true; }
virtual afxForceData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0)=0;
static void initPersistFields();
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxForce
class afxForce
{
afxForceData* datablock;
protected:
F32 fade_amt;
public:
/*C*/ afxForce();
/*D*/ ~afxForce();
virtual bool onNewDataBlock(afxForceData* dptr, bool reload);
void setFadeAmount(F32 amt) { fade_amt = amt; }
virtual void start() {};
virtual void update(F32 dt) {};
virtual Point3F evaluate(Point3F pos, Point3F v, F32 mass) { return Point3F(0,0,0); }; //=0;
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxForceDesc
{
private:
static Vector<afxForceDesc*>* forces;
public:
/*C*/ afxForceDesc();
virtual bool testForceType(const SimDataBlock*) const=0;
virtual afxForce* create() const=0;
static bool identifyForce(afxForceData*);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_FORCE_H_

View file

@ -0,0 +1,134 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
// Copyright (C) 2015 Faust Logic, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#include "afx/arcaneFX.h"
#include "afx/forces/afxForceSet.h"
#include "afx/forces/afxForce.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
afxForceSet::afxForceSet(const char* name)
{
this->name = (name) ? StringTable->insert(name) : ST_NULLSTRING;
update_dt = 10.0f; // seems like an ok maximum, force-xmods will probably lower it.
elapsed_dt = 0.0f;
elapsed_ms = 0;
num_updates = 0;
last_num_updates = 0;
}
void afxForceSet::remove(afxForce* force)
{
for (S32 i = 0; i < force_v.size(); i++)
{
if (force_v[i] == force)
{
force_v.erase(i);
return;
}
}
}
S32 afxForceSet::updateDT(F32 dt)
{
U32 now = Platform::getVirtualMilliseconds();
if (elapsed_ms == now)
return last_num_updates;
elapsed_ms = now;
elapsed_dt += dt;
if (elapsed_dt < update_dt)
{
last_num_updates = 0;
return 0;
}
num_updates = mFloor(elapsed_dt/update_dt);
elapsed_dt -= update_dt*num_updates;
last_num_updates = num_updates;
return num_updates;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
afxForceSetMgr::afxForceSetMgr()
{
}
afxForceSetMgr::~afxForceSetMgr()
{
for (S32 i = 0; i < forces_sets.size(); i++)
{
if (forces_sets[i])
delete forces_sets[i];
}
}
afxForceSet* afxForceSetMgr::findForceSet(StringTableEntry forces_set_name)
{
for (S32 i = 0; i < forces_sets.size(); i++)
{
if (forces_sets[i] && forces_sets[i]->getName() == forces_set_name)
return forces_sets[i];
}
return 0;
}
void afxForceSetMgr::registerForce(StringTableEntry forces_set_name, afxForce* force)
{
if (!force)
return;
// find forceSet by name
afxForceSet* fset = findForceSet(forces_set_name);
// create forceSet if it does not already exist
if (!fset)
{
fset = new afxForceSet(forces_set_name);
forces_sets.push_back(fset);
}
// add force to set
fset->add(force);
}
void afxForceSetMgr::unregisterForce(StringTableEntry forces_set_name, afxForce* force)
{
if (!force)
return;
afxForceSet* fset = findForceSet(forces_set_name);
if (!fset)
return;
fset->remove(force);
}

View file

@ -0,0 +1,80 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_FORCE_SET_H_
#define _AFX_FORCE_SET_H_
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxForce;
class afxForceSet
{
Vector<afxForce*> force_v;
StringTableEntry name;
// tick-based updating
F32 update_dt; // constant update interval, in seconds
F32 elapsed_dt; // runtime elapsed delta, in seconds
U32 elapsed_ms;
S32 num_updates;
S32 last_num_updates;
public:
/*C*/ afxForceSet(const char* name=0);
void add(afxForce* force) { force_v.push_back(force); }
void remove(afxForce* force);
S32 count() { return force_v.size(); }
afxForce* getForce(S32 idx) { return force_v[idx]; }
const char* getName() const { return name; }
void setUpdateDT(F32 update_dt) { this->update_dt = update_dt; }
F32 getUpdateDT() { return update_dt; }
S32 updateDT(F32 dt);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxForceSetMgr
{
Vector<afxForceSet*> forces_sets;
public:
/*C*/ afxForceSetMgr();
/*D*/ ~afxForceSetMgr();
afxForceSet* findForceSet(StringTableEntry name);
S32 numForceSets() const { return forces_sets.size(); }
void registerForce(StringTableEntry forces_set_name, afxForce* force);
void unregisterForce(StringTableEntry forces_set_name, afxForce* force);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_FORCE_SET_H_

View file

@ -0,0 +1,274 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
// Copyright (C) 2015 Faust Logic, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#include "afx/arcaneFX.h"
#include "math/mathIO.h"
#include "math/mathUtils.h"
#include "afx/afxEffectWrapper.h"
#include "afx/afxChoreographer.h"
#include "afx/xm/afxXfmMod.h"
#include "afx/afxEffectDefs.h"
#include "afx/forces/afxForce.h"
#include "afx/forces/afxForceSet.h"
//#define ECHO_DEBUG_INFO
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxXM_ForceData : public afxXM_WeightedBaseData, public afxEffectDefs
{
typedef afxXM_WeightedBaseData Parent;
public:
StringTableEntry force_set_name;
F32 update_dt;
public:
/*C*/ afxXM_ForceData();
/*C*/ afxXM_ForceData(const afxXM_ForceData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
afxXM_Base* create(afxEffectWrapper* fx, bool on_server);
DECLARE_CONOBJECT(afxXM_ForceData);
DECLARE_CATEGORY("AFX");
};
class afxXM_Force : public afxXM_WeightedBase, public afxEffectDefs
{
typedef afxXM_WeightedBase Parent;
afxForceSet* force_set;
Point3F pos_local;
Point3F velocity;
bool first;
F32 mass;
F32 mass_inverse;
afxXM_ForceData* db;
public:
/*C*/ afxXM_Force(afxXM_ForceData*, afxEffectWrapper*);
virtual void start(F32 timestamp);
virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
IMPLEMENT_CO_DATABLOCK_V1(afxXM_ForceData);
ConsoleDocClass( afxXM_ForceData,
"@brief An xmod datablock.\n\n"
"@ingroup afxExperimental\n"
"@ingroup afxXMods\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxXM_ForceData::afxXM_ForceData()
{
force_set_name = ST_NULLSTRING;
update_dt = -1.0f;
}
afxXM_ForceData::afxXM_ForceData(const afxXM_ForceData& other, bool temp_clone) : afxXM_WeightedBaseData(other, temp_clone)
{
force_set_name = other.force_set_name;
update_dt = other.update_dt;
}
void afxXM_ForceData::initPersistFields()
{
addField("forceSetName", TypeString, Offset(force_set_name, afxXM_ForceData),
"...");
addField("updateDT", TypeF32, Offset(update_dt, afxXM_ForceData),
"...");
Parent::initPersistFields();
}
void afxXM_ForceData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(force_set_name);
if (stream->writeFlag(update_dt < 0.0f))
stream->write(update_dt);
}
void afxXM_ForceData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
force_set_name = stream->readSTString();
if (stream->readFlag())
stream->read(&update_dt);
else
update_dt = -1.0f;
}
bool afxXM_ForceData::preload(bool server, String &errorStr)
{
if(!Parent::preload(server, errorStr))
return false;
return true;
}
afxXM_Base* afxXM_ForceData::create(afxEffectWrapper* fx, bool on_server)
{
afxXM_ForceData* datablock = this;
if (getSubstitutionCount() > 0)
{
datablock = new afxXM_ForceData(*this, true);
this->performSubstitutions(datablock, fx->getChoreographer(), fx->getGroupIndex());
}
return new afxXM_Force(datablock, fx);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
afxXM_Force::afxXM_Force(afxXM_ForceData* db, afxEffectWrapper* fxw)
: afxXM_WeightedBase(db, fxw)
{
this->db = db;
force_set = 0;
pos_local.zero();
velocity.zero();
mass = 1.0f;
mass_inverse = 1.0f;
first = true;
}
void afxXM_Force::start(F32 timestamp)
{
Parent::start(timestamp);
afxForceSetMgr* force_set_mgr = fx_wrapper->getChoreographer()->getForceSetMgr();
force_set = (force_set_mgr) ? force_set_mgr->findForceSet(db->force_set_name) : 0;
if (!force_set)
{
Con::errorf(ConsoleLogEntry::General,
"afxXM_Force::start() -- unable to find afxForceSet %s", db->force_set_name);
return;
}
mass = fx_wrapper->getMass();
// compute mass_inverse safely
mass_inverse = (mass > 0.0001f) ? (1.0f/mass) : 1.0f/0.0001f;
F32 update_dt = (db->update_dt < 0.0f) ? 1.0f/30.0f : db->update_dt;
if (force_set->getUpdateDT() > update_dt)
force_set->setUpdateDT(update_dt);
}
// JTF Note: answer these questions?
// Can mass be removed from the force and acceleration calculations?
// XFM Weight is not accounted for (yet).
void afxXM_Force::updateParams(F32 dt, F32 elapsed, afxXM_Params& params)
{
if (!force_set)
return;
#ifdef ECHO_DEBUG_INFO
Con::printf("afxXM_Force: elapsed=%f (dt=%f)", elapsed,dt);
#endif
if (first)
{
velocity = fx_wrapper->getDirection();
velocity.normalizeSafe();
params.ori.mulP(velocity);
velocity *= fx_wrapper->getSpeed();
#ifdef ECHO_DEBUG_INFO
Con::printf("INITIAL VELOCITY : %f %f %f", velocity.x, velocity.y, velocity.z);
Con::printf("MASS : %f %f", mass, mass_inverse );
#endif
first = false;
}
S32 num_updates = force_set->updateDT(dt);
if (num_updates == 0)
{
params.pos += pos_local;
return;
}
for (S32 j = 0; j < num_updates; j++)
{
Point3F F_net(0,0,0);
for (S32 i = 0; i < force_set->count(); i++)
{
afxForce* force = force_set->getForce(i);
#ifdef ECHO_DEBUG_INFO
Point3F F = force->evaluate(params.pos+pos_local, velocity, mass);
F_net += F;
Con::printf("(%d) F %i: %f %f %f", this, i, F.x, F.y, F.z);
#else
F_net += force->evaluate(params.pos+pos_local, velocity, mass);
#endif
}
Point3F acceleration = F_net * mass_inverse * force_set->getUpdateDT();
velocity += acceleration;
pos_local += velocity;
}
params.pos += pos_local;
#ifdef ECHO_DEBUG_INFO
Con::printf("velocity : %f %f %f", velocity.x, velocity.y, velocity.z);
Con::printf("pos: %f %f %f", params.pos.x, params.pos.y, params.pos.z);
#endif
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//