mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
virtuals removed and replaced with override where necessary on the rest of the code base, clang-tidy to the rescue.
436 lines
13 KiB
C++
436 lines
13 KiB
C++
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
// 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();
|
|
|
|
void ea_set_datablock(SimDataBlock*) override;
|
|
bool ea_start() override;
|
|
bool ea_update(F32 dt) override;
|
|
void ea_finish(bool was_stopped) override;
|
|
|
|
bool ea_is_enabled() override { return true; }
|
|
|
|
void getBaseColor(LinearColorF& color) override { color = zode_data->color; }
|
|
|
|
static void initPersistFields();
|
|
|
|
//DECLARE_CONOBJECT(afxEA_Zodiac);
|
|
DECLARE_CATEGORY("UNLISTED");
|
|
};
|
|
|
|
//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 (mTerrain_altitude >= zode_data->altitude_max)
|
|
return 0.0f;
|
|
return 1.0f - (mTerrain_altitude - zode_data->altitude_falloff)/altitude_falloff_range;
|
|
}
|
|
|
|
inline F32 afxEA_Zodiac::calc_interior_alt_bias()
|
|
{
|
|
if (mInterior_altitude >= zode_data->altitude_max)
|
|
return 0.0f;
|
|
return 1.0f - (mInterior_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 (!mIn_scope)
|
|
return true;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//
|
|
// Zodiac Color
|
|
|
|
zode_color = mUpdated_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 (mDo_fades)
|
|
{
|
|
if (mFade_value < 0.01f)
|
|
return true; // too transparent
|
|
|
|
if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
|
|
zode_color *= mFade_value * mLive_fade_factor;
|
|
else
|
|
zode_color.alpha *= mFade_value * mLive_fade_factor;
|
|
}
|
|
|
|
if (zode_color.alpha < 0.01f)
|
|
return true;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//
|
|
// Zodiac
|
|
|
|
// scale and grow zode
|
|
zode_radius = zode_data->radius_xy*mUpdated_scale.x + mLife_elapsed *zode_data->growth_rate;
|
|
|
|
// zode is growing
|
|
if (mLife_elapsed < zode_data->grow_in_time)
|
|
{
|
|
F32 t = mLife_elapsed /zode_data->grow_in_time;
|
|
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.2f, 0.8f);
|
|
}
|
|
// zode is shrinking
|
|
else if (mFull_lifetime - mLife_elapsed < zode_data->shrink_out_time)
|
|
{
|
|
F32 t = (mFull_lifetime - mLife_elapsed)/zode_data->shrink_out_time;
|
|
zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.0f, 0.9f);
|
|
}
|
|
|
|
zode_radius *= mLive_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 = mUpdated_pos;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//
|
|
// Zodiac Rotation
|
|
|
|
if (zode_data->respect_ori_cons)
|
|
{
|
|
afxConstraint* orient_constraint = getOrientConstraint();
|
|
if (orient_constraint)
|
|
{
|
|
VectorF shape_vec;
|
|
mUpdated_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(mLife_elapsed, mDatablock->rate_factor/ mProp_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 && mTerrain_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 && mInterior_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 (mIn_scope && mEW_timing.residue_lifetime > 0)
|
|
{
|
|
if (mDo_fades)
|
|
{
|
|
if (mFade_value < 0.01f)
|
|
return;
|
|
zode_color.alpha *= mFade_value;
|
|
}
|
|
if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_TERRAIN) != 0)
|
|
{
|
|
if (do_altitude_bias && mTerrain_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(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, zode_data, zode_pos, alt_rad,
|
|
alt_clr, zode_angle);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
became_residue = true;
|
|
afxResidueMgr::add_terrain_zodiac(mEW_timing.residue_lifetime, mEW_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 && mInterior_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(mEW_timing.residue_lifetime, mEW_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(mEW_timing.residue_lifetime, mEW_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, mChoreographer, mGroup_index);
|
|
}
|
|
}
|
|
|
|
#undef myOffset
|
|
#define myOffset(field) Offset(field, afxEA_Zodiac)
|
|
|
|
void afxEA_Zodiac::initPersistFields()
|
|
{
|
|
docsURL;
|
|
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:
|
|
bool testEffectType(const SimDataBlock*) const override;
|
|
bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const override;
|
|
bool runsOnServer(const afxEffectWrapperData*) const override { return false; }
|
|
bool runsOnClient(const afxEffectWrapperData*) const override { return true; }
|
|
|
|
afxEffectWrapper* create() const override { 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);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|