mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-27 07:15:37 +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
183
Engine/source/afx/forces/afxEA_Force.cpp
Normal file
183
Engine/source/afx/forces/afxEA_Force.cpp
Normal 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);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
|
||||
209
Engine/source/afx/forces/afxF_Drag.cpp
Normal file
209
Engine/source/afx/forces/afxF_Drag.cpp
Normal 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));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
171
Engine/source/afx/forces/afxF_Gravity.cpp
Normal file
171
Engine/source/afx/forces/afxF_Gravity.cpp
Normal 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));
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
148
Engine/source/afx/forces/afxForce.cpp
Normal file
148
Engine/source/afx/forces/afxForce.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
97
Engine/source/afx/forces/afxForce.h
Normal file
97
Engine/source/afx/forces/afxForce.h
Normal 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_
|
||||
134
Engine/source/afx/forces/afxForceSet.cpp
Normal file
134
Engine/source/afx/forces/afxForceSet.cpp
Normal 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);
|
||||
}
|
||||
|
||||
80
Engine/source/afx/forces/afxForceSet.h
Normal file
80
Engine/source/afx/forces/afxForceSet.h
Normal 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_
|
||||
274
Engine/source/afx/forces/afxXM_Force.cpp
Normal file
274
Engine/source/afx/forces/afxXM_Force.cpp
Normal 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
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue