Add all new AFX files

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

View file

@ -0,0 +1,217 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxAnimClip.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxAnimClipData
IMPLEMENT_CO_DATABLOCK_V1(afxAnimClipData);
ConsoleDocClass( afxAnimClipData,
"@brief A datablock that specifies an Animation Clip effect.\n\n"
"An Animation Clip forces a target ShapeBase-derived object, such as Player or AIPlayer, to perform a particular "
"animation sequence. Animation Clip does not supply any new animation data, but simply selects, by name, a "
"sequence that is already defined in the target. Animation Clip can also target afxModel effects within the same "
"choreographer."
"\n\n"
"The target of an Animation Clip is the constraint source object specified by the posConstraint field of the enclosing "
"effect wrapper. The target must be a ShapeBase-derived object, or an afxModel and it must contain an animation "
"sequence with the same name as the clipName field."
"\n\n"
"Animation Clip controls the rate of animation playback and can even play a sequence in reverse. When an Animation "
"Clip selects a blended animation sequence, it is mixed with the current animation instead of replacing it. Animation "
"Clips can be used to activate multiple, overlapping blend sequences."
"\n\n"
"Normally when an Animation Clip is applied to a user-controlled Player, any interactive user actions will override the "
"animation selected by the clip, but Animation Clips can be configured to temporarily block out some user actions for "
"the duration of the clip."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxAnimClipData::afxAnimClipData()
{
clip_name = ST_NULLSTRING;
rate = 1.0f;
pos_offset = 0.0;
trans = 0.12f;
flags = 0;
ignore_disabled = false;
ignore_enabled = false;
is_death_anim = false;
lock_anim = false;
ignore_first_person = false;
ignore_third_person = false;
}
afxAnimClipData::afxAnimClipData(const afxAnimClipData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
clip_name = other.clip_name;
rate = other.rate;
pos_offset = other.pos_offset;
trans = other.trans;
flags = other.flags;
expand_flags();
}
void afxAnimClipData::onStaticModified(const char* slot, const char* newValue)
{
Parent::onStaticModified(slot, newValue);
merge_flags();
}
#define myOffset(field) Offset(field, afxAnimClipData)
void afxAnimClipData::initPersistFields()
{
addField("clipName", TYPEID< StringTableEntry >(), myOffset(clip_name),
"The name of an animation sequence to be played by a ShapeBase-derived object to which this effect is "
"constrained. Also works on afxModel effects.\n"
"default: \"\"\n");
addField("rate", TYPEID< F32 >(), myOffset(rate),
"The desired playback speed for the sequence. A value of 1.0 indicates forward playback at a normal rate. Negative "
"values cause the sequence to play backwards.\n"
"default: 1.0\n");
addField("posOffset", TYPEID< F32 >(), myOffset(pos_offset),
"Sets a starting offset for the selected animation clip. It directly specifies an animation thread position in the 0.0 to "
"1.0 range as a fraction of the clip's duration.\n"
"default: 1.0\n");
addField("transitionTime", TYPEID< F32 >(), myOffset(trans),
"The duration in which the active animation overlaps and blends into the sequence selected by the animation clip.\n"
"default: 0.12\n");
addField("ignoreCorpse", TYPEID< bool >(), myOffset(ignore_disabled),
"Specifies if the animation clip should not be applied to corpses or anything else with a disabled damage state.\n"
"default: false\n");
addField("ignoreLiving", TYPEID< bool >(), myOffset(ignore_enabled),
"Specifies if the animation clip should not be applied to living objects or anything else with an enabled damage "
"state.\n"
"default: false\n");
addField("treatAsDeathAnim", TYPEID< bool >(), myOffset(is_death_anim),
"Indicates if the animation clip is a death animation. If the target object dies during the effect, this will prevent "
"the object from playing another standard death animation after this clip finishes.\n"
"default: false\n");
addField("lockAnimation", TYPEID< bool >(), myOffset(lock_anim),
"Indicates if user control of a Player should be temporarily blocked during the clip. (See afxAnimLockData.)\n"
"default: false\n");
addField("ignoreFirstPerson", TYPEID< bool >(), myOffset(ignore_first_person),
"If true, the clip will not be played on targets that are the control object and the camera is in first person mode.\n"
"default: false\n");
addField("ignoreThirdPerson", TYPEID< bool >(), myOffset(ignore_third_person),
"If true, the clip will not be played on targets that are the control object and the camera is in third person mode.\n"
"default: false\n");
// synonyms
addField("ignoreDisabled", TYPEID< bool >(), myOffset(ignore_disabled),
"A synonym for ignoreLiving.");
addField("ignoreEnabled", TYPEID< bool >(), myOffset(ignore_enabled),
"A synonym for ignoreCorpse.");
Parent::initPersistFields();
}
bool afxAnimClipData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxAnimClipData::packData(BitStream* stream)
{
Parent::packData(stream);
merge_flags();
stream->writeString(clip_name);
stream->write(rate);
stream->write(pos_offset);
stream->write(trans);
stream->write(flags);
}
void afxAnimClipData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
clip_name = stream->readSTString();
stream->read(&rate);
stream->read(&pos_offset);
stream->read(&trans);
stream->read(&flags);
expand_flags();
}
bool afxAnimClipData::writeField(StringTableEntry fieldname, const char* value)
{
if (!Parent::writeField(fieldname, value))
return false;
// don't write the synonyms
if( fieldname == StringTable->insert("ignoreDisabled") )
return false;
if( fieldname == StringTable->insert("ignoreEnabled") )
return false;
return true;
}
void afxAnimClipData::expand_flags()
{
ignore_disabled = ((flags & IGNORE_DISABLED) != 0);
ignore_enabled = ((flags & IGNORE_ENABLED) != 0);
lock_anim = ((flags & BLOCK_USER_CONTROL) != 0);
is_death_anim = ((flags & IS_DEATH_ANIM) != 0);
ignore_first_person = ((flags & IGNORE_FIRST_PERSON) != 0);
ignore_third_person = ((flags & IGNORE_THIRD_PERSON) != 0);
}
void afxAnimClipData::merge_flags()
{
flags = (((ignore_disabled) ? IGNORE_DISABLED : 0) |
((ignore_enabled) ? IGNORE_ENABLED : 0) |
((lock_anim) ? BLOCK_USER_CONTROL : 0) |
((ignore_first_person) ? IGNORE_FIRST_PERSON : 0) |
((ignore_third_person) ? IGNORE_THIRD_PERSON : 0) |
((is_death_anim) ? IS_DEATH_ANIM : 0));
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,81 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ANIM_CLIP_H_
#define _AFX_ANIM_CLIP_H_
class afxAnimClipData : public GameBaseData
{
typedef GameBaseData Parent;
enum
{
IGNORE_DISABLED = BIT(0),
IGNORE_ENABLED = BIT(1),
IS_DEATH_ANIM = BIT(2),
BLOCK_USER_CONTROL = BIT(3),
IGNORE_FIRST_PERSON = BIT(4),
IGNORE_THIRD_PERSON = BIT(5)
};
public:
StringTableEntry clip_name;
F32 rate;
F32 pos_offset;
F32 trans;
U8 flags;
bool ignore_disabled;
bool ignore_enabled;
bool is_death_anim;
bool lock_anim;
bool ignore_first_person;
bool ignore_third_person;
void expand_flags();
void merge_flags();
public:
/*C*/ afxAnimClipData();
/*C*/ afxAnimClipData(const afxAnimClipData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool writeField(StringTableEntry fieldname, const char* value);
virtual void onStaticModified(const char* slotName, const char* newValue = NULL);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxAnimClipData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ANIM_CLIP_H_

View file

@ -0,0 +1,95 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxAnimLock.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxAnimLockData
IMPLEMENT_CO_DATABLOCK_V1(afxAnimLockData);
ConsoleDocClass( afxAnimLockData,
"@brief A datablock that specifies an Animation Lock effect.\n\n"
"Animation Lock is used to temporarily lock out user-controlled Player actions, usually while an Animation Clip is "
"concurrently playing. Animation Clips can already do this, but must lock out user actions for the entire clip length. "
"Sometimes you only want to block user actions for a short section of a longer playing animation, such as the part where "
"the Player is thrown into the air from an impact. With Animation Lock, you can set a specific timespan for when user "
"actions are blocked, independent of any Animation Clip timing."
"\n\n"
"The target of an Animation Lock is the constraint source object specified by the posConstraint field of the enclosing effect "
"wrapper. The target must be a Player, a subclass of Player, or an afxModel."
"\n\n"
"The timing of the Animation Lock is determined by the timing fields of the enclosing effect wrapper."
"\n\n"
"Locking behavior timing is set by fields of the enclosing effect wrapper, so afxAnimLockData does not require any fields. "
"However, TorqueScript syntax disallows the declaration of an empty datablock. Therefore, it is recommended that you set "
"a dynamic field named 'priority' to zero in the body of the datablock as a workaround to this limitation."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxAnimLockData::afxAnimLockData()
{
}
#define myOffset(field) Offset(field, afxAnimLockData)
void afxAnimLockData::initPersistFields()
{
Parent::initPersistFields();
}
bool afxAnimLockData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxAnimLockData::packData(BitStream* stream)
{
Parent::packData(stream);
}
void afxAnimLockData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,48 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ANIM_LOCK_H_
#define _AFX_ANIM_LOCK_H_
class afxAnimLockData : public GameBaseData
{
typedef GameBaseData Parent;
public:
/*C*/ afxAnimLockData();
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
static void initPersistFields();
DECLARE_CONOBJECT(afxAnimLockData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ANIM_LOCK_H_

View file

@ -0,0 +1,121 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxAreaDamage.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxAreaDamageData
IMPLEMENT_CO_DATABLOCK_V1(afxAreaDamageData);
ConsoleDocClass( afxAreaDamageData,
"@brief A datablock that specifies an Area Damage effect.\n\n"
"An Area Damage effect is useful for assigning area damage with unusual timing that must be synchronized with other "
"effects. Negative damage amounts can be used for healing effects."
"\n\n"
"The primary difference between afxAreaDamageData and afxDamageData, which is also capable of inflicting area damage, "
"is that afxAreaDamageData effects calculate the area damage in C++ code rather than calling out to the script function "
"radiusDamage(). In cases where area damage needs to be inflicted repeatedly or in areas crowded with many targets, "
"afxAreaDamageData is likely to get better performance."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxAreaDamageData::afxAreaDamageData()
{
flavor = ST_NULLSTRING;
amount = 0;
radius = 0;
impulse = 0;
notify_damage_src = false;
exclude_cons_obj = false;
}
afxAreaDamageData::afxAreaDamageData(const afxAreaDamageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
flavor = other.flavor;
amount = other.amount;
radius = other.radius;
impulse = other.impulse;
notify_damage_src = other.notify_damage_src;
exclude_cons_obj = other.exclude_cons_obj;
}
#define myOffset(field) Offset(field, afxAreaDamageData)
void afxAreaDamageData::initPersistFields()
{
addField("flavor", TypeString, myOffset(flavor),
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
"method. It is used to classify a type of damage such as 'melee', 'magical', or "
"'fire'.");
addField("damage", TypeF32, myOffset(amount),
"An amount of area damage to inflict on a target. Objects within half the radius "
"receive full damage which then diminishes out to the full distance of the specified "
"radius.");
addField("radius", TypeF32, myOffset(radius),
"Radius centered at the effect position in which damage will be applied.");
addField("impulse", TypeF32, myOffset(impulse),
"Specifies an amount of force to apply to damaged objects. Objects within half the "
"radius receive full impulse which then diminishes out to the full distance of the "
"specified radius.");
addField("notifyDamageSource", TypeBool, myOffset(notify_damage_src),
"When true, the onInflictedAreaDamage() method of the damaged object will be called "
"to notify it of the damage. This is useful for starting some effects or action that "
"responds to the damage.");
addField("excludeConstraintObject", TypeBool, myOffset(exclude_cons_obj),
"When true, the object specified as the effect's primary position constraint will not "
"receive any damage.");
Parent::initPersistFields();
}
bool afxAreaDamageData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxAreaDamageData::packData(BitStream* stream)
{
Parent::packData(stream);
}
void afxAreaDamageData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,62 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_AREA_DAMAGE_H_
#define _AFX_AREA_DAMAGE_H_
#include "afx/afxEffectDefs.h"
class afxAreaDamageData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
StringTableEntry flavor;
F32 amount;
F32 radius;
F32 impulse;
bool notify_damage_src;
bool exclude_cons_obj;
public:
/*C*/ afxAreaDamageData();
/*C*/ afxAreaDamageData(const afxAreaDamageData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxAreaDamageData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_AREA_DAMAGE_H_

View file

@ -0,0 +1,246 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "sim/netConnection.h"
#include "sfx/sfxDescription.h"
#include "afx/ce/afxAudioBank.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
IMPLEMENT_CO_DATABLOCK_V1(afxAudioBank);
ConsoleDocClass( afxAudioBank,
"@brief A datablock that specifies an Audio Bank effect.\n\n"
"afxAudioBank is very similar to the stock Torque SFXProfile datablock but it allows specification of up to 32 different sound "
"files. The sound that actually plays is determined by the playIndex field."
"\n\n"
"afxAudioBank is most useful when used in combination with field substitutions, whereby a substitution statement "
"assigned to playIndex selects a different sound (perhaps randomly) each time the effect is used."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxAudioBank::afxAudioBank()
{
mPath = ST_NULLSTRING;
mDescriptionObjectID = 0;
mDescriptionObject = NULL;
mPreload = false;
play_index = -1;
for (S32 i = 0; i < 32; i++)
mFilenames[i] = ST_NULLSTRING;
}
afxAudioBank::afxAudioBank(const afxAudioBank& other, bool temp_clone) : SimDataBlock(other, temp_clone)
{
mPath = other.mPath;
mDescriptionObject = other.mDescriptionObject;
mDescriptionObjectID = other.mDescriptionObjectID; // -- for pack/unpack of mDescriptionObject ptr
mPreload = other.mPreload;
play_index = other.play_index;
for (S32 i = 0; i < 32; i++)
mFilenames[i] = other.mFilenames[i];
}
afxAudioBank::~afxAudioBank()
{
if (!isTempClone())
return;
if (mDescriptionObject && mDescriptionObject->isTempClone())
{
delete mDescriptionObject;
mDescriptionObject = 0;
}
}
afxAudioBank* afxAudioBank::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
{
if (!owner)
return this;
afxAudioBank* sub_profile_db = this;
SFXDescription* desc_db;
if (mDescriptionObject && mDescriptionObject->getSubstitutionCount() > 0)
{
SFXDescription* orig_db = mDescriptionObject;
desc_db = new SFXDescription(*orig_db, true);
orig_db->performSubstitutions(desc_db, owner, index);
}
else
desc_db = 0;
if (this->getSubstitutionCount() > 0 || desc_db)
{
sub_profile_db = new afxAudioBank(*this, true);
performSubstitutions(sub_profile_db, owner, index);
if (desc_db)
sub_profile_db->mDescriptionObject = desc_db;
}
return sub_profile_db;
}
void afxAudioBank::onPerformSubstitutions()
{
}
void afxAudioBank::initPersistFields()
{
addField("path", TypeFilename, Offset(mPath, afxAudioBank),
"A filesystem path to the folder containing the sound files specified by the "
"filenames[] field. All sound files used in a single AudioBank must be located in "
"the same folder.");
addField("filenames", TypeString, Offset(mFilenames, afxAudioBank), 32,
"Up to 32 names of sound files found in the path folder. The sound that is actually "
"played by an Audio Bank effect is determined by the playIndex field.");
addField("description", TYPEID<SFXDescription>(), Offset(mDescriptionObject, afxAudioBank),
"SFXDescription datablock to use with this set of sounds.");
addField("preload", TypeBool, Offset(mPreload, afxAudioBank),
"If set to true, file is pre-loaded, otherwise it is loaded on-demand.");
addField("playIndex", TypeS32, Offset(play_index, afxAudioBank),
"An array index that selects a sound to play from the filenames[] field. Values "
"outside of the range of assigned filename[] entries will not play any sound.");
Parent::initPersistFields();
}
bool afxAudioBank::preload(bool server, String &errorStr)
{
if(!Parent::preload(server, errorStr))
return false;
return true;
}
bool afxAudioBank::onAdd()
{
if (!Parent::onAdd())
return false;
if (!mDescriptionObject && mDescriptionObjectID)
Sim::findObject(mDescriptionObjectID , mDescriptionObject);
// if this is client side, make sure that description is as well
if(mDescriptionObject)
{ // client side dataBlock id's are not in the dataBlock id range
if (getId() >= DataBlockObjectIdFirst && getId() <= DataBlockObjectIdLast)
{
SimObjectId pid = mDescriptionObject->getId();
if (pid < DataBlockObjectIdFirst || pid > DataBlockObjectIdLast)
{
Con::errorf(ConsoleLogEntry::General,"afxAudioBank: data dataBlock not networkable (use datablock to create).");
return false;
}
}
}
return(true);
}
void afxAudioBank::packData(BitStream* stream)
{
Parent::packData(stream);
if (stream->writeFlag(mDescriptionObject))
stream->writeRangedU32(mDescriptionObject->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
/*
char buffer[256];
if(!mFilename)
buffer[0] = 0;
else
dStrcpy(buffer, mFilename);
stream->writeString(buffer);
*/
stream->writeString(mPath);
for (S32 i = 0; i < 32; i++)
{
stream->writeString(mFilenames[i]);
if (mFilenames[i] == ST_NULLSTRING)
break;
}
stream->writeFlag(mPreload);
if (stream->writeFlag(play_index >= 0 && play_index < 32))
stream->writeInt(play_index, 5);
}
void afxAudioBank::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
if (stream->readFlag()) // AudioDescription
{
SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
mDescriptionObjectID = id;
Sim::findObject(id, mDescriptionObject);
}
// Filename
/*
char buffer[256];
stream->readString(buffer);
mFilename = StringTable->insert(buffer);
*/
char buffer[256];
stream->readString(buffer);
mPath = StringTable->insert(buffer);
for (S32 i = 0; i < 32; i++)
{
stream->readString(buffer);
mFilenames[i] = StringTable->insert(buffer);
if (mFilenames[i] == ST_NULLSTRING)
break;
}
mPreload = stream->readFlag(); // Preload
if (stream->readFlag())
play_index = stream->readInt(5);
else
play_index = -1;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,67 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_AUDIO_BANK_H_
#define _AFX_AUDIO_BANK_H_
class SFXDescription;
class afxAudioBank: public SimDataBlock
{
private:
typedef SimDataBlock Parent;
public:
SFXDescription* mDescriptionObject;
U32 mDescriptionObjectID;
StringTableEntry mPath;
StringTableEntry mFilenames[32];
bool mPreload;
S32 play_index;
public:
/*C*/ afxAudioBank();
/*C*/ afxAudioBank(const afxAudioBank&, bool = false);
/*D*/ ~afxAudioBank();
static void initPersistFields();
virtual bool onAdd();
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
bool preload(bool server, String &errorStr);
afxAudioBank* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
virtual void onPerformSubstitutions();
virtual bool allowSubstitutions() const { return true; }
DECLARE_CONOBJECT(afxAudioBank);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_AUDIO_BANK_H_

View file

@ -0,0 +1,294 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "gfx/gfxAPI.h"
#include "math/mathIO.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxBillboard.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxBillboardData
IMPLEMENT_CO_DATABLOCK_V1(afxBillboardData);
ConsoleDocClass( afxBillboardData,
"@brief A datablock that specifies a Billboard effect.\n\n"
"A Billboard effect is a textured quadrangle which is always aligned to face towards the camera. It is much like a single "
"static particle and is rendered in a similar fashion."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxBillboardData::afxBillboardData()
{
color.set(1.0f, 1.0f, 1.0f, 1.0f);
txr_name = ST_NULLSTRING;
dimensions.set(1.0f, 1.0f);
texCoords[0].set(0.0f, 0.0f);
texCoords[1].set(0.0f, 1.0f);
texCoords[2].set(1.0f, 1.0f);
texCoords[3].set(1.0f, 0.0f);
blendStyle = BlendUndefined;
srcBlendFactor = BLEND_UNDEFINED;
dstBlendFactor = BLEND_UNDEFINED;
texFunc = TexFuncModulate;
}
afxBillboardData::afxBillboardData(const afxBillboardData& other, bool temp_clone)
: GameBaseData(other, temp_clone)
{
color = other.color;
txr_name = other.txr_name;
txr = other.txr;
dimensions = other.dimensions;
texCoords[0] = other.texCoords[0];
texCoords[1] = other.texCoords[1];
texCoords[2] = other.texCoords[2];
texCoords[3] = other.texCoords[3];
blendStyle = other.blendStyle;
srcBlendFactor = other.srcBlendFactor;
dstBlendFactor = other.dstBlendFactor;
texFunc = other.texFunc;
}
#define myOffset(field) Offset(field, afxBillboardData)
extern EnumTable srcBlendFactorTable;
extern EnumTable dstBlendFactorTable;
ImplementEnumType( afxBillboard_BlendStyle, "Possible blending types.\n" "@ingroup afxBillboard\n\n" )
{ afxBillboardData::BlendNormal, "NORMAL", "..." },
{ afxBillboardData::BlendAdditive, "ADDITIVE", "..." },
{ afxBillboardData::BlendSubtractive, "SUBTRACTIVE", "..." },
{ afxBillboardData::BlendPremultAlpha, "PREMULTALPHA", "..." },
EndImplementEnumType;
ImplementEnumType( afxBillboard_TexFuncType, "Possible texture function types.\n" "@ingroup afxBillboard\n\n" )
{ afxBillboardData::TexFuncReplace, "replace", "..." },
{ afxBillboardData::TexFuncModulate, "modulate", "..." },
{ afxBillboardData::TexFuncAdd, "add", "..." },
EndImplementEnumType;
void afxBillboardData::initPersistFields()
{
addField("color", TypeColorF, myOffset(color),
"The color assigned to the quadrangle geometry. The way it combines with the given "
"texture varies according to the setting of the textureFunction field.");
addField("texture", TypeFilename, myOffset(txr_name),
"An image to use as the billboard's texture.");
addField("dimensions", TypePoint2F, myOffset(dimensions),
"A value-pair that specifies the horizontal and vertical dimensions of the billboard "
"in scene units.");
addField("textureCoords", TypePoint2F, myOffset(texCoords), 4,
"An array of four value-pairs that specify the UV texture coordinates for the four "
"corners of the billboard's quadrangle.");
addField("blendStyle", TYPEID<afxBillboardData::BlendStyle>(), myOffset(blendStyle),
"Selects a common blend factor preset. When set to 'user', srcBlendFactor and "
"dstBlendFactor can be used to set additional blend factor combinations.\n"
"Possible values: normal, additive, subtractive, premultalpha, or user.");
addField("srcBlendFactor", TYPEID<GFXBlend>(), myOffset(srcBlendFactor),
"Specifies source blend factor when blendStyle is set to 'user'.\n"
"Possible values: GFXBlendZero, GFXBlendOne, GFXBlendDestColor, GFXBlendInvDestColor, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha, GFXBlendDestAlpha, GFXBlendInvDestAlpha, or GFXBlendSrcAlphaSat");
addField("dstBlendFactor", TYPEID<GFXBlend>(), myOffset(dstBlendFactor),
"Specifies destination blend factor when blendStyle is set to 'user'.\n"
"Possible values: GFXBlendZero, GFXBlendOne, GFXBlendSrcColor, GFXBlendInvSrcColor, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha, GFXBlendDestAlpha, or GFXBlendInvDestAlpha");
addField("textureFunction", TYPEID<afxBillboardData::TexFuncType>(), myOffset(texFunc),
"Selects a texture function that determines how the texture pixels are combined "
"with the shaded color of the billboard's quadrangle geometry.\n"
"Possible values: replace, modulate, or add.");
Parent::initPersistFields();
}
void afxBillboardData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(color);
stream->writeString(txr_name);
mathWrite(*stream, dimensions);
mathWrite(*stream, texCoords[0]);
mathWrite(*stream, texCoords[1]);
mathWrite(*stream, texCoords[2]);
mathWrite(*stream, texCoords[3]);
stream->writeInt(srcBlendFactor, 4);
stream->writeInt(dstBlendFactor, 4);
stream->writeInt(texFunc, 4);
}
void afxBillboardData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&color);
txr_name = stream->readSTString();
txr = GFXTexHandle();
mathRead(*stream, &dimensions);
mathRead(*stream, &texCoords[0]);
mathRead(*stream, &texCoords[1]);
mathRead(*stream, &texCoords[2]);
mathRead(*stream, &texCoords[3]);
srcBlendFactor = (GFXBlend) stream->readInt(4);
dstBlendFactor = (GFXBlend) stream->readInt(4);
texFunc = stream->readInt(4);
}
bool afxBillboardData::preload(bool server, String &errorStr)
{
if (!Parent::preload(server, errorStr))
return false;
if (!server)
{
if (txr_name && txr_name[0] != '\0')
{
txr.set(txr_name, &GFXStaticTextureSRGBProfile, "Billboard Texture");
}
}
// if blend-style is set to User, check for defined blend-factors
if (blendStyle == BlendUser && (srcBlendFactor == BLEND_UNDEFINED || dstBlendFactor == BLEND_UNDEFINED))
{
blendStyle = BlendUndefined;
Con::warnf(ConsoleLogEntry::General, "afxBillboardData(%s) incomplete blend factor specification.", getName());
}
// silently switch Undefined blend-style to User if blend factors are both defined
if (blendStyle == BlendUndefined && srcBlendFactor != BLEND_UNDEFINED && dstBlendFactor != BLEND_UNDEFINED)
{
blendStyle = BlendUser;
}
// set pre-defined blend-factors
switch (blendStyle)
{
case BlendNormal:
srcBlendFactor = GFXBlendSrcAlpha;
dstBlendFactor = GFXBlendInvSrcAlpha;
break;
case BlendSubtractive:
srcBlendFactor = GFXBlendZero;
dstBlendFactor = GFXBlendInvSrcColor;
break;
case BlendPremultAlpha:
srcBlendFactor = GFXBlendOne;
dstBlendFactor = GFXBlendInvSrcAlpha;
break;
case BlendUser:
break;
case BlendAdditive:
srcBlendFactor = GFXBlendSrcAlpha;
dstBlendFactor = GFXBlendOne;
break;
case BlendUndefined:
default:
blendStyle = BlendNormal;
srcBlendFactor = GFXBlendSrcAlpha;
dstBlendFactor = GFXBlendInvSrcAlpha;
break;
}
return true;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxBillboard
IMPLEMENT_CO_NETOBJECT_V1(afxBillboard);
ConsoleDocClass( afxBillboard,
"@brief A Billboard effect as defined by an afxBillboardData datablock.\n\n"
"A Billboard effect is a textured quadrangle which is always aligned to "
"face towards the camera. It is much like a single static particle and is rendered "
"in a similar fashion.\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxBillboard::afxBillboard()
{
mNetFlags.clear();
mNetFlags.set(IsGhost);
mDataBlock = 0;
fade_amt = 1.0f;
is_visible = true;
sort_priority = 0;
live_color.set(1.0f, 1.0f, 1.0f, 1.0f);
}
afxBillboard::~afxBillboard()
{
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxBillboard::onNewDataBlock(GameBaseData* dptr, bool reload)
{
mDataBlock = dynamic_cast<afxBillboardData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
return false;
live_color = mDataBlock->color;
return true;
}
bool afxBillboard::onAdd()
{
if(!Parent::onAdd())
return false;
F32 width = mDataBlock->dimensions.x * 0.5f;
F32 height = mDataBlock->dimensions.y * 0.5f;
mObjBox = Box3F(Point3F(-width, -0.01f, -height), Point3F(width, 0.01f, height));
addToScene();
return true;
}
void afxBillboard::onRemove()
{
removeFromScene();
Parent::onRemove();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,131 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_BILLBOARD_H_
#define _AFX_BILLBOARD_H_
#include "afx/afxEffectDefs.h"
#define BLEND_UNDEFINED GFXBlend_COUNT
class afxBillboardData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
// This enum specifies common blend settings with predefined values
// for src/dst blend factors.
enum BlendStyle {
BlendUndefined,
BlendNormal,
BlendAdditive,
BlendSubtractive,
BlendPremultAlpha,
BlendUser,
};
enum TexFuncType {
TexFuncReplace,
TexFuncModulate,
TexFuncAdd,
};
public:
StringTableEntry txr_name;
GFXTexHandle txr;
LinearColorF color;
Point2F texCoords[4];
Point2F dimensions;
S32 blendStyle;
GFXBlend srcBlendFactor;
GFXBlend dstBlendFactor;
S32 texFunc;
public:
/*C*/ afxBillboardData();
/*C*/ afxBillboardData(const afxBillboardData&, bool = false);
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxBillboardData);
DECLARE_CATEGORY("AFX");
};
typedef afxBillboardData::BlendStyle afxBillboard_BlendStyle;
DefineEnumType( afxBillboard_BlendStyle );
typedef afxBillboardData::TexFuncType afxBillboard_TexFuncType;
DefineEnumType( afxBillboard_TexFuncType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxBillboard
class afxBillboard : public GameBase, public afxEffectDefs
{
typedef GameBase Parent;
friend class afxEA_Billboard;
private:
afxBillboardData* mDataBlock;
F32 fade_amt;
bool is_visible;
S8 sort_priority;
LinearColorF live_color;
GFXStateBlockRef normal_sb;
GFXStateBlockRef reflected_sb;
public:
/*C*/ afxBillboard();
/*D*/ ~afxBillboard();
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
virtual bool onAdd();
virtual void onRemove();
void setFadeAmount(F32 amt) { fade_amt = amt; }
void setSortPriority(S8 priority) { sort_priority = priority; }
void setVisibility(bool flag) { is_visible = flag; }
virtual void prepRenderImage(SceneRenderState*);
void _renderBillboard(ObjectRenderInst*, SceneRenderState*, BaseMatInstance*);
DECLARE_CONOBJECT(afxBillboard);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_BILLBOARD_H_

View file

@ -0,0 +1,145 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "gfx/gfxTransformSaver.h"
#include "gfx/primBuilder.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxBillboard.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxBillboard::prepRenderImage(SceneRenderState* state)
{
if (!is_visible)
return;
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
ri->renderDelegate.bind(this, &afxBillboard::_renderBillboard);
ri->type = RenderPassManager::RIT_ObjectTranslucent;
ri->translucentSort = true;
ri->defaultKey = (U32)(dsize_t)mDataBlock;
ri->sortDistSq = getWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
state->getRenderPass()->addInst(ri);
}
void afxBillboard::_renderBillboard(ObjectRenderInst *ri, SceneRenderState* state, BaseMatInstance* overrideMat)
{
if (overrideMat)
return;
// predraw
if (normal_sb.isNull())
{
GFXStateBlockDesc desc;
// Culling -- it's a billboard, so no backfaces
desc.setCullMode(GFXCullCW);
// Blending
desc.setBlend(true, mDataBlock->srcBlendFactor, mDataBlock->dstBlendFactor);
desc.alphaTestEnable = (desc.blendSrc == GFXBlendSrcAlpha &&
(desc.blendDest == GFXBlendInvSrcAlpha || desc.blendDest == GFXBlendOne));
desc.alphaTestRef = 1;
desc.alphaTestFunc = GFXCmpGreaterEqual;
desc.setZReadWrite(true);
desc.zFunc = GFXCmpLessEqual;
desc.zWriteEnable = false;
desc.samplersDefined = true;
switch (mDataBlock->texFunc)
{
case afxBillboardData::TexFuncReplace:
desc.samplers[0].textureColorOp = GFXTOPDisable;
break;
case afxBillboardData::TexFuncModulate:
desc.samplers[0].textureColorOp = GFXTOPModulate;
break;
case afxBillboardData::TexFuncAdd:
desc.samplers[0].textureColorOp = GFXTOPAdd;
break;
}
desc.samplers[1].textureColorOp = GFXTOPDisable;
normal_sb = GFX->createStateBlock(desc);
desc.setCullMode(GFXCullCCW);
reflected_sb = GFX->createStateBlock(desc);
}
if (state->isReflectPass())
GFX->setStateBlock(reflected_sb);
else
GFX->setStateBlock(normal_sb);
GFXTransformSaver saver;
GFX->multWorld(getRenderTransform());
GFX->setTexture(0, mDataBlock->txr);
MatrixF worldmod = GFX->getWorldMatrix();
MatrixF viewmod = GFX->getViewMatrix();
Point4F Position;
MatrixF ModelView;
ModelView.mul(viewmod, worldmod);
ModelView.getColumn(3, &Position);
ModelView.identity();
ModelView.setColumn(3, Position);
GFX->setWorldMatrix(ModelView);
MatrixF ident;
ident.identity();
GFX->setViewMatrix(ident);
F32 width = mDataBlock->dimensions.x * 0.5f * mObjScale.x;
F32 height = mDataBlock->dimensions.y * 0.5f * mObjScale.z;
Point3F points[4];
points[0].set( width, 0.0f, -height);
points[1].set(-width, 0.0f, -height);
points[2].set(-width, 0.0f, height);
points[3].set( width, 0.0f, height);
PrimBuild::begin(GFXTriangleStrip, 4);
{
PrimBuild::color4f(live_color.red, live_color.green, live_color.blue, live_color.alpha*fade_amt);
PrimBuild::texCoord2f(mDataBlock->texCoords[1].x, mDataBlock->texCoords[1].y);
PrimBuild::vertex3fv(points[1]);
PrimBuild::texCoord2f(mDataBlock->texCoords[2].x, mDataBlock->texCoords[2].y);
PrimBuild::vertex3fv(points[0]);
PrimBuild::texCoord2f(mDataBlock->texCoords[0].x, mDataBlock->texCoords[0].y);
PrimBuild::vertex3fv(points[2]);
PrimBuild::texCoord2f(mDataBlock->texCoords[3].x, mDataBlock->texCoords[3].y);
PrimBuild::vertex3fv(points[3]);
}
PrimBuild::end();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,132 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxCameraPuppet.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxCameraPuppetData
IMPLEMENT_CO_DATABLOCK_V1(afxCameraPuppetData);
ConsoleDocClass( afxCameraPuppetData,
"@brief A datablock that specifies a Camera Puppet effect.\n\n"
"A Camera Puppet effect is used to control the position and orientation of the camera using the AFX constraint system. "
"Camera Puppet effects are useful for creating small cut-scenes and can add a lot of visual drama to a spell or effectron "
"effect."
"\n\n"
"Effective use of Camera Puppet effects require a fairly advanced understanding of how Torque cameras work in a "
"server-client context. Care must be taken to prevent client cameras from drifting too far out of sync from the server camera. "
"Otherwise, obvious discontinuities in the motion will result when the Camera Puppet ends and control is restored to the "
"server camera. Scoping problems can also result if a client camera is moved to a location that is inconsistent with the "
"scene scoping done by the server camera."
"\n\n"
"Often it is useful to manage camera controlling in an isolated effectron rather than directly incorporated into a magic-spell. "
"This way the camera controlling effectron can target the specific client associated with the spellcaster. The spellcasting "
"player observes the spell in a dramatic cut-scene-like fashion while other players continue to observe from their own "
"viewing locations."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxCameraPuppetData::afxCameraPuppetData()
{
cam_spec = ST_NULLSTRING;
networking = SERVER_AND_CLIENT;
}
afxCameraPuppetData::afxCameraPuppetData(const afxCameraPuppetData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
cam_spec = other.cam_spec;
networking = other.networking;
}
#define myOffset(field) Offset(field, afxCameraPuppetData)
void afxCameraPuppetData::initPersistFields()
{
addField("cameraSpec", TypeString, myOffset(cam_spec),
"This field is like the effect-wrapper fields for specifying constraint sources, "
"but here it specifies a target for the camera-puppet effect.");
addField("networking", TypeS8, myOffset(networking),
"Specifies the networking model used for the camerapuppet effect. The effect can "
"puppet just the server camera, just the client camera, or both.\n"
"Possible values: $AFX::SERVER_ONLY, $AFX::CLIENT_ONLY, or $AFX::SERVER_AND_CLIENT.");
// disallow some field substitutions
disableFieldSubstitutions("cameraSpec");
disableFieldSubstitutions("networking");
Parent::initPersistFields();
}
bool afxCameraPuppetData::onAdd()
{
if (Parent::onAdd() == false)
return false;
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
cam_def.parseSpec(cam_spec, runs_on_s, runs_on_c);
return true;
}
void afxCameraPuppetData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(cam_spec);
stream->write(networking);
}
void afxCameraPuppetData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
cam_spec = stream->readSTString();
stream->read(&networking);
}
void afxCameraPuppetData::gather_cons_defs(Vector<afxConstraintDef>& defs)
{
if (cam_def.isDefined())
defs.push_back(cam_def);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,64 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_CAMERA_PUPPET_H_
#define _AFX_CAMERA_PUPPET_H_
#include "afx/ce/afxComponentEffect.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxConstraint.h"
class afxCameraPuppetData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
{
typedef GameBaseData Parent;
public:
StringTableEntry cam_spec;
afxConstraintDef cam_def;
U8 networking;
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
public:
/*C*/ afxCameraPuppetData();
/*C*/ afxCameraPuppetData(const afxCameraPuppetData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxCameraPuppetData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_CAMERA_PUPPET_H_

View file

@ -0,0 +1,118 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxCameraShake.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxCameraShakeData
IMPLEMENT_CO_DATABLOCK_V1(afxCameraShakeData);
ConsoleDocClass( afxCameraShakeData,
"@brief A datablock that specifies a Camera Shake effect.\n\n"
"Camera Shake internally utilizes the standard Torque CameraShake class to implement a shaken camera effect."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxCameraShakeData::afxCameraShakeData()
{
camShakeFreq.set( 10.0, 10.0, 10.0 );
camShakeAmp.set( 1.0, 1.0, 1.0 );
camShakeRadius = 10.0;
camShakeFalloff = 10.0;
}
afxCameraShakeData::afxCameraShakeData(const afxCameraShakeData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
camShakeFreq = other.camShakeFreq;
camShakeAmp = other.camShakeAmp;
camShakeRadius = other.camShakeRadius;
camShakeFalloff = other.camShakeFalloff;
}
#define myOffset(field) Offset(field, afxCameraShakeData)
void afxCameraShakeData::initPersistFields()
{
addField("frequency", TypePoint3F, Offset(camShakeFreq, afxCameraShakeData),
"The camera shake frequencies for all three axes: X, Y, Z.");
addField("amplitude", TypePoint3F, Offset(camShakeAmp, afxCameraShakeData),
"The camera shake amplitudes for all three axes: X, Y, Z.");
addField("radius", TypeF32, Offset(camShakeRadius, afxCameraShakeData),
"Radius about the effect position in which shaking will be applied.");
addField("falloff", TypeF32, Offset(camShakeFalloff, afxCameraShakeData),
"Magnitude by which shaking decreases over distance to radius.");
Parent::initPersistFields();
}
bool afxCameraShakeData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxCameraShakeData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(camShakeFreq.x);
stream->write(camShakeFreq.y);
stream->write(camShakeFreq.z);
stream->write(camShakeAmp.x);
stream->write(camShakeAmp.y);
stream->write(camShakeAmp.z);
stream->write(camShakeRadius);
stream->write(camShakeFalloff);
}
void afxCameraShakeData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&camShakeFreq.x);
stream->read(&camShakeFreq.y);
stream->read(&camShakeFreq.z);
stream->read(&camShakeAmp.x);
stream->read(&camShakeAmp.y);
stream->read(&camShakeAmp.z);
stream->read(&camShakeRadius);
stream->read(&camShakeFalloff);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,57 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_CAMERA_SHAKE_H_
#define _AFX_CAMERA_SHAKE_H_
class afxCameraShakeData : public GameBaseData
{
typedef GameBaseData Parent;
public:
VectorF camShakeFreq;
VectorF camShakeAmp;
F32 camShakeRadius;
F32 camShakeFalloff;
public:
/*C*/ afxCameraShakeData();
/*C*/ afxCameraShakeData(const afxCameraShakeData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxCameraShakeData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_CAMERA_SHAKE_H_

View file

@ -0,0 +1,103 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxCollisionEvent.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxCollisionEventData
IMPLEMENT_CO_DATABLOCK_V1(afxCollisionEventData);
ConsoleDocClass( afxCollisionEventData,
"@brief A datablock that specifies a Collision Event effect.\n\n"
"MORE NEEDED HERE.\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxCollisionEventData::afxCollisionEventData()
{
method_name = ST_NULLSTRING;
script_data = ST_NULLSTRING;
gen_trigger = false;
trigger_bit = 0;
}
afxCollisionEventData::afxCollisionEventData(const afxCollisionEventData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
method_name = other.method_name;
script_data = other.script_data;
gen_trigger = other.gen_trigger;
trigger_bit = other.trigger_bit;
}
#define myOffset(field) Offset(field, afxCollisionEventData)
void afxCollisionEventData::initPersistFields()
{
addField("methodName", TypeString, myOffset(method_name),
"...");
addField("scriptData", TypeString, myOffset(script_data),
"...");
addField("generateTrigger", TypeBool, myOffset(gen_trigger),
"...");
addField("triggerBit", TypeS8, myOffset(trigger_bit),
"...");
Parent::initPersistFields();
}
void afxCollisionEventData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(method_name);
stream->writeString(script_data);
if (stream->writeFlag(gen_trigger))
stream->write(trigger_bit);
}
void afxCollisionEventData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
method_name = stream->readSTString();
script_data = stream->readSTString();
gen_trigger = stream->readFlag();
if (gen_trigger)
stream->read(&trigger_bit);
else
trigger_bit = 0;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,59 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_COLLISION_EVENT_H_
#define _AFX_COLLISION_EVENT_H_
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxCollisionEventData
struct afxCollisionEventData : public GameBaseData
{
typedef GameBaseData Parent;
public:
StringTableEntry method_name;
StringTableEntry script_data;
bool gen_trigger;
U8 trigger_bit;
public:
/*C*/ afxCollisionEventData();
/*C*/ afxCollisionEventData(const afxCollisionEventData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxCollisionEventData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_COLLISION_EVENT_H_

View file

@ -0,0 +1,41 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_COMPONENT_EFFECT_H_
#define _AFX_COMPONENT_EFFECT_H_
#include "core/util/tVector.h"
#include "afx/afxConstraint.h"
class afxComponentEffectData
{
public:
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs) { };
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_COMPONENT_EFFECT_H_

View file

@ -0,0 +1,93 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxConsoleMessage.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxConsoleMessageData
IMPLEMENT_CO_DATABLOCK_V1(afxConsoleMessageData);
ConsoleDocClass( afxConsoleMessageData,
"@brief A datablock that specifies a Console Message effect.\n\n"
"Console Message effects are useful for debugging purposes when you want to make sure that an effect with a certain kind "
"of timing is actually getting executed and for evaluating some kinds of field substitutions."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxConsoleMessageData::afxConsoleMessageData()
{
message_str = ST_NULLSTRING;
}
afxConsoleMessageData::afxConsoleMessageData(const afxConsoleMessageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
message_str = other.message_str;
}
#define myOffset(field) Offset(field, afxConsoleMessageData)
void afxConsoleMessageData::initPersistFields()
{
addField("message", TypeString, myOffset(message_str),
"A text message to be displayed when the effect is executed.");
Parent::initPersistFields();
}
bool afxConsoleMessageData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxConsoleMessageData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(message_str);
}
void afxConsoleMessageData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
message_str = stream->readSTString();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,54 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_CONSOLE_MESSAGE_H_
#define _AFX_CONSOLE_MESSAGE_H_
class afxConsoleMessageData : public GameBaseData
{
typedef GameBaseData Parent;
public:
StringTableEntry message_str;
public:
/*C*/ afxConsoleMessageData();
/*C*/ afxConsoleMessageData(const afxConsoleMessageData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxConsoleMessageData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_CONSOLE_MESSAGE_H_

View file

@ -0,0 +1,140 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxDamage.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxDamageData
IMPLEMENT_CO_DATABLOCK_V1(afxDamageData);
ConsoleDocClass( afxDamageData,
"@brief A datablock that specifies a Damage effect.\n\n"
"A Damage effect is useful for assigning damage with unusual timing that must be synchronized with other effects. They "
"can be used to deal direct damage, radius damage, and damage over time. Negative damage amounts can be used for "
"healing effects."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxDamageData::afxDamageData()
{
label = ST_NULLSTRING;
flavor = ST_NULLSTRING;
amount = 0;
repeats = 1;
ad_amount = 0;
radius = 0;
impulse = 0;
}
afxDamageData::afxDamageData(const afxDamageData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
label = other.label;
flavor = other.flavor;
amount = other.amount;
repeats = other.repeats;
ad_amount = other.ad_amount;
radius = other.radius;
impulse = other.impulse;
}
#define myOffset(field) Offset(field, afxDamageData)
void afxDamageData::initPersistFields()
{
addField("label", TypeString, myOffset(label),
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
"method. It can be used to identify which damage effect the damage came from in "
"cases where more than one damage effect is used in a single spell.");
addField("flavor", TypeString, myOffset(flavor),
"An arbitrary string which is passed as an argument to a spell's onDamage() script "
"method. It is used to classify a type of damage such as 'melee', 'magical', or "
"'fire'.");
addField("directDamage", TypeF32, myOffset(amount),
"An amount of direct damage to inflict on a target.");
addField("directDamageRepeats", TypeS8, myOffset(repeats),
"The number of times to inflict the damage specified by directDamage. Values "
"greater than 1 inflict damage over time, with the amount of directDamage "
"repeatedly dealt at evenly spaced intervals over the lifetime of the effect.");
addField("areaDamage", TypeF32, myOffset(ad_amount),
"An amount of area damage to inflict on a target. Objects within half the radius "
"receive full damage which then diminishes out to the full distance of "
"areaDamageRadius.");
addField("areaDamageRadius", TypeF32, myOffset(radius),
"Radius centered at the effect position in which damage will be applied.");
addField("areaDamageImpulse", TypeF32, myOffset(impulse),
"Specifies an amount of force to apply to damaged objects. Objects within half the "
"radius receive full impulse which then diminishes out to the full distance of "
"areaDamageRadius.");
Parent::initPersistFields();
}
bool afxDamageData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxDamageData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(label);
stream->writeString(flavor);
stream->write(amount);
stream->write(repeats);
stream->write(ad_amount);
stream->write(radius);
stream->write(impulse);
}
void afxDamageData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
label = stream->readSTString();
flavor = stream->readSTString();
stream->read(&amount);
stream->read(&repeats);
stream->read(&ad_amount);
stream->read(&radius);
stream->read(&impulse);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,63 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_DAMAGE_H_
#define _AFX_DAMAGE_H_
#include "afx/afxEffectDefs.h"
class afxDamageData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
StringTableEntry label;
StringTableEntry flavor;
F32 amount;
U8 repeats;
F32 ad_amount;
F32 radius;
F32 impulse;
public:
/*C*/ afxDamageData();
/*C*/ afxDamageData(const afxDamageData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxDamageData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_DAMAGE_H_

View file

@ -0,0 +1,116 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxFootSwitch.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxFootSwitchData
IMPLEMENT_CO_DATABLOCK_V1(afxFootSwitchData);
ConsoleDocClass( afxFootSwitchData,
"@brief A datablock that specifies a Foot Switch effect.\n\n"
"A Foot Switch effect is used to disable some or all of the standard built-in footstep effects generated by Player objects."
"\n\n"
"Stock Player objects generate footprint decals, footstep sounds, and puffs of particle dust in response to special "
"animation triggers embedded in the Player's dts model. With the help of Phase Effects, AFX can substitute alternatives for "
"these built-in effects. When this is done, it is often preferable to turn off some or all of the built-in footstep effects."
"\n\n"
"Foot Switch effects are only meaningful when the primary position constraint is a Player or Player-derived object."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxFootSwitchData::afxFootSwitchData()
{
override_all = false;
override_decals = false;
override_sounds = false;
override_dust = false;
}
afxFootSwitchData::afxFootSwitchData(const afxFootSwitchData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
override_all = other.override_all;
override_decals = other.override_decals;
override_sounds = other.override_sounds;
override_dust = other.override_dust;
}
#define myOffset(field) Offset(field, afxFootSwitchData)
void afxFootSwitchData::initPersistFields()
{
addField("overrideAll", TypeBool, myOffset(override_all),
"When true, all of a Player's footstep effects are turned off for the duration of "
"the foot-switch effect.");
addField("overrideDecals", TypeBool, myOffset(override_decals),
"Specifically selects whether the Player's footprint decals are enabled.");
addField("overrideSounds", TypeBool, myOffset(override_sounds),
"Specifically selects whether the Player's footstep sounds are enabled.");
addField("overrideDust", TypeBool, myOffset(override_dust),
"Specifically selects whether the Player's footstep puffs of dust are enabled.");
Parent::initPersistFields();
}
void afxFootSwitchData::packData(BitStream* stream)
{
Parent::packData(stream);
if (!stream->writeFlag(override_all))
{
stream->writeFlag(override_decals);
stream->writeFlag(override_sounds);
stream->writeFlag(override_dust);
}
}
void afxFootSwitchData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
override_all = stream->readFlag();
if (!override_all)
{
override_decals = stream->readFlag();
override_sounds = stream->readFlag();
override_dust = stream->readFlag();
}
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,56 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_FOOT_SWITCH_H_
#define _AFX_FOOT_SWITCH_H_
class afxFootSwitchData : public GameBaseData
{
typedef GameBaseData Parent;
public:
bool override_all;
bool override_decals;
bool override_sounds;
bool override_dust;
public:
/*C*/ afxFootSwitchData();
/*C*/ afxFootSwitchData(const afxFootSwitchData&, bool = false);
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxFootSwitchData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_FOOT_SWITCH_H_

View file

@ -0,0 +1,109 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "core/stream/bitStream.h"
#include "afx/ce/afxGuiController.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxGuiControllerData
IMPLEMENT_CO_DATABLOCK_V1(afxGuiControllerData);
ConsoleDocClass( afxGuiControllerData,
"@brief A datablock that specifies a Gui Controller effect.\n\n"
"A Gui Controller enables effect manipulation of pre-existing gui controls. With a Gui Controller effect, a regular gui control "
"is located by name, made visible during the lifetime of the effect, and potentially repositioned by projecting 3D constraint "
"positions into 2D screen space. In addition, when used with a progress-bar control, (GuiProgressCtrl, afxSpellCastBar, "
"afxStatusBar), the progress-bar will continuously reflect the elapsed progress of the effect over its lifetime."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxGuiControllerData::afxGuiControllerData()
{
control_name = ST_NULLSTRING;
preserve_pos = false;
ctrl_client_only = false;
}
afxGuiControllerData::afxGuiControllerData(const afxGuiControllerData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
control_name = other.control_name;
preserve_pos = other.preserve_pos;
ctrl_client_only = other.ctrl_client_only;
}
#define myOffset(field) Offset(field, afxGuiControllerData)
void afxGuiControllerData::initPersistFields()
{
addField("controlName", TypeString, myOffset(control_name),
"Specifies the name of an existing gui-control.");
addField("preservePosition", TypeBool, myOffset(preserve_pos),
"When true, the gui-control will retain its initial position, otherwise the "
"gui-control position will be continuously updated using a projection of the "
"3D constraint position into 2D screen coordinates.");
addField("controllingClientOnly", TypeBool, myOffset(ctrl_client_only),
"If true, the effect will only be applied to a gui-control on the client that "
"matches the controlling-client of the primary position constraint object.");
Parent::initPersistFields();
}
bool afxGuiControllerData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxGuiControllerData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(control_name);
stream->writeFlag(preserve_pos);
stream->writeFlag(ctrl_client_only);
}
void afxGuiControllerData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
control_name = stream->readSTString();
preserve_pos = stream->readFlag();
ctrl_client_only = stream->readFlag();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,58 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_GUI_CONTROLLER_H_
#define _AFX_GUI_CONTROLLER_H_
#include "afx/afxEffectDefs.h"
class afxGuiControllerData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
StringTableEntry control_name;
bool preserve_pos;
bool ctrl_client_only;
public:
/*C*/ afxGuiControllerData();
/*C*/ afxGuiControllerData(const afxGuiControllerData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxGuiControllerData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_GUI_CONTROLLER_H_

View file

@ -0,0 +1,103 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "core/stream/bitStream.h"
#include "afx/ce/afxGuiText.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxGuiTextData
IMPLEMENT_CO_DATABLOCK_V1(afxGuiTextData);
ConsoleDocClass( afxGuiTextData,
"@brief A datablock that specifies a Gui Text effect.\n\n"
"A Gui Text effect, with the help of an existing afxGuiTextHud, can be used to display 2D text effects on the Gui Canvas. "
"Essentially, using Gui Text effects with an afxGuiTextHud is like using the stock GuiShapeNameHud, but with the ability "
"to make additional text elements come and go as effects constrained to the projection of 3D positions onto the 2D screen."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxGuiTextData::afxGuiTextData()
{
text_str = ST_NULLSTRING;
text_clr.set(1,1,1,1);
}
afxGuiTextData::afxGuiTextData(const afxGuiTextData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
text_str = other.text_str;
text_clr = other.text_clr;
}
#define myOffset(field) Offset(field, afxGuiTextData)
void afxGuiTextData::initPersistFields()
{
addField("text", TypeString, myOffset(text_str),
"The literal text to display on the afxGuiTextHud. The center of the text will be "
"placed at the projection of the 3D constraint position into 2D screen space.\n"
"If the text field is set to the special string, '#shapeName', the shape name of the "
"primary position constraint object will be used. (This is only meaningful if the "
"constraint source is a ShapeBase-derived object.)");
addField("color", TypeColorF, myOffset(text_clr),
"A color value for the text label.");
Parent::initPersistFields();
}
bool afxGuiTextData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxGuiTextData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(text_str);
stream->write(text_clr);
}
void afxGuiTextData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
text_str = stream->readSTString();
stream->read(&text_clr);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,57 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_GUI_TEXT_H_
#define _AFX_GUI_TEXT_H_
#include "afx/afxEffectDefs.h"
class afxGuiTextData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
StringTableEntry text_str;
LinearColorF text_clr;
public:
/*C*/ afxGuiTextData();
/*C*/ afxGuiTextData(const afxGuiTextData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxGuiTextData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_GUI_TEXT_H_

View file

@ -0,0 +1,41 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxLight.h"
IMPLEMENT_CO_DATABLOCK_V1(afxLightData);
ConsoleDocClass( afxLightData,
"@brief afxLightData is a legacy datablock which is not supported for T3D.\n\n"
"In T3D, instead of afxLightData, use afxT3DPointLightData or afxT3DSpotLightData.\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,38 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_LIGHT_H_
#define _AFX_LIGHT_H_
struct afxLightData : public GameBaseData
{
typedef GameBaseData Parent;
DECLARE_CONOBJECT(afxLightData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_LIGHT_H_

View file

@ -0,0 +1,243 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "T3D/lightAnimData.h"
#include "afx/ce/afxLightBase_T3D.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxT3DLightBaseData
IMPLEMENT_CO_DATABLOCK_V1(afxT3DLightBaseData);
ConsoleDocClass( afxT3DLightBaseData,
"@brief A datablock baseclass for afxT3DPointLightData and afxT3DSpotLightData.\n\n"
"Not intended to be used directly, afxT3DLightBaseData exists to provide base member variables and generic functionality "
"for the derived classes afxT3DPointLightData and afxT3DSpotLightData."
"\n\n"
"@see afxT3DPointLightData\n\n"
"@see afxT3DSpotLightData\n\n"
"@see PointLight\n\n"
"@see SpotLight\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxT3DLightBaseData::afxT3DLightBaseData()
: mIsEnabled( true ),
mColor( LinearColorF::WHITE ),
mBrightness( 1.0f ),
mCastShadows( false ),
mPriority( 1.0f ),
mAnimationData( NULL ),
mFlareData( NULL ),
mFlareScale( 1.0f )
{
mLocalRenderViz = false;
// marked true if datablock ids need to
// be converted into pointers
do_id_convert = false;
}
afxT3DLightBaseData::afxT3DLightBaseData(const afxT3DLightBaseData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
mIsEnabled = other.mIsEnabled;
mColor = other.mColor;
mBrightness = other.mBrightness;
mCastShadows = other.mCastShadows;
mPriority = other.mPriority;
mAnimationData = other.mAnimationData;
mAnimState = other.mAnimState;
mFlareData = other.mFlareData;
mFlareScale = other.mFlareScale;
mLocalRenderViz = other.mLocalRenderViz;
do_id_convert = other.do_id_convert;
}
//
// NOTE: keep this as consistent as possible with LightBase::initPersistFields()
//
void afxT3DLightBaseData::initPersistFields()
{
// We only add the basic lighting options that all lighting
// systems would use... the specific lighting system options
// are injected at runtime by the lighting system itself.
addGroup( "Light" );
addField( "isEnabled", TypeBool, Offset( mIsEnabled, afxT3DLightBaseData ),
"Enables/Disables the object rendering and functionality in the scene.");
addField( "color", TypeColorF, Offset( mColor, afxT3DLightBaseData ),
"Changes the base color hue of the light.");
addField( "brightness", TypeF32, Offset( mBrightness, afxT3DLightBaseData ),
"Adjusts the lights power, 0 being off completely.");
addField( "castShadows", TypeBool, Offset( mCastShadows, afxT3DLightBaseData ),
"Enables/disables shadow casts by this light.");
addField( "priority", TypeF32, Offset( mPriority, afxT3DLightBaseData ),
"Used for sorting of lights by the light manager. Priority determines if a light "
"has a stronger effect than, those with a lower value");
addField( "localRenderViz", TypeBool, Offset( mLocalRenderViz, afxT3DLightBaseData ),
"Enables/disables a semi-transparent geometry to help visualize the light's "
"range and placement.");
endGroup( "Light" );
addGroup( "Light Animation" );
addField( "animate", TypeBool, Offset( mAnimState.active, afxT3DLightBaseData ),
"Toggles animation for the light on and off");
addField( "animationType", TYPEID<LightAnimData>(), Offset( mAnimationData, afxT3DLightBaseData ),
"Datablock containing light animation information (LightAnimData)");
addField( "animationPeriod", TypeF32, Offset( mAnimState.animationPeriod, afxT3DLightBaseData ),
"The length of time in seconds for a single playback of the light animation");
addField( "animationPhase", TypeF32, Offset( mAnimState.animationPhase, afxT3DLightBaseData ),
"The phase used to offset the animation start time to vary the animation of "
"nearby lights.");
endGroup( "Light Animation" );
addGroup( "Misc" );
addField( "flareType", TYPEID<LightFlareData>(), Offset( mFlareData, afxT3DLightBaseData ),
"Datablock containing light flare information (LightFlareData)");
addField( "flareScale", TypeF32, Offset( mFlareScale, afxT3DLightBaseData ),
"Globally scales all features of the light flare");
endGroup( "Misc" );
/*
// Now inject any light manager specific fields.
LightManager::initLightFields();
*/
// We do the parent fields at the end so that
// they show up that way in the inspector.
Parent::initPersistFields();
}
bool afxT3DLightBaseData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxT3DLightBaseData::packData(BitStream* stream)
{
Parent::packData(stream);
// note: BitStream's overloaded write() for LinearColorF will convert
// to ColorI for transfer and then back to LinearColorF. This is fine
// for most color usage but for lighting colors we want to preserve
// "pushed" color values which may be greater than 1.0 so the color
// is instead sent as individual color primaries.
stream->write( mColor.red );
stream->write( mColor.green );
stream->write( mColor.blue );
stream->write( mBrightness );
stream->writeFlag( mCastShadows );
stream->write( mAnimState.animationPeriod );
stream->write( mAnimState.animationPhase );
stream->write( mFlareScale );
writeDatablockID(stream, mAnimationData, packed);
writeDatablockID(stream, mFlareData, packed);
}
void afxT3DLightBaseData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read( &mColor.red );
stream->read( &mColor.green );
stream->read( &mColor.blue );
mColor.alpha = 1.0f;
stream->read( &mBrightness );
mCastShadows = stream->readFlag();
stream->read( &mAnimState.animationPeriod );
stream->read( &mAnimState.animationPhase );
stream->read( &mFlareScale );
mAnimationData = (LightAnimData*) readDatablockID(stream);
mFlareData = (LightFlareData*) readDatablockID(stream);
do_id_convert = true;
}
bool afxT3DLightBaseData::preload(bool server, String &errorStr)
{
if (!Parent::preload(server, errorStr))
return false;
// Resolve objects transmitted from server
if (!server)
{
if (do_id_convert)
{
SimObjectId anim_id = SimObjectId((uintptr_t)mAnimationData);
if (anim_id != 0)
{
// try to convert id to pointer
if (!Sim::findObject(anim_id, mAnimationData))
{
Con::errorf(ConsoleLogEntry::General,
"afxT3DLightBaseData::preload() -- bad datablockId: 0x%x (animationType)",
anim_id);
}
}
SimObjectId flare_id = SimObjectId((uintptr_t)mFlareData);
if (flare_id != 0)
{
// try to convert id to pointer
if (!Sim::findObject(flare_id, mFlareData))
{
Con::errorf(ConsoleLogEntry::General,
"afxT3DLightBaseData::preload() -- bad datablockId: 0x%x (flareType)",
flare_id);
}
}
do_id_convert = false;
}
}
return true;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,73 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_T3D_LIGHT_BASE_H_
#define _AFX_T3D_LIGHT_BASE_H_
#include "T3D/lightBase.h"
class LightAnimData;
class LightFlareData;
class afxT3DLightBaseData : public GameBaseData
{
typedef GameBaseData Parent;
public:
bool mIsEnabled;
LinearColorF mColor;
F32 mBrightness;
bool mCastShadows;
F32 mPriority;
LightAnimData* mAnimationData;
LightAnimState mAnimState;
bool mLocalRenderViz;
LightFlareData* mFlareData;
F32 mFlareScale;
bool do_id_convert;
public:
/*C*/ afxT3DLightBaseData();
/*C*/ afxT3DLightBaseData(const afxT3DLightBaseData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool preload(bool server, String &errorStr);
static void initPersistFields();
DECLARE_CONOBJECT(afxT3DLightBaseData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_T3D_LIGHT_BASE_H_

View file

@ -0,0 +1,127 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "lighting/lightInfo.h"
#include "T3D/projectile.h"
#include "afx/ce/afxMachineGun.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxMachineGunData
IMPLEMENT_CO_DATABLOCK_V1(afxMachineGunData);
ConsoleDocClass( afxMachineGunData,
"@brief A datablock that specifies a Machine Gun effect.\n\n"
"Machine Gun is a simple but useful effect for rapidly shooting standard Torque Projectile objects. For performance "
"reasons, keep in mind that each bullet is a separate Projectile object, which is not a very lightweight object."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxMachineGunData::afxMachineGunData()
{
projectile_data = 0;
rounds_per_minute = 60;
}
afxMachineGunData::afxMachineGunData(const afxMachineGunData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
projectile_data = other.projectile_data;
rounds_per_minute = other.rounds_per_minute;
}
#define myOffset(field) Offset(field, afxMachineGunData)
void afxMachineGunData::initPersistFields()
{
addField("projectile", TYPEID<ProjectileData>(), myOffset(projectile_data),
"A ProjectileData datablock describing the projectile to be launched.");
addField("roundsPerMinute", TypeS32, myOffset(rounds_per_minute),
"Specifies the number of projectiles fired over a minute of time. A value of 1200 "
"will create 20 projectiles per second.\n"
"Sample values for real machine guns:\n"
" AK-47 = 600, M16 = 750-900, UZI = 600");
Parent::initPersistFields();
// disallow some field substitutions
disableFieldSubstitutions("projectile");
}
bool afxMachineGunData::onAdd()
{
if (Parent::onAdd() == false)
return false;
if (projectile_data)
{
if (getId() >= DataBlockObjectIdFirst && getId() <= DataBlockObjectIdLast)
{
SimObjectId pid = projectile_data->getId();
if (pid < DataBlockObjectIdFirst || pid > DataBlockObjectIdLast)
{
Con::errorf(ConsoleLogEntry::General,"afxMachineGunData: bad ProjectileData datablock.");
return false;
}
}
}
return true;
}
void afxMachineGunData::packData(BitStream* stream)
{
Parent::packData(stream);
if (stream->writeFlag(projectile_data))
stream->writeRangedU32(projectile_data->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);
stream->write(rounds_per_minute);
}
void afxMachineGunData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
if (stream->readFlag())
{
SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
Sim::findObject(id, projectile_data);
}
stream->read(&rounds_per_minute);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,59 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_MACHINE_GUN_H_
#define _AFX_MACHINE_GUN_H_
#include "afx/afxEffectDefs.h"
class ProjectileData;
class afxMachineGunData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
ProjectileData* projectile_data;
S32 rounds_per_minute;
public:
/*C*/ afxMachineGunData();
/*C*/ afxMachineGunData(const afxMachineGunData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxMachineGunData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_MACHINE_GUN_H_

View file

@ -0,0 +1,770 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "T3D/objectTypes.h"
#include "T3D/gameBase/gameProcess.h"
#include "core/resourceManager.h"
#include "sim/netConnection.h"
#include "scene/sceneRenderState.h"
#include "scene/sceneManager.h"
#include "ts/tsShapeInstance.h"
#include "ts/tsMaterialList.h"
#include "afx/ce/afxModel.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxModelData
IMPLEMENT_CO_DATABLOCK_V1(afxModelData);
ConsoleDocClass( afxModelData,
"@brief A datablock that specifies a Model effect.\n\n"
"A Model effect is a lightweight client-only geometry object useful for effect-driven props."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxModelData::afxModelData()
{
shapeName = ST_NULLSTRING;
sequence = ST_NULLSTRING;
seq_rate = 1.0f;
seq_offset = 0.0f;
alpha_mult = 1.0f;
use_vertex_alpha = false;
force_on_material_flags = 0;
force_off_material_flags = 0;
texture_filtering = true;
fog_mult = 1.0f;
remap_txr_tags = ST_NULLSTRING;
remap_buffer = 0;
overrideLightingOptions = false;
receiveSunLight = true;
receiveLMLighting = true;
useAdaptiveSelfIllumination = false;
useCustomAmbientLighting = false;
customAmbientForSelfIllumination = false;
customAmbientLighting = LinearColorF(0.0f, 0.0f, 0.0f);
shadowEnable = false;
shadowSize = 128;
shadowMaxVisibleDistance = 80.0f;
shadowProjectionDistance = 10.0f;
shadowSphereAdjust = 1.0;
}
afxModelData::afxModelData(const afxModelData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
shapeName = other.shapeName;
shape = other.shape; // --
sequence = other.sequence;
seq_rate = other.seq_rate;
seq_offset = other.seq_offset;
alpha_mult = other.alpha_mult;
use_vertex_alpha = other.use_vertex_alpha;
force_on_material_flags = other.force_on_material_flags;
force_off_material_flags = other.force_off_material_flags;
texture_filtering = other.texture_filtering;
fog_mult = other.fog_mult;
remap_txr_tags = other.remap_txr_tags;
remap_buffer = other.remap_buffer;
overrideLightingOptions = other.overrideLightingOptions;
receiveSunLight = other.receiveSunLight;
receiveLMLighting = other.receiveLMLighting;
useAdaptiveSelfIllumination = other.useAdaptiveSelfIllumination;
useCustomAmbientLighting = other.useCustomAmbientLighting;
customAmbientForSelfIllumination = other.customAmbientForSelfIllumination;
customAmbientLighting = other.customAmbientLighting;
shadowEnable = other.shadowEnable;
}
afxModelData::~afxModelData()
{
if (remap_buffer)
dFree(remap_buffer);
}
bool afxModelData::preload(bool server, String &errorStr)
{
if (Parent::preload(server, errorStr) == false)
return false;
// don't need to do this stuff on the server
if (server)
return true;
if (shapeName != ST_NULLSTRING && !shape)
{
shape = ResourceManager::get().load(shapeName);
if (!shape)
{
errorStr = String::ToString("afxModelData::load: Failed to load shape \"%s\"", shapeName);
return false;
}
// just parse up the string and collect the remappings in txr_tag_remappings.
if (remap_txr_tags != ST_NULLSTRING)
{
txr_tag_remappings.clear();
if (remap_buffer)
dFree(remap_buffer);
remap_buffer = dStrdup(remap_txr_tags);
char* remap_token = dStrtok(remap_buffer, " \t");
while (remap_token != NULL)
{
char* colon = dStrchr(remap_token, ':');
if (colon)
{
*colon = '\0';
txr_tag_remappings.increment();
txr_tag_remappings.last().old_tag = remap_token;
txr_tag_remappings.last().new_tag = colon+1;
}
remap_token = dStrtok(NULL, " \t");
}
}
// this little hack messes things up when remapping texture tags
if (txr_tag_remappings.size() == 0)
{
// this little hack forces the textures to preload
TSShapeInstance* pDummy = new TSShapeInstance(shape);
delete pDummy;
}
}
return true;
}
#define myOffset(field) Offset(field, afxModelData)
void afxModelData::initPersistFields()
{
addField("shapeFile", TypeFilename, myOffset(shapeName),
"The name of a .dts format file to use for the model.");
addField("sequence", TypeFilename, myOffset(sequence),
"The name of an animation sequence to play in the model.");
addField("sequenceRate", TypeF32, myOffset(seq_rate),
"The rate of playback for the sequence.");
addField("sequenceOffset", TypeF32, myOffset(seq_offset),
"An offset in seconds indicating a starting point for the animation sequence "
"specified by the sequence field. A rate of 1.0 (rather than sequenceRate) is used "
"to convert from seconds to the thread offset.");
addField("alphaMult", TypeF32, myOffset(alpha_mult),
"An alpha multiplier used to set maximum opacity of the model.");
addField("fogMult", TypeF32, myOffset(fog_mult),
"");
addField("remapTextureTags", TypeString, myOffset(remap_txr_tags),
"Rename one or more texture tags in the model. Texture tags are what link a "
"model's textures to materials.\n"
"Field should be a string containing space-separated remapping tokens. A remapping "
"token is two names separated by a colon, ':'. The first name should be a texture-tag "
"that exists in the model, while the second is a new name to replace it. The string "
"can have any number of remapping tokens as long as the total string length does not "
"exceed 255.");
addField("shadowEnable", TypeBool, myOffset(shadowEnable),
"Sets whether the model casts a shadow.");
addField("useVertexAlpha", TypeBool, myOffset(use_vertex_alpha),
"deprecated");
addField("forceOnMaterialFlags", TypeS32, myOffset(force_on_material_flags),
"deprecated");
addField("forceOffMaterialFlags", TypeS32, myOffset(force_off_material_flags),
"deprecated");
addField("textureFiltering", TypeBool, myOffset(texture_filtering),
"deprecated");
addField("overrideLightingOptions", TypeBool, myOffset(overrideLightingOptions),
"deprecated");
addField("receiveSunLight", TypeBool, myOffset(receiveSunLight),
"");
addField("receiveLMLighting", TypeBool, myOffset(receiveLMLighting),
"deprecated");
addField("useAdaptiveSelfIllumination", TypeBool, myOffset(useAdaptiveSelfIllumination),
"deprecated");
addField("useCustomAmbientLighting", TypeBool, myOffset(useCustomAmbientLighting),
"deprecated");
addField("customAmbientSelfIllumination", TypeBool, myOffset(customAmbientForSelfIllumination),
"deprecated");
addField("customAmbientLighting", TypeColorF, myOffset(customAmbientLighting),
"deprecated");
addField("shadowSize", TypeS32, myOffset(shadowSize),
"deprecated");
addField("shadowMaxVisibleDistance", TypeF32, myOffset(shadowMaxVisibleDistance),
"deprecated");
addField("shadowProjectionDistance", TypeF32, myOffset(shadowProjectionDistance),
"deprecated");
addField("shadowSphereAdjust", TypeF32, myOffset(shadowSphereAdjust),
"deprecated");
Parent::initPersistFields();
// Material Flags
Con::setIntVariable("$MaterialFlags::S_Wrap", TSMaterialList::S_Wrap);
Con::setIntVariable("$MaterialFlags::T_Wrap", TSMaterialList::T_Wrap);
Con::setIntVariable("$MaterialFlags::Translucent", TSMaterialList::Translucent);
Con::setIntVariable("$MaterialFlags::Additive", TSMaterialList::Additive);
Con::setIntVariable("$MaterialFlags::Subtractive", TSMaterialList::Subtractive);
Con::setIntVariable("$MaterialFlags::SelfIlluminating", TSMaterialList::SelfIlluminating);
Con::setIntVariable("$MaterialFlags::NeverEnvMap", TSMaterialList::NeverEnvMap);
Con::setIntVariable("$MaterialFlags::NoMipMap", TSMaterialList::NoMipMap);
Con::setIntVariable("$MaterialFlags::MipMap_ZeroBorder", TSMaterialList::MipMap_ZeroBorder);
Con::setIntVariable("$MaterialFlags::AuxiliaryMap", TSMaterialList::AuxiliaryMap);
#if defined(AFX_CAP_AFXMODEL_TYPE)
Con::setIntVariable("$TypeMasks::afxModelObjectType", afxModelObjectType);
#endif
}
void afxModelData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(shapeName);
stream->writeString(sequence);
stream->write(seq_rate);
stream->write(seq_offset);
stream->write(alpha_mult);
stream->write(use_vertex_alpha);
stream->write(force_on_material_flags);
stream->write(force_off_material_flags);
stream->writeFlag(texture_filtering);
stream->write(fog_mult);
stream->writeString(remap_txr_tags);
stream->writeFlag(overrideLightingOptions);
stream->writeFlag(receiveSunLight);
stream->writeFlag(useAdaptiveSelfIllumination);
stream->writeFlag(useCustomAmbientLighting);
stream->writeFlag(customAmbientForSelfIllumination);
stream->write(customAmbientLighting);
stream->writeFlag(receiveLMLighting);
stream->writeFlag(shadowEnable);
stream->write(shadowSize);
stream->write(shadowMaxVisibleDistance);
stream->write(shadowProjectionDistance);
stream->write(shadowSphereAdjust);
}
void afxModelData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
shapeName = stream->readSTString();
sequence = stream->readSTString();
stream->read(&seq_rate);
stream->read(&seq_offset);
stream->read(&alpha_mult);
stream->read(&use_vertex_alpha);
stream->read(&force_on_material_flags);
stream->read(&force_off_material_flags);
texture_filtering = stream->readFlag();
stream->read(&fog_mult);
remap_txr_tags = stream->readSTString();
overrideLightingOptions = stream->readFlag();
receiveSunLight = stream->readFlag();
useAdaptiveSelfIllumination = stream->readFlag();
useCustomAmbientLighting = stream->readFlag();
customAmbientForSelfIllumination = stream->readFlag();
stream->read(&customAmbientLighting);
receiveLMLighting = stream->readFlag();
shadowEnable = stream->readFlag();
stream->read(&shadowSize);
stream->read(&shadowMaxVisibleDistance);
stream->read(&shadowProjectionDistance);
stream->read(&shadowSphereAdjust);
}
void afxModelData::onPerformSubstitutions()
{
if (shapeName != ST_NULLSTRING)
{
shape = ResourceManager::get().load(shapeName);
if (!shape)
{
Con::errorf("afxModelData::onPerformSubstitutions: Failed to load shape \"%s\"", shapeName);
return;
}
// REMAP-TEXTURE-TAGS ISSUES?
}
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxModel
IMPLEMENT_CO_NETOBJECT_V1(afxModel);
ConsoleDocClass( afxModel,
"@brief A Model effect as defined by an afxModelData datablock.\n\n"
"A Model effect is a lightweight client-only geometry object useful for effect-driven "
"props.\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxModel::afxModel()
{
mTypeMask |= DynamicShapeObjectType;
#if defined(AFX_CAP_AFXMODEL_TYPE)
mTypeMask |= afxModelObjectType;
#endif
shape_inst = 0;
main_seq_thread = 0;
main_seq_id = -1;
seq_rate_factor = 1.0f;
last_anim_tag = 0;
seq_animates_vis = false;
fade_amt = 1.0f;
is_visible = true;
sort_priority = 0;
mNetFlags.set( IsGhost );
}
afxModel::~afxModel()
{
delete shape_inst;
}
void afxModel::setSequenceRateFactor(F32 factor)
{
seq_rate_factor = factor;
if (shape_inst != NULL && main_seq_thread != NULL)
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxModel::onNewDataBlock(GameBaseData* dptr, bool reload)
{
mDataBlock = dynamic_cast<afxModelData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
return false;
return true;
}
bool afxModel::onAdd()
{
// first check if we have a server connection, if we don't then this is on the server
// and we should exit, then check if the parent fails to add the object
NetConnection* conn = NetConnection::getConnectionToServer();
if (!conn || !Parent::onAdd())
return false;
// setup our bounding box
if (mDataBlock->shape)
mObjBox = mDataBlock->shape->bounds;
else
mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
// setup the shape instance and sequence
if (mDataBlock->shape)
{
if (/*isClientObject() && */mDataBlock->txr_tag_remappings.size() > 0)
{
// temporarily substitute material tags with alternates
TSMaterialList* mat_list = mDataBlock->shape->materialList;
if (mat_list)
{
for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++)
{
afxModelData::TextureTagRemapping* remap = &mDataBlock->txr_tag_remappings[i];
Vector<String> & mat_names = (Vector<String>&) mat_list->getMaterialNameList();
for (S32 j = 0; j < mat_names.size(); j++)
{
if (mat_names[j].compare(remap->old_tag, dStrlen(remap->old_tag), String::NoCase) == 0)
{
//Con::printf("REMAP TEXTURE TAG [%s] TO [%s]", remap->old_tag, remap->new_tag);
mat_names[j] = String(remap->new_tag);
mat_names[j].insert(0,'#');
break;
}
}
}
}
}
shape_inst = new TSShapeInstance(mDataBlock->shape);
if (true) // isClientObject())
{
shape_inst->cloneMaterialList();
// restore the material tags to original form
if (mDataBlock->txr_tag_remappings.size() > 0)
{
TSMaterialList* mat_list = mDataBlock->shape->materialList;
if (mat_list)
{
for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++)
{
afxModelData::TextureTagRemapping* remap = &mDataBlock->txr_tag_remappings[i];
Vector<String> & mat_names = (Vector<String>&) mat_list->getMaterialNameList();
for (S32 j = 0; j < mat_names.size(); j++)
{
if (mat_names[j].compare(remap->new_tag, dStrlen(remap->new_tag)) == 0)
{
//Con::printf("UNREMAP TEXTURE TAG [%s] TO [%s]", remap->new_tag, remap->old_tag);
mat_names[j] = String(remap->old_tag);
break;
}
}
}
}
}
}
if (mDataBlock->sequence == ST_NULLSTRING)
{
main_seq_thread = 0;
main_seq_id = -1;
}
else
{
// here we start the default animation sequence
TSShape* shape = shape_inst->getShape();
main_seq_id = shape->findSequence(mDataBlock->sequence);
if (main_seq_id != -1)
{
main_seq_thread = shape_inst->addThread();
F32 seq_pos = 0.0f;
if (mDataBlock->seq_offset > 0.0f && mDataBlock->seq_offset < shape_inst->getDuration(main_seq_thread))
seq_pos = mDataBlock->seq_offset / shape_inst->getDuration(main_seq_thread);
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
shape_inst->setSequence(main_seq_thread, main_seq_id, seq_pos);
seq_animates_vis = shape->sequences[main_seq_id].visMatters.testAll();
}
}
// deal with material changes
if (shape_inst && (mDataBlock->force_on_material_flags | mDataBlock->force_off_material_flags))
{
shape_inst->cloneMaterialList();
TSMaterialList* mats = shape_inst->getMaterialList();
if (mDataBlock->force_on_material_flags != 0)
{
for (U32 i = 0; i < mats->size(); i++)
mats->setFlags(i, mats->getFlags(i) | mDataBlock->force_on_material_flags);
}
if (mDataBlock->force_off_material_flags != 0)
{
for (U32 i = 0; i < mats->size(); i++)
mats->setFlags(i, mats->getFlags(i) & ~mDataBlock->force_off_material_flags);
}
}
}
resetWorldBox();
if (mDataBlock->shape)
{
// Scan out the collision hulls...
static const String sCollisionStr( "collision-" );
for (U32 i = 0; i < mDataBlock->shape->details.size(); i++)
{
const String &name = mDataBlock->shape->names[mDataBlock->shape->details[i].nameIndex];
if (name.compare( sCollisionStr, sCollisionStr.length(), String::NoCase ) == 0)
{
mCollisionDetails.push_back(i);
// The way LOS works is that it will check to see if there is a LOS detail that matches
// the the collision detail + 1 + MaxCollisionShapes (this variable name should change in
// the future). If it can't find a matching LOS it will simply use the collision instead.
// We check for any "unmatched" LOS's further down
mLOSDetails.increment();
char buff[128];
dSprintf(buff, sizeof(buff), "LOS-%d", i + 1 + 8/*MaxCollisionShapes*/);
U32 los = mDataBlock->shape->findDetail(buff);
if (los == -1)
mLOSDetails.last() = i;
else
mLOSDetails.last() = los;
}
}
// Snag any "unmatched" LOS details
static const String sLOSStr( "LOS-" );
for (U32 i = 0; i < mDataBlock->shape->details.size(); i++)
{
const String &name = mDataBlock->shape->names[mDataBlock->shape->details[i].nameIndex];
if (name.compare( sLOSStr, sLOSStr.length(), String::NoCase ) == 0)
{
// See if we already have this LOS
bool found = false;
for (U32 j = 0; j < mLOSDetails.size(); j++)
{
if (mLOSDetails[j] == i)
{
found = true;
break;
}
}
if (!found)
mLOSDetails.push_back(i);
}
}
// Compute the hull accelerators (actually, just force the shape to compute them)
for (U32 i = 0; i < mCollisionDetails.size(); i++)
shape_inst->getShape()->getAccelerator(mCollisionDetails[i]);
}
// tell engine the model exists
gClientSceneGraph->addObjectToScene(this);
removeFromProcessList();
ClientProcessList::get()->addObject(this);
conn->addObject(this);
return true;
}
void afxModel::onRemove()
{
mSceneManager->removeObjectFromScene(this);
getContainer()->removeObject(this);
Parent::onRemove();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
void afxModel::advanceTime(F32 dt)
{
if (main_seq_thread)
shape_inst->advanceTime(dt, main_seq_thread);
for (S32 i = 0; i < blend_clips.size(); i++)
shape_inst->advanceTime(dt, blend_clips[i].thread);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
void afxModel::prepRenderImage(SceneRenderState* state)
{
if (!is_visible || !shape_inst)
return;
// calculate distance to camera
Point3F cameraOffset;
getRenderTransform().getColumn(3, &cameraOffset);
cameraOffset -= state->getCameraPosition();
F32 dist = cameraOffset.len();
if (dist < 0.01f)
dist = 0.01f;
F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z));
shape_inst->setDetailFromDistance(state, dist*invScale);
if ( shape_inst->getCurrentDetail() < 0 )
return;
renderObject(state);
}
bool afxModel::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
{
if (shape_inst)
{
RayInfo shortest;
shortest.t = 1e8;
info->object = NULL;
if (mLOSDetails.size() > 0)
{
for (U32 i = 0; i < mLOSDetails.size(); i++)
{
shape_inst->animate(mLOSDetails[i]);
if (shape_inst->castRay(start, end, info, mLOSDetails[i]))
{
info->object = this;
if (info->t < shortest.t)
shortest = *info;
}
}
}
else
{
if (mCollisionDetails.size() > 0)
{
for (U32 i = 0; i < mCollisionDetails.size(); i++)
{
shape_inst->animate(mCollisionDetails[i]);
if (shape_inst->castRay(start, end, info, mCollisionDetails[i]))
{
info->object = this;
if (info->t < shortest.t)
shortest = *info;
}
}
}
}
if (info->object == this)
{
// Copy out the shortest time...
*info = shortest;
return true;
}
}
return false;
}
U32 afxModel::unique_anim_tag_counter = 1;
#define BAD_ANIM_ID 999999999
U32 afxModel::setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans)
{
if (!shape_inst)
return 0;
TSShape* shape = shape_inst->getShape();
S32 seq_id = shape->findSequence(clip);
if (seq_id == -1)
{
Con::errorf("afxModel::setAnimClip() -- failed to find a sequence matching the name, \"%s\".", clip);
return 0;
}
// JTF Note: test if this blend implementation is working
if (shape->sequences[seq_id].isBlend())
{
BlendThread blend_clip;
blend_clip.tag = ((unique_anim_tag_counter++) | 0x80000000);
blend_clip.thread = shape_inst->addThread();
shape_inst->setSequence(blend_clip.thread, seq_id, pos);
shape_inst->setTimeScale(blend_clip.thread, rate);
blend_clips.push_back(blend_clip);
return blend_clip.tag;
}
if (!main_seq_thread)
{
main_seq_thread = shape_inst->addThread();
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*rate);
shape_inst->setSequence(main_seq_thread, seq_id, pos);
seq_animates_vis = shape->sequences[seq_id].visMatters.testAll();
}
else
{
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*rate);
F32 transTime = (trans < 0) ? 0.25 : trans;
if (transTime > 0.0f)
shape_inst->transitionToSequence(main_seq_thread, seq_id, pos, transTime, true);
else
shape_inst->setSequence(main_seq_thread, seq_id, pos);
seq_animates_vis = shape->sequences[seq_id].visMatters.testAll();
}
last_anim_tag = unique_anim_tag_counter++;
return last_anim_tag;
}
void afxModel::resetAnimation(U32 tag)
{
// check if this is a blended clip
if ((tag & 0x80000000) != 0)
{
for (S32 i = 0; i < blend_clips.size(); i++)
{
if (blend_clips[i].tag == tag)
{
if (blend_clips[i].thread)
{
//Con::printf("DESTROY THREAD %d of %d tag=%d" , i, blend_clips.size(), tag & 0x7fffffff);
shape_inst->destroyThread(blend_clips[i].thread);
}
blend_clips.erase_fast(i);
break;
}
}
return;
}
if (tag != 0 && tag == last_anim_tag)
{
// restore original non-animated state
if (main_seq_id == -1)
{
shape_inst->destroyThread(main_seq_thread);
main_seq_thread = 0;
}
// restore original sequence
else
{
shape_inst->setTimeScale(main_seq_thread, seq_rate_factor*mDataBlock->seq_rate);
shape_inst->transitionToSequence(main_seq_thread, main_seq_id , 0.0f, 0.25f, true);
}
last_anim_tag = 0;
}
}
F32 afxModel::getAnimClipDuration(const char* clip)
{
if (!shape_inst)
return 0.0f;
TSShape* shape = shape_inst->getShape();
S32 seq_id = shape->findSequence(clip);
return (seq_id != -1) ? shape->sequences[seq_id].duration : 0.0f;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,166 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_MODEL_H_
#define _AFX_MODEL_H_
#include "renderInstance/renderPassManager.h"
class ParticleEmitterData;
class ParticleEmitter;
class ExplosionData;
class TSPartInstance;
class TSShapeInstance;
class TSShape;
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxModel Data
struct afxModelData : public GameBaseData
{
typedef GameBaseData Parent;
StringTableEntry shapeName;
StringTableEntry sequence;
F32 seq_rate;
F32 seq_offset;
F32 alpha_mult;
bool use_vertex_alpha;
U32 force_on_material_flags;
U32 force_off_material_flags;
bool texture_filtering;
F32 fog_mult;
struct TextureTagRemapping
{
char* old_tag;
char* new_tag;
};
char* remap_buffer;
Vector<TextureTagRemapping> txr_tag_remappings;
StringTableEntry remap_txr_tags;
Resource<TSShape> shape;
bool overrideLightingOptions;
bool receiveSunLight;
bool receiveLMLighting;
bool useAdaptiveSelfIllumination;
bool useCustomAmbientLighting;
bool customAmbientForSelfIllumination;
LinearColorF customAmbientLighting;
bool shadowEnable;
U32 shadowSize;
F32 shadowMaxVisibleDistance;
F32 shadowProjectionDistance;
F32 shadowSphereAdjust;
public:
/*C*/ afxModelData();
/*C*/ afxModelData(const afxModelData&, bool = false);
/*D*/ ~afxModelData();
bool preload(bool server, String &errorStr);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
virtual void onPerformSubstitutions();
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxModelData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxModel
class afxModel : public GameBase
{
typedef GameBase Parent;
private:
afxModelData* mDataBlock;
TSShapeInstance* shape_inst;
TSThread* main_seq_thread;
S32 main_seq_id;
F32 seq_rate_factor;
bool seq_animates_vis;
U32 last_anim_tag;
F32 fade_amt;
bool is_visible;
S8 sort_priority;
struct BlendThread
{
TSThread* thread;
U32 tag;
};
Vector<BlendThread> blend_clips;
static U32 unique_anim_tag_counter;
protected:
Vector<S32> mCollisionDetails;
Vector<S32> mLOSDetails;
bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
virtual void advanceTime(F32 dt);
virtual void prepRenderImage(SceneRenderState*);
void renderObject(SceneRenderState*);
virtual bool onAdd();
virtual void onRemove();
public:
/*C*/ afxModel();
/*D*/ ~afxModel();
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
void setFadeAmount(F32 amt) { fade_amt = amt; }
void setSequenceRateFactor(F32 factor);
void setSortPriority(S8 priority) { sort_priority = priority; }
const char* getShapeFileName() const { return mDataBlock->shapeName; }
void setVisibility(bool flag) { is_visible = flag; }
TSShape* getTSShape() { return mDataBlock->shape; }
TSShapeInstance* getTSShapeInstance() { return shape_inst; }
U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans);
void resetAnimation(U32 tag);
F32 getAnimClipDuration(const char* clip);
DECLARE_CONOBJECT(afxModel);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_MODEL_H_

View file

@ -0,0 +1,71 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "scene/sceneRenderState.h"
#include "scene/sceneManager.h"
#include "ts/tsShapeInstance.h"
#include "lighting/lightQuery.h"
#include "afx/ce/afxModel.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxModel::renderObject(SceneRenderState* state)
{
MatrixF proj = GFX->getProjectionMatrix();
RectI viewport = GFX->getViewport();
MatrixF world = GFX->getWorldMatrix();
GFX->pushWorldMatrix();
TSRenderState rdata;
rdata.setSceneState( state );
rdata.setFadeOverride(fade_amt*mDataBlock->alpha_mult);
// We might have some forward lit materials
// so pass down a query to gather lights.
LightQuery query;
query.init( getWorldSphere() );
rdata.setLightQuery( &query );
MatrixF mat = getRenderTransform();
mat.scale( mObjScale );
GFX->setWorldMatrix( mat );
shape_inst->animate();
shape_inst->render(rdata);
GFX->popWorldMatrix();
GFX->setProjectionMatrix( proj );
GFX->setViewport( viewport );
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,278 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/afxChoreographer.h"
#include "afx/ce/afxMooring.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxMooringData
IMPLEMENT_CO_DATABLOCK_V1(afxMooringData);
ConsoleDocClass( afxMooringData,
"@brief A datablock that specifies a Mooring effect.\n\n"
"A Mooring is an invisible effect object which can be positioned and oriented within a scene like other objects. Its main "
"purpose is to serve as a common mount point for other effects within the same choreographer. Typically one uses AFX "
"animation features to create movement for a Mooring and then other effects are bound to it using effect-to-effect "
"constraints (#effect)."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxMooringData::afxMooringData()
{
track_pos_only = false;
networking = SCOPE_ALWAYS;
display_axis_marker = false;
}
afxMooringData::afxMooringData(const afxMooringData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
track_pos_only = other.track_pos_only;
networking = other.networking;
display_axis_marker = other.display_axis_marker;
}
#define myOffset(field) Offset(field, afxMooringData)
void afxMooringData::initPersistFields()
{
addField("displayAxisMarker", TypeBool, myOffset(display_axis_marker),
"Specifies whether to display an axis to help visualize the position and orientation "
"of the mooring.");
addField("trackPosOnly", TypeBool, myOffset(track_pos_only),
"This field is only meaningful for networking settings of SCOPE_ALWAYS and GHOSTABLE. "
"In these cases, client moorings are ghosting a mooring on the server, and "
"trackPosOnly determines if the client moorings need to be updated with the server "
"mooring's complete transform or just its position. If only the position needs to be "
"tracked, setting trackPosOnly to true will reduce the network traffic.");
addField("networking", TypeS8, myOffset(networking),
"Specifies the networking model used for the mooring and should be one of: "
"$AFX::SCOPE_ALWAYS, $AFX::GHOSTABLE, $AFX::SERVER_ONLY, or $AFX::CLIENT_ONLY");
Parent::initPersistFields();
}
bool afxMooringData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxMooringData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(display_axis_marker);
stream->write(track_pos_only);
stream->write(networking);
}
void afxMooringData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&display_axis_marker);
stream->read(&track_pos_only);
stream->read(&networking);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxMooring
IMPLEMENT_CO_NETOBJECT_V1(afxMooring);
ConsoleDocClass( afxMooring,
"@brief A Mooring effect as defined by an afxMooringData datablock.\n\n"
"A Mooring is an invisible effect object which can be positioned and oriented within "
"a scene like other objects. Its main purpose is to serve as a common mount point for "
"other effects within the same choreographer. Typically one uses AFX animation "
"features to create movement for a Mooring and then other effects are bound to it "
"using effect-to-effect constraints (#effect).\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxMooring::afxMooring()
{
mNetFlags.set(Ghostable | ScopeAlways);
chor_id = 0;
hookup_with_chor = false;
ghost_cons_name = ST_NULLSTRING;
}
afxMooring::afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name)
{
if (networking & SCOPE_ALWAYS)
{
mNetFlags.clear();
mNetFlags.set(Ghostable | ScopeAlways);
}
else if (networking & GHOSTABLE)
{
mNetFlags.clear();
mNetFlags.set(Ghostable);
}
else if (networking & SERVER_ONLY)
{
mNetFlags.clear();
}
else // if (networking & CLIENT_ONLY)
{
mNetFlags.clear();
mNetFlags.set(IsGhost);
}
this->chor_id = chor_id;
hookup_with_chor = false;
this->ghost_cons_name = cons_name;
}
afxMooring::~afxMooring()
{
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxMooring::onNewDataBlock(GameBaseData* dptr, bool reload)
{
mDataBlock = dynamic_cast<afxMooringData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
return false;
return true;
}
void afxMooring::advanceTime(F32 dt)
{
Parent::advanceTime(dt);
if (hookup_with_chor)
{
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
if (chor)
{
chor->setGhostConstraintObject(this, ghost_cons_name);
hookup_with_chor = false;
}
}
Point3F pos = getRenderPosition();
}
U32 afxMooring::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(conn, mask, stream);
// InitialUpdate
if (stream->writeFlag(mask & InitialUpdateMask))
{
stream->write(chor_id);
stream->writeString(ghost_cons_name);
}
if (stream->writeFlag(mask & PositionMask))
{
if (mDataBlock->track_pos_only)
mathWrite(*stream, mObjToWorld.getPosition());
else
stream->writeAffineTransform(mObjToWorld);
}
return retMask;
}
//~~~~~~~~~~~~~~~~~~~~//
void afxMooring::unpackUpdate(NetConnection * conn, BitStream * stream)
{
Parent::unpackUpdate(conn, stream);
// InitialUpdate
if (stream->readFlag())
{
stream->read(&chor_id);
ghost_cons_name = stream->readSTString();
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
hookup_with_chor = true;
}
if (stream->readFlag())
{
if (mDataBlock->track_pos_only)
{
Point3F pos;
mathRead(*stream, &pos);
setPosition(pos);
}
else
{
MatrixF mat;
stream->readAffineTransform(&mat);
setTransform(mat);
setRenderTransform(mat);
}
}
}
void afxMooring::setTransform(const MatrixF& mat)
{
Parent::setTransform(mat);
setMaskBits(PositionMask);
}
bool afxMooring::onAdd()
{
if(!Parent::onAdd())
return false;
mObjBox = Box3F(Point3F(-0.5, -0.5, -0.5), Point3F(0.5, 0.5, 0.5));
addToScene();
return true;
}
void afxMooring::onRemove()
{
removeFromScene();
Parent::onRemove();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,102 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_MOORING_H_
#define _AFX_MOORING_H_
#include "renderInstance/renderPassManager.h"
#include "afx/afxEffectDefs.h"
class afxMooringData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
U8 networking;
bool track_pos_only;
bool display_axis_marker;
public:
/*C*/ afxMooringData();
/*C*/ afxMooringData(const afxMooringData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxMooringData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxMooring
class afxMooring : public GameBase, public afxEffectDefs
{
typedef GameBase Parent;
private:
afxMooringData* mDataBlock;
U32 chor_id;
bool hookup_with_chor;
StringTableEntry ghost_cons_name;
GFXStateBlockRef axis_sb;
void _renderAxisLines(ObjectRenderInst*, SceneRenderState*, BaseMatInstance*);
protected:
enum MaskBits
{
PositionMask = Parent::NextFreeMask,
NextFreeMask = Parent::NextFreeMask << 1
};
public:
/*C*/ afxMooring();
/*C*/ afxMooring(U32 networking, U32 chor_id, StringTableEntry cons_name);
/*D*/ ~afxMooring();
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
virtual void advanceTime(F32 dt);
virtual bool onAdd();
virtual void onRemove();
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
virtual void unpackUpdate(NetConnection*, BitStream*);
virtual void setTransform(const MatrixF&);
virtual void prepRenderImage(SceneRenderState*);
DECLARE_CONOBJECT(afxMooring);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_MOORING_H_

View file

@ -0,0 +1,88 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "gfx/gfxTransformSaver.h"
#include "gfx/primBuilder.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxMooring.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxMooring::prepRenderImage(SceneRenderState* state)
{
if (!mDataBlock->display_axis_marker)
return;
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
ri->renderDelegate.bind(this, &afxMooring::_renderAxisLines);
ri->type = RenderPassManager::RIT_ObjectTranslucent;
ri->translucentSort = true;
ri->defaultKey = (U32)(dsize_t)mDataBlock;
ri->sortDistSq = getWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
state->getRenderPass()->addInst(ri);
}
void afxMooring::_renderAxisLines(ObjectRenderInst *ri, SceneRenderState* state, BaseMatInstance* overrideMat)
{
if (overrideMat)
return;
if (axis_sb.isNull())
{
GFXStateBlockDesc desc;
desc.blendDefined = true;
desc.blendEnable = false;
desc.cullDefined = true;
desc.cullMode = GFXCullNone;
desc.ffLighting = false;
desc.zDefined = true;
desc.zWriteEnable = false;
axis_sb = GFX->createStateBlock(desc);
}
GFX->setStateBlock(axis_sb);
GFXTransformSaver saver;
GFX->multWorld(getRenderTransform());
PrimBuild::begin(GFXLineList, 6);
PrimBuild::color(LinearColorF(1.0, 0.0, 0.0));
PrimBuild::vertex3f(-0.5, 0.0, 0.0);
PrimBuild::vertex3f( 0.5, 0.0, 0.0);
PrimBuild::color(LinearColorF(0.0, 1.0, 0.0));
PrimBuild::vertex3f( 0.0, -0.5, 0.0);
PrimBuild::vertex3f( 0.0, 0.5, 0.0);
PrimBuild::color(LinearColorF(0.0, 0.0, 1.0));
PrimBuild::vertex3f( 0.0, 0.0, -0.5);
PrimBuild::vertex3f( 0.0, 0.0, 0.5);
PrimBuild::end();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,40 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxMultiLight.h"
IMPLEMENT_CO_DATABLOCK_V1(afxMultiLightData);
ConsoleDocClass( afxMultiLightData,
"@brief afxMultiLightData is a legacy datablock which is not supported for T3D.\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,38 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_MULTI_LIGHT_H_
#define _AFX_MULTI_LIGHT_H_
struct afxMultiLightData : public GameBaseData
{
typedef GameBaseData Parent;
DECLARE_CONOBJECT(afxMultiLightData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_MULTI_LIGHT_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,350 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_EMITTER_PARTICLE_H_
#define _AFX_EMITTER_PARTICLE_H_
#include "T3D/fx/particleEmitter.h"
class afxPathData;
class afxPath3D;
class afxParticleEmitterData : public ParticleEmitterData
{
typedef ParticleEmitterData Parent;
public:
// The afx enhanced particle emitter allows fading
// of particle color, size, velocity, and/or offset.
// Fading is controlled by a common value which is
// set externally using setFadeAmount().
//
bool fade_velocity;
bool fade_offset;
Point3F pe_vector;
// new -- consider vector in world space?
bool pe_vector_is_world;
// new -- transform paths?
StringTableEntry tpaths_string; //
Vector<afxPathData*> tPathDataBlocks; // datablocks for paths
Vector<U32> tPathDataBlockIds; // datablock IDs which correspond to the pathDataBlocks
public:
/*C*/ afxParticleEmitterData();
/*C*/ afxParticleEmitterData(const afxParticleEmitterData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool onAdd();
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxParticleEmitterData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// VECTOR
class afxParticleEmitterVectorData : public afxParticleEmitterData
{
typedef afxParticleEmitterData Parent;
public:
/*C*/ afxParticleEmitterVectorData();
/*C*/ afxParticleEmitterVectorData(const afxParticleEmitterVectorData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool onAdd();
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxParticleEmitterVectorData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// CONE
class afxParticleEmitterConeData : public afxParticleEmitterData
{
typedef afxParticleEmitterData Parent;
public:
F32 spread_min;
F32 spread_max;
public:
/*C*/ afxParticleEmitterConeData();
/*C*/ afxParticleEmitterConeData(const afxParticleEmitterConeData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool onAdd();
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxParticleEmitterConeData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// PATH
class afxParticleEmitterPathData : public afxParticleEmitterData
{
typedef afxParticleEmitterData Parent;
public:
enum PathOriginType
{
PATHEMIT_ORIGIN,
PATHEMIT_POINT,
PATHEMIT_VECTOR,
PATHEMIT_TANGENT
};
StringTableEntry epaths_string; //
Vector<afxPathData*> epathDataBlocks; // datablocks for paths
Vector<U32> epathDataBlockIds; // datablock IDs which correspond to the pathDataBlocks
U32 path_origin_type;
bool ground_conform;
bool ground_conform_terrain;
bool ground_conform_interiors;
F32 ground_conform_height;
public:
/*C*/ afxParticleEmitterPathData();
/*C*/ afxParticleEmitterPathData(const afxParticleEmitterPathData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool onAdd();
bool preload(bool server, String &errorStr);
virtual void onPerformSubstitutions();
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxParticleEmitterPathData);
DECLARE_CATEGORY("AFX");
};
typedef afxParticleEmitterPathData::PathOriginType afxParticleEmitterPath_OriginType;
DefineEnumType( afxParticleEmitterPath_OriginType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// DISC
class afxParticleEmitterDiscData : public afxParticleEmitterData
{
typedef afxParticleEmitterData Parent;
public:
F32 pe_radius_min;
F32 pe_radius_max;
public:
/*C*/ afxParticleEmitterDiscData();
/*C*/ afxParticleEmitterDiscData(const afxParticleEmitterDiscData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
bool onAdd();
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxParticleEmitterDiscData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxParticleEmitter : public ParticleEmitter
{
typedef ParticleEmitter Parent;
private:
afxParticleEmitterData* mDataBlock;
protected:
Point3F pe_vector, pe_vector_norm;
// these go with the "pathsTransform" field
Vector<afxPath3D*> tpaths;
Vector<F32> tpath_mults;
U32 n_tpath_points;
Point3F** tpath_points;
const SimObject* afx_owner;
void init_paths();
void cleanup_paths();
Particle* alloc_particle();
ParticleData* pick_particle_type();
void afx_emitParticles(const Point3F& point, const bool useLastPosition, const Point3F& velocity, const U32 numMilliseconds);
void afx_emitParticles(const Point3F& start, const Point3F& end, const Point3F& velocity, const U32 numMilliseconds);
void preCompute(const MatrixF& mat);
virtual void sub_particleUpdate(Particle*);
virtual void sub_preCompute(const MatrixF& mat)=0;
virtual void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx)=0;
public:
/*C*/ afxParticleEmitter();
/*D*/ ~afxParticleEmitter();
virtual void emitParticlesExt(const MatrixF& xfm, const Point3F& point, const Point3F& velocity, const U32 numMilliseconds);
afxParticleEmitterData* getDataBlock(){ return mDataBlock; }
void setAFXOwner(const SimObject* owner) { afx_owner = owner; }
bool onNewDataBlock(GameBaseData* dptr, bool reload);
bool onAdd();
void onRemove();
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// VECTOR
class afxParticleEmitterVector : public afxParticleEmitter
{
typedef afxParticleEmitter Parent;
private:
afxParticleEmitterVectorData* mDataBlock;
public:
/*C*/ afxParticleEmitterVector();
/*D*/ ~afxParticleEmitterVector();
bool onNewDataBlock(GameBaseData* dptr, bool reload);
protected:
void sub_preCompute(const MatrixF& mat);
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offse, S32 part_idxt);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// CONE
class afxParticleEmitterCone : public afxParticleEmitter
{
typedef afxParticleEmitter Parent;
private:
afxParticleEmitterData* mDataBlock;
Point3F cone_v, cone_s0, cone_s1;
public:
/*C*/ afxParticleEmitterCone();
/*D*/ ~afxParticleEmitterCone();
bool onNewDataBlock(GameBaseData* dptr, bool reload);
protected:
void sub_preCompute(const MatrixF& mat);
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// PATH
class afxParticleEmitterPath : public afxParticleEmitter
{
typedef afxParticleEmitter Parent;
private:
afxParticleEmitterPathData* mDataBlock;
Vector<afxPath3D*> epaths;
Vector<F32> epath_mults;
U32 n_epath_points;
Point3F** epath_points;
void init_paths();
void cleanup_paths();
void groundConformPoint(Point3F& point, const MatrixF& mat);
public:
/*C*/ afxParticleEmitterPath();
/*D*/ ~afxParticleEmitterPath();
bool onNewDataBlock(GameBaseData* dptr, bool reload);
protected:
bool onAdd();
void onRemove();
void sub_preCompute(const MatrixF& mat);
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// DISC
class afxParticleEmitterDisc : public afxParticleEmitter
{
typedef afxParticleEmitter Parent;
private:
afxParticleEmitterDiscData* mDataBlock;
Point3F disc_v, disc_r;
public:
/*C*/ afxParticleEmitterDisc();
/*D*/ ~afxParticleEmitterDisc();
bool onNewDataBlock(GameBaseData* dptr, bool reload);
protected:
void sub_preCompute(const MatrixF& mat);
void sub_addParticle(const Point3F& pos, const Point3F& vel, const U32 age_offset, S32 part_idx);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_EMITTER_PARTICLE_H_

View file

@ -0,0 +1,312 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/engineAPI.h"
#include "afx/afxEffectWrapper.h"
#include "afx/ce/afxPhraseEffect.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPhraseEffectData::ewValidator
//
// When an effect is added using "addEffect", this validator intercepts the value
// and adds it to the dynamic effects list.
//
void afxPhraseEffectData::ewValidator::validateType(SimObject* object, void* typePtr)
{
afxPhraseEffectData* eff_data = dynamic_cast<afxPhraseEffectData*>(object);
afxEffectBaseData** ew = (afxEffectBaseData**)(typePtr);
if (eff_data && ew)
{
eff_data->fx_list.push_back(*ew);
*ew = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPhraseEffectData
IMPLEMENT_CO_DATABLOCK_V1(afxPhraseEffectData);
ConsoleDocClass( afxPhraseEffectData,
"@brief A datablock that specifies a Phrase Effect, a grouping of other effects.\n\n"
"A Phrase Effect is a grouping or phrase of effects that do nothing until certain trigger events occur. It's like having a whole "
"Effectron organized as an individual effect."
"\n\n"
"Phrase effects can respond to a number of different kinds of triggers:\n"
" -- Player triggers such as footsteps, jumps, landings, and idle triggers.\n"
" -- Arbitrary animation triggers on dts-based scene objects.\n"
" -- Arbitrary trigger bits assigned to active choreographer objects."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxPhraseEffectData::afxPhraseEffectData()
{
duration = 0.0f;
n_loops = 1;
// dummy entry holds effect-wrapper pointer while a special validator
// grabs it and adds it to an appropriate effects list
dummy_fx_entry = NULL;
// marked true if datablock ids need to
// be converted into pointers
do_id_convert = false;
trigger_mask = 0;
match_type = MATCH_ANY;
match_state = STATE_ON;
phrase_type = PHRASE_TRIGGERED;
no_choreographer_trigs = false;
no_cons_trigs = false;
no_player_trigs = false;
on_trig_cmd = ST_NULLSTRING;
}
afxPhraseEffectData::afxPhraseEffectData(const afxPhraseEffectData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
duration = other.duration;
n_loops = other.n_loops;
dummy_fx_entry = other.dummy_fx_entry;
do_id_convert = other.do_id_convert; // --
trigger_mask = other.trigger_mask;
match_type = other.match_type;
match_state = other.match_state;
phrase_type = other.phrase_type;
no_choreographer_trigs = other.no_choreographer_trigs;
no_cons_trigs = other.no_cons_trigs;
no_player_trigs = other.no_player_trigs;
on_trig_cmd = other.on_trig_cmd;
// fx_list; // -- ??
}
void afxPhraseEffectData::reloadReset()
{
fx_list.clear();
}
ImplementEnumType( afxPhraseEffect_MatchType, "Possible phrase effect match types.\n" "@ingroup afxPhraseEffect\n\n" )
{ afxPhraseEffectData::MATCH_ANY, "any", "..." },
{ afxPhraseEffectData::MATCH_ALL, "all", "..." },
EndImplementEnumType;
ImplementEnumType( afxPhraseEffect_StateType, "Possible phrase effect state types.\n" "@ingroup afxPhraseEffect\n\n" )
{ afxPhraseEffectData::STATE_ON, "on", "..." },
{ afxPhraseEffectData::STATE_OFF, "off", "..." },
{ afxPhraseEffectData::STATE_ON_AND_OFF, "both", "..." },
EndImplementEnumType;
ImplementEnumType( afxPhraseEffect_PhraseType, "Possible phrase effect types.\n" "@ingroup afxPhraseEffect\n\n" )
{ afxPhraseEffectData::PHRASE_TRIGGERED, "triggered", "..." },
{ afxPhraseEffectData::PHRASE_CONTINUOUS, "continuous", "..." },
EndImplementEnumType;
#define myOffset(field) Offset(field, afxPhraseEffectData)
void afxPhraseEffectData::initPersistFields()
{
addField("duration", TypeF32, myOffset(duration),
"Specifies a duration for the phrase-effect. If set to infinity, the phrase-effect "
"needs to have a phraseType of continuous. Set infinite duration using "
"$AFX::INFINITE_TIME.");
addField("numLoops", TypeS32, myOffset(n_loops),
"Specifies the number of times the phrase-effect should loop. If set to infinity, "
"the phrase-effect needs to have a phraseType of continuous. Set infinite looping "
"using $AFX::INFINITE_REPEATS.");
addField("triggerMask", TypeS32, myOffset(trigger_mask),
"Sets which bits to consider in the current trigger-state which consists of 32 "
"trigger-bits combined from (possibly overlapping) player trigger bits, constraint "
"trigger bits, and choreographer trigger bits.");
addField("matchType", TYPEID<afxPhraseEffectData::MatchType>(), myOffset(match_type),
"Selects what combination of bits in triggerMask lead to a trigger. When set to "
"'any', any bit in triggerMask matching the current trigger-state will cause a "
"trigger. If set to 'all', every bit in triggerMask must match the trigger-state. "
"Possible values: any or all.");
addField("matchState", TYPEID<afxPhraseEffectData::StateType>(), myOffset(match_state),
"Selects which bit-state(s) of bits in the triggerMask to consider when comparing to "
"the current trigger-state. Possible values: on, off, or both.");
addField("phraseType", TYPEID<afxPhraseEffectData::PhraseType>(), myOffset(phrase_type),
"Selects between triggered and continuous types of phrases. When set to 'triggered', "
"the phrase-effect is triggered when the relevant trigger-bits change state. When set "
"to 'continuous', the phrase-effect will stay active as long as the trigger-bits "
"remain in a matching state. Possible values: triggered or continuous.");
addField("ignoreChoreographerTriggers", TypeBool, myOffset(no_choreographer_trigs),
"When true, trigger-bits on the choreographer will be ignored.");
addField("ignoreConstraintTriggers", TypeBool, myOffset(no_cons_trigs),
"When true, animation triggers from dts-based constraint source objects will be "
"ignored.");
addField("ignorePlayerTriggers", TypeBool, myOffset(no_player_trigs),
"When true, Player-specific triggers from Player-derived constraint source objects "
"will be ignored.");
addField("onTriggerCommand", TypeString, myOffset(on_trig_cmd),
"Like a field substitution statement without the leading '$$' token, this eval "
"statement will be executed when a trigger occurs. Any '%%' and '##' tokens will be "
"substituted.");
// effect lists
// for each of these, dummy_fx_entry is set and then a validator adds it to the appropriate effects list
static ewValidator emptyValidator(0);
addFieldV("addEffect", TYPEID< afxEffectBaseData >(), myOffset(dummy_fx_entry), &emptyValidator,
"A field macro which adds an effect wrapper datablock to a list of effects associated "
"with the phrase-effect's single phrase. Unlike other fields, addEffect follows an "
"unusual syntax. Order is important since the effects will resolve in the order they "
"are added to each list.");
Parent::initPersistFields();
// disallow some field substitutions
disableFieldSubstitutions("addEffect");
}
bool afxPhraseEffectData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxPhraseEffectData::pack_fx(BitStream* stream, const afxEffectList& fx, bool packed)
{
stream->writeInt(fx.size(), EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < fx.size(); i++)
writeDatablockID(stream, fx[i], packed);
}
void afxPhraseEffectData::unpack_fx(BitStream* stream, afxEffectList& fx)
{
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
}
void afxPhraseEffectData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(duration);
stream->write(n_loops);
stream->write(trigger_mask);
stream->writeInt(match_type, 1);
stream->writeInt(match_state, 2);
stream->writeInt(phrase_type, 1);
stream->writeFlag(no_choreographer_trigs);
stream->writeFlag(no_cons_trigs);
stream->writeFlag(no_player_trigs);
stream->writeString(on_trig_cmd);
pack_fx(stream, fx_list, packed);
}
void afxPhraseEffectData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&duration);
stream->read(&n_loops);
stream->read(&trigger_mask);
match_type = stream->readInt(1);
match_state = stream->readInt(2);
phrase_type = stream->readInt(1);
no_choreographer_trigs = stream->readFlag();
no_cons_trigs = stream->readFlag();
no_player_trigs = stream->readFlag();
on_trig_cmd = stream->readSTString();
do_id_convert = true;
unpack_fx(stream, fx_list);
}
bool afxPhraseEffectData::preload(bool server, String &errorStr)
{
if (!Parent::preload(server, errorStr))
return false;
// Resolve objects transmitted from server
if (!server)
{
if (do_id_convert)
{
for (S32 i = 0; i < fx_list.size(); i++)
{
SimObjectId db_id = SimObjectId((uintptr_t)fx_list[i]);
if (db_id != 0)
{
// try to convert id to pointer
if (!Sim::findObject(db_id, fx_list[i]))
{
Con::errorf(ConsoleLogEntry::General,
"afxPhraseEffectData::preload() -- bad datablockId: 0x%x",
db_id);
}
}
}
do_id_convert = false;
}
}
return true;
}
void afxPhraseEffectData::gather_cons_defs(Vector<afxConstraintDef>& defs)
{
afxConstraintDef::gather_cons_defs(defs, fx_list);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
DefineEngineMethod( afxPhraseEffectData, addEffect, void, ( afxEffectBaseData* effectData ),,
"Add a child effect to a phrase effect datablock. Argument can be an afxEffectWrappperData or an afxEffectGroupData.\n" )
{
if (!effectData)
{
Con::errorf("afxPhraseEffectData::addEffect() -- failed to resolve effect datablock.");
return;
}
object->fx_list.push_back(effectData);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,120 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_PHRASE_EFFECT_H_
#define _AFX_PHRASE_EFFECT_H_
#include "console/typeValidators.h"
#include "afx/ce/afxComponentEffect.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxEffectWrapper.h"
#include "afx/afxPhrase.h"
class afxPhraseEffectData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
{
typedef GameBaseData Parent;
class ewValidator : public TypeValidator
{
U32 id;
public:
ewValidator(U32 id) { this->id = id; }
void validateType(SimObject *object, void *typePtr);
};
bool do_id_convert;
public:
enum MatchType {
MATCH_ANY = 0,
MATCH_ALL = 1
};
enum StateType {
STATE_ON = 1,
STATE_OFF = 2,
STATE_ON_AND_OFF = STATE_ON | STATE_OFF
};
enum PhraseType
{
PHRASE_TRIGGERED = 0,
PHRASE_CONTINUOUS = 1
};
public:
afxEffectList fx_list;
F32 duration;
S32 n_loops;
U32 trigger_mask;
U32 match_type;
U32 match_state;
U32 phrase_type;
bool no_choreographer_trigs;
bool no_cons_trigs;
bool no_player_trigs;
StringTableEntry on_trig_cmd;
afxEffectBaseData* dummy_fx_entry;
private:
void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
void unpack_fx(BitStream* stream, afxEffectList& fx);
public:
/*C*/ afxPhraseEffectData();
/*C*/ afxPhraseEffectData(const afxPhraseEffectData&, bool = false);
virtual void reloadReset();
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool preload(bool server, String &errorStr);
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxPhraseEffectData);
DECLARE_CATEGORY("AFX");
};
typedef afxPhraseEffectData::MatchType afxPhraseEffect_MatchType;
DefineEnumType( afxPhraseEffect_MatchType );
typedef afxPhraseEffectData::StateType afxPhraseEffect_StateType;
DefineEnumType( afxPhraseEffect_StateType );
typedef afxPhraseEffectData::PhraseType afxPhraseEffect_PhraseType;
DefineEnumType( afxPhraseEffect_PhraseType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_PHRASE_EFFECT_H_

View file

@ -0,0 +1,114 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "T3D/physicalZone.h"
#include "afx/ce/afxPhysicalZone.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPhysicalZoneData
IMPLEMENT_CO_DATABLOCK_V1(afxPhysicalZoneData);
ConsoleDocClass( afxPhysicalZoneData,
"@brief A datablock that specifies a PhysicalZone effect.\n\n"
"A Physical Zone is a Torque effect that applies physical forces to Players and other movable objects that enter a specific "
"region of influence. AFX has enhanced Physical Zones by allowing orientation of vector forces and adding radial forces. "
"AFX has also optimized Physical Zone networking so that they can be constrained to moving objects for a variety of "
"effects including repelling and flying."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxPhysicalZoneData::afxPhysicalZoneData()
{
mVelocityMod = 1.0f;
mGravityMod = 1.0f;
mAppliedForce.zero();
mPolyhedron = ST_NULLSTRING;
force_type = PhysicalZone::VECTOR;
orient_force = false;
exclude_cons_obj = false;
}
afxPhysicalZoneData::afxPhysicalZoneData(const afxPhysicalZoneData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
mVelocityMod = other.mVelocityMod;
mGravityMod = other.mGravityMod;
mAppliedForce = other.mAppliedForce;
mPolyhedron = other.mPolyhedron;
force_type = other.force_type;
orient_force = other.orient_force;
exclude_cons_obj = other.exclude_cons_obj;
}
#define myOffset(field) Offset(field, afxPhysicalZoneData)
void afxPhysicalZoneData::initPersistFields()
{
addField("velocityMod", TypeF32, myOffset(mVelocityMod),
"A multiplier that biases the velocity of an object every tick it is within the "
"zone.");
addField("gravityMod", TypeF32, myOffset(mGravityMod),
"A multiplier that biases the influence of gravity on objects within the zone.");
addField("appliedForce", TypePoint3F, myOffset(mAppliedForce),
"A three-valued vector representing a directional force applied to objects withing "
"the zone.");
addField("polyhedron", TypeString, myOffset(mPolyhedron),
"Floating point values describing the outer bounds of the PhysicalZone's region of "
"influence.");
addField("forceType", TYPEID<PhysicalZone::ForceType>(), myOffset(force_type),
"This enumerated attribute defines the type of force used in the PhysicalZone. "
"Possible values: vector, sphere, or cylinder.");
addField("orientForce", TypeBool, myOffset(orient_force),
"Determines if the force can be oriented by the PhysicalZone's transform matrix.");
addField("excludeConstraintObject", TypeBool, myOffset(exclude_cons_obj),
"When true, an object used as the primary position constraint of a physical-zone "
"effect will not be influenced by the forces of the zone.");
Parent::initPersistFields();
}
void afxPhysicalZoneData::packData(BitStream* stream)
{
Parent::packData(stream);
}
void afxPhysicalZoneData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,65 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_PHYSICAL_ZONE_H_
#define _AFX_PHYSICAL_ZONE_H_
#include "T3D/gameBase/gameBase.h"
#include "T3D/trigger.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPhysicalZoneData
class afxPhysicalZoneData : public GameBaseData
{
typedef GameBaseData Parent;
public:
F32 mVelocityMod;
F32 mGravityMod;
Point3F mAppliedForce;
StringTableEntry mPolyhedron;
S32 force_type;
bool orient_force;
bool exclude_cons_obj;
public:
/*C*/ afxPhysicalZoneData();
/*C*/ afxPhysicalZoneData(const afxPhysicalZoneData&, bool = false);
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxPhysicalZoneData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_PHYSICAL_ZONE_H_

View file

@ -0,0 +1,140 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxPlayerMovement.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPlayerMovementData
IMPLEMENT_CO_DATABLOCK_V1(afxPlayerMovementData);
ConsoleDocClass( afxPlayerMovementData,
"@brief A datablock that specifies a Player Movement effect.\n\n"
"Player Movement effects are used to directly alter the speed and/or movement direction of Player objects. The Player "
"Movement effect is similar to the Player Puppet effect, but where puppet effects totally take over a Player's transformation "
"using the AFX constraint system, Player Movement effects 'steer' the player using the same mechanisms that allow "
"Player control from mouse and keyboard input. Another difference is that Player Movement effects only influence the "
"server instance of a Player. Puppet effects can influence both the Player's server instance and its client ghosts."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
static Point3F default_movement(F32_MAX, F32_MAX, F32_MAX);
afxPlayerMovementData::afxPlayerMovementData()
{
speed_bias = 1.0f;
movement = default_movement;
movement_op = OP_MULTIPLY;
}
afxPlayerMovementData::afxPlayerMovementData(const afxPlayerMovementData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
speed_bias = other.speed_bias;
movement = other.movement;
movement_op = other.movement_op;
}
ImplementEnumType( afxPlayerMovement_OpType, "Possible player movement operation types.\n" "@ingroup afxPlayerMovemen\n\n" )
{ afxPlayerMovementData::OP_ADD, "add", "..." },
{ afxPlayerMovementData::OP_MULTIPLY, "multiply", "..." },
{ afxPlayerMovementData::OP_REPLACE, "replace", "..." },
{ afxPlayerMovementData::OP_MULTIPLY, "mult", "..." },
EndImplementEnumType;
#define myOffset(field) Offset(field, afxPlayerMovementData)
void afxPlayerMovementData::initPersistFields()
{
addField("speedBias", TypeF32, myOffset(speed_bias),
"A floating-point multiplier that scales the constraint Player's movement speed.");
addField("movement", TypePoint3F, myOffset(movement),
"");
addField("movementOp", TYPEID<afxPlayerMovementData::OpType>(), myOffset(movement_op),
"Possible values: add, multiply, or replace.");
Parent::initPersistFields();
}
bool afxPlayerMovementData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxPlayerMovementData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(speed_bias);
if (stream->writeFlag(movement != default_movement))
{
stream->write(movement.x);
stream->write(movement.y);
stream->write(movement.z);
stream->writeInt(movement_op, OP_BITS);
}
}
void afxPlayerMovementData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&speed_bias);
if (stream->readFlag())
{
stream->read(&movement.x);
stream->read(&movement.y);
stream->read(&movement.z);
movement_op = stream->readInt(OP_BITS);
}
else
{
movement = default_movement;
movement_op = OP_MULTIPLY;
}
}
bool afxPlayerMovementData::hasMovementOverride()
{
return (movement != default_movement);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,73 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_PLAYER_MOVEMENT_H_
#define _AFX_PLAYER_MOVEMENT_H_
#include "afx/ce/afxComponentEffect.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxConstraint.h"
class afxPlayerMovementData : public GameBaseData, public afxEffectDefs
{
typedef GameBaseData Parent;
public:
enum OpType
{
OP_ADD = 0,
OP_MULTIPLY,
OP_REPLACE,
OP_BITS = 2,
};
public:
F32 speed_bias;
Point3F movement;
U32 movement_op;
public:
/*C*/ afxPlayerMovementData();
/*C*/ afxPlayerMovementData(const afxPlayerMovementData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool hasMovementOverride();
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxPlayerMovementData);
DECLARE_CATEGORY("AFX");
};
typedef afxPlayerMovementData::OpType afxPlayerMovement_OpType;
DefineEnumType( afxPlayerMovement_OpType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_PLAYER_MOVEMENT_H_

View file

@ -0,0 +1,122 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxPlayerPuppet.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxPlayerPuppetData
IMPLEMENT_CO_DATABLOCK_V1(afxPlayerPuppetData);
ConsoleDocClass( afxPlayerPuppetData,
"@brief A datablock that specifies a Player Puppet effect.\n\n"
"Player Puppet effects are defined using the afxPlayerPuppetData datablock and are used to control the movement of "
"Player objects with the AFX constraint system. The Player Puppet effect is similar to the Player Movement effect, but "
"where movement effects 'steer' the player using the same mechanisms that allow Player control from mouse and keyboard "
"input, Player Puppet effects totally take over a Player's transformation using the AFX constraint system."
"\n\n"
"Player Puppet can be configured to directly move a Player's client ghosts as well as its server instance. When doing this, "
"it is important to keep the general motion of the Player object and its ghosts somewhat consistent. Otherwise, obvious "
"discontinuities in the motion will result when the Player Puppet ends and control is restored to the server Player."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxPlayerPuppetData::afxPlayerPuppetData()
{
obj_spec = ST_NULLSTRING;
networking = SERVER_ONLY;
}
afxPlayerPuppetData::afxPlayerPuppetData(const afxPlayerPuppetData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
obj_spec = other.obj_spec;
networking = other.networking;
}
#define myOffset(field) Offset(field, afxPlayerPuppetData)
void afxPlayerPuppetData::initPersistFields()
{
addField("objectSpec", TypeString, myOffset(obj_spec),
"...");
addField("networking", TypeS8, myOffset(networking),
"...");
Parent::initPersistFields();
// disallow some field substitutions
disableFieldSubstitutions("objectSpec");
disableFieldSubstitutions("networking");
}
bool afxPlayerPuppetData::onAdd()
{
if (Parent::onAdd() == false)
return false;
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
obj_def.parseSpec(obj_spec, runs_on_s, runs_on_c);
return true;
}
void afxPlayerPuppetData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(obj_spec);
stream->write(networking);
}
void afxPlayerPuppetData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
obj_spec = stream->readSTString();
stream->read(&networking);
}
void afxPlayerPuppetData::gather_cons_defs(Vector<afxConstraintDef>& defs)
{
if (obj_def.isDefined())
defs.push_back(obj_def);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,64 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_PLAYER_PUPPET_H_
#define _AFX_PLAYER_PUPPET_H_
#include "afx/ce/afxComponentEffect.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxConstraint.h"
class afxPlayerPuppetData : public GameBaseData, public afxEffectDefs, public afxComponentEffectData
{
typedef GameBaseData Parent;
public:
StringTableEntry obj_spec;
afxConstraintDef obj_def;
U8 networking;
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
public:
/*C*/ afxPlayerPuppetData();
/*C*/ afxPlayerPuppetData(const afxPlayerPuppetData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxPlayerPuppetData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_PLAYER_PUPPET_H_

View file

@ -0,0 +1,103 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxPointLight_T3D.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxT3DPointLightData
IMPLEMENT_CO_DATABLOCK_V1(afxT3DPointLightData);
ConsoleDocClass( afxT3DPointLightData,
"@brief A datablock that specifies a dynamic Point Light effect.\n\n"
"A Point Light effect that uses the T3D PointLight object. afxT3DPointLightData has the same fields found in PointLight but "
"in a datablock structure."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxT3DPointLightData::afxT3DPointLightData()
: mRadius( 5.0f )
{
}
afxT3DPointLightData::afxT3DPointLightData(const afxT3DPointLightData& other, bool temp_clone) : afxT3DLightBaseData(other, temp_clone)
{
mRadius = other.mRadius;
}
//
// NOTE: keep this as consistent as possible with PointLight::initPersistFields()
//
void afxT3DPointLightData::initPersistFields()
{
addGroup( "Light" );
addField( "radius", TypeF32, Offset( mRadius, afxT3DPointLightData ),
"Controls the falloff of the light emission");
endGroup( "Light" );
// We do the parent fields at the end so that
// they show up that way in the inspector.
Parent::initPersistFields();
// Remove the scale field... it's already
// defined by the light radius.
removeField( "scale" );
}
bool afxT3DPointLightData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxT3DPointLightData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write( mRadius );
}
void afxT3DPointLightData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read( &mRadius );
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,56 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_T3D_POINT_LIGHT_H_
#define _AFX_T3D_POINT_LIGHT_H_
#include "afx/ce/afxLightBase_T3D.h"
class afxT3DPointLightData : public afxT3DLightBaseData
{
typedef afxT3DLightBaseData Parent;
public:
F32 mRadius;
public:
/*C*/ afxT3DPointLightData();
/*C*/ afxT3DPointLightData(const afxT3DPointLightData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxT3DPointLightData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_T3D_POINT_LIGHT_H_

View file

@ -0,0 +1,371 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "T3D/shapeBase.h"
#include "afx/ce/afxProjectile.h"
#include "afx/afxChoreographer.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxProjectileData
IMPLEMENT_CO_DATABLOCK_V1(afxProjectileData);
ConsoleDocClass( afxProjectileData,
"@brief A datablock that specifies a Projectile effect.\n\n"
"afxProjectileData inherits from ProjectileData and adds some AFX specific fields."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxProjectileData::afxProjectileData()
{
networking = GHOSTABLE;
launch_pos_spec = ST_NULLSTRING;
launch_dir_bias.zero();
ignore_src_timeout = false;
dynamicCollisionMask = 0;
staticCollisionMask = 0;
override_collision_masks = false;
launch_dir_method = TowardPos2Constraint;
}
afxProjectileData::afxProjectileData(const afxProjectileData& other, bool temp_clone) : ProjectileData(other, temp_clone)
{
networking = other.networking;
launch_pos_spec = other.launch_pos_spec;
launch_pos_def = other.launch_pos_def;
launch_dir_bias = other.launch_dir_bias;
ignore_src_timeout = other.ignore_src_timeout;
dynamicCollisionMask = other.dynamicCollisionMask;
staticCollisionMask = other.staticCollisionMask;
override_collision_masks = other.override_collision_masks;
launch_dir_method = other.launch_dir_method;
}
ImplementEnumType( afxProjectile_LaunchDirType, "Possible projectile launch direction types.\n" "@ingroup afxProjectile\n\n" )
{ afxProjectileData::TowardPos2Constraint, "towardPos2Constraint", "..." },
{ afxProjectileData::OrientConstraint, "orientConstraint", "..." },
{ afxProjectileData::LaunchDirField, "launchDirField", "..." },
EndImplementEnumType;
#define myOffset(field) Offset(field, afxProjectileData)
void afxProjectileData::initPersistFields()
{
addField("networking", TypeS8, myOffset(networking),
"...");
addField("launchPosSpec", TypeString, myOffset(launch_pos_spec),
"...");
addField("launchDirBias", TypePoint3F, myOffset(launch_dir_bias),
"...");
addField("ignoreSourceTimeout", TypeBool, myOffset(ignore_src_timeout),
"...");
addField("dynamicCollisionMask", TypeS32, myOffset(dynamicCollisionMask),
"...");
addField("staticCollisionMask", TypeS32, myOffset(staticCollisionMask),
"...");
addField("overrideCollisionMasks", TypeBool, myOffset(override_collision_masks),
"...");
addField("launchDirMethod", TYPEID<afxProjectileData::LaunchDirType>(), myOffset(launch_dir_method),
"Possible values: towardPos2Constraint, orientConstraint, or launchDirField.");
Parent::initPersistFields();
}
bool afxProjectileData::onAdd()
{
if (Parent::onAdd() == false)
return false;
bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0);
bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0);
launch_pos_def.parseSpec(launch_pos_spec, runs_on_s, runs_on_c);
return true;
}
void afxProjectileData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write(networking);
stream->writeString(launch_pos_spec);
if (stream->writeFlag(!launch_dir_bias.isZero()))
{
stream->write(launch_dir_bias.x);
stream->write(launch_dir_bias.y);
stream->write(launch_dir_bias.z);
}
stream->writeFlag(ignore_src_timeout);
if (stream->writeFlag(override_collision_masks))
{
stream->write(dynamicCollisionMask);
stream->write(staticCollisionMask);
}
stream->writeInt(launch_dir_method, 2);
}
void afxProjectileData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read(&networking);
launch_pos_spec = stream->readSTString();
if (stream->readFlag())
{
stream->read(&launch_dir_bias.x);
stream->read(&launch_dir_bias.y);
stream->read(&launch_dir_bias.z);
}
else
launch_dir_bias.zero();
ignore_src_timeout = stream->readFlag();
if ((override_collision_masks = stream->readFlag()) == true)
{
stream->read(&dynamicCollisionMask);
stream->read(&staticCollisionMask);
}
else
{
dynamicCollisionMask = 0;
staticCollisionMask = 0;
}
launch_dir_method = (U32) stream->readInt(2);
}
void afxProjectileData::gather_cons_defs(Vector<afxConstraintDef>& defs)
{
if (launch_pos_def.isDefined())
defs.push_back(launch_pos_def);
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxProjectile
IMPLEMENT_CO_NETOBJECT_V1(afxProjectile);
ConsoleDocClass( afxProjectile,
"@brief A Projectile effect as defined by an afxProjectileData datablock.\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxProjectile::afxProjectile()
{
chor_id = 0;
hookup_with_chor = false;
ghost_cons_name = ST_NULLSTRING;
client_only = false;
}
afxProjectile::afxProjectile(U32 networking, U32 chor_id, StringTableEntry cons_name)
{
if (networking & SCOPE_ALWAYS)
{
mNetFlags.clear();
mNetFlags.set(Ghostable | ScopeAlways);
client_only = false;
}
else if (networking & GHOSTABLE)
{
mNetFlags.clear();
mNetFlags.set(Ghostable);
client_only = false;
}
else if (networking & SERVER_ONLY)
{
mNetFlags.clear();
client_only = false;
}
else // if (networking & CLIENT_ONLY)
{
mNetFlags.clear();
mNetFlags.set(IsGhost);
client_only = true;
}
this->chor_id = chor_id;
hookup_with_chor = false;
this->ghost_cons_name = cons_name;
}
afxProjectile::~afxProjectile()
{
}
void afxProjectile::init(Point3F& pos, Point3F& vel, ShapeBase* src_obj)
{
mCurrPosition = pos;
mCurrVelocity = vel;
if (src_obj)
{
mSourceObject = src_obj;
mSourceObjectId = src_obj->getId();
mSourceObjectSlot = 0;
}
setPosition(mCurrPosition);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxProjectile::onNewDataBlock(GameBaseData* dptr, bool reload)
{
return Parent::onNewDataBlock(dptr, reload);
}
void afxProjectile::processTick(const Move* move)
{
// note: this deletion test must occur before calling to the parent's
// processTick() because if this is a server projectile, the parent
// might decide to delete it and then client_only will no longer be
// valid after the return.
bool do_delete = (client_only && mCurrTick >= mDataBlock->lifetime);
Parent::processTick(move);
if (do_delete)
deleteObject();
}
void afxProjectile::interpolateTick(F32 delta)
{
if (client_only)
return;
Parent::interpolateTick(delta);
}
void afxProjectile::advanceTime(F32 dt)
{
Parent::advanceTime(dt);
if (hookup_with_chor)
{
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
if (chor)
{
chor->setGhostConstraintObject(this, ghost_cons_name);
hookup_with_chor = false;
}
}
}
bool afxProjectile::onAdd()
{
if(!Parent::onAdd())
return false;
if (isClientObject())
{
// add to client side mission cleanup
SimGroup *cleanup = dynamic_cast<SimGroup *>( Sim::findObject( "ClientMissionCleanup") );
if( cleanup != NULL )
{
cleanup->addObject( this );
}
else
{
AssertFatal( false, "Error, could not find ClientMissionCleanup group" );
return false;
}
}
return true;
}
void afxProjectile::onRemove()
{
Parent::onRemove();
}
//~~~~~~~~~~~~~~~~~~~~
U32 afxProjectile::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(conn, mask, stream);
// InitialUpdate
if (stream->writeFlag(mask & InitialUpdateMask))
{
stream->write(chor_id);
stream->writeString(ghost_cons_name);
}
return retMask;
}
//~~~~~~~~~~~~~~~~~~~~//
void afxProjectile::unpackUpdate(NetConnection * conn, BitStream * stream)
{
Parent::unpackUpdate(conn, stream);
// InitialUpdate
if (stream->readFlag())
{
stream->read(&chor_id);
ghost_cons_name = stream->readSTString();
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
hookup_with_chor = true;
}
}
class afxProjectileDeleteEvent : public SimEvent
{
public:
void process(SimObject *object)
{
object->deleteObject();
}
};
void afxProjectile::explode(const Point3F& p, const Point3F& n, const U32 collideType)
{
// Make sure we don't explode twice...
if ( isHidden() )
return;
Parent::explode(p, n, collideType);
if (isClientObject() && client_only)
Sim::postEvent(this, new afxProjectileDeleteEvent, Sim::getCurrentTime() + DeleteWaitTime);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,117 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_PROJECTILE_H_
#define _AFX_PROJECTILE_H_
#include "lighting/lightInfo.h"
#include "T3D/projectile.h"
#include "afx/afxEffectDefs.h"
#include "afx/afxConstraint.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxProjectileData
class afxProjectileData : public ProjectileData, public afxEffectDefs
{
typedef ProjectileData Parent;
public:
enum LaunchDirType {
TowardPos2Constraint,
OrientConstraint,
LaunchDirField
};
public:
U8 networking;
StringTableEntry launch_pos_spec;
afxConstraintDef launch_pos_def;
Point3F launch_dir_bias;
bool ignore_src_timeout;
U32 dynamicCollisionMask;
U32 staticCollisionMask;
bool override_collision_masks;
U32 launch_dir_method;
virtual void gather_cons_defs(Vector<afxConstraintDef>& defs);
public:
/*C*/ afxProjectileData();
/*C*/ afxProjectileData(const afxProjectileData&, bool = false);
virtual bool onAdd();
void packData(BitStream* stream);
void unpackData(BitStream* stream);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxProjectileData);
DECLARE_CATEGORY("AFX");
};
typedef afxProjectileData::LaunchDirType afxProjectile_LaunchDirType;
DefineEnumType( afxProjectile_LaunchDirType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxProjectile
class afxProjectile : public Projectile, public afxEffectDefs
{
typedef Projectile Parent;
private:
U32 chor_id;
bool hookup_with_chor;
StringTableEntry ghost_cons_name;
bool client_only;
public:
/*C*/ afxProjectile();
/*C*/ afxProjectile(U32 networking, U32 chor_id, StringTableEntry cons_name);
/*D*/ ~afxProjectile();
void init(Point3F& pos, Point3F& vel, ShapeBase* src_obj);
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
virtual void processTick(const Move *move);
virtual void interpolateTick(F32 delta);
virtual void advanceTime(F32 dt);
virtual bool onAdd();
virtual void onRemove();
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
virtual void unpackUpdate(NetConnection*, BitStream*);
virtual void explode(const Point3F& p, const Point3F& n, const U32 collideType);
DECLARE_CONOBJECT(afxProjectile);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_PROJECTILE_H_

View file

@ -0,0 +1,94 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxScriptEvent.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxScriptEventData
IMPLEMENT_CO_DATABLOCK_V1(afxScriptEventData);
ConsoleDocClass( afxScriptEventData,
"@brief A datablock that specifies a Script Event effect.\n\n"
"Arbitrary script functions can be called as an AFX effect using afxScriptEventData. They are useful for implementing "
"high-level scripted side-effects such as character resurrection or teleportation."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxScriptEventData::afxScriptEventData()
{
method_name = ST_NULLSTRING;
script_data = ST_NULLSTRING;
}
afxScriptEventData::afxScriptEventData(const afxScriptEventData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
method_name = other.method_name;
script_data = other.script_data;
}
#define myOffset(field) Offset(field, afxScriptEventData)
void afxScriptEventData::initPersistFields()
{
addField("methodName", TypeString, myOffset(method_name),
"The name of a script method defined for the instance class of an effects "
"choreographer. The arguments used to call this method are determined by the type "
"of choreographer.");
addField("scriptData", TypeString, myOffset(script_data),
"An arbitrary blind data value which is passed in as an argument of the script event "
"method. The value of scriptData can be used to differentiate uses when handling "
"different script event effects with a single method.");
Parent::initPersistFields();
}
void afxScriptEventData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(method_name);
stream->writeString(script_data);
}
void afxScriptEventData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
method_name = stream->readSTString();
script_data = stream->readSTString();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,57 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_SCRIPT_EVENT_H_
#define _AFX_SCRIPT_EVENT_H_
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxScriptEventData
struct afxScriptEventData : public GameBaseData
{
typedef GameBaseData Parent;
public:
StringTableEntry method_name;
StringTableEntry script_data;
public:
/*C*/ afxScriptEventData();
/*C*/ afxScriptEventData(const afxScriptEventData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxScriptEventData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_SCRIPT_EVENT_H_

View file

@ -0,0 +1,112 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "afx/ce/afxSpotLight_T3D.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxT3DSpotLightData
IMPLEMENT_CO_DATABLOCK_V1(afxT3DSpotLightData);
ConsoleDocClass( afxT3DSpotLightData,
"@brief A datablock that specifies a dynamic Spot Light effect.\n\n"
"A Spot Light effect that uses the T3D SpotLight object. afxT3DSpotLightData has the same fields found in SpotLight but in "
"a datablock structure."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxT3DSpotLightData::afxT3DSpotLightData()
: mRange( 10.0f ),
mInnerConeAngle( 40.0f ),
mOuterConeAngle( 45.0f )
{
}
afxT3DSpotLightData::afxT3DSpotLightData(const afxT3DSpotLightData& other, bool temp_clone) : afxT3DLightBaseData(other, temp_clone)
{
mRange = other.mRange;
mInnerConeAngle = other.mInnerConeAngle;
mOuterConeAngle = other.mOuterConeAngle;
}
//
// NOTE: keep this as consistent as possible with PointLight::initPersistFields()
//
void afxT3DSpotLightData::initPersistFields()
{
addGroup( "Light" );
addField( "range", TypeF32, Offset( mRange, afxT3DSpotLightData ),
"...");
addField( "innerAngle", TypeF32, Offset( mInnerConeAngle, afxT3DSpotLightData ),
"...");
addField( "outerAngle", TypeF32, Offset( mOuterConeAngle, afxT3DSpotLightData ),
"...");
endGroup( "Light" );
// We do the parent fields at the end so that
// they show up that way in the inspector.
Parent::initPersistFields();
}
bool afxT3DSpotLightData::onAdd()
{
if (Parent::onAdd() == false)
return false;
return true;
}
void afxT3DSpotLightData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->write( mRange );
stream->write( mInnerConeAngle );
stream->write( mOuterConeAngle );
}
void afxT3DSpotLightData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
stream->read( &mRange );
stream->read( &mInnerConeAngle );
stream->read( &mOuterConeAngle );
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,58 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_T3D_SPOT_LIGHT_H_
#define _AFX_T3D_SPOT_LIGHT_H_
#include "afx/ce/afxLightBase_T3D.h"
class afxT3DSpotLightData : public afxT3DLightBaseData
{
typedef afxT3DLightBaseData Parent;
public:
F32 mRange;
F32 mInnerConeAngle;
F32 mOuterConeAngle;
public:
/*C*/ afxT3DSpotLightData();
/*C*/ afxT3DSpotLightData(const afxT3DSpotLightData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxT3DSpotLightData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_T3D_SPOT_LIGHT_H_

View file

@ -0,0 +1,241 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "ts/tsShapeInstance.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxStaticShape.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxStaticShapeData
IMPLEMENT_CO_DATABLOCK_V1(afxStaticShapeData);
ConsoleDocClass( afxStaticShapeData,
"@brief A datablock that specifies a StaticShape effect.\n\n"
"afxStaticShapeData inherits from StaticShapeData and adds some AFX specific fields. StaticShape effects should be "
"specified using afxStaticShapeData rather than StaticShapeData datablocks."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxStaticShapeData::afxStaticShapeData()
{
sequence = ST_NULLSTRING;
ignore_scene_amb = false;
use_custom_scene_amb = false;
custom_scene_amb.set(0.5f, 0.5f, 0.5f);
do_spawn = false;
}
afxStaticShapeData::afxStaticShapeData(const afxStaticShapeData& other, bool temp_clone) : StaticShapeData(other, temp_clone)
{
sequence = other.sequence;
ignore_scene_amb = other.ignore_scene_amb;
use_custom_scene_amb = other.use_custom_scene_amb;
custom_scene_amb = other.custom_scene_amb;
do_spawn = other.do_spawn;
}
#define myOffset(field) Offset(field, afxStaticShapeData)
void afxStaticShapeData::initPersistFields()
{
addField("sequence", TypeFilename, myOffset(sequence),
"An animation sequence in the StaticShape to play.");
addField("ignoreSceneAmbient", TypeBool, myOffset(ignore_scene_amb),
"...");
addField("useCustomSceneAmbient", TypeBool, myOffset(use_custom_scene_amb),
"...");
addField("customSceneAmbient", TypeColorF, myOffset(custom_scene_amb),
"...");
addField("doSpawn", TypeBool, myOffset(do_spawn),
"When true, the StaticShape effect will leave behind the StaticShape object as a "
"permanent part of the scene.");
Parent::initPersistFields();
}
void afxStaticShapeData::packData(BitStream* stream)
{
Parent::packData(stream);
stream->writeString(sequence);
stream->writeFlag(ignore_scene_amb);
if (stream->writeFlag(use_custom_scene_amb))
stream->write(custom_scene_amb);
stream->writeFlag(do_spawn);
}
void afxStaticShapeData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
sequence = stream->readSTString();
ignore_scene_amb = stream->readFlag();
if ((use_custom_scene_amb = stream->readFlag()) == true)
stream->read(&custom_scene_amb);
do_spawn = stream->readFlag();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxStaticShape
IMPLEMENT_CO_NETOBJECT_V1(afxStaticShape);
ConsoleDocClass( afxStaticShape,
"@brief A StaticShape effect as defined by an afxStaticShapeData datablock.\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxStaticShape::afxStaticShape()
{
afx_data = 0;
is_visible = true;
chor_id = 0;
hookup_with_chor = false;
ghost_cons_name = ST_NULLSTRING;
}
afxStaticShape::~afxStaticShape()
{
}
void afxStaticShape::init(U32 chor_id, StringTableEntry cons_name)
{
this->chor_id = chor_id;
ghost_cons_name = cons_name;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxStaticShape::onNewDataBlock(GameBaseData* dptr, bool reload)
{
mDataBlock = dynamic_cast<StaticShapeData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
return false;
afx_data = dynamic_cast<afxStaticShapeData*>(mDataBlock);
if (!mShapeInstance)
return true;
const char* seq_name = 0;
// if datablock is afxStaticShapeData we get the sequence setting
// directly from the datablock on the client-side only
if (afx_data)
{
if (isClientObject())
seq_name = afx_data->sequence;
}
// otherwise datablock is stock StaticShapeData and we look for
// a sequence name on a dynamic field on the server.
else
{
if (isServerObject())
seq_name = mDataBlock->getDataField(StringTable->insert("sequence"),0);
}
// if we have a sequence name, attempt to start a thread
if (seq_name)
{
TSShape* shape = mShapeInstance->getShape();
if (shape)
{
S32 seq = shape->findSequence(seq_name);
if (seq != -1)
setThreadSequence(0,seq);
}
}
return true;
}
void afxStaticShape::advanceTime(F32 dt)
{
Parent::advanceTime(dt);
if (hookup_with_chor)
{
afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id);
if (chor)
{
chor->setGhostConstraintObject(this, ghost_cons_name);
hookup_with_chor = false;
}
}
}
U32 afxStaticShape::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(conn, mask, stream);
// InitialUpdate
if (stream->writeFlag(mask & InitialUpdateMask))
{
stream->write(chor_id);
stream->writeString(ghost_cons_name);
}
return retMask;
}
//~~~~~~~~~~~~~~~~~~~~//
void afxStaticShape::unpackUpdate(NetConnection * conn, BitStream * stream)
{
Parent::unpackUpdate(conn, stream);
// InitialUpdate
if (stream->readFlag())
{
stream->read(&chor_id);
ghost_cons_name = stream->readSTString();
if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING)
hookup_with_chor = true;
}
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
void afxStaticShape::prepRenderImage(SceneRenderState* state)
{
if (is_visible)
Parent::prepRenderImage(state);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,98 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_STATIC_SHAPE_H_
#define _AFX_STATIC_SHAPE_H_
#include "T3D/staticShape.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxStaticShapeData
class afxStaticShapeData : public StaticShapeData
{
typedef StaticShapeData Parent;
public:
StringTableEntry sequence;
bool ignore_scene_amb;
bool use_custom_scene_amb;
LinearColorF custom_scene_amb;
bool do_spawn;
public:
/*C*/ afxStaticShapeData();
/*C*/ afxStaticShapeData(const afxStaticShapeData&, bool = false);
void packData(BitStream* stream);
void unpackData(BitStream* stream);
virtual bool allowSubstitutions() const { return true; }
static void initPersistFields();
DECLARE_CONOBJECT(afxStaticShapeData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxStaticShape
class afxStaticShape : public StaticShape
{
typedef StaticShape Parent;
private:
StaticShapeData* mDataBlock;
afxStaticShapeData* afx_data;
bool is_visible;
U32 chor_id;
bool hookup_with_chor;
StringTableEntry ghost_cons_name;
protected:
virtual void prepRenderImage(SceneRenderState*);
public:
/*C*/ afxStaticShape();
/*D*/ ~afxStaticShape();
void init(U32 chor_id, StringTableEntry cons_name);
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
virtual void advanceTime(F32 dt);
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
virtual void unpackUpdate(NetConnection*, BitStream*);
const char* getShapeFileName() const { return mDataBlock->shapeName; }
void setVisibility(bool flag) { is_visible = flag; }
DECLARE_CONOBJECT(afxStaticShape);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_STATIC_SHAPE_H_

View file

@ -0,0 +1,40 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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/ce/afxVolumeLight.h"
IMPLEMENT_CO_DATABLOCK_V1(afxVolumeLightData);
ConsoleDocClass( afxVolumeLightData,
"@brief afxVolumeLightData is a legacy datablock which is not supported for T3D.\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,38 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_VOLUME_LIGHT_H_
#define _AFX_VOLUME_LIGHT_H_
struct afxVolumeLightData : public GameBaseData
{
typedef GameBaseData Parent;
DECLARE_CONOBJECT(afxVolumeLightData);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_VOLUME_LIGHT_H_

View file

@ -0,0 +1,418 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "core/frameAllocator.h"
#include "terrain/terrRender.h"
#include "gfx/primBuilder.h"
#include "afx/ce/afxZodiac.h"
GFX_ImplementTextureProfile(AFX_GFXZodiacTextureProfile,
GFXTextureProfile::DiffuseMap,
GFXTextureProfile::Static | GFXTextureProfile::NoMipmap | GFXTextureProfile::PreserveSize,
GFXTextureProfile::NONE);
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxZodiacData::convertGradientRangeFromDegrees(Point2F& gradrange, const Point2F& gradrange_deg)
{
F32 x = mCos(mDegToRad(gradrange_deg.x));
F32 y = mCos(mDegToRad(gradrange_deg.y));
if (y > x)
gradrange.set(x, y);
else
gradrange.set(y, x);
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacData
IMPLEMENT_CO_DATABLOCK_V1(afxZodiacData);
ConsoleDocClass( afxZodiacData,
"@brief A datablock that specifies a decal-like Zodiac effect.\n\n"
"Zodiacs are special-purpose decal textures, often circular, that are always projected vertically onto the ground. Parameters "
"control dynamic rotation and scale as well as texture, color, and blending style."
"\n\n"
"Zodiacs render on objects of type TerrainBlock, InteriorInstance, GroundPlane, MeshRoad, and TSStatic. They are very "
"effective as spellcasting lighting rings, explosion shockwaves, scorched earth decals, and selection indicators."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
StringTableEntry afxZodiacData::GradientRangeSlot;
bool afxZodiacData::sPreferDestinationGradients = false;
afxZodiacData::afxZodiacData()
{
txr_name = ST_NULLSTRING;
radius_xy = 1;
vert_range.set(0.0f, 0.0f);
start_ang = 0;
ang_per_sec = 0;
color.set(1,1,1,1);
grow_in_time = 0.0f;
shrink_out_time = 0.0f;
growth_rate = 0.0f;
blend_flags = BLEND_NORMAL;
terrain_ok = true;
interiors_ok = true;
reflected_ok = false;
non_reflected_ok = true;
respect_ori_cons = false;
scale_vert_range = true;
interior_h_only = false;
interior_v_ignore = false;
interior_back_ignore = false;
interior_opaque_ignore = false;
interior_transp_ignore = true;
altitude_max = 0.0f;
altitude_falloff = 0.0f;
altitude_shrinks = false;
altitude_fades = false;
distance_max = 75.0f;
distance_falloff = 30.0f;
use_grade_range = false;
prefer_dest_grade = sPreferDestinationGradients;
grade_range_user.set(0.0f, 45.0f);
afxZodiacData::convertGradientRangeFromDegrees(grade_range, grade_range_user);
inv_grade_range = false;
}
afxZodiacData::afxZodiacData(const afxZodiacData& other, bool temp_clone) : GameBaseData(other, temp_clone)
{
txr_name = other.txr_name;
txr = other.txr;
radius_xy = other.radius_xy;
vert_range = other.vert_range;
start_ang = other.start_ang;
ang_per_sec = other.ang_per_sec;
grow_in_time = other.grow_in_time;
shrink_out_time = other.shrink_out_time;
growth_rate = other.growth_rate;
color = other.color;
altitude_max = other.altitude_max;
altitude_falloff = other.altitude_falloff;
altitude_shrinks = other.altitude_shrinks;
altitude_fades = other.altitude_fades;
distance_max = other.distance_max;
distance_falloff = other.distance_falloff;
use_grade_range = other.use_grade_range;
prefer_dest_grade = other.prefer_dest_grade;
grade_range = other.grade_range;
inv_grade_range = other.inv_grade_range;
zflags = other.zflags;
expand_zflags();
}
ImplementEnumType( afxZodiac_BlendType, "Possible zodiac blend types.\n" "@ingroup afxZodiac\n\n" )
{ afxZodiacData::BLEND_NORMAL, "normal", "..." },
{ afxZodiacData::BLEND_ADDITIVE, "additive", "..." },
{ afxZodiacData::BLEND_SUBTRACTIVE, "subtractive", "..." },
EndImplementEnumType;
void afxZodiacData::initPersistFields()
{
addField("texture", TypeFilename, Offset(txr_name, afxZodiacData),
"An image to use as the zodiac's texture.");
addField("radius", TypeF32, Offset(radius_xy, afxZodiacData),
"The zodiac's radius in scene units.");
addField("verticalRange", TypePoint2F, Offset(vert_range, afxZodiacData),
"For interior zodiacs only, verticalRange specifies distances above and below the "
"zodiac's position. If both values are 0.0, the radius is used.");
addField("scaleVerticalRange", TypeBool, Offset(scale_vert_range, afxZodiacData),
"Specifies if the zodiac's verticalRange should scale according to changes in the "
"radius. When a zodiacs is used as an expanding shockwave, this value should be set "
"to false, otherwise the zodiac can expand to cover an entire interior.");
addField("startAngle", TypeF32, Offset(start_ang, afxZodiacData),
"The starting angle in degrees of the zodiac's rotation.");
addField("rotationRate", TypeF32, Offset(ang_per_sec, afxZodiacData),
"The rate of rotation in degrees-per-second. Zodiacs with a positive rotationRate "
"rotate clockwise, while those with negative values turn counter-clockwise.");
addField("growInTime", TypeF32, Offset(grow_in_time, afxZodiacData),
"A duration of time in seconds over which the zodiac grows from a zero size to its "
"full size as specified by the radius.");
addField("shrinkOutTime", TypeF32, Offset(shrink_out_time, afxZodiacData),
"A duration of time in seconds over which the zodiac shrinks from full size to "
"invisible.");
addField("growthRate", TypeF32, Offset(growth_rate, afxZodiacData),
"A rate in meters-per-second at which the zodiac grows in size. A negative value will "
"shrink the zodiac.");
addField("color", TypeColorF, Offset(color, afxZodiacData),
"A color value for the zodiac.");
addField("blend", TYPEID<BlendType>(), Offset(blend_flags, afxZodiacData),
"A blending style for the zodiac. Possible values: normal, additive, or subtractive.");
addField("showOnTerrain", TypeBool, Offset(terrain_ok, afxZodiacData),
"Specifies if the zodiac should be rendered on terrain or terrain-like surfaces.");
addField("showOnInteriors", TypeBool, Offset(interiors_ok, afxZodiacData),
"Specifies if the zodiac should be rendered on interior or interior-like surfaces.");
addField("showInReflections", TypeBool, Offset(reflected_ok, afxZodiacData),
"Specifies if the zodiac should be rendered on the reflection rendering pass of the "
"object it will be projected onto.");
addField("showInNonReflections", TypeBool, Offset(non_reflected_ok, afxZodiacData),
"Specifies if the zodiac should be rendered on the non-reflection rendering pass of "
"the object it will be projected onto.");
addField("trackOrientConstraint", TypeBool, Offset(respect_ori_cons, afxZodiacData),
"Specifies if the zodiac's rotation should be defined by its constrained "
"transformation.");
addField("interiorHorizontalOnly", TypeBool, Offset(interior_h_only, afxZodiacData),
"Specifies if interior zodiacs should be rendered exclusively on perfectly horizontal "
"interior surfaces.");
addField("interiorIgnoreVertical", TypeBool, Offset(interior_v_ignore, afxZodiacData),
"Specifies if interior zodiacs should not be rendered on perfectly vertical interior "
"surfaces.");
addField("interiorIgnoreBackfaces", TypeBool, Offset(interior_back_ignore, afxZodiacData),
"Specifies if interior zodiacs should not be rendered on interior surface which are "
"backfacing to the zodiac's center.");
addField("interiorIgnoreOpaque", TypeBool, Offset(interior_opaque_ignore, afxZodiacData),
"");
addField("interiorIgnoreTransparent", TypeBool, Offset(interior_transp_ignore, afxZodiacData),
"");
addField("altitudeMax", TypeF32, Offset(altitude_max, afxZodiacData),
"The altitude at which zodiac becomes invisible as the result of fading out or "
"becoming too small.");
addField("altitudeFalloff", TypeF32, Offset(altitude_falloff, afxZodiacData),
"The altitude at which zodiac begins to fade and/or shrink.");
addField("altitudeShrinks", TypeBool, Offset(altitude_shrinks, afxZodiacData),
"When true, zodiac becomes smaller as altitude increases.");
addField("altitudeFades", TypeBool, Offset(altitude_fades, afxZodiacData),
"When true, zodiac fades out as altitude increases.");
addField("distanceMax", TypeF32, Offset(distance_max, afxZodiacData),
"The distance from camera at which the zodiac becomes invisible as the result of "
"fading out.");
addField("distanceFalloff", TypeF32, Offset(distance_falloff, afxZodiacData),
"The distance from camera at which the zodiac begins to fade out.");
addField("useGradientRange", TypeBool, Offset(use_grade_range, afxZodiacData),
"When true, gradientRange will be used to determine on which polygons the zodiac will "
"render.");
addField("preferDestinationGradients", TypeBool, Offset(prefer_dest_grade, afxZodiacData),
"When true, a gradientRange specified on an InteriorInstance or TSStatic will be used "
"instead of the zodiac's gradientRange.");
addField("gradientRange", TypePoint2F, Offset(grade_range_user, afxZodiacData),
"Zodiac will render on polygons with gradients within the range specified by "
"gradientRange. 0 for floor polys, 90 for wall polys, 180 for ceiling polys.");
addField("invertGradientRange", TypeBool, Offset(inv_grade_range, afxZodiacData),
"When true, the zodiac will render on polygons with gradients outside of the range "
"specified by gradientRange.");
Parent::initPersistFields();
GradientRangeSlot = StringTable->lookup("gradientRange");
Con::addVariable("pref::afxZodiac::preferDestinationGradients", TypeBool, &sPreferDestinationGradients);
}
bool afxZodiacData::onAdd()
{
if (Parent::onAdd() == false)
return false;
if (altitude_falloff > altitude_max)
altitude_falloff = altitude_max;
if (distance_falloff > distance_max)
distance_falloff = distance_max;
return true;
}
void afxZodiacData::packData(BitStream* stream)
{
Parent::packData(stream);
merge_zflags();
stream->writeString(txr_name);
stream->write(radius_xy);
stream->write(vert_range.x);
stream->write(vert_range.y);
stream->write(grade_range.x);
stream->write(grade_range.y);
stream->write(start_ang);
stream->write(ang_per_sec);
stream->write(grow_in_time);
stream->write(shrink_out_time);
stream->write(growth_rate);
stream->write(color);
stream->write(zflags);
stream->write(altitude_max);
stream->write(altitude_falloff);
stream->writeFlag(altitude_shrinks);
stream->writeFlag(altitude_fades);
stream->write(distance_max);
stream->write(distance_falloff);
}
void afxZodiacData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
txr_name = stream->readSTString();
txr = GFXTexHandle();
stream->read(&radius_xy);
stream->read(&vert_range.x);
stream->read(&vert_range.y);
stream->read(&grade_range.x);
stream->read(&grade_range.y);
stream->read(&start_ang);
stream->read(&ang_per_sec);
stream->read(&grow_in_time);
stream->read(&shrink_out_time);
stream->read(&growth_rate);
stream->read(&color);
stream->read(&zflags);
stream->read(&altitude_max);
stream->read(&altitude_falloff);
altitude_shrinks = stream->readFlag();
altitude_fades = stream->readFlag();
stream->read(&distance_max);
stream->read(&distance_falloff);
expand_zflags();
}
bool afxZodiacData::preload(bool server, String &errorStr)
{
if (!Parent::preload(server, errorStr))
return false;
if (!server)
{
if (txr_name && txr_name[0] != '\0')
{
txr.set(txr_name, &AFX_GFXZodiacTextureProfile, "Zodiac Texture");
}
}
if (vert_range.x == 0.0f && vert_range.y == 0.0f)
vert_range.x = vert_range.y = radius_xy;
return true;
}
void afxZodiacData::onStaticModified(const char* slot, const char* newValue)
{
Parent::onStaticModified(slot, newValue);
if (slot == GradientRangeSlot)
{
convertGradientRangeFromDegrees(grade_range, grade_range_user);
return;
}
merge_zflags();
}
void afxZodiacData::onPerformSubstitutions()
{
if (txr_name && txr_name[0] != '\0')
{
txr.set(txr_name, &AFX_GFXZodiacTextureProfile, "Zodiac Texture");
}
}
F32 afxZodiacData::calcRotationAngle(F32 elapsed, F32 rate_factor)
{
F32 angle = start_ang + elapsed*ang_per_sec*rate_factor;
angle = mFmod(angle, 360.0f);
return angle;
}
void afxZodiacData::expand_zflags()
{
blend_flags = (zflags & BLEND_MASK);
terrain_ok = ((zflags & SHOW_ON_TERRAIN) != 0);
interiors_ok = ((zflags & SHOW_ON_INTERIORS) != 0);
reflected_ok = ((zflags & SHOW_IN_REFLECTIONS) != 0);
non_reflected_ok = ((zflags & SHOW_IN_NON_REFLECTIONS) != 0);
respect_ori_cons = ((zflags & RESPECT_ORIENTATION) != 0);
scale_vert_range = ((zflags & SCALE_VERT_RANGE) != 0);
interior_h_only = ((zflags & INTERIOR_HORIZ_ONLY) != 0);
interior_v_ignore = ((zflags & INTERIOR_VERT_IGNORE) != 0);
interior_back_ignore = ((zflags & INTERIOR_BACK_IGNORE) != 0);
interior_opaque_ignore = ((zflags & INTERIOR_OPAQUE_IGNORE) != 0);
interior_transp_ignore = ((zflags & INTERIOR_TRANSP_IGNORE) != 0);
use_grade_range = ((zflags & USE_GRADE_RANGE) != 0);
prefer_dest_grade = ((zflags & PREFER_DEST_GRADE) != 0);
inv_grade_range = ((zflags & INVERT_GRADE_RANGE) != 0);
}
void afxZodiacData::merge_zflags()
{
zflags = (blend_flags & BLEND_MASK);
if (terrain_ok)
zflags |= SHOW_ON_TERRAIN;
if (interiors_ok)
zflags |= SHOW_ON_INTERIORS;
if (reflected_ok)
zflags |= SHOW_IN_REFLECTIONS;
if (non_reflected_ok)
zflags |= SHOW_IN_NON_REFLECTIONS;
if (respect_ori_cons)
zflags |= RESPECT_ORIENTATION;
if (scale_vert_range)
zflags |= SCALE_VERT_RANGE;
if (interior_h_only)
zflags |= INTERIOR_HORIZ_ONLY;
if (interior_v_ignore)
zflags |= INTERIOR_VERT_IGNORE;
if (interior_back_ignore)
zflags |= INTERIOR_BACK_IGNORE;
if (interior_opaque_ignore)
zflags |= INTERIOR_OPAQUE_IGNORE;
if (interior_transp_ignore)
zflags |= INTERIOR_TRANSP_IGNORE;
if (use_grade_range)
zflags |= USE_GRADE_RANGE;
if (prefer_dest_grade)
zflags |= PREFER_DEST_GRADE;
if (inv_grade_range)
zflags |= INVERT_GRADE_RANGE;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,132 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ZODIAC_H_
#define _AFX_ZODIAC_H_
#ifndef _ARCANE_FX_H_
#include "afx/arcaneFX.h"
#endif
#ifndef _AFX_ZODIAC_DEFS_H_
#include "afx/ce/afxZodiacDefs.h"
#endif
#include "console/typeValidators.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacData
class afxZodiacData : public GameBaseData, public afxZodiacDefs
{
typedef GameBaseData Parent;
public:
enum BlendType
{
BLEND_NORMAL = 0x0,
BLEND_ADDITIVE = 0x1,
BLEND_SUBTRACTIVE = 0x2,
BLEND_RESERVED = 0x3,
BLEND_MASK = 0x3
};
static void convertGradientRangeFromDegrees(Point2F& gradrange, const Point2F& gradrange_deg);
public:
StringTableEntry txr_name;
GFXTexHandle txr;
F32 radius_xy;
Point2F vert_range;
F32 start_ang;
F32 ang_per_sec;
F32 grow_in_time;
F32 shrink_out_time;
F32 growth_rate;
LinearColorF color;
U32 blend_flags;
bool terrain_ok;
bool interiors_ok;
bool reflected_ok;
bool non_reflected_ok;
bool respect_ori_cons;
bool scale_vert_range;
bool interior_h_only;
bool interior_v_ignore;
bool interior_back_ignore;
bool interior_opaque_ignore;
bool interior_transp_ignore;
U32 zflags;
F32 altitude_max;
F32 altitude_falloff;
bool altitude_shrinks;
bool altitude_fades;
F32 distance_max;
F32 distance_falloff;
bool use_grade_range;
bool prefer_dest_grade;
Point2F grade_range_user;
Point2F grade_range;
bool inv_grade_range;
static StringTableEntry GradientRangeSlot;
static bool sPreferDestinationGradients;
void expand_zflags();
void merge_zflags();
public:
/*C*/ afxZodiacData();
/*C*/ afxZodiacData(const afxZodiacData&, bool = false);
virtual bool onAdd();
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool preload(bool server, String &errorStr);
virtual void onStaticModified(const char* slotName, const char* newValue = NULL);
virtual void onPerformSubstitutions();
virtual bool allowSubstitutions() const { return true; }
F32 calcRotationAngle(F32 elapsed, F32 rate_factor=1.0f);
static void initPersistFields();
DECLARE_CONOBJECT(afxZodiacData);
DECLARE_CATEGORY("AFX");
};
typedef afxZodiacData::BlendType afxZodiac_BlendType;
DefineEnumType( afxZodiac_BlendType );
GFX_DeclareTextureProfile(AFX_GFXZodiacTextureProfile);
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ZODIAC_H_

View file

@ -0,0 +1,163 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ZODIAC_DEFS_H_
#define _AFX_ZODIAC_DEFS_H_
class afxZodiacDefs
{
public:
enum
{
MAX_ZODIACS = 256,
N_ZODIAC_FIELD_INTS = (MAX_ZODIACS - 1) / 32 + 1,
};
enum
{
BLEND_NORMAL = 0x0,
BLEND_ADDITIVE = 0x1,
BLEND_SUBTRACTIVE = 0x2,
BLEND_RESERVED = 0x3,
BLEND_MASK = 0x3
};
enum
{
SHOW_ON_TERRAIN = BIT(2),
SHOW_ON_INTERIORS = BIT(3),
SHOW_ON_WATER = BIT(4),
SHOW_ON_MODELS = BIT(5),
//
SHOW_IN_NON_REFLECTIONS = BIT(6),
SHOW_IN_REFLECTIONS = BIT(7),
//
RESPECT_ORIENTATION = BIT(8),
SCALE_VERT_RANGE = BIT(9),
INVERT_GRADE_RANGE = BIT(10),
USE_GRADE_RANGE = BIT(11),
PREFER_DEST_GRADE = BIT(12),
//
INTERIOR_VERT_IGNORE = BIT(13),
INTERIOR_HORIZ_ONLY = BIT(14),
INTERIOR_BACK_IGNORE = BIT(15),
INTERIOR_OPAQUE_IGNORE = BIT(16),
INTERIOR_TRANSP_IGNORE = BIT(17),
//
INTERIOR_FILTERS = INTERIOR_VERT_IGNORE | INTERIOR_HORIZ_ONLY | INTERIOR_BACK_IGNORE
};
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
class afxZodiacBitmask : public afxZodiacDefs
{
U32 mBits[N_ZODIAC_FIELD_INTS];
public:
afxZodiacBitmask() { clear(); }
afxZodiacBitmask(const afxZodiacBitmask& field) { *this = field; }
bool test(U32 index)
{
U32 word = index / 32;
U32 bit = index % 32;
return mBits[word] & (1 << bit);
}
void set(U32 index)
{
U32 word = index / 32;
U32 bit = index % 32;
mBits[word] |= 1 << bit;
}
void unset(U32 index)
{
U32 word = index / 32;
U32 bit = index % 32;
mBits[word] &= ~(1 << bit);
}
S32 findLastSetBit(U32 startbit=(MAX_ZODIACS-1))
{
U32 word = startbit / 32;
U32 bit = startbit % 32;
if (mBits[word] != 0)
{
U32 mask = mBits[word] << (31-bit);
for (U32 j = bit; j >= 0; j--)
{
if (mask & 0x80000000)
return word*32 + j;
mask <<= 1;
}
}
for (U32 k = word-1; k >= 0; k--)
{
if (mBits[k] != 0)
{
U32 mask = mBits[k];
for (U32 j = 31; j >= 0; j--)
{
if (mask & 0x80000000)
return k*32 + j;
mask <<= 1;
}
}
}
return -1;
}
void clear()
{
for (U32 k = 0; k < N_ZODIAC_FIELD_INTS; k++)
mBits[k] = 0x00000000;
}
bool isEmpty()
{
for (U32 k = 0; k < N_ZODIAC_FIELD_INTS; k++)
if (mBits[k] != 0)
return false;
return true;
}
afxZodiacBitmask& operator=(const afxZodiacBitmask& field)
{
for (U32 k = 0; k < N_ZODIAC_FIELD_INTS; k++)
mBits[k] = field.mBits[k];
return *this;
}
operator bool() { return !isEmpty(); }
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ZODIAC_DEFS_H_

View file

@ -0,0 +1,131 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "terrain/terrRender.h"
#include "afx/ce/afxZodiac.h"
#include "afx/ce/afxZodiacMgr.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacMgr
Vector<afxZodiacMgr::ZodiacSpec> afxZodiacMgr::terr_zodes;
Vector<afxZodiacMgr::ZodiacSpec> afxZodiacMgr::inter_zodes;
afxZodiacMgr::ZodiacTriangle* afxZodiacMgr::zode_tris_head = NULL;
afxZodiacMgr::ZodiacTriangle* afxZodiacMgr::zode_tris_tail = NULL;
afxZodiacMgr::ZodiacTriangle* afxZodiacMgr::zode_tris = NULL;
U32 afxZodiacMgr::zode_tris_idx = 0;
U32 afxZodiacMgr::n_zode_tris = 0;
afxZodiacMgr::ZodiacSpec* afxZodiacMgr::live_zodiac = 0;
ShaderData* afxZodiacMgr::terrain_zode_shader = 0;
ShaderData* afxZodiacMgr::atlas_zode_shader = 0;
ShaderData* afxZodiacMgr::interior_zode_shader = 0;
ShaderData* afxZodiacMgr::polysoup_zode_shader = 0;
void afxZodiacMgr::addTerrainZodiac(Point3F& pos, F32 radius, LinearColorF& color, F32 angle, afxZodiacData* zode)
{
if (radius < 0.001f)
return;
ZodiacSpec z;
z.pos = pos;
z.radius_xy = radius;
z.vert_range.set(0.0f, 0.0f);
z.grade_range.set(0.0f, 1.0f);
z.color = color.toColorI();
z.angle = mDegToRad(angle);
z.zflags = zode->zflags;
z.txr = &zode->txr;
z.distance_max = zode->distance_max*zode->distance_max;
z.distance_falloff = zode->distance_falloff*zode->distance_falloff;
z.distance_delta = z.distance_max - z.distance_falloff;
if (terr_zodes.size() < MAX_ZODIACS)
terr_zodes.push_back(z);
}
void afxZodiacMgr::addInteriorZodiac(Point3F& pos, F32 radius, Point2F& vert_range, LinearColorF& color, F32 angle, afxZodiacData* zode)
{
if (radius < 0.001f)
return;
ZodiacSpec z;
z.pos = pos;
z.radius_xy = radius;
z.vert_range = vert_range;
z.grade_range = zode->grade_range;
z.color = color.toColorI();
z.angle = mDegToRad(angle);
z.zflags = zode->zflags;
z.txr = &zode->txr;
z.distance_max = zode->distance_max*zode->distance_max;
z.distance_falloff = zode->distance_falloff*zode->distance_falloff;
z.distance_delta = z.distance_max - z.distance_falloff;
if (inter_zodes.size() < MAX_ZODIACS)
inter_zodes.push_back(z);
}
void afxZodiacMgr::frameReset()
{
terr_zodes.clear();
inter_zodes.clear();
}
void afxZodiacMgr::missionCleanup()
{
terrain_zode_shader = 0;
atlas_zode_shader = 0;
interior_zode_shader = 0;
polysoup_zode_shader = 0;
}
// REGULAR TERRAIN ZODIACS //
void afxZodiacMgr::transformTerrainZodiacs(const MatrixF& world_xfm)
{
VectorF facing_vec;
world_xfm.getColumn(1, &facing_vec);
F32 yaw = mAtan2(facing_vec.x, facing_vec.y);
while (yaw < 0.0) yaw += M_2PI_F;
for (S32 i = 0; i < terr_zodes.size(); i++)
{
world_xfm.mulP(terr_zodes[i].pos, &terr_zodes[i].loc_pos);
F32 ang = terr_zodes[i].angle + yaw;
terr_zodes[i].loc_cos_ang = mCos(ang);
terr_zodes[i].loc_sin_ang = mSin(ang);
}
zode_tris_head = zode_tris_tail = NULL;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,150 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ZODIAC_MGR_H_
#define _AFX_ZODIAC_MGR_H_
#ifndef _ARCANE_FX_H_
#include "afx/arcaneFX.h"
#endif
#ifndef _AFX_ZODIAC_DEFS_H_
#include "afx/ce/afxZodiacDefs.h"
#endif
#ifndef _AFX_ZODIAC_H_
#include "afx/ce/afxZodiac.h"
#endif
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
struct GridSquare;
class ShaderData;
class TSStatic;
class GroundPlane;
class MeshRoad;
class TerrainBlock;
class TerrCell;
class afxZodiacMgr : public afxZodiacDefs
{
friend class afxZodiacTerrainRenderer;
friend class afxZodiacPolysoupRenderer;
friend class afxZodiacGroundPlaneRenderer;
friend class afxZodiacMeshRoadRenderer;
friend struct TerrainRender;
private:
struct ZodiacSpec
{
Point3F pos; //12// world position
F32 radius_xy; // 4// radius of zodiac
Point2F vert_range; // 8// vertical range
Point2F grade_range; // 8// plane gradient range
ColorI color; // 4// color of zodiac
F32 angle; // 4// angle in radians
U32 zflags; // 4// 0=normal,1=additive,2=subtractive
GFXTexHandle* txr; // 4// zodiac texture
F32 distance_max;
F32 distance_falloff;
F32 distance_delta;
Point3F loc_pos; //12// transformed to local position
F32 loc_cos_ang; // 4// cosine of local rotation angle
F32 loc_sin_ang; // 4// sine of local rotation angle
F32 calcDistanceFadeBias(F32 camDist) const
{
if (camDist < distance_falloff)
return 1.0f;
if (camDist < distance_max)
return (1.0f - (camDist - distance_falloff)/distance_delta);
return 0.0f;
}
};
struct ZodiacTriangle
{
ColorI color;
Point2F texco1;
Point3F point1;
Point2F texco2;
Point3F point2;
Point2F texco3;
Point3F point3;
U32 zflags; // 0=normal,1=additive,2=subtractive
GFXTexHandle* txr;
ZodiacTriangle* next;
};
static Vector<ZodiacSpec> terr_zodes;
static Vector<ZodiacSpec> inter_zodes;
static ZodiacTriangle* zode_tris_head;
static ZodiacTriangle* zode_tris_tail;
static ZodiacTriangle* zode_tris;
static U32 zode_tris_idx;
static U32 n_zode_tris;
public:
static ZodiacSpec* live_zodiac;
private:
static ShaderData* terrain_zode_shader;
static ShaderData* atlas_zode_shader;
static ShaderData* interior_zode_shader;
static ShaderData* polysoup_zode_shader;
public:
static void addTerrainZodiac(Point3F& pos, F32 rad, LinearColorF&, F32 ang, afxZodiacData*);
static void addInteriorZodiac(Point3F& pos, F32 rad, Point2F& vrange, LinearColorF&, F32 ang, afxZodiacData*);
static void frameReset();
static void missionCleanup();
static S32 numTerrainZodiacs() { return terr_zodes.size(); }
static S32 numInteriorZodiacs() { return inter_zodes.size(); }
static void transformTerrainZodiacs(const MatrixF& world_xfm);
static void testTerrainOverlap(GridSquare*, S32 level, Point2I sq_pos, afxZodiacBitmask&);
static bool doesBoxOverlapZodiac(const Box3F& box, const ZodiacSpec& zode);
static bool doesBlockContainZodiacs(SceneRenderState*, TerrainBlock* block_);
static bool renderTerrainZodiacs(SceneRenderState*, TerrainBlock*, TerrCell*);
static ShaderData* getTerrainZodiacShader();
static void renderPolysoupZodiacs(SceneRenderState*, TSStatic*);
static ShaderData* getPolysoupZodiacShader();
static void renderGroundPlaneZodiacs(SceneRenderState*, GroundPlane*);
static ShaderData* getGroundPlaneZodiacShader();
static void renderMeshRoadZodiacs(SceneRenderState*, MeshRoad*);
static ShaderData* getMeshRoadZodiacShader();
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ZODIAC_MGR_H_

View file

@ -0,0 +1,319 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "materials/shaderData.h"
#include "core/frameAllocator.h"
#include "terrain/terrRender.h"
#include "T3D/tsStatic.h"
#include "T3D/groundPlane.h"
#include "environment/meshRoad.h"
#include "collision/concretePolyList.h"
#include "gfx/primBuilder.h"
#include "terrain/terrCell.h"
#include "afx/ce/afxZodiac.h"
#include "afx/ce/afxZodiacMgr.h"
#include "afx/afxZodiacTerrainRenderer_T3D.h"
#include "afx/afxZodiacGroundPlaneRenderer_T3D.h"
#include "afx/afxZodiacMeshRoadRenderer_T3D.h"
#include "afx/afxZodiacPolysoupRenderer_T3D.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// POLYSOUP INTERIOR ZODIACS //
void afxZodiacMgr::renderPolysoupZodiacs(SceneRenderState* state, TSStatic* tss)
{
// check for active interior zodiacs
S32 n_zodes = inter_zodes.size();
if (n_zodes <= 0)
return;
static SphereF dummy_sphere;
const Box3F& mWorldBox = tss->getWorldBox();
const Point3F& cam_pos = state->getCameraPosition();
// loop through the interior zodiacs
for (U32 i = 0; i < n_zodes; i++)
{
// calculate zodiac extents
F32 radius = inter_zodes[i].radius_xy;
Box3F box_w; box_w.minExtents = box_w.maxExtents = inter_zodes[i].pos;
box_w.minExtents -= Point3F(radius, radius, inter_zodes[i].vert_range.x);
box_w.maxExtents += Point3F(radius, radius, inter_zodes[i].vert_range.y);
// skip zodiacs not overlapping this object
if (mWorldBox.isOverlapped(box_w) == false)
continue;
// collect list of zodiac-intersecting polygons
ConcretePolyList* poly_list = new ConcretePolyList();
((SceneObject*)tss)->buildPolyList(PLC_Decal, poly_list, box_w, dummy_sphere);
// render the polys if we get any
if (!poly_list->mPolyList.empty())
{
// calculate zodiac distance from camera
Point3F cam_vec = cam_pos - inter_zodes[i].pos;
F32 cam_dist = cam_vec.lenSquared();
// render zodiacs
afxZodiacPolysoupRenderer::getMaster()->addZodiac(i, poly_list, inter_zodes[i].pos, inter_zodes[i].angle, tss, cam_dist);
// note: poly_list will be deleted by render-manager after rendering is done.
}
else
{
delete poly_list; // avoids crash when overlapping box but not polygons
}
}
}
ShaderData* afxZodiacMgr::getPolysoupZodiacShader()
{
if (!polysoup_zode_shader)
{
if( !Sim::findObject("afxZodiacPolysoupShader", polysoup_zode_shader))
{
Con::errorf("afxZodiacMgr::getPolysoupZodiacShader() - failed to find shader 'afxZodiacPolysoupShader'.");
return 0;
}
}
return polysoup_zode_shader;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
bool afxZodiacMgr::doesBoxOverlapZodiac(const Box3F& box, const afxZodiacMgr::ZodiacSpec& zode)
{
if ((zode.pos.x - zode.radius_xy) > box.maxExtents.x ||
(zode.pos.y - zode.radius_xy) > box.maxExtents.y)
return false;
if ((zode.pos.x + zode.radius_xy) < box.minExtents.x ||
( zode.pos.y + zode.radius_xy) < box.minExtents.y)
return false;
return true;
}
static U32 last_terr_zode_idx = 0;
bool afxZodiacMgr::doesBlockContainZodiacs(SceneRenderState* state, TerrainBlock* block)
{
// for now, only look at diffuse-passes
if (!state->isDiffusePass())
return false;
// check for active terrain zodiacs
S32 n_zodes = terr_zodes.size();
if (n_zodes <= 0)
return false;
const Box3F& block_box = block->getWorldBox();
last_terr_zode_idx = 0;
for (U32 i = 0; i < n_zodes; i++)
{
if (doesBoxOverlapZodiac(block_box, terr_zodes[i]))
{
last_terr_zode_idx = i;
return true;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
bool afxZodiacMgr::renderTerrainZodiacs(SceneRenderState* state, TerrainBlock* block, TerrCell* cell)
{
// we assume here that afxZodiacMgr::doesBlockContainZodiacs() was recently called to
// determine that at least one zodiac intersects the block and its index is last_terr_zode_idx.
bool cell_has_zodiacs = false;
const Point3F& cam_pos = state->getCameraPosition();
const Box3F& block_box = block->getWorldBox();
S32 n_zodes = terr_zodes.size();
for (U32 i = last_terr_zode_idx; i < n_zodes; i++)
{
// first test against block's box
if (!doesBoxOverlapZodiac(block_box, terr_zodes[i]))
continue;
const MatrixF& mRenderObjToWorld = block->getRenderTransform();
Box3F cell_box = cell->getBounds();
mRenderObjToWorld.mul(cell_box);
if (!doesBoxOverlapZodiac(cell_box, terr_zodes[i]))
continue;
// at this point we know the zodiac overlaps AABB of cell...
// calculate zodiac distance from camera
Point3F cam_vec = cam_pos - terr_zodes[i].pos;
F32 cam_dist = cam_vec.lenSquared();
//if (cam_dist > 2500)
// continue;
// render zodiacs
afxZodiacTerrainRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, block, cell, mRenderObjToWorld, cam_dist);
cell_has_zodiacs = true;
}
last_terr_zode_idx = 0;
return cell_has_zodiacs;
}
ShaderData* afxZodiacMgr::getTerrainZodiacShader()
{
if (!terrain_zode_shader)
{
if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
{
Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
return 0;
}
}
return terrain_zode_shader;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxZodiacMgr::renderGroundPlaneZodiacs(SceneRenderState* state, GroundPlane* ground_plane)
{
// check for active terrain zodiacs
S32 n_zodes = terr_zodes.size();
if (n_zodes <= 0)
return;
// we currently expect gound-plane to be infinite
if (!ground_plane->isGlobalBounds())
{
return;
}
static SphereF dummy_sphere;
static Box3F dummy_box;
const Point3F& cam_pos = state->getCameraPosition();
// loop through the terrain zodiacs
for (U32 i = 0; i < n_zodes; i++)
{
// calculate zodiac distance from camera
Point3F cam_vec = cam_pos - terr_zodes[i].pos;
F32 cam_dist = cam_vec.lenSquared();
// render zodiacs
afxZodiacGroundPlaneRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, ground_plane, cam_dist);
}
}
ShaderData* afxZodiacMgr::getGroundPlaneZodiacShader()
{
if (!terrain_zode_shader)
{
if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
{
Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
return 0;
}
}
return terrain_zode_shader;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
void afxZodiacMgr::renderMeshRoadZodiacs(SceneRenderState* state, MeshRoad* mesh_road)
{
// check for active terrain zodiacs
S32 n_zodes = terr_zodes.size();
if (n_zodes <= 0)
return;
const Box3F& mWorldBox = mesh_road->getWorldBox();
const Point3F& cam_pos = state->getCameraPosition();
// loop through the terrain zodiacs
for (U32 i = 0; i < n_zodes; i++)
{
// calculate zodiac extents
F32 radius = terr_zodes[i].radius_xy;
Box3F box_w; box_w.minExtents = box_w.maxExtents = terr_zodes[i].pos;
box_w.minExtents -= Point3F(radius, radius, terr_zodes[i].vert_range.x);
box_w.maxExtents += Point3F(radius, radius, terr_zodes[i].vert_range.y);
// skip zodiacs not overlapping this object
if (mWorldBox.isOverlapped(box_w) == false)
continue;
// collect list of zodiac-intersecting polygons
ConcretePolyList* poly_list = new ConcretePolyList();
mesh_road->buildTopPolyList(PLC_Decal, poly_list);
// render the polys if we get any
if (!poly_list->mPolyList.empty())
{
// calculate zodiac distance from camera
Point3F cam_vec = cam_pos - terr_zodes[i].pos;
F32 cam_dist = cam_vec.lenSquared();
// render zodiacs
afxZodiacMeshRoadRenderer::getMaster()->addZodiac(i, poly_list, terr_zodes[i].pos, terr_zodes[i].angle, mesh_road, cam_dist);
// note: poly_list will be deleted by render-manager after rendering is done.
}
else
{
delete poly_list; // avoids crash when overlapping box but not polygons
}
}
}
ShaderData* afxZodiacMgr::getMeshRoadZodiacShader()
{
if (!terrain_zode_shader)
{
if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
{
Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
return 0;
}
}
return terrain_zode_shader;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,313 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "renderInstance/renderPassManager.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxZodiac.h"
#include "afx/ce/afxZodiacPlane.h"
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacPlaneData
IMPLEMENT_CO_DATABLOCK_V1(afxZodiacPlaneData);
ConsoleDocClass( afxZodiacPlaneData,
"@brief A datablock that specifies a Zodiac Plane effect.\n\n"
"afxZodiacData describes a zodiac-like effect called a zodiac plane. It reproduces most of the behavior of normal zodiacs "
"but unlike zodiac decals, it is represented as a flat plane of geometry that can be more flexibly positioned and oriented."
"\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
"@ingroup Datablocks\n"
);
afxZodiacPlaneData::afxZodiacPlaneData()
{
txr_name = ST_NULLSTRING;
radius_xy = 1;
start_ang = 0;
ang_per_sec = 0;
grow_in_time = 0.0f;
shrink_out_time = 0.0f;
growth_rate = 0.0f;
color.set(1,1,1,1);
blend_flags = BLEND_NORMAL;
respect_ori_cons = false;
double_sided = true;
face_dir = FACES_UP;
use_full_xfm = false;
}
afxZodiacPlaneData::afxZodiacPlaneData(const afxZodiacPlaneData& other, bool temp_clone)
: GameBaseData(other, temp_clone)
{
txr_name = other.txr_name;
txr = other.txr;
radius_xy = other.radius_xy;
start_ang = other.start_ang;
ang_per_sec = other.ang_per_sec;
grow_in_time = other.grow_in_time;
shrink_out_time = other.shrink_out_time;
growth_rate = other.growth_rate;
color = other.color;
double_sided = other.double_sided;
face_dir = other.face_dir;
use_full_xfm = other.use_full_xfm;
zflags = other.zflags;
expand_zflags();
}
ImplementEnumType( afxZodiacPlane_BlendType, "Possible zodiac blend types.\n" "@ingroup afxZodiacPlane\n\n" )
{ afxZodiacData::BLEND_NORMAL, "normal", "..." },
{ afxZodiacData::BLEND_ADDITIVE, "additive", "..." },
{ afxZodiacData::BLEND_SUBTRACTIVE, "subtractive", "..." },
EndImplementEnumType;
ImplementEnumType( afxZodiacPlane_FacingType, "Possible zodiac plane facing types.\n" "@ingroup afxZodiacPlane\n\n" )
{ afxZodiacPlaneData::FACES_UP, "up", "..." },
{ afxZodiacPlaneData::FACES_DOWN, "down", "..." },
{ afxZodiacPlaneData::FACES_FORWARD, "forward", "..." },
{ afxZodiacPlaneData::FACES_BACK, "backward", "..." },
{ afxZodiacPlaneData::FACES_RIGHT, "right", "..." },
{ afxZodiacPlaneData::FACES_LEFT, "left", "..." },
{ afxZodiacPlaneData::FACES_FORWARD, "front", "..." },
{ afxZodiacPlaneData::FACES_BACK, "back", "..." },
EndImplementEnumType;
#define myOffset(field) Offset(field, afxZodiacPlaneData)
void afxZodiacPlaneData::initPersistFields()
{
addField("texture", TypeFilename, myOffset(txr_name),
"An image to use as the zodiac's texture.");
addField("radius", TypeF32, myOffset(radius_xy),
"The zodiac's radius in scene units.");
addField("startAngle", TypeF32, myOffset(start_ang),
"The starting angle in degrees of the zodiac's rotation.");
addField("rotationRate", TypeF32, myOffset(ang_per_sec),
"The rate of rotation in degrees-per-second. Zodiacs with a positive rotationRate "
"rotate clockwise, while those with negative values turn counter-clockwise.");
addField("growInTime", TypeF32, myOffset(grow_in_time),
"A duration of time in seconds over which the zodiac grows from a zero size to its "
"full size as specified by the radius.");
addField("shrinkOutTime", TypeF32, myOffset(shrink_out_time),
"A duration of time in seconds over which the zodiac shrinks from full size to "
"invisible.");
addField("growthRate", TypeF32, myOffset(growth_rate),
"A rate in meters-per-second at which the zodiac grows in size. A negative value will "
"shrink the zodiac.");
addField("color", TypeColorF, myOffset(color),
"A color value for the zodiac.");
addField("blend", TYPEID<BlendType>(), myOffset(blend_flags),
"A blending style for the zodiac. Possible values: normal, additive, or subtractive.");
addField("trackOrientConstraint", TypeBool, myOffset(respect_ori_cons),
"Specifies if the zodiac's rotation should be defined by its constrained "
"transformation.");
addField("doubleSided", TypeBool, myOffset(double_sided),
"Controls whether the zodiac-plane's polygons are rendered when viewed from either "
"side. If set to false, the zodiac-plane will only be seen when viewed from the "
"direction it is facing (according to faceDir).");
addField("faceDir", TYPEID<afxZodiacPlaneData::FacingType>(), myOffset(face_dir),
"Specifies which direction the zodiac-plane's polygons face. Possible values: "
"up, down, front, back, right, or left.");
addField("useFullTransform", TypeBool, myOffset(use_full_xfm),
"Normal zodiacs have only one degree of freedom, a rotation around the z-axis. "
"Depending on the setting for trackOrientConstraint, this means that the effect's "
"orientation is either ignored or is limited to influencing the zodiac's angle of "
"rotation. By default, zodiac-plane reproduces this limited behavior in order to "
"match normal zodiacs. When useFullTransform is set to true, the zodiac can be "
"arbitrarily oriented.");
Parent::initPersistFields();
}
void afxZodiacPlaneData::packData(BitStream* stream)
{
Parent::packData(stream);
merge_zflags();
stream->writeString(txr_name);
stream->write(radius_xy);
stream->write(start_ang);
stream->write(ang_per_sec);
stream->write(grow_in_time);
stream->write(shrink_out_time);
stream->write(growth_rate);
stream->write(color);
stream->write(zflags);
stream->write(double_sided);
stream->writeFlag(use_full_xfm);
stream->writeInt(face_dir, FACES_BITS);
}
void afxZodiacPlaneData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
txr_name = stream->readSTString();
txr = GFXTexHandle();
stream->read(&radius_xy);
stream->read(&start_ang);
stream->read(&ang_per_sec);
stream->read(&grow_in_time);
stream->read(&shrink_out_time);
stream->read(&growth_rate);
stream->read(&color);
stream->read(&zflags);
stream->read(&double_sided);
use_full_xfm = stream->readFlag();
face_dir = stream->readInt(FACES_BITS);
expand_zflags();
}
bool afxZodiacPlaneData::preload(bool server, String &errorStr)
{
if (!Parent::preload(server, errorStr))
return false;
if (!server)
{
if (txr_name && txr_name[0] != '\0')
{
txr.set(txr_name, &AFX_GFXZodiacTextureProfile, "Zodiac Texture");
}
}
return true;
}
F32 afxZodiacPlaneData::calcRotationAngle(F32 elapsed, F32 rate_factor)
{
F32 angle = start_ang + elapsed*ang_per_sec*rate_factor;
angle = mFmod(angle, 360.0f);
return angle;
}
void afxZodiacPlaneData::expand_zflags()
{
blend_flags = (zflags & BLEND_MASK);
respect_ori_cons = ((zflags & RESPECT_ORIENTATION) != 0);
}
void afxZodiacPlaneData::merge_zflags()
{
zflags = (blend_flags & BLEND_MASK);
if (respect_ori_cons)
zflags |= RESPECT_ORIENTATION;
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacPlane
IMPLEMENT_CO_NETOBJECT_V1(afxZodiacPlane);
ConsoleDocClass( afxZodiacPlane,
"@brief A ZodiacPlane effect as defined by an afxZodiacPlaneData datablock.\n\n"
"@ingroup afxEffects\n"
"@ingroup AFX\n"
);
afxZodiacPlane::afxZodiacPlane()
{
mNetFlags.clear();
mNetFlags.set(IsGhost);
mDataBlock = 0;
color.set(1,1,1,1);
radius = 1;
is_visible = true;
}
afxZodiacPlane::~afxZodiacPlane()
{
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
bool afxZodiacPlane::onNewDataBlock(GameBaseData* dptr, bool reload)
{
mDataBlock = dynamic_cast<afxZodiacPlaneData*>(dptr);
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
return false;
return true;
}
bool afxZodiacPlane::onAdd()
{
if(!Parent::onAdd())
return false;
F32 len = mDataBlock->radius_xy;
switch (mDataBlock->face_dir)
{
case afxZodiacPlaneData::FACES_UP:
case afxZodiacPlaneData::FACES_DOWN:
mObjBox = Box3F(Point3F(-len, -len, -0.01f), Point3F(len, len, 0.01f));
break;
case afxZodiacPlaneData::FACES_FORWARD:
case afxZodiacPlaneData::FACES_BACK:
mObjBox = Box3F(Point3F(-len, -0.01f, -len), Point3F(len, 0.01f, len));
break;
case afxZodiacPlaneData::FACES_RIGHT:
case afxZodiacPlaneData::FACES_LEFT:
mObjBox = Box3F(Point3F(-0.01f, -len, -len), Point3F(0.01f, len, len));
break;
}
addToScene();
return true;
}
void afxZodiacPlane::onRemove()
{
removeFromScene();
Parent::onRemove();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//

View file

@ -0,0 +1,143 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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_ZODIAC_PLANE_H_
#define _AFX_ZODIAC_PLANE_H_
#include "afx/ce/afxZodiacDefs.h"
class afxZodiacPlaneData : public GameBaseData, public afxZodiacDefs
{
typedef GameBaseData Parent;
public:
enum BlendType
{
BLEND_NORMAL = 0x0,
BLEND_ADDITIVE = 0x1,
BLEND_SUBTRACTIVE = 0x2,
BLEND_RESERVED = 0x3,
BLEND_MASK = 0x3
};
enum FacingType
{
FACES_UP = 0,
FACES_DOWN,
FACES_FORWARD,
FACES_BACK,
FACES_RIGHT,
FACES_LEFT,
FACES_BITS = 3
};
public:
StringTableEntry txr_name;
GFXTexHandle txr;
F32 radius_xy;
F32 start_ang;
F32 ang_per_sec;
F32 grow_in_time;
F32 shrink_out_time;
F32 growth_rate;
LinearColorF color;
U32 blend_flags;
bool respect_ori_cons;
bool use_full_xfm;
U32 zflags;
U32 face_dir;
bool double_sided;
void expand_zflags();
void merge_zflags();
public:
/*C*/ afxZodiacPlaneData();
/*C*/ afxZodiacPlaneData(const afxZodiacPlaneData&, bool = false);
virtual void packData(BitStream*);
virtual void unpackData(BitStream*);
bool preload(bool server, String &errorStr);
virtual bool allowSubstitutions() const { return true; }
F32 calcRotationAngle(F32 elapsed, F32 rate_factor=1.0f);
static void initPersistFields();
DECLARE_CONOBJECT(afxZodiacPlaneData);
DECLARE_CATEGORY("AFX");
};
typedef afxZodiacPlaneData::BlendType afxZodiacPlane_BlendType;
DefineEnumType( afxZodiacPlane_BlendType );
typedef afxZodiacPlaneData::FacingType afxZodiacPlane_FacingType;
DefineEnumType( afxZodiacPlane_FacingType );
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// afxZodiacPlane
class afxZodiacPlane : public GameBase, public afxZodiacDefs
{
typedef GameBase Parent;
private:
afxZodiacPlaneData* mDataBlock;
LinearColorF color;
F32 radius;
bool is_visible;
void preDraw();
void draw();
void postDraw();
GFXStateBlockRef normal_sb;
GFXStateBlockRef reflected_sb;
public:
/*C*/ afxZodiacPlane();
/*D*/ ~afxZodiacPlane();
virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
virtual bool onAdd();
virtual void onRemove();
void setRadius(F32 rad) { radius = rad; }
void setColor(const LinearColorF& clr) { color = clr; }
void setVisibility(bool flag) { is_visible = flag; }
virtual void prepRenderImage(SceneRenderState*);
void _renderZodiacPlane(ObjectRenderInst*, SceneRenderState*, BaseMatInstance*);
DECLARE_CONOBJECT(afxZodiacPlane);
DECLARE_CATEGORY("AFX");
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
#endif // _AFX_ZODIAC_PLANE_H_

View file

@ -0,0 +1,229 @@
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
// 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 "gfx/gfxTransformSaver.h"
#include "gfx/primBuilder.h"
#include "afx/afxChoreographer.h"
#include "afx/ce/afxZodiacPlane.h"
void afxZodiacPlane::prepRenderImage(SceneRenderState* state)
{
if (!is_visible)
return;
ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
ri->renderDelegate.bind(this, &afxZodiacPlane::_renderZodiacPlane);
ri->type = RenderPassManager::RIT_ObjectTranslucent;
ri->translucentSort = true;
ri->defaultKey = (U32)(dsize_t)mDataBlock;
if (false)
{
ri->sortDistSq = getWorldBox().getSqDistanceToPoint( state->getCameraPosition() );
}
else // (sort by radius distance)
{
Point3F xyz_scale = getScale();
F32 uni_scalar = getMax(xyz_scale.x, xyz_scale.y);
uni_scalar = getMax(uni_scalar, xyz_scale.z);
Point3F uni_scale(uni_scalar, uni_scalar, uni_scalar);
Point3F local_cam_pos = state->getCameraPosition();
getRenderWorldTransform().mulP(local_cam_pos);
local_cam_pos.convolveInverse(uni_scale);
switch (mDataBlock->face_dir)
{
case afxZodiacPlaneData::FACES_UP:
case afxZodiacPlaneData::FACES_DOWN:
local_cam_pos.z = 0;
break;
case afxZodiacPlaneData::FACES_FORWARD:
case afxZodiacPlaneData::FACES_BACK:
local_cam_pos.y = 0;
break;
case afxZodiacPlaneData::FACES_RIGHT:
case afxZodiacPlaneData::FACES_LEFT:
local_cam_pos.x = 0;
break;
}
/* AFX_T3D_BROKEN -- enhanced transparency sorting of ZodiacPlanes JTF Note: evaluate this
if (local_cam_pos.lenSquared() <= radius*radius)
{
ri->sortPoint = local_cam_pos;
}
else
{
local_cam_pos.normalize();
ri->sortPoint = local_cam_pos*radius;
}
ri->sortPoint.convolve(uni_scale);
getRenderTransform().mulP(ri->sortPoint);
*/
}
state->getRenderPass()->addInst(ri);
}
void afxZodiacPlane::_renderZodiacPlane(ObjectRenderInst *ri, SceneRenderState* state, BaseMatInstance* overrideMat)
{
if (overrideMat)
return;
// projection
// predraw
if (normal_sb.isNull())
{
GFXStateBlockDesc desc;
// Culling
desc.setCullMode((mDataBlock->double_sided) ? GFXCullNone : GFXCullCW);
// Blending
U32 blend = (mDataBlock->zflags & BLEND_MASK);
switch (blend)
{
case BLEND_ADDITIVE:
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendOne);
break;
case BLEND_SUBTRACTIVE:
desc.setBlend(true, GFXBlendZero, GFXBlendInvSrcColor);
break;
case BLEND_NORMAL:
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
break;
}
// JTF Note: check this desc.setAlphaTest((blend != BLEND_SUBTRACTIVE), GFXCmpGreater, 0);
desc.setAlphaTest(true, GFXCmpGreater, 0);
desc.setZReadWrite(true);
desc.zFunc = GFXCmpLessEqual;
desc.zWriteEnable = false;
desc.samplersDefined = true;
desc.samplers[0].textureColorOp = GFXTOPModulate;
desc.samplers[1].textureColorOp = GFXTOPDisable;
normal_sb = GFX->createStateBlock(desc);
if (mDataBlock->double_sided)
reflected_sb = normal_sb;
else
{
desc.setCullMode(GFXCullCCW);
reflected_sb = GFX->createStateBlock(desc);
}
}
if (state->isReflectPass())
GFX->setStateBlock(reflected_sb);
else
GFX->setStateBlock(normal_sb);
Point3F basePoints[4];
switch (mDataBlock->face_dir)
{
case afxZodiacPlaneData::FACES_UP:
basePoints[0].set( 0.5f, -0.5f, 0.0f);
basePoints[1].set(-0.5f, -0.5f, 0.0f);
basePoints[2].set(-0.5f, 0.5f, 0.0f);
basePoints[3].set( 0.5f, 0.5f, 0.0f);
break;
case afxZodiacPlaneData::FACES_DOWN:
basePoints[3].set(-0.5f, 0.5f, 0.0f);
basePoints[2].set( 0.5f, 0.5f, 0.0f);
basePoints[1].set( 0.5f, -0.5f, 0.0f);
basePoints[0].set(-0.5f, -0.5f, 0.0f);
break;
case afxZodiacPlaneData::FACES_FORWARD:
basePoints[0].set( 0.5f, 0.0f, -0.5f);
basePoints[1].set(-0.5f, 0.0f, -0.5f);
basePoints[2].set(-0.5f, 0.0f, 0.5f);
basePoints[3].set( 0.5f, 0.0f, 0.5f);
break;
case afxZodiacPlaneData::FACES_BACK:
basePoints[3].set(-0.5f, 0.0f, 0.5f);
basePoints[2].set( 0.5f, 0.0f, 0.5f);
basePoints[1].set( 0.5f, 0.0f, -0.5f);
basePoints[0].set(-0.5f, 0.0f, -0.5f);
break;
case afxZodiacPlaneData::FACES_RIGHT:
basePoints[0].set(0.0f, 0.5f, -0.5f);
basePoints[1].set(0.0f, -0.5f, -0.5f);
basePoints[2].set(0.0f, -0.5f, 0.5f);
basePoints[3].set(0.0f, 0.5f, 0.5f);
break;
case afxZodiacPlaneData::FACES_LEFT:
basePoints[3].set(0.0f, -0.5f, 0.5f);
basePoints[2].set(0.0f, 0.5f, 0.5f);
basePoints[1].set(0.0f, 0.5f, -0.5f);
basePoints[0].set(0.0f, -0.5f, -0.5f);
break;
}
F32 len = 2*radius;
Point3F points[4];
Point2F texCoords[4]; // default: {{0.0,0.0}, {0.0,1.0}, {1.0,1.0}, {1.0,0.0}}
texCoords[0].set(1.0,1.0);
texCoords[1].set(0.0,1.0);
texCoords[2].set(0.0,0.0);
texCoords[3].set(1.0,0.0);
for( int i=0; i<4; i++ )
{
points[i].x = basePoints[i].x;
points[i].y = basePoints[i].y;
points[i].z = basePoints[i].z;
points[i] *= len;
}
GFXTransformSaver saver;
GFX->multWorld(getRenderTransform());
GFX->setTexture(0, mDataBlock->txr);
PrimBuild::begin(GFXTriangleStrip, 4);
{
PrimBuild::color4f(color.red, color.green, color.blue, color.alpha);
PrimBuild::texCoord2f(texCoords[1].x, texCoords[1].y);
PrimBuild::vertex3f(points[1].x, points[1].y, points[1].z);
PrimBuild::texCoord2f(texCoords[0].x, texCoords[0].y);
PrimBuild::vertex3f(points[0].x, points[0].y, points[0].z);
PrimBuild::texCoord2f(texCoords[2].x, texCoords[2].y);
PrimBuild::vertex3f(points[2].x, points[2].y, points[2].z);
PrimBuild::texCoord2f(texCoords[3].x, texCoords[3].y);
PrimBuild::vertex3f(points[3].x, points[3].y, points[3].z);
}
PrimBuild::end();
}
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//