mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
virtuals removed and replaced with override where necessary on the rest of the code base, clang-tidy to the rescue.
344 lines
9.6 KiB
C++
344 lines
9.6 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/util/afxEase.h"
|
|
#include "afx/afxResidueMgr.h"
|
|
#include "afx/ce/afxZodiacPlane.h"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
// afxEA_ZodiacPlane
|
|
|
|
class afxEA_ZodiacPlane : public afxEffectWrapper
|
|
{
|
|
typedef afxEffectWrapper Parent;
|
|
|
|
afxZodiacPlaneData* zode_data;
|
|
afxZodiacPlane* pzode;
|
|
|
|
F32 zode_angle_offset;
|
|
AngAxisF aa_rot;
|
|
|
|
F32 live_color_factor;
|
|
LinearColorF live_color;
|
|
|
|
F32 calc_facing_angle();
|
|
void do_runtime_substitutions();
|
|
|
|
public:
|
|
/*C*/ afxEA_ZodiacPlane();
|
|
/*D*/ ~afxEA_ZodiacPlane();
|
|
|
|
void ea_set_datablock(SimDataBlock*) override;
|
|
bool ea_start() override;
|
|
bool ea_update(F32 dt) override;
|
|
void ea_finish(bool was_stopped) override;
|
|
void ea_set_scope_status(bool flag) override;
|
|
void onDeleteNotify(SimObject*) override;
|
|
void getUpdatedBoxCenter(Point3F& pos) override;
|
|
void getBaseColor(LinearColorF& color) override { color = zode_data->color; }
|
|
};
|
|
|
|
F32 afxEA_ZodiacPlane::calc_facing_angle()
|
|
{
|
|
// get direction player is facing
|
|
VectorF shape_vec;
|
|
MatrixF shape_xfm;
|
|
|
|
afxConstraint* orient_constraint = getOrientConstraint();
|
|
if (orient_constraint)
|
|
orient_constraint->getTransform(shape_xfm);
|
|
else
|
|
shape_xfm.identity();
|
|
|
|
shape_xfm.getColumn(1, &shape_vec);
|
|
shape_vec.z = 0.0f;
|
|
shape_vec.normalize();
|
|
|
|
F32 pitch, yaw;
|
|
MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
|
|
|
|
return mRadToDeg(yaw);
|
|
}
|
|
|
|
afxEA_ZodiacPlane::afxEA_ZodiacPlane()
|
|
{
|
|
zode_data = 0;
|
|
pzode = 0;
|
|
zode_angle_offset = 0;
|
|
live_color.set(1,1,1,1);
|
|
live_color_factor = 0.0f;
|
|
}
|
|
|
|
afxEA_ZodiacPlane::~afxEA_ZodiacPlane()
|
|
{
|
|
if (pzode)
|
|
pzode->deleteObject();
|
|
if (zode_data && zode_data->isTempClone())
|
|
delete zode_data;
|
|
zode_data = 0;
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::ea_set_datablock(SimDataBlock* db)
|
|
{
|
|
zode_data = dynamic_cast<afxZodiacPlaneData*>(db);
|
|
}
|
|
|
|
bool afxEA_ZodiacPlane::ea_start()
|
|
{
|
|
if (!zode_data)
|
|
{
|
|
Con::errorf("afxEA_ZodiacPlane::ea_start() -- missing or incompatible datablock.");
|
|
return false;
|
|
}
|
|
|
|
do_runtime_substitutions();
|
|
|
|
if (!zode_data->use_full_xfm)
|
|
zode_angle_offset = calc_facing_angle();
|
|
|
|
switch (zode_data->face_dir)
|
|
{
|
|
case afxZodiacPlaneData::FACES_UP:
|
|
aa_rot.set(Point3F(0.0f,0.0f,1.0f),0.0f);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_DOWN:
|
|
aa_rot.set(Point3F(0.0f,0.0f,-1.0f),0.0f);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_FORWARD:
|
|
aa_rot.set(Point3F(0.0f,1.0f,0.0f),0.0f);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_BACK:
|
|
aa_rot.set(Point3F(0.0f,-1.0f,0.0f),0.0f);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_RIGHT:
|
|
aa_rot.set(Point3F(1.0f,0.0f,0.0f),0.0f);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_LEFT:
|
|
aa_rot.set(Point3F(-1.0f,0.0f,0.0f),0.0f);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool afxEA_ZodiacPlane::ea_update(F32 dt)
|
|
{
|
|
if (!pzode)
|
|
{
|
|
// create and register effect
|
|
pzode = new afxZodiacPlane();
|
|
pzode->onNewDataBlock(zode_data, false);
|
|
if (!pzode->registerObject())
|
|
{
|
|
delete pzode;
|
|
pzode = 0;
|
|
Con::errorf("afxEA_ZodiacPlane::ea_update() -- effect failed to register.");
|
|
return false;
|
|
}
|
|
deleteNotify(pzode);
|
|
|
|
///pzode->setSequenceRateFactor(datablock->rate_factor/prop_time_factor);
|
|
///pzode->setSortPriority(datablock->sort_priority);
|
|
}
|
|
|
|
if (pzode)
|
|
{
|
|
//LinearColorF zode_color = zode_data->color;
|
|
LinearColorF zode_color = mUpdated_color;
|
|
|
|
if (live_color_factor > 0.0)
|
|
zode_color.interpolate(zode_color, live_color, live_color_factor);
|
|
|
|
if (mDo_fades)
|
|
{
|
|
if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
|
|
zode_color *= mFade_value *mLive_fade_factor;
|
|
else
|
|
zode_color.alpha *= mFade_value * mLive_fade_factor;
|
|
}
|
|
|
|
// scale and grow zode
|
|
//F32 zode_radius = zode_data->radius_xy*updated_scale.x + life_elapsed*zode_data->growth_rate;
|
|
F32 zode_radius = zode_data->radius_xy + 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_data->respect_ori_cons && !zode_data->use_full_xfm)
|
|
{
|
|
VectorF shape_vec;
|
|
mUpdated_xfm.getColumn(1, &shape_vec);
|
|
shape_vec.normalize();
|
|
|
|
F32 ang;
|
|
|
|
switch (zode_data->face_dir)
|
|
{
|
|
case afxZodiacPlaneData::FACES_FORWARD:
|
|
case afxZodiacPlaneData::FACES_BACK:
|
|
ang = mAtan2(shape_vec.x, shape_vec.z);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_RIGHT:
|
|
case afxZodiacPlaneData::FACES_LEFT:
|
|
ang = mAtan2(shape_vec.y, shape_vec.z);
|
|
break;
|
|
case afxZodiacPlaneData::FACES_UP:
|
|
case afxZodiacPlaneData::FACES_DOWN:
|
|
default:
|
|
ang = mAtan2(shape_vec.x, shape_vec.y);
|
|
break;
|
|
}
|
|
|
|
if (ang < 0.0f)
|
|
ang += M_2PI_F;
|
|
|
|
switch (zode_data->face_dir)
|
|
{
|
|
case afxZodiacPlaneData::FACES_DOWN:
|
|
case afxZodiacPlaneData::FACES_BACK:
|
|
case afxZodiacPlaneData::FACES_LEFT:
|
|
ang = -ang;
|
|
break;
|
|
}
|
|
|
|
zode_angle_offset = mRadToDeg(ang);
|
|
}
|
|
|
|
F32 zode_angle = zode_data->calcRotationAngle(mLife_elapsed, mDatablock->rate_factor/ mProp_time_factor);
|
|
zode_angle = mFmod(zode_angle + zode_angle_offset, 360.0f);
|
|
aa_rot.angle = mDegToRad(zode_angle);
|
|
|
|
MatrixF spin_xfm;
|
|
aa_rot.setMatrix(&spin_xfm);
|
|
|
|
// set color, radius
|
|
pzode->setColor(zode_color);
|
|
pzode->setRadius(zode_radius);
|
|
if (zode_data->use_full_xfm)
|
|
{
|
|
mUpdated_xfm.mul(spin_xfm);
|
|
pzode->setTransform(mUpdated_xfm);
|
|
}
|
|
else
|
|
pzode->setTransform(spin_xfm);
|
|
pzode->setPosition(mUpdated_pos);
|
|
pzode->setScale(mUpdated_scale);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::ea_finish(bool was_stopped)
|
|
{
|
|
if (!pzode)
|
|
return;
|
|
|
|
pzode->deleteObject();
|
|
pzode = 0;
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::ea_set_scope_status(bool in_scope)
|
|
{
|
|
if (pzode)
|
|
pzode->setVisibility(in_scope);
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::onDeleteNotify(SimObject* obj)
|
|
{
|
|
if (pzode == dynamic_cast<afxZodiacPlane*>(obj))
|
|
pzode = 0;
|
|
|
|
Parent::onDeleteNotify(obj);
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::getUpdatedBoxCenter(Point3F& pos)
|
|
{
|
|
if (pzode)
|
|
pos = pzode->getBoxCenter();
|
|
}
|
|
|
|
void afxEA_ZodiacPlane::do_runtime_substitutions()
|
|
{
|
|
// only clone the datablock if there are substitutions
|
|
if (zode_data->getSubstitutionCount() > 0)
|
|
{
|
|
// clone the datablock and perform substitutions
|
|
afxZodiacPlaneData* orig_db = zode_data;
|
|
zode_data = new afxZodiacPlaneData(*orig_db, true);
|
|
orig_db->performSubstitutions(zode_data, mChoreographer, mGroup_index);
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
class afxEA_ZodiacPlaneDesc : public afxEffectAdapterDesc, public afxEffectDefs
|
|
{
|
|
static afxEA_ZodiacPlaneDesc 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_ZodiacPlane; }
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
afxEA_ZodiacPlaneDesc afxEA_ZodiacPlaneDesc::desc;
|
|
|
|
bool afxEA_ZodiacPlaneDesc::testEffectType(const SimDataBlock* db) const
|
|
{
|
|
return (typeid(afxZodiacPlaneData) == typeid(*db));
|
|
}
|
|
|
|
bool afxEA_ZodiacPlaneDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
|
|
{
|
|
return (timing.lifetime < 0);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|