123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- #include "pch.h"
- //////////////////////////////////////////////////////////////////////////////
- //
- // ExplosionGeo
- //
- //////////////////////////////////////////////////////////////////////////////
- class ExplosionGeoImpl :
- public ExplosionGeo
- {
- private:
- //////////////////////////////////////////////////////////////////////////////
- //
- // Types
- //
- //////////////////////////////////////////////////////////////////////////////
- class ExplosionData : IObject {
- public:
- TRef<AnimatedImage> m_pimage;
- Vector m_position;
- Vector m_dposition;
- float m_angle;
- float m_timeStart;
- float m_scale;
- };
- class ShockwaveData : IObject {
- public:
- TRef<Image> m_pimageShockwave;
- Vector m_position;
- Vector m_dposition;
- Vector m_forward;
- Vector m_right;
- Color m_color;
- float m_timeStart;
- float m_scale;
- };
- typedef TList<ExplosionData> ExplosionDataList;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Members
- //
- //////////////////////////////////////////////////////////////////////////////
- TList<ShockwaveData> m_listShockwave;
- TVector<ExplosionDataList> m_vlistExplosion;
- //////////////////////////////////////////////////////////////////////////////
- //
- // Value Members
- //
- //////////////////////////////////////////////////////////////////////////////
- Number* GetTime() { return Number::Cast(GetChild(0)); }
- public:
- ExplosionGeoImpl(Number* ptime) :
- ExplosionGeo(ptime),
- m_vlistExplosion(24)
- {
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Methods
- //
- //////////////////////////////////////////////////////////////////////////////
- void AddExplosion(
- const Vector& position,
- const Vector& forward,
- const Vector& right,
- const Vector& dposition,
- float radiusExplosion,
- float radiusShockWave,
- const Color& color,
- int countDecals,
- TVector<TRef<AnimatedImage> > vpimage,
- Image* pimageShockwave
- ) {
- //
- // Add the shockwave
- //
- if (pimageShockwave != NULL) {
- m_listShockwave.PushFront();
- ShockwaveData& sdata = m_listShockwave.GetFront();
- sdata.m_timeStart = GetTime()->GetValue();
- sdata.m_pimageShockwave = pimageShockwave;
- sdata.m_color = color;
- sdata.m_position = position;
- sdata.m_dposition = dposition;
- sdata.m_scale = radiusShockWave;
- sdata.m_forward = forward;
- sdata.m_right = right;
- }
- //
- // Add the little explosions
- //
- int countImage = vpimage.GetCount();
- int indexImage = 0;
- for (int index = 0; index < countDecals; index++) {
- ExplosionDataList& list = m_vlistExplosion.Get(index);
- list.PushFront();
- ExplosionData& edata = list.GetFront();
- edata.m_timeStart = GetTime()->GetValue() + index * 0.25f;
- edata.m_pimage = vpimage[indexImage];
- edata.m_position = position + Vector::RandomPosition(radiusExplosion * 0.5f);
- edata.m_dposition = dposition;
- edata.m_angle = random(0, 2 * pi);
- edata.m_scale = radiusExplosion;
- indexImage++;
- if (indexImage >= countImage) {
- indexImage = 0;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Value Methods
- //
- //////////////////////////////////////////////////////////////////////////////
- ZString GetFunctionName() { return "ExplosionGeo"; }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Geometry Methods
- //
- //////////////////////////////////////////////////////////////////////////////
- float RenderShockwaves(Context* pcontext)
- {
- float fill = 0;
- TList<ShockwaveData>::Iterator iter(m_listShockwave);
- while (!iter.End()) {
- ShockwaveData& sdata = iter.Value();
- float time = GetTime()->GetValue() - sdata.m_timeStart;
- float bright = 1.0f - time * time;
- if (bright <= 0) {
- iter.Remove();
- } else {
- float scale = time * sdata.m_scale;
- fill +=
- pcontext->DrawDecal(
- sdata.m_pimageShockwave->GetSurface(),
- bright * sdata.m_color,
- sdata.m_position + time * sdata.m_dposition,
- scale * sdata.m_forward,
- scale * sdata.m_right,
- 0,
- 0
- );
- iter.Next();
- }
- };
- return fill;
- }
- float RenderExplosions(
- Context* pcontext,
- ExplosionDataList& list
- ) {
- float fill = 0;
- ExplosionDataList::Iterator iter(list);
- while (!iter.End()) {
- ExplosionData& edata = iter.Value();
- float time = GetTime()->GetValue() - edata.m_timeStart;
- if (time >= 0) {
- int frame = (int)(time * 20.0f);
- if (frame >= edata.m_pimage->GetCount()) {
- iter.Remove();
- continue;
- } else {
- fill +=
- pcontext->DrawDecal(
- edata.m_pimage->GetSurface(frame),
- Color::White(),
- edata.m_position + time * edata.m_dposition,
- Vector::GetZero(),
- Vector::GetZero(),
- edata.m_scale,
- edata.m_angle
- );
- }
- }
- iter.Next();
- }
- return fill;
- }
- void Render(Context* pcontext)
- {
- float fill = 0;
-
- fill += RenderShockwaves(pcontext);
- int count = m_vlistExplosion.GetCount();
- for (int index = 0; index < count; index++) {
- fill += RenderExplosions(pcontext, m_vlistExplosion.Get(index));
- //
- // If we have passed the fill limit throw away the rest of the explosions
- //
- if (fill > 2.0f) {
- for (int index2 = index + 1; index2 < count; index2++) {
- m_vlistExplosion.Get(index2).SetEmpty();
- }
- return;
- }
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // ExplosionGeo Factory
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<ExplosionGeo> CreateExplosionGeo(Number* ptime)
- {
- return new ExplosionGeoImpl(ptime);
- }
|