mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
334 lines
9.1 KiB
C++
334 lines
9.1 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 "afx/arcaneFX.h"
|
|
|
|
#include "afx/afxEffectWrapper.h"
|
|
#include "afx/util/afxEase.h"
|
|
#include "afx/xm/afxXfmMod.h"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
afxXM_Params::afxXM_Params()
|
|
{
|
|
pos.zero();
|
|
ori.identity();
|
|
scale.set(1.0f,1.0f,1.0f);
|
|
pos2.zero();
|
|
color.set(0.0f,0.0f,0.0f,0.0f);
|
|
vis = 0.0;
|
|
}
|
|
|
|
U32 afxXM_Params::getParameterOffset(U32 param, S32 component)
|
|
{
|
|
switch (param)
|
|
{
|
|
|
|
case POSITION:
|
|
switch (component)
|
|
{
|
|
case 0:
|
|
return Offset(pos.x, afxXM_Params);
|
|
case 1:
|
|
return Offset(pos.y, afxXM_Params);
|
|
case 2:
|
|
return Offset(pos.z, afxXM_Params);
|
|
default:
|
|
return Offset(pos, afxXM_Params);
|
|
}
|
|
break;
|
|
|
|
case ORIENTATION:
|
|
return Offset(ori, afxXM_Params);
|
|
|
|
case POSITION2:
|
|
switch (component)
|
|
{
|
|
case 0:
|
|
return Offset(pos2.x, afxXM_Params);
|
|
case 1:
|
|
return Offset(pos2.y, afxXM_Params);
|
|
case 2:
|
|
return Offset(pos2.z, afxXM_Params);
|
|
default:
|
|
return Offset(pos2, afxXM_Params);
|
|
}
|
|
break;
|
|
|
|
case SCALE:
|
|
switch (component)
|
|
{
|
|
case 0:
|
|
return Offset(scale.x, afxXM_Params);
|
|
case 1:
|
|
return Offset(scale.y, afxXM_Params);
|
|
case 2:
|
|
return Offset(scale.z, afxXM_Params);
|
|
default:
|
|
return Offset(scale, afxXM_Params);
|
|
}
|
|
break;
|
|
|
|
case COLOR:
|
|
switch (component)
|
|
{
|
|
case 0:
|
|
return Offset(color.red, afxXM_Params);
|
|
case 1:
|
|
return Offset(color.green, afxXM_Params);
|
|
case 2:
|
|
return Offset(color.blue, afxXM_Params);
|
|
case 3:
|
|
return Offset(color.alpha, afxXM_Params);
|
|
default:
|
|
return Offset(color, afxXM_Params);
|
|
}
|
|
break;
|
|
|
|
case VISIBILITY:
|
|
return Offset(vis, afxXM_Params);
|
|
}
|
|
|
|
return BAD_OFFSET;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
// BASE CLASSES
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
IMPLEMENT_CO_DATABLOCK_V1(afxXM_BaseData);
|
|
|
|
afxXM_BaseData::afxXM_BaseData()
|
|
{
|
|
ignore_time_factor = false;
|
|
}
|
|
|
|
afxXM_BaseData::afxXM_BaseData(const afxXM_BaseData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
|
{
|
|
ignore_time_factor = other.ignore_time_factor;
|
|
}
|
|
|
|
void afxXM_BaseData::initPersistFields()
|
|
{
|
|
addField("ignoreTimeFactor", TypeBool, Offset(ignore_time_factor, afxXM_BaseData),
|
|
"...");
|
|
|
|
Parent::initPersistFields();
|
|
|
|
Con::setIntVariable("$afxXfmMod::POS", POSITION);
|
|
Con::setIntVariable("$afxXfmMod::ORI", ORIENTATION);
|
|
Con::setIntVariable("$afxXfmMod::POS2", POSITION2);
|
|
Con::setIntVariable("$afxXfmMod::SCALE", SCALE);
|
|
Con::setIntVariable("$afxXfmMod::ALL_BUT_SCALE", ALL_BUT_SCALE);
|
|
Con::setIntVariable("$afxXfmMod::ALL", ALL);
|
|
}
|
|
|
|
void afxXM_BaseData::packData(BitStream* stream)
|
|
{
|
|
Parent::packData(stream);
|
|
|
|
stream->write(ignore_time_factor);
|
|
}
|
|
|
|
void afxXM_BaseData::unpackData(BitStream* stream)
|
|
{
|
|
Parent::unpackData(stream);
|
|
|
|
stream->read(&ignore_time_factor);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
afxXM_Base::afxXM_Base(afxXM_BaseData* db, afxEffectWrapper* fxw)
|
|
{
|
|
fx_wrapper = fxw;
|
|
time_factor = (db->ignore_time_factor) ? 1.0f : fxw->getTimeFactor();
|
|
datablock = db;
|
|
}
|
|
|
|
afxXM_Base::~afxXM_Base()
|
|
{
|
|
if (datablock && datablock->isTempClone())
|
|
delete datablock;
|
|
datablock = 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
IMPLEMENT_CO_DATABLOCK_V1(afxXM_WeightedBaseData);
|
|
|
|
afxXM_WeightedBaseData::afxXM_WeightedBaseData()
|
|
{
|
|
delay = 0;
|
|
lifetime = afxEffectDefs::INFINITE_LIFETIME;
|
|
fade_in_time = 0;
|
|
fade_out_time = 0;
|
|
fadein_ease.set(0.0f, 1.0f);
|
|
fadeout_ease.set(0.0f, 1.0f);
|
|
life_bias = 1.0f;
|
|
}
|
|
|
|
afxXM_WeightedBaseData::afxXM_WeightedBaseData(const afxXM_WeightedBaseData& other, bool temp_clone) : afxXM_BaseData(other, temp_clone)
|
|
{
|
|
delay = other.delay;
|
|
lifetime = other.lifetime;
|
|
fade_in_time = other.fade_in_time;
|
|
fade_out_time = other.fade_out_time;
|
|
fadein_ease = other.fadein_ease;
|
|
fadeout_ease = other.fadeout_ease;
|
|
life_bias = other.life_bias;
|
|
}
|
|
|
|
bool afxXM_WeightedBaseData::hasFixedWeight() const
|
|
{
|
|
return (delay == 0.0f && lifetime == afxEffectDefs::INFINITE_LIFETIME && fade_in_time == 0.0f && fade_out_time == 0.0f);
|
|
}
|
|
|
|
F32 afxXM_WeightedBaseData::getWeightFactor() const
|
|
{
|
|
return 1.0f;
|
|
}
|
|
|
|
void afxXM_WeightedBaseData::initPersistFields()
|
|
{
|
|
addField("delay", TypeF32, Offset(delay, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("lifetime", TypeF32, Offset(lifetime, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("fadeInTime", TypeF32, Offset(fade_in_time, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("fadeOutTime", TypeF32, Offset(fade_out_time, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("fadeInEase", TypePoint2F, Offset(fadein_ease, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("fadeOutEase", TypePoint2F, Offset(fadeout_ease, afxXM_WeightedBaseData),
|
|
"...");
|
|
addField("lifetimeBias", TypeF32, Offset(life_bias, afxXM_WeightedBaseData),
|
|
"...");
|
|
|
|
Parent::initPersistFields();
|
|
}
|
|
|
|
void afxXM_WeightedBaseData::packData(BitStream* stream)
|
|
{
|
|
Parent::packData(stream);
|
|
|
|
if (stream->writeFlag(!hasFixedWeight()))
|
|
{
|
|
stream->write(delay);
|
|
stream->write(lifetime);
|
|
stream->write(fade_in_time);
|
|
stream->write(fade_out_time);
|
|
if (stream->writeFlag(fadein_ease.x != 0.0f || fadein_ease.y != 1.0f))
|
|
{
|
|
stream->writeFloat(fadein_ease.x, 16);
|
|
stream->writeFloat(fadein_ease.y, 16);
|
|
}
|
|
if (stream->writeFlag(fadeout_ease.x != 0.0f || fadeout_ease.y != 1.0f))
|
|
{
|
|
stream->writeFloat(fadeout_ease.x, 16);
|
|
stream->writeFloat(fadeout_ease.y, 16);
|
|
}
|
|
stream->write(life_bias);
|
|
}
|
|
}
|
|
|
|
void afxXM_WeightedBaseData::unpackData(BitStream* stream)
|
|
{
|
|
Parent::unpackData(stream);
|
|
|
|
if (stream->readFlag()) // WEIGHTED?
|
|
{
|
|
stream->read(&delay);
|
|
stream->read(&lifetime);
|
|
stream->read(&fade_in_time);
|
|
stream->read(&fade_out_time);
|
|
if (stream->readFlag()) // FADE-IN EASED?
|
|
{
|
|
fadein_ease.x = stream->readFloat(16);
|
|
fadein_ease.y = stream->readFloat(16);
|
|
}
|
|
else
|
|
fadein_ease.set(0.0f, 1.0f);
|
|
if (stream->readFlag()) // FADE-OUT EASED?
|
|
{
|
|
fadeout_ease.x = stream->readFloat(16);
|
|
fadeout_ease.y = stream->readFloat(16);
|
|
}
|
|
else
|
|
fadeout_ease.set(0.0f, 1.0f);
|
|
stream->read(&life_bias);
|
|
}
|
|
else
|
|
{
|
|
delay = 0.0f;
|
|
lifetime = afxEffectDefs::INFINITE_LIFETIME;
|
|
fade_in_time = 0.0f;
|
|
fade_out_time = 0.0f;
|
|
fadein_ease.set(0.0f, 1.0f);
|
|
fadeout_ease.set(0.0f, 1.0f);
|
|
life_bias = 1.0f;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
afxXM_WeightedBase::afxXM_WeightedBase(afxXM_WeightedBaseData* db, afxEffectWrapper* fxw)
|
|
: afxXM_Base(db, fxw)
|
|
{
|
|
wt_fadein = db->fade_in_time*db->life_bias;
|
|
wt_fadeout = db->fade_out_time*db->life_bias;
|
|
wt_fadein_ease = db->fadein_ease;
|
|
wt_fadeout_ease = db->fadeout_ease;
|
|
wt_start_time = db->delay;
|
|
wt_full_time = wt_start_time + wt_fadein;
|
|
wt_fade_time = wt_start_time + db->lifetime*db->life_bias;
|
|
wt_done_time = wt_fade_time + wt_fadeout;
|
|
}
|
|
|
|
F32 afxXM_WeightedBase::calc_weight_factor(F32 elapsed)
|
|
{
|
|
if (elapsed < wt_start_time) // pre
|
|
return 0.0f;
|
|
else if (elapsed < wt_full_time) // fade-in
|
|
{
|
|
F32 t = (elapsed - wt_start_time)/wt_fadein;
|
|
return afxEase::t(t, wt_fadein_ease.x, wt_fadein_ease.y);
|
|
}
|
|
else if (elapsed < wt_fade_time) // full
|
|
return 1.0f;
|
|
else if (elapsed < wt_done_time) // fade-out
|
|
{
|
|
F32 t = (wt_done_time - elapsed)/wt_fadeout;
|
|
return afxEase::t(t, wt_fadeout_ease.x, wt_fadeout_ease.y);
|
|
}
|
|
else // post
|
|
return 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
|
|