mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-13 18:17:49 -04:00
Fix line endings and tabs
This commit is contained in:
@ -1,34 +1,34 @@
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
set(plParticleSystem_SOURCES
|
||||
plBoundInterface.cpp
|
||||
plConvexVolume.cpp
|
||||
plParticleApplicator.cpp
|
||||
plParticleEffect.cpp
|
||||
plParticleEmitter.cpp
|
||||
plParticleGenerator.cpp
|
||||
plParticleSDLMod.cpp
|
||||
plParticleSystem.cpp
|
||||
)
|
||||
|
||||
set(plParticleSystem_HEADERS
|
||||
plBoundInterface.h
|
||||
plConvexVolume.h
|
||||
plEffectTargetInfo.h
|
||||
plParticle.h
|
||||
plParticleApplicator.h
|
||||
plParticleCreatable.h
|
||||
plParticleEffect.h
|
||||
plParticleEmitter.h
|
||||
plParticleGenerator.h
|
||||
plParticleSDLMod.h
|
||||
plParticleSystem.h
|
||||
)
|
||||
|
||||
add_library(plParticleSystem STATIC ${plParticleSystem_SOURCES} ${plParticleSystem_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plParticleSystem_SOURCES})
|
||||
source_group("Header Files" FILES ${plParticleSystem_HEADERS})
|
||||
include_directories("../../CoreLib")
|
||||
include_directories("../../NucleusLib/inc")
|
||||
include_directories("../../NucleusLib")
|
||||
include_directories("../../PubUtilLib")
|
||||
|
||||
set(plParticleSystem_SOURCES
|
||||
plBoundInterface.cpp
|
||||
plConvexVolume.cpp
|
||||
plParticleApplicator.cpp
|
||||
plParticleEffect.cpp
|
||||
plParticleEmitter.cpp
|
||||
plParticleGenerator.cpp
|
||||
plParticleSDLMod.cpp
|
||||
plParticleSystem.cpp
|
||||
)
|
||||
|
||||
set(plParticleSystem_HEADERS
|
||||
plBoundInterface.h
|
||||
plConvexVolume.h
|
||||
plEffectTargetInfo.h
|
||||
plParticle.h
|
||||
plParticleApplicator.h
|
||||
plParticleCreatable.h
|
||||
plParticleEffect.h
|
||||
plParticleEmitter.h
|
||||
plParticleGenerator.h
|
||||
plParticleSDLMod.h
|
||||
plParticleSystem.h
|
||||
)
|
||||
|
||||
add_library(plParticleSystem STATIC ${plParticleSystem_SOURCES} ${plParticleSystem_HEADERS})
|
||||
|
||||
source_group("Source Files" FILES ${plParticleSystem_SOURCES})
|
||||
source_group("Header Files" FILES ${plParticleSystem_HEADERS})
|
||||
|
@ -1,76 +1,76 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsGeometry3.h"
|
||||
#include "plBoundInterface.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
plBoundInterface::plBoundInterface() : fBounds(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plBoundInterface::~plBoundInterface()
|
||||
{
|
||||
ReleaseData();
|
||||
}
|
||||
|
||||
void plBoundInterface::ReleaseData()
|
||||
{
|
||||
delete fBounds;
|
||||
fBounds = nil;
|
||||
}
|
||||
|
||||
void plBoundInterface::Init(plConvexVolume *bounds)
|
||||
{
|
||||
ReleaseData();
|
||||
fBounds = bounds;
|
||||
}
|
||||
|
||||
// Right now, this is ignoring the enabled property of ObjInterface, since I'm not aware that
|
||||
// anything ever makes use of it (and if nothing does, this saves us on some needless matrix
|
||||
// copying). Should we make use of the disabled prop, this function should just store the l2w
|
||||
// matrix, but not send an update to fBounds.
|
||||
void plBoundInterface::SetTransform(const hsMatrix44 &l2w, const hsMatrix44&w2l)
|
||||
{
|
||||
if (fBounds != nil)
|
||||
fBounds->Update(l2w);
|
||||
}
|
||||
|
||||
void plBoundInterface::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Read(s, mgr);
|
||||
fBounds = plConvexVolume::ConvertNoRef(mgr->ReadCreatable(s));
|
||||
//mgr->ReadKeyNotifyMe(s, new plIntRefMsg(GetKey(), plRefMsg::kOnCreate, 0, plIntRefMsg::kOwner), plRefFlags::kPassiveRef);
|
||||
}
|
||||
|
||||
void plBoundInterface::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Write(s, mgr);
|
||||
mgr->WriteCreatable(s, fBounds);
|
||||
//mgr->WriteKey(s, fBounds);
|
||||
}
|
||||
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsGeometry3.h"
|
||||
#include "plBoundInterface.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
plBoundInterface::plBoundInterface() : fBounds(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plBoundInterface::~plBoundInterface()
|
||||
{
|
||||
ReleaseData();
|
||||
}
|
||||
|
||||
void plBoundInterface::ReleaseData()
|
||||
{
|
||||
delete fBounds;
|
||||
fBounds = nil;
|
||||
}
|
||||
|
||||
void plBoundInterface::Init(plConvexVolume *bounds)
|
||||
{
|
||||
ReleaseData();
|
||||
fBounds = bounds;
|
||||
}
|
||||
|
||||
// Right now, this is ignoring the enabled property of ObjInterface, since I'm not aware that
|
||||
// anything ever makes use of it (and if nothing does, this saves us on some needless matrix
|
||||
// copying). Should we make use of the disabled prop, this function should just store the l2w
|
||||
// matrix, but not send an update to fBounds.
|
||||
void plBoundInterface::SetTransform(const hsMatrix44 &l2w, const hsMatrix44&w2l)
|
||||
{
|
||||
if (fBounds != nil)
|
||||
fBounds->Update(l2w);
|
||||
}
|
||||
|
||||
void plBoundInterface::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Read(s, mgr);
|
||||
fBounds = plConvexVolume::ConvertNoRef(mgr->ReadCreatable(s));
|
||||
//mgr->ReadKeyNotifyMe(s, new plIntRefMsg(GetKey(), plRefMsg::kOnCreate, 0, plIntRefMsg::kOwner), plRefFlags::kPassiveRef);
|
||||
}
|
||||
|
||||
void plBoundInterface::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Write(s, mgr);
|
||||
mgr->WriteCreatable(s, fBounds);
|
||||
//mgr->WriteKey(s, fBounds);
|
||||
}
|
||||
|
||||
// No need to save/load. The coordinate interface on our sceneObject will update us.
|
@ -1,67 +1,67 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plBoundInterface_inc
|
||||
#define plBoundInterface_inc
|
||||
|
||||
#include "pnSceneObject/plObjInterface.h"
|
||||
|
||||
class plConvexVolume;
|
||||
struct hsMatrix44;
|
||||
|
||||
class plBoundInterface : public plObjInterface
|
||||
{
|
||||
enum {
|
||||
kDisable = 0x0,
|
||||
|
||||
kNumProps // last
|
||||
};
|
||||
|
||||
protected:
|
||||
//hsMatrix44 fLocalToWorld;
|
||||
plConvexVolume *fBounds;
|
||||
|
||||
public:
|
||||
plBoundInterface();
|
||||
~plBoundInterface();
|
||||
|
||||
void Init(plConvexVolume *bounds);
|
||||
plConvexVolume *GetVolume() { return fBounds; }
|
||||
|
||||
CLASSNAME_REGISTER( plBoundInterface );
|
||||
GETINTERFACE_ANY( plBoundInterface, plObjInterface );
|
||||
|
||||
virtual Int32 GetNumProperties() const { return kNumProps; }
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
virtual void ReleaseData();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // plBoundInterface_inc
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plBoundInterface_inc
|
||||
#define plBoundInterface_inc
|
||||
|
||||
#include "pnSceneObject/plObjInterface.h"
|
||||
|
||||
class plConvexVolume;
|
||||
struct hsMatrix44;
|
||||
|
||||
class plBoundInterface : public plObjInterface
|
||||
{
|
||||
enum {
|
||||
kDisable = 0x0,
|
||||
|
||||
kNumProps // last
|
||||
};
|
||||
|
||||
protected:
|
||||
//hsMatrix44 fLocalToWorld;
|
||||
plConvexVolume *fBounds;
|
||||
|
||||
public:
|
||||
plBoundInterface();
|
||||
~plBoundInterface();
|
||||
|
||||
void Init(plConvexVolume *bounds);
|
||||
plConvexVolume *GetVolume() { return fBounds; }
|
||||
|
||||
CLASSNAME_REGISTER( plBoundInterface );
|
||||
GETINTERFACE_ANY( plBoundInterface, plObjInterface );
|
||||
|
||||
virtual Int32 GetNumProperties() const { return kNumProps; }
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
virtual void ReleaseData();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // plBoundInterface_inc
|
||||
|
@ -1,193 +1,193 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
plConvexVolume::plConvexVolume()
|
||||
{
|
||||
//fFlags = nil;
|
||||
fLocalPlanes = nil;
|
||||
fWorldPlanes = nil;
|
||||
fNumPlanes = 0;
|
||||
}
|
||||
|
||||
plConvexVolume::~plConvexVolume()
|
||||
{
|
||||
IClear();
|
||||
}
|
||||
|
||||
void plConvexVolume::IClear()
|
||||
{
|
||||
//delete [] fFlags;
|
||||
delete [] fLocalPlanes;
|
||||
delete [] fWorldPlanes;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::AddPlane(const hsPlane3 &plane)
|
||||
{
|
||||
// First check for a redundant plane (since we're convex, a comparison of normals should do)
|
||||
int i;
|
||||
// Start the comparison with the most recently added plane, it's most likely to match
|
||||
for (i = fNumPlanes - 1; i >= 0; i--)
|
||||
{
|
||||
const float MIN_COS_THETA = 0.99999f; // translates to < 0.25 degree angle
|
||||
// If the angle betwen the normals is close enough, count them as equal.
|
||||
if (fLocalPlanes[i].fN.InnerProduct(plane.fN) >= MIN_COS_THETA)
|
||||
return false; // no need to add it
|
||||
}
|
||||
fNumPlanes++;
|
||||
//delete [] fFlags;
|
||||
//fFlags = TRACKED_NEW UInt32[fNumPlanes];
|
||||
|
||||
hsPlane3 *tempPlanes = TRACKED_NEW hsPlane3[fNumPlanes];
|
||||
for (i = 0; i < fNumPlanes - 1; i++)
|
||||
{
|
||||
tempPlanes[i] = fLocalPlanes[i];
|
||||
}
|
||||
tempPlanes[fNumPlanes - 1] = plane;
|
||||
|
||||
delete [] fLocalPlanes;
|
||||
fLocalPlanes = tempPlanes;
|
||||
delete [] fWorldPlanes;
|
||||
fWorldPlanes = TRACKED_NEW hsPlane3[fNumPlanes];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plConvexVolume::Update(const hsMatrix44 &l2w)
|
||||
{
|
||||
int i;
|
||||
hsPoint3 planePt;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
// Since fN is an hsVector3, it will only apply the rotational aspect of the transform...
|
||||
fWorldPlanes[i].fN = l2w * fLocalPlanes[i].fN;
|
||||
planePt.Set(&(fLocalPlanes[i].fN * fLocalPlanes[i].fD));
|
||||
fWorldPlanes[i].fD = -(l2w * planePt).InnerProduct(fWorldPlanes[i].fN);
|
||||
}
|
||||
}
|
||||
|
||||
void plConvexVolume::SetNumPlanesAndClear(const UInt32 num)
|
||||
{
|
||||
IClear();
|
||||
//fFlags = TRACKED_NEW UInt32[num];
|
||||
fLocalPlanes = TRACKED_NEW hsPlane3[num];
|
||||
fWorldPlanes = TRACKED_NEW hsPlane3[num];
|
||||
fNumPlanes = num;
|
||||
}
|
||||
|
||||
void plConvexVolume::SetPlane(const hsPlane3 &plane, const UInt32 index)
|
||||
{
|
||||
fLocalPlanes[index] = plane;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::IsInside(const hsPoint3 &pos) const
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fNumPlanes; i++ )
|
||||
{
|
||||
if (!TestPlane(pos, fWorldPlanes[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::ResolvePoint(hsPoint3 &pos) const
|
||||
{
|
||||
hsScalar minDist = 1.e33f;
|
||||
Int32 minIndex = -1;
|
||||
|
||||
hsScalar currDist;
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
currDist = -fWorldPlanes[i].fD - fWorldPlanes[i].fN.InnerProduct(pos);
|
||||
if (currDist < 0)
|
||||
return false; // We're not inside this plane, and thus outside the volume
|
||||
|
||||
if (currDist < minDist)
|
||||
{
|
||||
minDist = currDist;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
pos += (-fWorldPlanes[minIndex].fD - fWorldPlanes[minIndex].fN.InnerProduct(pos)) * fWorldPlanes[minIndex].fN;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::BouncePoint(hsPoint3 &pos, hsVector3 &velocity, hsScalar bounce, hsScalar friction) const
|
||||
{
|
||||
hsScalar minDist = 1.e33f;
|
||||
Int32 minIndex = -1;
|
||||
|
||||
hsScalar currDist;
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
currDist = -fWorldPlanes[i].fD - fWorldPlanes[i].fN.InnerProduct(pos);
|
||||
if (currDist < 0)
|
||||
return false; // We're not inside this plane, and thus outside the volume
|
||||
|
||||
if (currDist < minDist)
|
||||
{
|
||||
minDist = currDist;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
pos += (-fWorldPlanes[minIndex].fD - fWorldPlanes[minIndex].fN.InnerProduct(pos)) * fWorldPlanes[minIndex].fN;
|
||||
hsVector3 bnc = -velocity.InnerProduct(fWorldPlanes[minIndex].fN) * fWorldPlanes[minIndex].fN;
|
||||
velocity += bnc;
|
||||
velocity *= 1.f - friction;
|
||||
velocity += bnc * bounce;
|
||||
// velocity += (velocity.InnerProduct(fWorldPlanes[minIndex].fN) * -(1.f + bounce)) * fWorldPlanes[minIndex].fN;
|
||||
return true;
|
||||
}
|
||||
|
||||
void plConvexVolume::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
SetNumPlanesAndClear(s->ReadSwap32());
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
fLocalPlanes[i].Read(s);
|
||||
//fFlags[i] = s->ReadSwap32();
|
||||
}
|
||||
}
|
||||
|
||||
void plConvexVolume::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwap32(fNumPlanes);
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
fLocalPlanes[i].Write(s);
|
||||
//s->WriteSwap32(fFlags[i]);
|
||||
}
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
plConvexVolume::plConvexVolume()
|
||||
{
|
||||
//fFlags = nil;
|
||||
fLocalPlanes = nil;
|
||||
fWorldPlanes = nil;
|
||||
fNumPlanes = 0;
|
||||
}
|
||||
|
||||
plConvexVolume::~plConvexVolume()
|
||||
{
|
||||
IClear();
|
||||
}
|
||||
|
||||
void plConvexVolume::IClear()
|
||||
{
|
||||
//delete [] fFlags;
|
||||
delete [] fLocalPlanes;
|
||||
delete [] fWorldPlanes;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::AddPlane(const hsPlane3 &plane)
|
||||
{
|
||||
// First check for a redundant plane (since we're convex, a comparison of normals should do)
|
||||
int i;
|
||||
// Start the comparison with the most recently added plane, it's most likely to match
|
||||
for (i = fNumPlanes - 1; i >= 0; i--)
|
||||
{
|
||||
const float MIN_COS_THETA = 0.99999f; // translates to < 0.25 degree angle
|
||||
// If the angle betwen the normals is close enough, count them as equal.
|
||||
if (fLocalPlanes[i].fN.InnerProduct(plane.fN) >= MIN_COS_THETA)
|
||||
return false; // no need to add it
|
||||
}
|
||||
fNumPlanes++;
|
||||
//delete [] fFlags;
|
||||
//fFlags = TRACKED_NEW UInt32[fNumPlanes];
|
||||
|
||||
hsPlane3 *tempPlanes = TRACKED_NEW hsPlane3[fNumPlanes];
|
||||
for (i = 0; i < fNumPlanes - 1; i++)
|
||||
{
|
||||
tempPlanes[i] = fLocalPlanes[i];
|
||||
}
|
||||
tempPlanes[fNumPlanes - 1] = plane;
|
||||
|
||||
delete [] fLocalPlanes;
|
||||
fLocalPlanes = tempPlanes;
|
||||
delete [] fWorldPlanes;
|
||||
fWorldPlanes = TRACKED_NEW hsPlane3[fNumPlanes];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plConvexVolume::Update(const hsMatrix44 &l2w)
|
||||
{
|
||||
int i;
|
||||
hsPoint3 planePt;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
// Since fN is an hsVector3, it will only apply the rotational aspect of the transform...
|
||||
fWorldPlanes[i].fN = l2w * fLocalPlanes[i].fN;
|
||||
planePt.Set(&(fLocalPlanes[i].fN * fLocalPlanes[i].fD));
|
||||
fWorldPlanes[i].fD = -(l2w * planePt).InnerProduct(fWorldPlanes[i].fN);
|
||||
}
|
||||
}
|
||||
|
||||
void plConvexVolume::SetNumPlanesAndClear(const UInt32 num)
|
||||
{
|
||||
IClear();
|
||||
//fFlags = TRACKED_NEW UInt32[num];
|
||||
fLocalPlanes = TRACKED_NEW hsPlane3[num];
|
||||
fWorldPlanes = TRACKED_NEW hsPlane3[num];
|
||||
fNumPlanes = num;
|
||||
}
|
||||
|
||||
void plConvexVolume::SetPlane(const hsPlane3 &plane, const UInt32 index)
|
||||
{
|
||||
fLocalPlanes[index] = plane;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::IsInside(const hsPoint3 &pos) const
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fNumPlanes; i++ )
|
||||
{
|
||||
if (!TestPlane(pos, fWorldPlanes[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::ResolvePoint(hsPoint3 &pos) const
|
||||
{
|
||||
hsScalar minDist = 1.e33f;
|
||||
Int32 minIndex = -1;
|
||||
|
||||
hsScalar currDist;
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
currDist = -fWorldPlanes[i].fD - fWorldPlanes[i].fN.InnerProduct(pos);
|
||||
if (currDist < 0)
|
||||
return false; // We're not inside this plane, and thus outside the volume
|
||||
|
||||
if (currDist < minDist)
|
||||
{
|
||||
minDist = currDist;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
pos += (-fWorldPlanes[minIndex].fD - fWorldPlanes[minIndex].fN.InnerProduct(pos)) * fWorldPlanes[minIndex].fN;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plConvexVolume::BouncePoint(hsPoint3 &pos, hsVector3 &velocity, hsScalar bounce, hsScalar friction) const
|
||||
{
|
||||
hsScalar minDist = 1.e33f;
|
||||
Int32 minIndex = -1;
|
||||
|
||||
hsScalar currDist;
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
currDist = -fWorldPlanes[i].fD - fWorldPlanes[i].fN.InnerProduct(pos);
|
||||
if (currDist < 0)
|
||||
return false; // We're not inside this plane, and thus outside the volume
|
||||
|
||||
if (currDist < minDist)
|
||||
{
|
||||
minDist = currDist;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
pos += (-fWorldPlanes[minIndex].fD - fWorldPlanes[minIndex].fN.InnerProduct(pos)) * fWorldPlanes[minIndex].fN;
|
||||
hsVector3 bnc = -velocity.InnerProduct(fWorldPlanes[minIndex].fN) * fWorldPlanes[minIndex].fN;
|
||||
velocity += bnc;
|
||||
velocity *= 1.f - friction;
|
||||
velocity += bnc * bounce;
|
||||
// velocity += (velocity.InnerProduct(fWorldPlanes[minIndex].fN) * -(1.f + bounce)) * fWorldPlanes[minIndex].fN;
|
||||
return true;
|
||||
}
|
||||
|
||||
void plConvexVolume::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
SetNumPlanesAndClear(s->ReadSwap32());
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
fLocalPlanes[i].Read(s);
|
||||
//fFlags[i] = s->ReadSwap32();
|
||||
}
|
||||
}
|
||||
|
||||
void plConvexVolume::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwap32(fNumPlanes);
|
||||
int i;
|
||||
for (i = 0; i < fNumPlanes; i++)
|
||||
{
|
||||
fLocalPlanes[i].Write(s);
|
||||
//s->WriteSwap32(fFlags[i]);
|
||||
}
|
||||
}
|
||||
|
@ -1,87 +1,87 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plConvexVolume_inc
|
||||
#define plConvexVolume_inc
|
||||
|
||||
#include "pnSceneObject/plObjInterface.h"
|
||||
|
||||
struct hsPlane3;
|
||||
struct hsPoint3;
|
||||
struct hsMatrix44;
|
||||
class hsResMgr;
|
||||
|
||||
// A convex volume defined by several boundary planes
|
||||
// For now it assumes the user won't add planes that make it concave
|
||||
|
||||
class plConvexVolume : public plCreatable
|
||||
{
|
||||
public:
|
||||
plConvexVolume();
|
||||
~plConvexVolume();
|
||||
|
||||
CLASSNAME_REGISTER( plConvexVolume );
|
||||
GETINTERFACE_ANY( plConvexVolume, plCreatable );
|
||||
|
||||
void Update(const hsMatrix44 &l2w);
|
||||
|
||||
hsBool AddPlane(const hsPlane3 &plane);
|
||||
void SetNumPlanesAndClear(const UInt32 num);
|
||||
void SetPlane(const hsPlane3 &plane, const UInt32 index);
|
||||
|
||||
// If you only care about the test, call this. Otherwise call ResolvePoint.
|
||||
hsBool IsInside(const hsPoint3 &pos) const;
|
||||
|
||||
// returns true if the point was inside the volume, and thus moved outward.
|
||||
hsBool ResolvePoint(hsPoint3 &pos) const;
|
||||
|
||||
// returns true if the point was inside and pos and velocity updated to bounce off offending plane.
|
||||
// input bounce==1.f for perfect bounce, bounce==0 to slide.
|
||||
hsBool BouncePoint(hsPoint3 &pos, hsVector3 &velocity, hsScalar bounce, hsScalar friction) const;
|
||||
|
||||
inline hsBool TestPlane(const hsPoint3 &pos, const hsPlane3 &plane) const; // Is the point inside the plane?
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
//virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
protected:
|
||||
void IClear();
|
||||
|
||||
hsPlane3 *fLocalPlanes;
|
||||
hsPlane3 *fWorldPlanes;
|
||||
UInt32 fNumPlanes;
|
||||
};
|
||||
|
||||
inline hsBool plConvexVolume::TestPlane(const hsPoint3 &pos, const hsPlane3 &plane) const
|
||||
{
|
||||
hsScalar dis = plane.fN.InnerProduct(pos);
|
||||
dis += plane.fD;
|
||||
if( dis >= 0.f )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plConvexVolume_inc
|
||||
#define plConvexVolume_inc
|
||||
|
||||
#include "pnSceneObject/plObjInterface.h"
|
||||
|
||||
struct hsPlane3;
|
||||
struct hsPoint3;
|
||||
struct hsMatrix44;
|
||||
class hsResMgr;
|
||||
|
||||
// A convex volume defined by several boundary planes
|
||||
// For now it assumes the user won't add planes that make it concave
|
||||
|
||||
class plConvexVolume : public plCreatable
|
||||
{
|
||||
public:
|
||||
plConvexVolume();
|
||||
~plConvexVolume();
|
||||
|
||||
CLASSNAME_REGISTER( plConvexVolume );
|
||||
GETINTERFACE_ANY( plConvexVolume, plCreatable );
|
||||
|
||||
void Update(const hsMatrix44 &l2w);
|
||||
|
||||
hsBool AddPlane(const hsPlane3 &plane);
|
||||
void SetNumPlanesAndClear(const UInt32 num);
|
||||
void SetPlane(const hsPlane3 &plane, const UInt32 index);
|
||||
|
||||
// If you only care about the test, call this. Otherwise call ResolvePoint.
|
||||
hsBool IsInside(const hsPoint3 &pos) const;
|
||||
|
||||
// returns true if the point was inside the volume, and thus moved outward.
|
||||
hsBool ResolvePoint(hsPoint3 &pos) const;
|
||||
|
||||
// returns true if the point was inside and pos and velocity updated to bounce off offending plane.
|
||||
// input bounce==1.f for perfect bounce, bounce==0 to slide.
|
||||
hsBool BouncePoint(hsPoint3 &pos, hsVector3 &velocity, hsScalar bounce, hsScalar friction) const;
|
||||
|
||||
inline hsBool TestPlane(const hsPoint3 &pos, const hsPlane3 &plane) const; // Is the point inside the plane?
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
//virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
protected:
|
||||
void IClear();
|
||||
|
||||
hsPlane3 *fLocalPlanes;
|
||||
hsPlane3 *fWorldPlanes;
|
||||
UInt32 fNumPlanes;
|
||||
};
|
||||
|
||||
inline hsBool plConvexVolume::TestPlane(const hsPoint3 &pos, const hsPlane3 &plane) const
|
||||
{
|
||||
hsScalar dis = plane.fN.InnerProduct(pos);
|
||||
dis += plane.fD;
|
||||
if( dis >= 0.f )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,82 +1,82 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plEffectTargetInfo_inc
|
||||
#define plEffectTargetInfo_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
struct hsPoint3;
|
||||
class plPipeline;
|
||||
class plParticleSystem;
|
||||
|
||||
// This is the rendering context passed into an effect to let it cache up
|
||||
// anything it needs to compute that will be the same for all particles.
|
||||
// Not a lot of context to go on to begin with, but this will let that
|
||||
// expand without any interface changes.
|
||||
class plParticleContext
|
||||
{
|
||||
public:
|
||||
plPipeline* fPipeline;
|
||||
plParticleSystem* fSystem;
|
||||
double fSecs;
|
||||
hsScalar fDelSecs;
|
||||
};
|
||||
|
||||
|
||||
// This is just a collection of arrays and strides that a plParticleEffect object will reference and modify
|
||||
// in the course of doing its job.
|
||||
|
||||
class plEffectTargetInfo
|
||||
{
|
||||
public:
|
||||
// Byte arrays. Declared as type UInt8 so that adding the stride to the pointer is guaranteed to advance
|
||||
// the exact number of bytes.
|
||||
UInt8 *fPos;
|
||||
UInt8 *fVelocity;
|
||||
UInt8 *fInvMass;
|
||||
UInt8 *fAcceleration;
|
||||
UInt8 *fColor;
|
||||
UInt8 *fRadsPerSec;
|
||||
UInt8 *fMiscFlags;
|
||||
|
||||
UInt32 fPosStride;
|
||||
UInt32 fVelocityStride;
|
||||
UInt32 fInvMassStride;
|
||||
UInt32 fAccelerationStride;
|
||||
UInt32 fColorStride;
|
||||
UInt32 fRadsPerSecStride;
|
||||
UInt32 fMiscFlagsStride;
|
||||
|
||||
plParticleContext fContext;
|
||||
UInt32 fNumValidParticles;
|
||||
UInt32 fFirstNewParticle;
|
||||
|
||||
// We're going to need some sort of connectivity data for constraint satisfaction, but at least we have
|
||||
// a system that allows that to be added in smoothly when it's needed, so for now, let's get the main
|
||||
// goop working.
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plEffectTargetInfo_inc
|
||||
#define plEffectTargetInfo_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
struct hsPoint3;
|
||||
class plPipeline;
|
||||
class plParticleSystem;
|
||||
|
||||
// This is the rendering context passed into an effect to let it cache up
|
||||
// anything it needs to compute that will be the same for all particles.
|
||||
// Not a lot of context to go on to begin with, but this will let that
|
||||
// expand without any interface changes.
|
||||
class plParticleContext
|
||||
{
|
||||
public:
|
||||
plPipeline* fPipeline;
|
||||
plParticleSystem* fSystem;
|
||||
double fSecs;
|
||||
hsScalar fDelSecs;
|
||||
};
|
||||
|
||||
|
||||
// This is just a collection of arrays and strides that a plParticleEffect object will reference and modify
|
||||
// in the course of doing its job.
|
||||
|
||||
class plEffectTargetInfo
|
||||
{
|
||||
public:
|
||||
// Byte arrays. Declared as type UInt8 so that adding the stride to the pointer is guaranteed to advance
|
||||
// the exact number of bytes.
|
||||
UInt8 *fPos;
|
||||
UInt8 *fVelocity;
|
||||
UInt8 *fInvMass;
|
||||
UInt8 *fAcceleration;
|
||||
UInt8 *fColor;
|
||||
UInt8 *fRadsPerSec;
|
||||
UInt8 *fMiscFlags;
|
||||
|
||||
UInt32 fPosStride;
|
||||
UInt32 fVelocityStride;
|
||||
UInt32 fInvMassStride;
|
||||
UInt32 fAccelerationStride;
|
||||
UInt32 fColorStride;
|
||||
UInt32 fRadsPerSecStride;
|
||||
UInt32 fMiscFlagsStride;
|
||||
|
||||
plParticleContext fContext;
|
||||
UInt32 fNumValidParticles;
|
||||
UInt32 fFirstNewParticle;
|
||||
|
||||
// We're going to need some sort of connectivity data for constraint satisfaction, but at least we have
|
||||
// a system that allows that to be added in smoothly when it's needed, so for now, let's get the main
|
||||
// goop working.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,98 +1,98 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticle_inc
|
||||
#define plParticle_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
// The meat of the particle. These classes, in combination with the plParticleEmitter that spawned it,
|
||||
// should contain everything specific to a particle, necessary to build a renderable poly to represent a
|
||||
// particular particle. (The emitter is necessary for properties (like texture) that are common among all
|
||||
// particles that originated from the same emitter.
|
||||
|
||||
// For any reference in this object to a particle's poly vertices, the structure is as follows:
|
||||
/*
|
||||
|
||||
|---| "HSize"
|
||||
|
||||
V3-----V2 -
|
||||
| / | | "VSize"
|
||||
| / | |
|
||||
| P | -
|
||||
| / |
|
||||
| / | ("P" is the current position of the particle)
|
||||
V0-----V1
|
||||
|
||||
So the vertices are arranged counter-clockwise, starting in the lower-left corner. Order all other attributes
|
||||
accordingly.
|
||||
|
||||
*/
|
||||
|
||||
// The class plParticleCore should ONLY contain data necessary for the Drawable to create renderable polys
|
||||
// Everything else goes into plParticleExt.
|
||||
|
||||
// plParticleEmitter is depending on the order that member variables appear in these classes, so
|
||||
// DON'T MODIFY THEM WITHOUT MAKING SURE THE CONSTRUCTOR TO plParticleEmitter PROPERLY COMPUTES
|
||||
// BASE ADDRESSES AND STRIDES!
|
||||
|
||||
// No initialization on construct. In nearly all cases, a default value won't be appropriate
|
||||
// so there's no sense doing extra memory writes
|
||||
|
||||
class plParticleCore
|
||||
{
|
||||
public:
|
||||
hsPoint3 fPos;
|
||||
UInt32 fColor; // Particle opacity goes into the color's alpha.
|
||||
hsPoint3 fOrientation; // fMiscFlags determines how this should be used.
|
||||
hsVector3 fNormal;
|
||||
hsScalar fHSize, fVSize; // distance from the heart of the particle to the borders of its poly.
|
||||
hsPoint3 fUVCoords[4];
|
||||
};
|
||||
|
||||
class plParticleExt
|
||||
{
|
||||
public:
|
||||
//hsPoint3 fOldPos;
|
||||
hsVector3 fVelocity;
|
||||
hsScalar fInvMass; // The inverse (1 / mass) is what we actually need for calculations. Storing it this
|
||||
// way allows us to make an object immovable with an inverse mass of 0 (and save a divide).
|
||||
hsVector3 fAcceleration; // Accumulated from multiple forces.
|
||||
hsScalar fLife; // how many seconds before we recycle this? (My particle has more of a life than I do...)
|
||||
hsScalar fStartLife;
|
||||
hsScalar fScale;
|
||||
hsScalar fRadsPerSec;
|
||||
//UInt32 fOrigColor;
|
||||
|
||||
enum // Miscellaneous flags for particles
|
||||
{
|
||||
kImmortal = 0x00000001,
|
||||
};
|
||||
UInt32 fMiscFlags; // I know... 32 bits for a single flag...
|
||||
// Feel free to change this if you've got something to pack it against.
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticle_inc
|
||||
#define plParticle_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
// The meat of the particle. These classes, in combination with the plParticleEmitter that spawned it,
|
||||
// should contain everything specific to a particle, necessary to build a renderable poly to represent a
|
||||
// particular particle. (The emitter is necessary for properties (like texture) that are common among all
|
||||
// particles that originated from the same emitter.
|
||||
|
||||
// For any reference in this object to a particle's poly vertices, the structure is as follows:
|
||||
/*
|
||||
|
||||
|---| "HSize"
|
||||
|
||||
V3-----V2 -
|
||||
| / | | "VSize"
|
||||
| / | |
|
||||
| P | -
|
||||
| / |
|
||||
| / | ("P" is the current position of the particle)
|
||||
V0-----V1
|
||||
|
||||
So the vertices are arranged counter-clockwise, starting in the lower-left corner. Order all other attributes
|
||||
accordingly.
|
||||
|
||||
*/
|
||||
|
||||
// The class plParticleCore should ONLY contain data necessary for the Drawable to create renderable polys
|
||||
// Everything else goes into plParticleExt.
|
||||
|
||||
// plParticleEmitter is depending on the order that member variables appear in these classes, so
|
||||
// DON'T MODIFY THEM WITHOUT MAKING SURE THE CONSTRUCTOR TO plParticleEmitter PROPERLY COMPUTES
|
||||
// BASE ADDRESSES AND STRIDES!
|
||||
|
||||
// No initialization on construct. In nearly all cases, a default value won't be appropriate
|
||||
// so there's no sense doing extra memory writes
|
||||
|
||||
class plParticleCore
|
||||
{
|
||||
public:
|
||||
hsPoint3 fPos;
|
||||
UInt32 fColor; // Particle opacity goes into the color's alpha.
|
||||
hsPoint3 fOrientation; // fMiscFlags determines how this should be used.
|
||||
hsVector3 fNormal;
|
||||
hsScalar fHSize, fVSize; // distance from the heart of the particle to the borders of its poly.
|
||||
hsPoint3 fUVCoords[4];
|
||||
};
|
||||
|
||||
class plParticleExt
|
||||
{
|
||||
public:
|
||||
//hsPoint3 fOldPos;
|
||||
hsVector3 fVelocity;
|
||||
hsScalar fInvMass; // The inverse (1 / mass) is what we actually need for calculations. Storing it this
|
||||
// way allows us to make an object immovable with an inverse mass of 0 (and save a divide).
|
||||
hsVector3 fAcceleration; // Accumulated from multiple forces.
|
||||
hsScalar fLife; // how many seconds before we recycle this? (My particle has more of a life than I do...)
|
||||
hsScalar fStartLife;
|
||||
hsScalar fScale;
|
||||
hsScalar fRadsPerSec;
|
||||
//UInt32 fOrigColor;
|
||||
|
||||
enum // Miscellaneous flags for particles
|
||||
{
|
||||
kImmortal = 0x00000001,
|
||||
};
|
||||
UInt32 fMiscFlags; // I know... 32 bits for a single flag...
|
||||
// Feel free to change this if you've got something to pack it against.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,119 +1,119 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "plParticleApplicator.h"
|
||||
#include "plAvatar/plScalarChannel.h"
|
||||
#include "plAvatar/plAGModifier.h"
|
||||
#include "plMessage/plParticleUpdateMsg.h"
|
||||
#include "pnSceneObject/plSceneObject.h"
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
plParticleGenerator *plParticleApplicator::IGetParticleGen(plSceneObject *so)
|
||||
{
|
||||
UInt32 numMods = so->GetNumModifiers();
|
||||
int i;
|
||||
for (i = 0; i < numMods; i++)
|
||||
{
|
||||
const plParticleSystem *result = plParticleSystem::ConvertNoRef(so->GetModifier(i));
|
||||
if (result != nil)
|
||||
return result->GetExportedGenerator();
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plParticleLifeMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamPartLifeMin,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleLifeMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamPartLifeMax,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticlePPSApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleAngleApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamInitPitchRange,
|
||||
(hsScalar)(chan->Value(time) * PI / 180.f));
|
||||
}
|
||||
|
||||
void plParticleVelMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamVelMin,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleVelMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamVelMax,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleScaleMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamScaleMin,
|
||||
chan->Value(time) / 100.f);
|
||||
}
|
||||
|
||||
void plParticleScaleMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamScaleMax,
|
||||
chan->Value(time) / 100.f);
|
||||
}
|
||||
|
||||
void plParticleGravityApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
// IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
// chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleDragApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
// IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
// chan->Value(time));
|
||||
}
|
||||
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "plParticleApplicator.h"
|
||||
#include "plAvatar/plScalarChannel.h"
|
||||
#include "plAvatar/plAGModifier.h"
|
||||
#include "plMessage/plParticleUpdateMsg.h"
|
||||
#include "pnSceneObject/plSceneObject.h"
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
plParticleGenerator *plParticleApplicator::IGetParticleGen(plSceneObject *so)
|
||||
{
|
||||
UInt32 numMods = so->GetNumModifiers();
|
||||
int i;
|
||||
for (i = 0; i < numMods; i++)
|
||||
{
|
||||
const plParticleSystem *result = plParticleSystem::ConvertNoRef(so->GetModifier(i));
|
||||
if (result != nil)
|
||||
return result->GetExportedGenerator();
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void plParticleLifeMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamPartLifeMin,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleLifeMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamPartLifeMax,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticlePPSApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleAngleApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamInitPitchRange,
|
||||
(hsScalar)(chan->Value(time) * PI / 180.f));
|
||||
}
|
||||
|
||||
void plParticleVelMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamVelMin,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleVelMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamVelMax,
|
||||
chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleScaleMinApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamScaleMin,
|
||||
chan->Value(time) / 100.f);
|
||||
}
|
||||
|
||||
void plParticleScaleMaxApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamScaleMax,
|
||||
chan->Value(time) / 100.f);
|
||||
}
|
||||
|
||||
void plParticleGravityApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
// IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
// chan->Value(time));
|
||||
}
|
||||
|
||||
void plParticleDragApplicator::IApply(const plAGModifier *mod, double time)
|
||||
{
|
||||
plScalarChannel *chan = plScalarChannel::ConvertNoRef(fChannel);
|
||||
// IGetParticleGen(mod->GetTarget(0))->UpdateParam(plParticleUpdateMsg::kParamParticlesPerSecond,
|
||||
// chan->Value(time));
|
||||
}
|
||||
|
||||
|
@ -1,145 +1,145 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef PLPARTICLEAPPLICATOR_INC
|
||||
#define PLPARTICLEAPPLICATOR_INC
|
||||
|
||||
#include "plAvatar/plAGChannel.h"
|
||||
#include "plAvatar/plAGApplicator.h"
|
||||
|
||||
class plParticleSystem;
|
||||
|
||||
class plParticleApplicator : public plAGApplicator
|
||||
{
|
||||
protected:
|
||||
plParticleGenerator *IGetParticleGen(plSceneObject *so);
|
||||
virtual void IApply(const plAGModifier *mod, double time) = 0;
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleApplicator );
|
||||
GETINTERFACE_ANY( plParticleApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleLifeMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleLifeMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleLifeMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleLifeMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleLifeMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleLifeMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticlePPSApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticlePPSApplicator );
|
||||
GETINTERFACE_ANY( plParticlePPSApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleAngleApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleAngleApplicator );
|
||||
GETINTERFACE_ANY( plParticleAngleApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleVelMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleVelMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleVelMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleVelMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleVelMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleVelMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleScaleMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleScaleMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleScaleMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleScaleMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleScaleMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleScaleMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleGravityApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleGravityApplicator );
|
||||
GETINTERFACE_ANY( plParticleGravityApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleDragApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleDragApplicator );
|
||||
GETINTERFACE_ANY( plParticleDragApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef PLPARTICLEAPPLICATOR_INC
|
||||
#define PLPARTICLEAPPLICATOR_INC
|
||||
|
||||
#include "plAvatar/plAGChannel.h"
|
||||
#include "plAvatar/plAGApplicator.h"
|
||||
|
||||
class plParticleSystem;
|
||||
|
||||
class plParticleApplicator : public plAGApplicator
|
||||
{
|
||||
protected:
|
||||
plParticleGenerator *IGetParticleGen(plSceneObject *so);
|
||||
virtual void IApply(const plAGModifier *mod, double time) = 0;
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleApplicator );
|
||||
GETINTERFACE_ANY( plParticleApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleLifeMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleLifeMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleLifeMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleLifeMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleLifeMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleLifeMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticlePPSApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticlePPSApplicator );
|
||||
GETINTERFACE_ANY( plParticlePPSApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleAngleApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleAngleApplicator );
|
||||
GETINTERFACE_ANY( plParticleAngleApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleVelMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleVelMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleVelMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleVelMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleVelMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleVelMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleScaleMinApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleScaleMinApplicator );
|
||||
GETINTERFACE_ANY( plParticleScaleMinApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleScaleMaxApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleScaleMaxApplicator );
|
||||
GETINTERFACE_ANY( plParticleScaleMaxApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleGravityApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleGravityApplicator );
|
||||
GETINTERFACE_ANY( plParticleGravityApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
class plParticleDragApplicator : public plParticleApplicator
|
||||
{
|
||||
protected:
|
||||
virtual void IApply(const plAGModifier *mod, double time);
|
||||
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleDragApplicator );
|
||||
GETINTERFACE_ANY( plParticleDragApplicator, plAGApplicator );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,73 +1,73 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plParticleCreatable_inc
|
||||
#define plParticleCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleEffect.h"
|
||||
#include "plParticleEmitter.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleApplicator.h"
|
||||
#include "plParticleSDLMod.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "plBoundInterface.h"
|
||||
|
||||
REGISTER_CREATABLE( plParticleSystem );
|
||||
REGISTER_NONCREATABLE( plParticleEffect );
|
||||
REGISTER_NONCREATABLE( plParticleCollisionEffect );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectBeat );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectDie );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectBounce );
|
||||
REGISTER_CREATABLE( plParticleFadeVolumeEffect );
|
||||
REGISTER_NONCREATABLE( plParticleGenerator );
|
||||
REGISTER_CREATABLE( plSimpleParticleGenerator );
|
||||
REGISTER_CREATABLE( plOneTimeParticleGenerator );
|
||||
REGISTER_CREATABLE( plParticleEmitter );
|
||||
REGISTER_CREATABLE( plConvexVolume );
|
||||
REGISTER_CREATABLE( plBoundInterface );
|
||||
REGISTER_NONCREATABLE( plParticleApplicator );
|
||||
REGISTER_CREATABLE( plParticleLifeMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleLifeMaxApplicator );
|
||||
REGISTER_CREATABLE( plParticlePPSApplicator );
|
||||
REGISTER_CREATABLE( plParticleAngleApplicator );
|
||||
REGISTER_CREATABLE( plParticleVelMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleVelMaxApplicator );
|
||||
REGISTER_CREATABLE( plParticleScaleMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleScaleMaxApplicator );
|
||||
//REGISTER_CREATABLE( plParticleGravityApplicator );
|
||||
//REGISTER_CREATABLE( plParticleDragApplicator );
|
||||
REGISTER_NONCREATABLE( plParticleWindEffect );
|
||||
REGISTER_CREATABLE( plParticleLocalWind );
|
||||
REGISTER_CREATABLE( plParticleUniformWind );
|
||||
REGISTER_CREATABLE( plParticleFlockEffect );
|
||||
REGISTER_CREATABLE( plParticleFollowSystemEffect );
|
||||
REGISTER_CREATABLE( plParticleSDLMod );
|
||||
|
||||
#endif // plParticleCreatable_inc
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plParticleCreatable_inc
|
||||
#define plParticleCreatable_inc
|
||||
|
||||
#include "pnFactory/plCreator.h"
|
||||
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleEffect.h"
|
||||
#include "plParticleEmitter.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleApplicator.h"
|
||||
#include "plParticleSDLMod.h"
|
||||
#include "plConvexVolume.h"
|
||||
#include "plBoundInterface.h"
|
||||
|
||||
REGISTER_CREATABLE( plParticleSystem );
|
||||
REGISTER_NONCREATABLE( plParticleEffect );
|
||||
REGISTER_NONCREATABLE( plParticleCollisionEffect );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectBeat );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectDie );
|
||||
REGISTER_CREATABLE( plParticleCollisionEffectBounce );
|
||||
REGISTER_CREATABLE( plParticleFadeVolumeEffect );
|
||||
REGISTER_NONCREATABLE( plParticleGenerator );
|
||||
REGISTER_CREATABLE( plSimpleParticleGenerator );
|
||||
REGISTER_CREATABLE( plOneTimeParticleGenerator );
|
||||
REGISTER_CREATABLE( plParticleEmitter );
|
||||
REGISTER_CREATABLE( plConvexVolume );
|
||||
REGISTER_CREATABLE( plBoundInterface );
|
||||
REGISTER_NONCREATABLE( plParticleApplicator );
|
||||
REGISTER_CREATABLE( plParticleLifeMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleLifeMaxApplicator );
|
||||
REGISTER_CREATABLE( plParticlePPSApplicator );
|
||||
REGISTER_CREATABLE( plParticleAngleApplicator );
|
||||
REGISTER_CREATABLE( plParticleVelMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleVelMaxApplicator );
|
||||
REGISTER_CREATABLE( plParticleScaleMinApplicator );
|
||||
REGISTER_CREATABLE( plParticleScaleMaxApplicator );
|
||||
//REGISTER_CREATABLE( plParticleGravityApplicator );
|
||||
//REGISTER_CREATABLE( plParticleDragApplicator );
|
||||
REGISTER_NONCREATABLE( plParticleWindEffect );
|
||||
REGISTER_CREATABLE( plParticleLocalWind );
|
||||
REGISTER_CREATABLE( plParticleUniformWind );
|
||||
REGISTER_CREATABLE( plParticleFlockEffect );
|
||||
REGISTER_CREATABLE( plParticleFollowSystemEffect );
|
||||
REGISTER_CREATABLE( plParticleSDLMod );
|
||||
|
||||
#endif // plParticleCreatable_inc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,340 +1,340 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleEffect_inc
|
||||
#define plParticleEffect_inc
|
||||
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
class plEffectTargetInfo;
|
||||
class plConvexVolume;
|
||||
class hsResMgr;
|
||||
class plSceneObject;
|
||||
|
||||
class plParticleEffect : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleEffect );
|
||||
GETINTERFACE_ANY( plParticleEffect, hsKeyedObject );
|
||||
|
||||
// Order is:
|
||||
// PrepareEffect is called with a given target (including valid
|
||||
// ParticleContext).
|
||||
// ApplyEffect is called some once for each particle (maybe zero times).
|
||||
// It can return true to kill a particle.
|
||||
// Target and Context passed in with Prepare will be
|
||||
// guaranteed to remain valid until,
|
||||
// EndEffect marks no more particles will be processed with the above
|
||||
// context (invalidating anything cached).
|
||||
// Defaults for Prepare and End are no-ops.
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target) {}
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i) = 0;
|
||||
virtual void EndEffect(const plEffectTargetInfo& target) {}
|
||||
};
|
||||
|
||||
class plParticleCollisionEffect : public plParticleEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffect();
|
||||
~plParticleCollisionEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffect );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
|
||||
protected:
|
||||
plSceneObject *fSceneObj;
|
||||
plConvexVolume *fBounds;
|
||||
};
|
||||
|
||||
// Default particle blocker. Doesn't affect particle's velocity,
|
||||
// so it'll keep "beat"ing on the deflector until the velocity
|
||||
// dotted with the deflector normal slides it off an edge.
|
||||
class plParticleCollisionEffectBeat : public plParticleCollisionEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffectBeat();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectBeat );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectBeat, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
};
|
||||
|
||||
// This particle blocker just kills any particles that hit it.
|
||||
class plParticleCollisionEffectDie : public plParticleCollisionEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffectDie();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectDie );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectDie, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
};
|
||||
|
||||
class plParticleCollisionEffectBounce : public plParticleCollisionEffect
|
||||
{
|
||||
protected:
|
||||
hsScalar fBounce;
|
||||
hsScalar fFriction;
|
||||
public:
|
||||
plParticleCollisionEffectBounce();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectBounce );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectBounce, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
void SetBounce(hsScalar b) { fBounce = b; }
|
||||
hsScalar GetBounce() const { return fBounce; }
|
||||
|
||||
void SetFriction(hsScalar f) { fFriction = f; }
|
||||
hsScalar GetFriction() const { return fFriction; }
|
||||
};
|
||||
|
||||
class plParticleFadeVolumeEffect : public plParticleEffect
|
||||
{
|
||||
protected:
|
||||
// Some cached properties. These will be the same for all
|
||||
// particles between matching PrepareEffect and EndEffect calls.
|
||||
hsPoint3 fMax;
|
||||
hsPoint3 fMin;
|
||||
hsPoint3 fNorm;
|
||||
|
||||
public:
|
||||
plParticleFadeVolumeEffect();
|
||||
~plParticleFadeVolumeEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleFadeVolumeEffect );
|
||||
GETINTERFACE_ANY( plParticleFadeVolumeEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
//virtual hsBool MsgReceive(plMessage *msg);
|
||||
|
||||
hsScalar fLength;
|
||||
hsBool fIgnoreZ;
|
||||
};
|
||||
|
||||
class plParticleWindEffect : public plParticleEffect
|
||||
{
|
||||
protected:
|
||||
// The properties that define the wind. These might/should be animatable.
|
||||
hsScalar fStrength;
|
||||
hsScalar fConstancy;
|
||||
hsScalar fSwirl;
|
||||
hsBool fHorizontal;
|
||||
hsVector3 fRefDir;
|
||||
|
||||
// Some cached properties. These will be the same for all
|
||||
// particles between matching PrepareEffect and EndEffect calls.
|
||||
// These define the current state of the wind.
|
||||
hsVector3 fWindVec;
|
||||
hsVector3 fRandDir;
|
||||
hsVector3 fDir;
|
||||
double fLastDirSecs;
|
||||
public:
|
||||
|
||||
plParticleWindEffect();
|
||||
~plParticleWindEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleWindEffect );
|
||||
GETINTERFACE_ANY( plParticleWindEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i) = 0;
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
void SetStrength(hsScalar v) { fStrength = v; }
|
||||
hsScalar GetStrength() const { return fStrength; }
|
||||
|
||||
void SetConstancy(hsScalar c) { fConstancy = c; }
|
||||
hsScalar GetConstancy() const { return fConstancy; }
|
||||
|
||||
void SetSwirl(hsScalar s) { fSwirl = s; }
|
||||
hsScalar GetSwirl() const { return fSwirl; }
|
||||
|
||||
void SetHorizontal(hsBool on) { fHorizontal = on; }
|
||||
hsBool GetHorizontal() const { return fHorizontal; }
|
||||
|
||||
void SetRefDirection(const hsVector3& v);
|
||||
const hsVector3& GetRefDirection() const { return fRefDir; }
|
||||
};
|
||||
|
||||
class plParticleLocalWind : public plParticleWindEffect
|
||||
{
|
||||
protected:
|
||||
hsVector3 fScale;
|
||||
hsScalar fSpeed;
|
||||
|
||||
hsVector3 fPhase;
|
||||
hsVector3 fInvScale;
|
||||
double fLastPhaseSecs;
|
||||
|
||||
public:
|
||||
plParticleLocalWind();
|
||||
~plParticleLocalWind();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleLocalWind );
|
||||
GETINTERFACE_ANY( plParticleLocalWind, plParticleWindEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetScale(const hsVector3& v) { fScale = v; }
|
||||
const hsVector3& GetScale() const { return fScale; }
|
||||
|
||||
void SetSpeed(hsScalar v) { fSpeed = v; }
|
||||
hsScalar GetSpeed() const { return fSpeed; }
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
};
|
||||
|
||||
class plParticleUniformWind : public plParticleWindEffect
|
||||
{
|
||||
protected:
|
||||
|
||||
hsScalar fFreqMin;
|
||||
hsScalar fFreqMax;
|
||||
hsScalar fFreqCurr;
|
||||
hsScalar fFreqRate;
|
||||
double fCurrPhase;
|
||||
|
||||
double fLastFreqSecs;
|
||||
|
||||
hsScalar fCurrentStrength;
|
||||
public:
|
||||
plParticleUniformWind();
|
||||
~plParticleUniformWind();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleUniformWind );
|
||||
GETINTERFACE_ANY( plParticleUniformWind, plParticleWindEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetFrequencyRange(hsScalar minSecsPerCycle, hsScalar maxSecsPerCycle);
|
||||
void SetFrequencyRate(hsScalar secsPerCycle);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
};
|
||||
|
||||
class plParticleInfluenceInfo
|
||||
{
|
||||
public:
|
||||
hsVector3 fAvgVel;
|
||||
hsVector3 fRepDir;
|
||||
};
|
||||
|
||||
class plParticleFlockEffect : public plParticleEffect
|
||||
{
|
||||
//protected:
|
||||
protected:
|
||||
hsPoint3 fTargetOffset; // Worldspace offset from our target to get the true goal
|
||||
hsPoint3 fDissenterTarget; // Where to particles go when they get scared and leave us?
|
||||
hsScalar fInfAvgRadSq; // Square of the radius of influence for average velocity matching.
|
||||
hsScalar fInfRepRadSq; // Same, for repelling from neighbors.
|
||||
hsScalar fAvgVelStr; // How strongly are we influenced by average dir?
|
||||
hsScalar fRepDirStr; // Same for repelling
|
||||
hsScalar fGoalOrbitStr; // Same for the goal (when we're within the desired distance)
|
||||
hsScalar fGoalChaseStr; // Same for the goal (when we're too far away, and chasing it)
|
||||
hsScalar fGoalDistSq;
|
||||
hsScalar fFullChaseDistSq;
|
||||
hsScalar fMaxOrbitSpeed;
|
||||
hsScalar fMaxChaseSpeed;
|
||||
|
||||
UInt16 fMaxParticles;
|
||||
hsScalar *fDistSq; // Table of distances from particle to particle
|
||||
plParticleInfluenceInfo *fInfluences;
|
||||
|
||||
void IUpdateDistances(const plEffectTargetInfo &target);
|
||||
void IUpdateInfluences(const plEffectTargetInfo &target);
|
||||
|
||||
public:
|
||||
plParticleFlockEffect();
|
||||
~plParticleFlockEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleFlockEffect );
|
||||
GETINTERFACE_ANY( plParticleFlockEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetTargetOffset(const hsPoint3 &offset) { fTargetOffset = offset; }
|
||||
void SetDissenterTarget(const hsPoint3 &target) { fDissenterTarget = target; }
|
||||
void SetInfluenceAvgRadius(hsScalar val) { fInfAvgRadSq = val * val; }
|
||||
void SetInfluenceRepelRadius(hsScalar val) { fInfRepRadSq = val * val; }
|
||||
void SetGoalRadius(hsScalar val) { fGoalDistSq = val * val; }
|
||||
void SetFullChaseRadius(hsScalar val) { fFullChaseDistSq = val * val; }
|
||||
void SetConformStr(hsScalar val) { fAvgVelStr = val; }
|
||||
void SetRepelStr(hsScalar val) { fRepDirStr = val; }
|
||||
void SetGoalOrbitStr(hsScalar val) { fGoalOrbitStr = val; }
|
||||
void SetGoalChaseStr(hsScalar val) { fGoalChaseStr = val; }
|
||||
void SetMaxOrbitSpeed(hsScalar val) { fMaxOrbitSpeed = val; }
|
||||
void SetMaxChaseSpeed(hsScalar val) { fMaxChaseSpeed = val; }
|
||||
void SetMaxParticles(UInt16 num);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
};
|
||||
|
||||
class plParticleFollowSystemEffect : public plParticleEffect
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleFollowSystemEffect );
|
||||
GETINTERFACE_ANY( plParticleFollowSystemEffect, plParticleEffect );
|
||||
|
||||
plParticleFollowSystemEffect();
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
virtual void EndEffect(const plEffectTargetInfo& target);
|
||||
|
||||
protected:
|
||||
hsMatrix44 fOldW2L;
|
||||
hsBool fEvalThisFrame;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleEffect_inc
|
||||
#define plParticleEffect_inc
|
||||
|
||||
#include "pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
class plEffectTargetInfo;
|
||||
class plConvexVolume;
|
||||
class hsResMgr;
|
||||
class plSceneObject;
|
||||
|
||||
class plParticleEffect : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleEffect );
|
||||
GETINTERFACE_ANY( plParticleEffect, hsKeyedObject );
|
||||
|
||||
// Order is:
|
||||
// PrepareEffect is called with a given target (including valid
|
||||
// ParticleContext).
|
||||
// ApplyEffect is called some once for each particle (maybe zero times).
|
||||
// It can return true to kill a particle.
|
||||
// Target and Context passed in with Prepare will be
|
||||
// guaranteed to remain valid until,
|
||||
// EndEffect marks no more particles will be processed with the above
|
||||
// context (invalidating anything cached).
|
||||
// Defaults for Prepare and End are no-ops.
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target) {}
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i) = 0;
|
||||
virtual void EndEffect(const plEffectTargetInfo& target) {}
|
||||
};
|
||||
|
||||
class plParticleCollisionEffect : public plParticleEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffect();
|
||||
~plParticleCollisionEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffect );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
|
||||
protected:
|
||||
plSceneObject *fSceneObj;
|
||||
plConvexVolume *fBounds;
|
||||
};
|
||||
|
||||
// Default particle blocker. Doesn't affect particle's velocity,
|
||||
// so it'll keep "beat"ing on the deflector until the velocity
|
||||
// dotted with the deflector normal slides it off an edge.
|
||||
class plParticleCollisionEffectBeat : public plParticleCollisionEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffectBeat();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectBeat );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectBeat, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
};
|
||||
|
||||
// This particle blocker just kills any particles that hit it.
|
||||
class plParticleCollisionEffectDie : public plParticleCollisionEffect
|
||||
{
|
||||
public:
|
||||
plParticleCollisionEffectDie();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectDie );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectDie, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
};
|
||||
|
||||
class plParticleCollisionEffectBounce : public plParticleCollisionEffect
|
||||
{
|
||||
protected:
|
||||
hsScalar fBounce;
|
||||
hsScalar fFriction;
|
||||
public:
|
||||
plParticleCollisionEffectBounce();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleCollisionEffectBounce );
|
||||
GETINTERFACE_ANY( plParticleCollisionEffectBounce, plParticleCollisionEffect );
|
||||
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
void SetBounce(hsScalar b) { fBounce = b; }
|
||||
hsScalar GetBounce() const { return fBounce; }
|
||||
|
||||
void SetFriction(hsScalar f) { fFriction = f; }
|
||||
hsScalar GetFriction() const { return fFriction; }
|
||||
};
|
||||
|
||||
class plParticleFadeVolumeEffect : public plParticleEffect
|
||||
{
|
||||
protected:
|
||||
// Some cached properties. These will be the same for all
|
||||
// particles between matching PrepareEffect and EndEffect calls.
|
||||
hsPoint3 fMax;
|
||||
hsPoint3 fMin;
|
||||
hsPoint3 fNorm;
|
||||
|
||||
public:
|
||||
plParticleFadeVolumeEffect();
|
||||
~plParticleFadeVolumeEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleFadeVolumeEffect );
|
||||
GETINTERFACE_ANY( plParticleFadeVolumeEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
//virtual hsBool MsgReceive(plMessage *msg);
|
||||
|
||||
hsScalar fLength;
|
||||
hsBool fIgnoreZ;
|
||||
};
|
||||
|
||||
class plParticleWindEffect : public plParticleEffect
|
||||
{
|
||||
protected:
|
||||
// The properties that define the wind. These might/should be animatable.
|
||||
hsScalar fStrength;
|
||||
hsScalar fConstancy;
|
||||
hsScalar fSwirl;
|
||||
hsBool fHorizontal;
|
||||
hsVector3 fRefDir;
|
||||
|
||||
// Some cached properties. These will be the same for all
|
||||
// particles between matching PrepareEffect and EndEffect calls.
|
||||
// These define the current state of the wind.
|
||||
hsVector3 fWindVec;
|
||||
hsVector3 fRandDir;
|
||||
hsVector3 fDir;
|
||||
double fLastDirSecs;
|
||||
public:
|
||||
|
||||
plParticleWindEffect();
|
||||
~plParticleWindEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleWindEffect );
|
||||
GETINTERFACE_ANY( plParticleWindEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i) = 0;
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
void SetStrength(hsScalar v) { fStrength = v; }
|
||||
hsScalar GetStrength() const { return fStrength; }
|
||||
|
||||
void SetConstancy(hsScalar c) { fConstancy = c; }
|
||||
hsScalar GetConstancy() const { return fConstancy; }
|
||||
|
||||
void SetSwirl(hsScalar s) { fSwirl = s; }
|
||||
hsScalar GetSwirl() const { return fSwirl; }
|
||||
|
||||
void SetHorizontal(hsBool on) { fHorizontal = on; }
|
||||
hsBool GetHorizontal() const { return fHorizontal; }
|
||||
|
||||
void SetRefDirection(const hsVector3& v);
|
||||
const hsVector3& GetRefDirection() const { return fRefDir; }
|
||||
};
|
||||
|
||||
class plParticleLocalWind : public plParticleWindEffect
|
||||
{
|
||||
protected:
|
||||
hsVector3 fScale;
|
||||
hsScalar fSpeed;
|
||||
|
||||
hsVector3 fPhase;
|
||||
hsVector3 fInvScale;
|
||||
double fLastPhaseSecs;
|
||||
|
||||
public:
|
||||
plParticleLocalWind();
|
||||
~plParticleLocalWind();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleLocalWind );
|
||||
GETINTERFACE_ANY( plParticleLocalWind, plParticleWindEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetScale(const hsVector3& v) { fScale = v; }
|
||||
const hsVector3& GetScale() const { return fScale; }
|
||||
|
||||
void SetSpeed(hsScalar v) { fSpeed = v; }
|
||||
hsScalar GetSpeed() const { return fSpeed; }
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
};
|
||||
|
||||
class plParticleUniformWind : public plParticleWindEffect
|
||||
{
|
||||
protected:
|
||||
|
||||
hsScalar fFreqMin;
|
||||
hsScalar fFreqMax;
|
||||
hsScalar fFreqCurr;
|
||||
hsScalar fFreqRate;
|
||||
double fCurrPhase;
|
||||
|
||||
double fLastFreqSecs;
|
||||
|
||||
hsScalar fCurrentStrength;
|
||||
public:
|
||||
plParticleUniformWind();
|
||||
~plParticleUniformWind();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleUniformWind );
|
||||
GETINTERFACE_ANY( plParticleUniformWind, plParticleWindEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetFrequencyRange(hsScalar minSecsPerCycle, hsScalar maxSecsPerCycle);
|
||||
void SetFrequencyRate(hsScalar secsPerCycle);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
|
||||
};
|
||||
|
||||
class plParticleInfluenceInfo
|
||||
{
|
||||
public:
|
||||
hsVector3 fAvgVel;
|
||||
hsVector3 fRepDir;
|
||||
};
|
||||
|
||||
class plParticleFlockEffect : public plParticleEffect
|
||||
{
|
||||
//protected:
|
||||
protected:
|
||||
hsPoint3 fTargetOffset; // Worldspace offset from our target to get the true goal
|
||||
hsPoint3 fDissenterTarget; // Where to particles go when they get scared and leave us?
|
||||
hsScalar fInfAvgRadSq; // Square of the radius of influence for average velocity matching.
|
||||
hsScalar fInfRepRadSq; // Same, for repelling from neighbors.
|
||||
hsScalar fAvgVelStr; // How strongly are we influenced by average dir?
|
||||
hsScalar fRepDirStr; // Same for repelling
|
||||
hsScalar fGoalOrbitStr; // Same for the goal (when we're within the desired distance)
|
||||
hsScalar fGoalChaseStr; // Same for the goal (when we're too far away, and chasing it)
|
||||
hsScalar fGoalDistSq;
|
||||
hsScalar fFullChaseDistSq;
|
||||
hsScalar fMaxOrbitSpeed;
|
||||
hsScalar fMaxChaseSpeed;
|
||||
|
||||
UInt16 fMaxParticles;
|
||||
hsScalar *fDistSq; // Table of distances from particle to particle
|
||||
plParticleInfluenceInfo *fInfluences;
|
||||
|
||||
void IUpdateDistances(const plEffectTargetInfo &target);
|
||||
void IUpdateInfluences(const plEffectTargetInfo &target);
|
||||
|
||||
public:
|
||||
plParticleFlockEffect();
|
||||
~plParticleFlockEffect();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleFlockEffect );
|
||||
GETINTERFACE_ANY( plParticleFlockEffect, plParticleEffect );
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
|
||||
void SetTargetOffset(const hsPoint3 &offset) { fTargetOffset = offset; }
|
||||
void SetDissenterTarget(const hsPoint3 &target) { fDissenterTarget = target; }
|
||||
void SetInfluenceAvgRadius(hsScalar val) { fInfAvgRadSq = val * val; }
|
||||
void SetInfluenceRepelRadius(hsScalar val) { fInfRepRadSq = val * val; }
|
||||
void SetGoalRadius(hsScalar val) { fGoalDistSq = val * val; }
|
||||
void SetFullChaseRadius(hsScalar val) { fFullChaseDistSq = val * val; }
|
||||
void SetConformStr(hsScalar val) { fAvgVelStr = val; }
|
||||
void SetRepelStr(hsScalar val) { fRepDirStr = val; }
|
||||
void SetGoalOrbitStr(hsScalar val) { fGoalOrbitStr = val; }
|
||||
void SetGoalChaseStr(hsScalar val) { fGoalChaseStr = val; }
|
||||
void SetMaxOrbitSpeed(hsScalar val) { fMaxOrbitSpeed = val; }
|
||||
void SetMaxChaseSpeed(hsScalar val) { fMaxChaseSpeed = val; }
|
||||
void SetMaxParticles(UInt16 num);
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
virtual hsBool MsgReceive(plMessage *msg);
|
||||
};
|
||||
|
||||
class plParticleFollowSystemEffect : public plParticleEffect
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plParticleFollowSystemEffect );
|
||||
GETINTERFACE_ANY( plParticleFollowSystemEffect, plParticleEffect );
|
||||
|
||||
plParticleFollowSystemEffect();
|
||||
|
||||
virtual void PrepareEffect(const plEffectTargetInfo& target);
|
||||
virtual hsBool ApplyEffect(const plEffectTargetInfo& target, Int32 i);
|
||||
virtual void EndEffect(const plEffectTargetInfo& target);
|
||||
|
||||
protected:
|
||||
hsMatrix44 fOldW2L;
|
||||
hsBool fEvalThisFrame;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,143 +1,143 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleEmitter_inc
|
||||
#define plParticleEmitter_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsBounds.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
class hsBounds3Ext;
|
||||
class plParticleSystem;
|
||||
class plParticleCore;
|
||||
class plParticleExt;
|
||||
class plParticleGenerator;
|
||||
class plSimpleParticleGenerator;
|
||||
class hsResMgr;
|
||||
|
||||
#include "plEffectTargetInfo.h"
|
||||
|
||||
// This just holds a bunch of parameters for an emission location. A particle system can have several of these
|
||||
|
||||
class plParticleEmitter : public plCreatable
|
||||
{
|
||||
friend plParticleSystem;
|
||||
friend plSimpleParticleGenerator;
|
||||
|
||||
public:
|
||||
plParticleEmitter();
|
||||
~plParticleEmitter();
|
||||
void Init(plParticleSystem *system, UInt32 maxParticles, UInt32 spanIndex, UInt32 miscFlags,
|
||||
plParticleGenerator *gen = nil);
|
||||
void Clone(plParticleEmitter* src, UInt32 spanIndex);
|
||||
|
||||
plParticleCore *GetParticleArray() const { return fParticleCores; }
|
||||
UInt32 GetParticleCount() const { return fNumValidParticles; }
|
||||
UInt32 GetNumTiles() const;
|
||||
const hsBounds3Ext &GetBoundingBox() const { return fBoundBox; }
|
||||
UInt32 GetSpanIndex() const { return fSpanIndex; }
|
||||
const hsMatrix44 &GetLocalToWorld() const;
|
||||
|
||||
void AddParticle(hsPoint3 &pos, hsVector3 &velocity, UInt32 tileIndex,
|
||||
hsScalar hSize, hsScalar vSize, hsScalar scale, hsScalar invMass, hsScalar life,
|
||||
hsPoint3 &orientation, UInt32 miscFlags, hsScalar radsPerSec=0);
|
||||
void WipeExistingParticles();
|
||||
void KillParticles(hsScalar num, hsScalar timeToDie, UInt8 flags);
|
||||
UInt16 StealParticlesFrom(plParticleEmitter *victim, UInt16 num); // returns the number actually stolen
|
||||
void TranslateAllParticles(hsPoint3 &amount); // Used to recenter the system when linking between ages.
|
||||
void UpdateGenerator(UInt32 paramID, hsScalar paramValue);
|
||||
|
||||
static UInt32 CreateHexColor(const hsColorRGBA &color);
|
||||
static UInt32 CreateHexColor(const hsScalar r, const hsScalar g, const hsScalar b, const hsScalar a);
|
||||
|
||||
void OverrideLocalToWorld(const hsMatrix44& l2w);
|
||||
void UnOverrideLocalToWorld() { fMiscFlags &= ~kOverrideLocalToWorld; }
|
||||
hsBool LocalToWorldOverridden() const { return 0 != (fMiscFlags & kOverrideLocalToWorld); }
|
||||
void SetTimeToLive(hsScalar dt) { fTimeToLive = dt; }
|
||||
hsScalar GetTimeToLive() const { return fTimeToLive; } // 0 time to live is never turn off.
|
||||
|
||||
CLASSNAME_REGISTER( plParticleEmitter );
|
||||
GETINTERFACE_ANY( plParticleEmitter, plCreatable);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
enum // Miscellaneous flags
|
||||
{
|
||||
kMatIsEmissive = 0x00000001,
|
||||
|
||||
kNormalUp = 0x00000010,
|
||||
kNormalVelUpVel = 0x00000020,
|
||||
kNormalFromCenter = 0x00000040,
|
||||
kNormalDynamicMask = kNormalVelUpVel | kNormalFromCenter, // precalc methods that need updating each frame
|
||||
kNormalPrecalcMask = kNormalDynamicMask | kNormalUp, // All types where emitter precalculates the normal
|
||||
|
||||
kNormalViewFacing = 0x00000100,
|
||||
kNormalNearestLight = 0x00000200,
|
||||
|
||||
kNeedsUpdate = 0x01000000,
|
||||
kBorrowedGenerator = 0x02000000,
|
||||
kOverrideLocalToWorld = 0x04000000,
|
||||
kOnReserve = 0x08000000,
|
||||
|
||||
kOrientationUp = 0x10000000,
|
||||
kOrientationVelocityBased = 0x20000000,
|
||||
kOrientationVelocityStretch = 0x40000000,
|
||||
kOrientationVelocityFlow = 0x80000000,
|
||||
kOrientationVelocityMask = kOrientationVelocityBased | kOrientationVelocityStretch | kOrientationVelocityFlow, // Velocity dependent
|
||||
kOrientationMask = kOrientationUp | kOrientationVelocityMask,
|
||||
};
|
||||
UInt32 fMiscFlags;
|
||||
|
||||
protected:
|
||||
|
||||
plParticleSystem *fSystem; // The particle system this belongs to.
|
||||
plParticleCore *fParticleCores; // The particle pool, created on init, initialized as needed, and recycled.
|
||||
plParticleExt *fParticleExts; // Same mapping as the Core pool. Contains extra info the render pipeline
|
||||
// doesn't need.
|
||||
|
||||
plParticleGenerator *fGenerator; // Optional auto generator (have this be nil if you don't want auto-generation)
|
||||
UInt32 fSpanIndex; // Index of the span that this emitter uses.
|
||||
UInt32 fNumValidParticles;
|
||||
UInt32 fMaxParticles;
|
||||
hsBounds3Ext fBoundBox;
|
||||
plEffectTargetInfo fTargetInfo; // A collection of pointers and strides that plParticleEffects will manipulate.
|
||||
hsColorRGBA fColor;
|
||||
|
||||
hsMatrix44 fLocalToWorld;
|
||||
hsScalar fTimeToLive;
|
||||
|
||||
void IClear();
|
||||
void ISetupParticleMem();
|
||||
void ISetSystem(plParticleSystem *sys) { fSystem = sys; }
|
||||
hsBool IUpdate(hsScalar delta);
|
||||
void IUpdateParticles(hsScalar delta);
|
||||
void IUpdateBoundsAndNormals(hsScalar delta);
|
||||
void IRemoveParticle(UInt32 index);
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleEmitter_inc
|
||||
#define plParticleEmitter_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsBounds.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
class hsBounds3Ext;
|
||||
class plParticleSystem;
|
||||
class plParticleCore;
|
||||
class plParticleExt;
|
||||
class plParticleGenerator;
|
||||
class plSimpleParticleGenerator;
|
||||
class hsResMgr;
|
||||
|
||||
#include "plEffectTargetInfo.h"
|
||||
|
||||
// This just holds a bunch of parameters for an emission location. A particle system can have several of these
|
||||
|
||||
class plParticleEmitter : public plCreatable
|
||||
{
|
||||
friend plParticleSystem;
|
||||
friend plSimpleParticleGenerator;
|
||||
|
||||
public:
|
||||
plParticleEmitter();
|
||||
~plParticleEmitter();
|
||||
void Init(plParticleSystem *system, UInt32 maxParticles, UInt32 spanIndex, UInt32 miscFlags,
|
||||
plParticleGenerator *gen = nil);
|
||||
void Clone(plParticleEmitter* src, UInt32 spanIndex);
|
||||
|
||||
plParticleCore *GetParticleArray() const { return fParticleCores; }
|
||||
UInt32 GetParticleCount() const { return fNumValidParticles; }
|
||||
UInt32 GetNumTiles() const;
|
||||
const hsBounds3Ext &GetBoundingBox() const { return fBoundBox; }
|
||||
UInt32 GetSpanIndex() const { return fSpanIndex; }
|
||||
const hsMatrix44 &GetLocalToWorld() const;
|
||||
|
||||
void AddParticle(hsPoint3 &pos, hsVector3 &velocity, UInt32 tileIndex,
|
||||
hsScalar hSize, hsScalar vSize, hsScalar scale, hsScalar invMass, hsScalar life,
|
||||
hsPoint3 &orientation, UInt32 miscFlags, hsScalar radsPerSec=0);
|
||||
void WipeExistingParticles();
|
||||
void KillParticles(hsScalar num, hsScalar timeToDie, UInt8 flags);
|
||||
UInt16 StealParticlesFrom(plParticleEmitter *victim, UInt16 num); // returns the number actually stolen
|
||||
void TranslateAllParticles(hsPoint3 &amount); // Used to recenter the system when linking between ages.
|
||||
void UpdateGenerator(UInt32 paramID, hsScalar paramValue);
|
||||
|
||||
static UInt32 CreateHexColor(const hsColorRGBA &color);
|
||||
static UInt32 CreateHexColor(const hsScalar r, const hsScalar g, const hsScalar b, const hsScalar a);
|
||||
|
||||
void OverrideLocalToWorld(const hsMatrix44& l2w);
|
||||
void UnOverrideLocalToWorld() { fMiscFlags &= ~kOverrideLocalToWorld; }
|
||||
hsBool LocalToWorldOverridden() const { return 0 != (fMiscFlags & kOverrideLocalToWorld); }
|
||||
void SetTimeToLive(hsScalar dt) { fTimeToLive = dt; }
|
||||
hsScalar GetTimeToLive() const { return fTimeToLive; } // 0 time to live is never turn off.
|
||||
|
||||
CLASSNAME_REGISTER( plParticleEmitter );
|
||||
GETINTERFACE_ANY( plParticleEmitter, plCreatable);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
enum // Miscellaneous flags
|
||||
{
|
||||
kMatIsEmissive = 0x00000001,
|
||||
|
||||
kNormalUp = 0x00000010,
|
||||
kNormalVelUpVel = 0x00000020,
|
||||
kNormalFromCenter = 0x00000040,
|
||||
kNormalDynamicMask = kNormalVelUpVel | kNormalFromCenter, // precalc methods that need updating each frame
|
||||
kNormalPrecalcMask = kNormalDynamicMask | kNormalUp, // All types where emitter precalculates the normal
|
||||
|
||||
kNormalViewFacing = 0x00000100,
|
||||
kNormalNearestLight = 0x00000200,
|
||||
|
||||
kNeedsUpdate = 0x01000000,
|
||||
kBorrowedGenerator = 0x02000000,
|
||||
kOverrideLocalToWorld = 0x04000000,
|
||||
kOnReserve = 0x08000000,
|
||||
|
||||
kOrientationUp = 0x10000000,
|
||||
kOrientationVelocityBased = 0x20000000,
|
||||
kOrientationVelocityStretch = 0x40000000,
|
||||
kOrientationVelocityFlow = 0x80000000,
|
||||
kOrientationVelocityMask = kOrientationVelocityBased | kOrientationVelocityStretch | kOrientationVelocityFlow, // Velocity dependent
|
||||
kOrientationMask = kOrientationUp | kOrientationVelocityMask,
|
||||
};
|
||||
UInt32 fMiscFlags;
|
||||
|
||||
protected:
|
||||
|
||||
plParticleSystem *fSystem; // The particle system this belongs to.
|
||||
plParticleCore *fParticleCores; // The particle pool, created on init, initialized as needed, and recycled.
|
||||
plParticleExt *fParticleExts; // Same mapping as the Core pool. Contains extra info the render pipeline
|
||||
// doesn't need.
|
||||
|
||||
plParticleGenerator *fGenerator; // Optional auto generator (have this be nil if you don't want auto-generation)
|
||||
UInt32 fSpanIndex; // Index of the span that this emitter uses.
|
||||
UInt32 fNumValidParticles;
|
||||
UInt32 fMaxParticles;
|
||||
hsBounds3Ext fBoundBox;
|
||||
plEffectTargetInfo fTargetInfo; // A collection of pointers and strides that plParticleEffects will manipulate.
|
||||
hsColorRGBA fColor;
|
||||
|
||||
hsMatrix44 fLocalToWorld;
|
||||
hsScalar fTimeToLive;
|
||||
|
||||
void IClear();
|
||||
void ISetupParticleMem();
|
||||
void ISetSystem(plParticleSystem *sys) { fSystem = sys; }
|
||||
hsBool IUpdate(hsScalar delta);
|
||||
void IUpdateParticles(hsScalar delta);
|
||||
void IUpdateBoundsAndNormals(hsScalar delta);
|
||||
void IRemoveParticle(UInt32 index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,438 +1,438 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsFastMath.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plParticle.h"
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleEmitter.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "plMessage/plParticleUpdateMsg.h"
|
||||
#include "plInterp/plController.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "plMath/plRandom.h"
|
||||
|
||||
static const hsScalar DEFAULT_INVERSE_MASS = 1.f;
|
||||
|
||||
static plRandom sRandom;
|
||||
|
||||
const void plParticleGenerator::ComputeDirection(float pitch, float yaw, hsVector3 &direction)
|
||||
{
|
||||
hsScalar cosPitch, sinPitch;
|
||||
hsScalar cosYaw, sinYaw;
|
||||
hsFastMath::SinCos(pitch, sinPitch, cosPitch);
|
||||
hsFastMath::SinCos(yaw, sinYaw, cosYaw);
|
||||
|
||||
direction.Set(-sinYaw * cosPitch, sinPitch, cosPitch * cosYaw);
|
||||
}
|
||||
|
||||
// Inverse function of ComputeDirection. Give it a normalized vector, and it will tell you a
|
||||
// pitch and yaw (angles for the unit Z vector) to get there.
|
||||
const void plParticleGenerator::ComputePitchYaw(float &pitch, float &yaw, const hsVector3 &dir)
|
||||
{
|
||||
const float PI = 3.14159f;
|
||||
pitch = asin(dir.fY);
|
||||
float cos_pitch = cos(pitch);
|
||||
if (cos_pitch == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
return;
|
||||
}
|
||||
float inv = -dir.fX / cos_pitch;
|
||||
if (inv > 1.0f)
|
||||
inv = 1.0f;
|
||||
if (inv < -1.0f)
|
||||
inv = -1.0f;
|
||||
yaw = asin(inv);
|
||||
if (dir.fZ < 0)
|
||||
yaw = PI - yaw;
|
||||
}
|
||||
|
||||
plSimpleParticleGenerator::plSimpleParticleGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
plSimpleParticleGenerator::~plSimpleParticleGenerator()
|
||||
{
|
||||
delete [] fInitPos;
|
||||
delete [] fInitPitch;
|
||||
delete [] fInitYaw;
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Init(hsScalar genLife, hsScalar partLifeMin, hsScalar partLifeMax,
|
||||
hsScalar particlesPerSecond, UInt32 numSources, hsPoint3 *initPos,
|
||||
hsScalar *initPitch, hsScalar *initYaw, hsScalar angleRange,
|
||||
hsScalar initVelMin, hsScalar initVelMax,
|
||||
hsScalar xSize, hsScalar ySize,
|
||||
hsScalar scaleMin, hsScalar scaleMax,
|
||||
hsScalar massRange, hsScalar radsPerSecRange)
|
||||
{
|
||||
fGenLife = genLife;
|
||||
fPartLifeMin = partLifeMin;
|
||||
fPartLifeMax = partLifeMax;
|
||||
fParticlesPerSecond = particlesPerSecond;
|
||||
fNumSources = numSources;
|
||||
fInitPos = initPos;
|
||||
fInitPitch = initPitch;
|
||||
fInitYaw = initYaw;
|
||||
fAngleRange = angleRange;
|
||||
fVelMin = initVelMin;
|
||||
fVelMax = initVelMax;
|
||||
fXSize = xSize;
|
||||
fYSize = ySize;
|
||||
fScaleMin = scaleMin;
|
||||
fScaleMax = scaleMax;
|
||||
|
||||
fPartInvMassMin = 1.f / (DEFAULT_INVERSE_MASS + massRange);
|
||||
fPartInvMassRange = 1.f / DEFAULT_INVERSE_MASS - fPartInvMassMin;
|
||||
|
||||
fPartRadsPerSecRange = radsPerSecRange;
|
||||
|
||||
fParticleSum = 0;
|
||||
fMiscFlags = 0;
|
||||
if (fGenLife < 0) fMiscFlags |= kImmortal;
|
||||
}
|
||||
|
||||
hsBool plSimpleParticleGenerator::AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced /* = 0 */)
|
||||
{
|
||||
Int32 numNewParticles;
|
||||
|
||||
if (numForced == 0)
|
||||
{
|
||||
fGenLife -= dt;
|
||||
if ((fGenLife < 0 && !(fMiscFlags & kImmortal)) || (fMiscFlags & kDisabled))
|
||||
return true; // Leave it around so that a message can bring it back to life.
|
||||
|
||||
fParticleSum += fParticlesPerSecond * dt;
|
||||
numNewParticles = (Int32)fParticleSum;
|
||||
|
||||
if (numNewParticles <= 0 || fParticlesPerSecond == 0)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
numNewParticles = numForced;
|
||||
}
|
||||
|
||||
UInt32 miscFlags = 0;
|
||||
hsPoint3 currStart;
|
||||
fParticleSum -= numNewParticles;
|
||||
|
||||
hsPoint3 orientation;
|
||||
hsVector3 initDirection;
|
||||
hsScalar vel = (fVelMax + fVelMin) * 0.5f;
|
||||
hsScalar velRange = vel - fVelMin;
|
||||
hsScalar initVelocity;
|
||||
hsScalar initLife;
|
||||
hsScalar life = (fPartLifeMax + fPartLifeMin) * 0.5f;
|
||||
hsScalar lifeRange = life - fPartLifeMin;
|
||||
hsScalar currSizeVar;
|
||||
hsScalar scale = (fScaleMax + fScaleMin) * 0.5f;
|
||||
hsScalar scaleRange = scale - fScaleMin;
|
||||
hsScalar radsPerSec = 0;
|
||||
UInt32 tile;
|
||||
UInt32 sourceIndex;
|
||||
|
||||
const hsScalar lifeDiff = dt / numNewParticles;
|
||||
hsScalar lifeSoFar;
|
||||
int i;
|
||||
for (i = 0, lifeSoFar = 0; i < numNewParticles; i++, lifeSoFar += lifeDiff)
|
||||
{
|
||||
initLife = life + lifeRange * sRandom.RandMinusOneToOne() - lifeSoFar;
|
||||
|
||||
// Careful here... if we're supposed to generate immortal particles, we do so
|
||||
// by giving them a negative life. This is different that generating one with
|
||||
// a positive lifetime that is now negative because of "lifeSoFar". The if is
|
||||
// saying "if it's dead, but it was alive before we took away lifeSoFar, ignore it"
|
||||
if (initLife <= 0 && initLife + lifeSoFar >= 0)
|
||||
continue;
|
||||
|
||||
sourceIndex = (UInt32)(sRandom.RandZeroToOne() * fNumSources);
|
||||
|
||||
ComputeDirection(fInitPitch[sourceIndex] + fAngleRange * sRandom.RandMinusOneToOne(),
|
||||
fInitYaw[sourceIndex] + fAngleRange * sRandom.RandMinusOneToOne(), initDirection);
|
||||
initDirection = emitter->GetLocalToWorld() * initDirection;
|
||||
initVelocity = (vel + velRange * sRandom.RandMinusOneToOne());
|
||||
|
||||
currStart = (emitter->GetLocalToWorld() * fInitPos[sourceIndex])
|
||||
+ (initDirection * initVelocity * lifeSoFar) // Vo * t
|
||||
+ (emitter->fSystem->fAccel * lifeSoFar * lifeSoFar); // at^2
|
||||
|
||||
if (emitter->fMiscFlags & emitter->kOrientationUp)
|
||||
orientation.Set(0.0f, -1.0f, 0.0f);
|
||||
else
|
||||
orientation.Set(&initDirection);
|
||||
|
||||
tile = (UInt32)(sRandom.RandZeroToOne() * emitter->GetNumTiles());
|
||||
currSizeVar = scale + scaleRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
hsScalar invMass = fPartInvMassMin;
|
||||
// Might be faster to just do the math instead of checking for zero...
|
||||
if( fPartInvMassRange > 0 )
|
||||
invMass += fPartInvMassRange * sRandom.RandZeroToOne();
|
||||
|
||||
if( fPartRadsPerSecRange > 0 )
|
||||
radsPerSec = fPartRadsPerSecRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
emitter->AddParticle(currStart, initDirection * initVelocity, tile, fXSize, fYSize, currSizeVar,
|
||||
invMass, initLife, orientation, miscFlags, radsPerSec);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::UpdateParam(UInt32 paramID, hsScalar paramValue)
|
||||
{
|
||||
switch (paramID)
|
||||
{
|
||||
case plParticleUpdateMsg::kParamParticlesPerSecond:
|
||||
fParticlesPerSecond = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamInitPitchRange:
|
||||
case plParticleUpdateMsg::kParamInitYawRange:
|
||||
fAngleRange = paramValue;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamInitVel:
|
||||
// fInitVel = paramValue;
|
||||
// break;
|
||||
// case plParticleUpdateMsg::kParamInitVelRange:
|
||||
// fInitVelRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamVelMin:
|
||||
fVelMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamVelMax:
|
||||
fVelMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamXSize:
|
||||
fXSize = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamYSize:
|
||||
fYSize = paramValue;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamSizeRange:
|
||||
// fSizeRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamScaleMin:
|
||||
fScaleMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamScaleMax:
|
||||
fScaleMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamGenLife:
|
||||
fGenLife = paramValue;
|
||||
if (fGenLife < 0)
|
||||
fMiscFlags |= kImmortal;
|
||||
else
|
||||
fMiscFlags &= ~kImmortal;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamPartLife:
|
||||
// fPartLife = paramValue;
|
||||
// if (fPartLife < 0)
|
||||
// fPartLifeRange = 0;
|
||||
// break;
|
||||
// case plParticleUpdateMsg::kParamPartLifeRange:
|
||||
// fPartLifeRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamPartLifeMin:
|
||||
fPartLifeMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamPartLifeMax:
|
||||
fPartLifeMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamEnabled:
|
||||
if (paramValue == 0.f)
|
||||
fMiscFlags |= kDisabled;
|
||||
else
|
||||
fMiscFlags &= ~kDisabled;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
hsScalar genLife = s->ReadSwapScalar();
|
||||
hsScalar partLifeMin = s->ReadSwapScalar();
|
||||
hsScalar partLifeMax = s->ReadSwapScalar();
|
||||
hsScalar pps = s->ReadSwapScalar();
|
||||
UInt32 numSources = s->ReadSwap32();
|
||||
hsPoint3 *pos = TRACKED_NEW hsPoint3[numSources];
|
||||
hsScalar *pitch = TRACKED_NEW hsScalar[numSources];
|
||||
hsScalar *yaw = TRACKED_NEW hsScalar[numSources];
|
||||
int i;
|
||||
for (i = 0; i < numSources; i++)
|
||||
{
|
||||
pos[i].Read(s);
|
||||
pitch[i] = s->ReadSwapScalar();
|
||||
yaw[i] = s->ReadSwapScalar();
|
||||
}
|
||||
hsScalar angleRange = s->ReadSwapScalar();
|
||||
hsScalar velMin = s->ReadSwapScalar();
|
||||
hsScalar velMax = s->ReadSwapScalar();
|
||||
hsScalar xSize = s->ReadSwapScalar();
|
||||
hsScalar ySize = s->ReadSwapScalar();
|
||||
hsScalar scaleMin = s->ReadSwapScalar();
|
||||
hsScalar scaleMax = s->ReadSwapScalar();
|
||||
hsScalar massRange = s->ReadSwapScalar();
|
||||
hsScalar radsPerSec = s->ReadSwapScalar();
|
||||
|
||||
Init(genLife, partLifeMin, partLifeMax, pps, numSources, pos, pitch, yaw, angleRange, velMin, velMax,
|
||||
xSize, ySize, scaleMin, scaleMax, massRange, radsPerSec);
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwapScalar(fGenLife);
|
||||
s->WriteSwapScalar(fPartLifeMin);
|
||||
s->WriteSwapScalar(fPartLifeMax);
|
||||
s->WriteSwapScalar(fParticlesPerSecond);
|
||||
s->WriteSwap32(fNumSources);
|
||||
int i;
|
||||
for (i = 0; i < fNumSources; i++)
|
||||
{
|
||||
fInitPos[i].Write(s);
|
||||
s->WriteSwapScalar(fInitPitch[i]);
|
||||
s->WriteSwapScalar(fInitYaw[i]);
|
||||
}
|
||||
s->WriteSwapScalar(fAngleRange);
|
||||
s->WriteSwapScalar(fVelMin);
|
||||
s->WriteSwapScalar(fVelMax);
|
||||
s->WriteSwapScalar(fXSize);
|
||||
s->WriteSwapScalar(fYSize);
|
||||
s->WriteSwapScalar(fScaleMin);
|
||||
s->WriteSwapScalar(fScaleMax);
|
||||
|
||||
hsScalar massRange = 1.f / fPartInvMassMin - DEFAULT_INVERSE_MASS;
|
||||
s->WriteSwapScalar(massRange);
|
||||
s->WriteSwapScalar(fPartRadsPerSecRange);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plOneTimeParticleGenerator::plOneTimeParticleGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
plOneTimeParticleGenerator::~plOneTimeParticleGenerator()
|
||||
{
|
||||
delete [] fPosition;
|
||||
delete [] fDirection;
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Init(hsScalar count, hsPoint3 *pointArray, hsVector3 *dirArray,
|
||||
hsScalar xSize, hsScalar ySize, hsScalar scaleMin, hsScalar scaleMax, hsScalar radsPerSecRange)
|
||||
{
|
||||
fCount = count;
|
||||
fPosition = pointArray;
|
||||
fDirection = dirArray;
|
||||
fXSize = xSize;
|
||||
fYSize = ySize;
|
||||
fScaleMin = scaleMin;
|
||||
fScaleMax = scaleMax;
|
||||
fPartRadsPerSecRange = radsPerSecRange;
|
||||
}
|
||||
|
||||
// The numForced param is required by the parent class, but ignored by this particular generator
|
||||
hsBool plOneTimeParticleGenerator::AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced /* = 0 */)
|
||||
{
|
||||
hsScalar currSizeVar;
|
||||
hsScalar scale = (fScaleMax + fScaleMin) / 2;
|
||||
hsScalar scaleRange = scale - fScaleMin;
|
||||
|
||||
hsScalar tile;
|
||||
hsPoint3 currStart;
|
||||
hsPoint3 orientation;
|
||||
hsVector3 initDirection;
|
||||
hsVector3 zeroVel(0.f, 0.f, 0.f);
|
||||
hsScalar radsPerSec = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fCount; i++)
|
||||
{
|
||||
currStart = emitter->GetLocalToWorld() * fPosition[i];
|
||||
initDirection = emitter->GetLocalToWorld() * fDirection[i];
|
||||
|
||||
if (emitter->fMiscFlags & emitter->kOrientationUp)
|
||||
orientation.Set(0.0f, -1.0f, 0.0f);
|
||||
else
|
||||
orientation.Set(&initDirection);
|
||||
|
||||
tile = (hsScalar)(sRandom.Rand() % emitter->GetNumTiles());
|
||||
currSizeVar = scale + scaleRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
if( fPartRadsPerSecRange > 0 )
|
||||
radsPerSec = fPartRadsPerSecRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
emitter->AddParticle(currStart, zeroVel, (UInt32)tile, fXSize, fYSize, currSizeVar,
|
||||
DEFAULT_INVERSE_MASS, -1, orientation, 0, radsPerSec);
|
||||
}
|
||||
emitter->fMiscFlags &= ~plParticleEmitter::kNeedsUpdate;
|
||||
return false; // We've done our one-time job. Let the emitter know to delete us.
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
UInt32 count = s->ReadSwap32();
|
||||
hsScalar xSize = s->ReadSwapScalar();
|
||||
hsScalar ySize = s->ReadSwapScalar();
|
||||
hsScalar scaleMin = s->ReadSwapScalar();
|
||||
hsScalar scaleMax = s->ReadSwapScalar();
|
||||
hsScalar radsPerSecRange = s->ReadSwapScalar();
|
||||
|
||||
hsPoint3 *pos = TRACKED_NEW hsPoint3[count];
|
||||
hsVector3 *dir = TRACKED_NEW hsVector3[count];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
pos[i].Read(s);
|
||||
dir[i].Read(s);
|
||||
}
|
||||
|
||||
Init((hsScalar)count, pos, dir, xSize, ySize, scaleMin, scaleMax, radsPerSecRange);
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwap32((UInt32)fCount);
|
||||
s->WriteSwapScalar(fXSize);
|
||||
s->WriteSwapScalar(fYSize);
|
||||
s->WriteSwapScalar(fScaleMin);
|
||||
s->WriteSwapScalar(fScaleMax);
|
||||
s->WriteSwapScalar(fPartRadsPerSecRange);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fCount; i++)
|
||||
{
|
||||
fPosition[i].Write(s);
|
||||
fDirection[i].Write(s);
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTypes.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsFastMath.h"
|
||||
#include "hsUtils.h"
|
||||
#include "plParticle.h"
|
||||
#include "plParticleSystem.h"
|
||||
#include "plParticleEmitter.h"
|
||||
#include "plParticleGenerator.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "plMessage/plParticleUpdateMsg.h"
|
||||
#include "plInterp/plController.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "plMath/plRandom.h"
|
||||
|
||||
static const hsScalar DEFAULT_INVERSE_MASS = 1.f;
|
||||
|
||||
static plRandom sRandom;
|
||||
|
||||
const void plParticleGenerator::ComputeDirection(float pitch, float yaw, hsVector3 &direction)
|
||||
{
|
||||
hsScalar cosPitch, sinPitch;
|
||||
hsScalar cosYaw, sinYaw;
|
||||
hsFastMath::SinCos(pitch, sinPitch, cosPitch);
|
||||
hsFastMath::SinCos(yaw, sinYaw, cosYaw);
|
||||
|
||||
direction.Set(-sinYaw * cosPitch, sinPitch, cosPitch * cosYaw);
|
||||
}
|
||||
|
||||
// Inverse function of ComputeDirection. Give it a normalized vector, and it will tell you a
|
||||
// pitch and yaw (angles for the unit Z vector) to get there.
|
||||
const void plParticleGenerator::ComputePitchYaw(float &pitch, float &yaw, const hsVector3 &dir)
|
||||
{
|
||||
const float PI = 3.14159f;
|
||||
pitch = asin(dir.fY);
|
||||
float cos_pitch = cos(pitch);
|
||||
if (cos_pitch == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
return;
|
||||
}
|
||||
float inv = -dir.fX / cos_pitch;
|
||||
if (inv > 1.0f)
|
||||
inv = 1.0f;
|
||||
if (inv < -1.0f)
|
||||
inv = -1.0f;
|
||||
yaw = asin(inv);
|
||||
if (dir.fZ < 0)
|
||||
yaw = PI - yaw;
|
||||
}
|
||||
|
||||
plSimpleParticleGenerator::plSimpleParticleGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
plSimpleParticleGenerator::~plSimpleParticleGenerator()
|
||||
{
|
||||
delete [] fInitPos;
|
||||
delete [] fInitPitch;
|
||||
delete [] fInitYaw;
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Init(hsScalar genLife, hsScalar partLifeMin, hsScalar partLifeMax,
|
||||
hsScalar particlesPerSecond, UInt32 numSources, hsPoint3 *initPos,
|
||||
hsScalar *initPitch, hsScalar *initYaw, hsScalar angleRange,
|
||||
hsScalar initVelMin, hsScalar initVelMax,
|
||||
hsScalar xSize, hsScalar ySize,
|
||||
hsScalar scaleMin, hsScalar scaleMax,
|
||||
hsScalar massRange, hsScalar radsPerSecRange)
|
||||
{
|
||||
fGenLife = genLife;
|
||||
fPartLifeMin = partLifeMin;
|
||||
fPartLifeMax = partLifeMax;
|
||||
fParticlesPerSecond = particlesPerSecond;
|
||||
fNumSources = numSources;
|
||||
fInitPos = initPos;
|
||||
fInitPitch = initPitch;
|
||||
fInitYaw = initYaw;
|
||||
fAngleRange = angleRange;
|
||||
fVelMin = initVelMin;
|
||||
fVelMax = initVelMax;
|
||||
fXSize = xSize;
|
||||
fYSize = ySize;
|
||||
fScaleMin = scaleMin;
|
||||
fScaleMax = scaleMax;
|
||||
|
||||
fPartInvMassMin = 1.f / (DEFAULT_INVERSE_MASS + massRange);
|
||||
fPartInvMassRange = 1.f / DEFAULT_INVERSE_MASS - fPartInvMassMin;
|
||||
|
||||
fPartRadsPerSecRange = radsPerSecRange;
|
||||
|
||||
fParticleSum = 0;
|
||||
fMiscFlags = 0;
|
||||
if (fGenLife < 0) fMiscFlags |= kImmortal;
|
||||
}
|
||||
|
||||
hsBool plSimpleParticleGenerator::AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced /* = 0 */)
|
||||
{
|
||||
Int32 numNewParticles;
|
||||
|
||||
if (numForced == 0)
|
||||
{
|
||||
fGenLife -= dt;
|
||||
if ((fGenLife < 0 && !(fMiscFlags & kImmortal)) || (fMiscFlags & kDisabled))
|
||||
return true; // Leave it around so that a message can bring it back to life.
|
||||
|
||||
fParticleSum += fParticlesPerSecond * dt;
|
||||
numNewParticles = (Int32)fParticleSum;
|
||||
|
||||
if (numNewParticles <= 0 || fParticlesPerSecond == 0)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
numNewParticles = numForced;
|
||||
}
|
||||
|
||||
UInt32 miscFlags = 0;
|
||||
hsPoint3 currStart;
|
||||
fParticleSum -= numNewParticles;
|
||||
|
||||
hsPoint3 orientation;
|
||||
hsVector3 initDirection;
|
||||
hsScalar vel = (fVelMax + fVelMin) * 0.5f;
|
||||
hsScalar velRange = vel - fVelMin;
|
||||
hsScalar initVelocity;
|
||||
hsScalar initLife;
|
||||
hsScalar life = (fPartLifeMax + fPartLifeMin) * 0.5f;
|
||||
hsScalar lifeRange = life - fPartLifeMin;
|
||||
hsScalar currSizeVar;
|
||||
hsScalar scale = (fScaleMax + fScaleMin) * 0.5f;
|
||||
hsScalar scaleRange = scale - fScaleMin;
|
||||
hsScalar radsPerSec = 0;
|
||||
UInt32 tile;
|
||||
UInt32 sourceIndex;
|
||||
|
||||
const hsScalar lifeDiff = dt / numNewParticles;
|
||||
hsScalar lifeSoFar;
|
||||
int i;
|
||||
for (i = 0, lifeSoFar = 0; i < numNewParticles; i++, lifeSoFar += lifeDiff)
|
||||
{
|
||||
initLife = life + lifeRange * sRandom.RandMinusOneToOne() - lifeSoFar;
|
||||
|
||||
// Careful here... if we're supposed to generate immortal particles, we do so
|
||||
// by giving them a negative life. This is different that generating one with
|
||||
// a positive lifetime that is now negative because of "lifeSoFar". The if is
|
||||
// saying "if it's dead, but it was alive before we took away lifeSoFar, ignore it"
|
||||
if (initLife <= 0 && initLife + lifeSoFar >= 0)
|
||||
continue;
|
||||
|
||||
sourceIndex = (UInt32)(sRandom.RandZeroToOne() * fNumSources);
|
||||
|
||||
ComputeDirection(fInitPitch[sourceIndex] + fAngleRange * sRandom.RandMinusOneToOne(),
|
||||
fInitYaw[sourceIndex] + fAngleRange * sRandom.RandMinusOneToOne(), initDirection);
|
||||
initDirection = emitter->GetLocalToWorld() * initDirection;
|
||||
initVelocity = (vel + velRange * sRandom.RandMinusOneToOne());
|
||||
|
||||
currStart = (emitter->GetLocalToWorld() * fInitPos[sourceIndex])
|
||||
+ (initDirection * initVelocity * lifeSoFar) // Vo * t
|
||||
+ (emitter->fSystem->fAccel * lifeSoFar * lifeSoFar); // at^2
|
||||
|
||||
if (emitter->fMiscFlags & emitter->kOrientationUp)
|
||||
orientation.Set(0.0f, -1.0f, 0.0f);
|
||||
else
|
||||
orientation.Set(&initDirection);
|
||||
|
||||
tile = (UInt32)(sRandom.RandZeroToOne() * emitter->GetNumTiles());
|
||||
currSizeVar = scale + scaleRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
hsScalar invMass = fPartInvMassMin;
|
||||
// Might be faster to just do the math instead of checking for zero...
|
||||
if( fPartInvMassRange > 0 )
|
||||
invMass += fPartInvMassRange * sRandom.RandZeroToOne();
|
||||
|
||||
if( fPartRadsPerSecRange > 0 )
|
||||
radsPerSec = fPartRadsPerSecRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
emitter->AddParticle(currStart, initDirection * initVelocity, tile, fXSize, fYSize, currSizeVar,
|
||||
invMass, initLife, orientation, miscFlags, radsPerSec);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::UpdateParam(UInt32 paramID, hsScalar paramValue)
|
||||
{
|
||||
switch (paramID)
|
||||
{
|
||||
case plParticleUpdateMsg::kParamParticlesPerSecond:
|
||||
fParticlesPerSecond = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamInitPitchRange:
|
||||
case plParticleUpdateMsg::kParamInitYawRange:
|
||||
fAngleRange = paramValue;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamInitVel:
|
||||
// fInitVel = paramValue;
|
||||
// break;
|
||||
// case plParticleUpdateMsg::kParamInitVelRange:
|
||||
// fInitVelRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamVelMin:
|
||||
fVelMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamVelMax:
|
||||
fVelMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamXSize:
|
||||
fXSize = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamYSize:
|
||||
fYSize = paramValue;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamSizeRange:
|
||||
// fSizeRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamScaleMin:
|
||||
fScaleMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamScaleMax:
|
||||
fScaleMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamGenLife:
|
||||
fGenLife = paramValue;
|
||||
if (fGenLife < 0)
|
||||
fMiscFlags |= kImmortal;
|
||||
else
|
||||
fMiscFlags &= ~kImmortal;
|
||||
break;
|
||||
// case plParticleUpdateMsg::kParamPartLife:
|
||||
// fPartLife = paramValue;
|
||||
// if (fPartLife < 0)
|
||||
// fPartLifeRange = 0;
|
||||
// break;
|
||||
// case plParticleUpdateMsg::kParamPartLifeRange:
|
||||
// fPartLifeRange = paramValue;
|
||||
// break;
|
||||
case plParticleUpdateMsg::kParamPartLifeMin:
|
||||
fPartLifeMin = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamPartLifeMax:
|
||||
fPartLifeMax = paramValue;
|
||||
break;
|
||||
case plParticleUpdateMsg::kParamEnabled:
|
||||
if (paramValue == 0.f)
|
||||
fMiscFlags |= kDisabled;
|
||||
else
|
||||
fMiscFlags &= ~kDisabled;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
hsScalar genLife = s->ReadSwapScalar();
|
||||
hsScalar partLifeMin = s->ReadSwapScalar();
|
||||
hsScalar partLifeMax = s->ReadSwapScalar();
|
||||
hsScalar pps = s->ReadSwapScalar();
|
||||
UInt32 numSources = s->ReadSwap32();
|
||||
hsPoint3 *pos = TRACKED_NEW hsPoint3[numSources];
|
||||
hsScalar *pitch = TRACKED_NEW hsScalar[numSources];
|
||||
hsScalar *yaw = TRACKED_NEW hsScalar[numSources];
|
||||
int i;
|
||||
for (i = 0; i < numSources; i++)
|
||||
{
|
||||
pos[i].Read(s);
|
||||
pitch[i] = s->ReadSwapScalar();
|
||||
yaw[i] = s->ReadSwapScalar();
|
||||
}
|
||||
hsScalar angleRange = s->ReadSwapScalar();
|
||||
hsScalar velMin = s->ReadSwapScalar();
|
||||
hsScalar velMax = s->ReadSwapScalar();
|
||||
hsScalar xSize = s->ReadSwapScalar();
|
||||
hsScalar ySize = s->ReadSwapScalar();
|
||||
hsScalar scaleMin = s->ReadSwapScalar();
|
||||
hsScalar scaleMax = s->ReadSwapScalar();
|
||||
hsScalar massRange = s->ReadSwapScalar();
|
||||
hsScalar radsPerSec = s->ReadSwapScalar();
|
||||
|
||||
Init(genLife, partLifeMin, partLifeMax, pps, numSources, pos, pitch, yaw, angleRange, velMin, velMax,
|
||||
xSize, ySize, scaleMin, scaleMax, massRange, radsPerSec);
|
||||
}
|
||||
|
||||
void plSimpleParticleGenerator::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwapScalar(fGenLife);
|
||||
s->WriteSwapScalar(fPartLifeMin);
|
||||
s->WriteSwapScalar(fPartLifeMax);
|
||||
s->WriteSwapScalar(fParticlesPerSecond);
|
||||
s->WriteSwap32(fNumSources);
|
||||
int i;
|
||||
for (i = 0; i < fNumSources; i++)
|
||||
{
|
||||
fInitPos[i].Write(s);
|
||||
s->WriteSwapScalar(fInitPitch[i]);
|
||||
s->WriteSwapScalar(fInitYaw[i]);
|
||||
}
|
||||
s->WriteSwapScalar(fAngleRange);
|
||||
s->WriteSwapScalar(fVelMin);
|
||||
s->WriteSwapScalar(fVelMax);
|
||||
s->WriteSwapScalar(fXSize);
|
||||
s->WriteSwapScalar(fYSize);
|
||||
s->WriteSwapScalar(fScaleMin);
|
||||
s->WriteSwapScalar(fScaleMax);
|
||||
|
||||
hsScalar massRange = 1.f / fPartInvMassMin - DEFAULT_INVERSE_MASS;
|
||||
s->WriteSwapScalar(massRange);
|
||||
s->WriteSwapScalar(fPartRadsPerSecRange);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plOneTimeParticleGenerator::plOneTimeParticleGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
plOneTimeParticleGenerator::~plOneTimeParticleGenerator()
|
||||
{
|
||||
delete [] fPosition;
|
||||
delete [] fDirection;
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Init(hsScalar count, hsPoint3 *pointArray, hsVector3 *dirArray,
|
||||
hsScalar xSize, hsScalar ySize, hsScalar scaleMin, hsScalar scaleMax, hsScalar radsPerSecRange)
|
||||
{
|
||||
fCount = count;
|
||||
fPosition = pointArray;
|
||||
fDirection = dirArray;
|
||||
fXSize = xSize;
|
||||
fYSize = ySize;
|
||||
fScaleMin = scaleMin;
|
||||
fScaleMax = scaleMax;
|
||||
fPartRadsPerSecRange = radsPerSecRange;
|
||||
}
|
||||
|
||||
// The numForced param is required by the parent class, but ignored by this particular generator
|
||||
hsBool plOneTimeParticleGenerator::AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced /* = 0 */)
|
||||
{
|
||||
hsScalar currSizeVar;
|
||||
hsScalar scale = (fScaleMax + fScaleMin) / 2;
|
||||
hsScalar scaleRange = scale - fScaleMin;
|
||||
|
||||
hsScalar tile;
|
||||
hsPoint3 currStart;
|
||||
hsPoint3 orientation;
|
||||
hsVector3 initDirection;
|
||||
hsVector3 zeroVel(0.f, 0.f, 0.f);
|
||||
hsScalar radsPerSec = 0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fCount; i++)
|
||||
{
|
||||
currStart = emitter->GetLocalToWorld() * fPosition[i];
|
||||
initDirection = emitter->GetLocalToWorld() * fDirection[i];
|
||||
|
||||
if (emitter->fMiscFlags & emitter->kOrientationUp)
|
||||
orientation.Set(0.0f, -1.0f, 0.0f);
|
||||
else
|
||||
orientation.Set(&initDirection);
|
||||
|
||||
tile = (hsScalar)(sRandom.Rand() % emitter->GetNumTiles());
|
||||
currSizeVar = scale + scaleRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
if( fPartRadsPerSecRange > 0 )
|
||||
radsPerSec = fPartRadsPerSecRange * sRandom.RandMinusOneToOne();
|
||||
|
||||
emitter->AddParticle(currStart, zeroVel, (UInt32)tile, fXSize, fYSize, currSizeVar,
|
||||
DEFAULT_INVERSE_MASS, -1, orientation, 0, radsPerSec);
|
||||
}
|
||||
emitter->fMiscFlags &= ~plParticleEmitter::kNeedsUpdate;
|
||||
return false; // We've done our one-time job. Let the emitter know to delete us.
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Read(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
UInt32 count = s->ReadSwap32();
|
||||
hsScalar xSize = s->ReadSwapScalar();
|
||||
hsScalar ySize = s->ReadSwapScalar();
|
||||
hsScalar scaleMin = s->ReadSwapScalar();
|
||||
hsScalar scaleMax = s->ReadSwapScalar();
|
||||
hsScalar radsPerSecRange = s->ReadSwapScalar();
|
||||
|
||||
hsPoint3 *pos = TRACKED_NEW hsPoint3[count];
|
||||
hsVector3 *dir = TRACKED_NEW hsVector3[count];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
pos[i].Read(s);
|
||||
dir[i].Read(s);
|
||||
}
|
||||
|
||||
Init((hsScalar)count, pos, dir, xSize, ySize, scaleMin, scaleMax, radsPerSecRange);
|
||||
}
|
||||
|
||||
void plOneTimeParticleGenerator::Write(hsStream* s, hsResMgr *mgr)
|
||||
{
|
||||
s->WriteSwap32((UInt32)fCount);
|
||||
s->WriteSwapScalar(fXSize);
|
||||
s->WriteSwapScalar(fYSize);
|
||||
s->WriteSwapScalar(fScaleMin);
|
||||
s->WriteSwapScalar(fScaleMax);
|
||||
s->WriteSwapScalar(fPartRadsPerSecRange);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fCount; i++)
|
||||
{
|
||||
fPosition[i].Write(s);
|
||||
fDirection[i].Write(s);
|
||||
}
|
||||
}
|
@ -1,132 +1,132 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleGenerator_inc
|
||||
#define plParticleGenerator_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
class plParticleEmitter;
|
||||
class plScalarController;
|
||||
|
||||
// This class is responsible for all the details of automatically generating particles for a plParticleEmitter.
|
||||
// It gets a change in time, and must do whatever necessary to generate the appropriate number of particles
|
||||
// for that timespan
|
||||
|
||||
class plParticleGenerator : public plCreatable
|
||||
{
|
||||
|
||||
public:
|
||||
// returns false if it's done generating particles and is safe to delete.
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced = 0) = 0;
|
||||
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue) = 0;
|
||||
|
||||
CLASSNAME_REGISTER( plParticleGenerator );
|
||||
GETINTERFACE_ANY( plParticleGenerator, plCreatable );
|
||||
|
||||
static const void ComputeDirection(float pitch, float yaw, hsVector3 &direction);
|
||||
static const void ComputePitchYaw(float &pitch, float &yaw, const hsVector3 &dir);
|
||||
static inline float GetRandomVar() { return 2.0f * (float)hsRand() / RAND_MAX - 1; } // returns a num between +/- 1.0
|
||||
};
|
||||
|
||||
class plSimpleParticleGenerator : public plParticleGenerator
|
||||
{
|
||||
public:
|
||||
plSimpleParticleGenerator();
|
||||
~plSimpleParticleGenerator();
|
||||
void Init(hsScalar genLife, hsScalar partLifeMin, hsScalar partLifeMax, hsScalar particlesPerSecond,
|
||||
UInt32 numSources, hsPoint3 *pos, hsScalar *initPitch, hsScalar *initYaw, hsScalar angleRange,
|
||||
hsScalar initVelMin, hsScalar initVelMax, hsScalar xSize, hsScalar ySize,
|
||||
hsScalar scaleMin, hsScalar scaleMax,
|
||||
hsScalar massRange, hsScalar radsPerSecRange);
|
||||
|
||||
CLASSNAME_REGISTER( plSimpleParticleGenerator );
|
||||
GETINTERFACE_ANY( plSimpleParticleGenerator, plParticleGenerator);
|
||||
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced);
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
protected:
|
||||
hsScalar fParticlesPerSecond;
|
||||
UInt32 fNumSources;
|
||||
hsPoint3 *fInitPos;
|
||||
hsScalar *fInitPitch, *fInitYaw;
|
||||
hsScalar fAngleRange;
|
||||
hsScalar fVelMin, fVelMax;
|
||||
hsScalar fXSize, fYSize, fScaleMin, fScaleMax;
|
||||
hsScalar fGenLife; // How long shall we spit out particles from this location? When this time runs out, we stop
|
||||
// spitting particles, but we don't actually die until all of our particles die naturally.
|
||||
// (Even the ones that we feel are suffering needlessly.)
|
||||
|
||||
hsScalar fPartLifeMin; // lifespan for the particles we generate
|
||||
hsScalar fPartLifeMax;
|
||||
|
||||
hsScalar fPartInvMassMin; // Doing a uniform variant over the inverse mass range (instead of over the mass range
|
||||
hsScalar fPartInvMassRange; // and then inverting) will favor the low end of the mass range, but then again,
|
||||
// it's just a freaking game. Note though that fPartInvMassMin == 1.f / massMAX.
|
||||
|
||||
hsScalar fPartRadsPerSecRange; // Zero means no rot, otherwise uniform random between [-range..range]
|
||||
|
||||
hsScalar fParticleSum;
|
||||
|
||||
enum
|
||||
{
|
||||
kImmortal = 0x1,
|
||||
kDisabled = 0x2,
|
||||
};
|
||||
UInt32 fMiscFlags;
|
||||
};
|
||||
|
||||
class plOneTimeParticleGenerator : public plParticleGenerator
|
||||
{
|
||||
public:
|
||||
|
||||
plOneTimeParticleGenerator();
|
||||
~plOneTimeParticleGenerator();
|
||||
void Init(hsScalar count, hsPoint3 *pointArray, hsVector3 *dirArray,
|
||||
hsScalar xSize, hsScalar ySize, hsScalar scaleMin, hsScalar scaleMax, hsScalar radsPerSec);
|
||||
|
||||
CLASSNAME_REGISTER( plOneTimeParticleGenerator );
|
||||
GETINTERFACE_ANY( plOneTimeParticleGenerator, plParticleGenerator);
|
||||
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced = 0);
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue) {}
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
protected:
|
||||
hsScalar fCount;
|
||||
hsPoint3 *fPosition;
|
||||
hsVector3 *fDirection;
|
||||
hsScalar fXSize, fYSize, fScaleMin, fScaleMax;
|
||||
hsScalar fPartRadsPerSecRange; // Zero means no rot, otherwise uniform random between [-range..range]
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleGenerator_inc
|
||||
#define plParticleGenerator_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
class plParticleEmitter;
|
||||
class plScalarController;
|
||||
|
||||
// This class is responsible for all the details of automatically generating particles for a plParticleEmitter.
|
||||
// It gets a change in time, and must do whatever necessary to generate the appropriate number of particles
|
||||
// for that timespan
|
||||
|
||||
class plParticleGenerator : public plCreatable
|
||||
{
|
||||
|
||||
public:
|
||||
// returns false if it's done generating particles and is safe to delete.
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced = 0) = 0;
|
||||
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue) = 0;
|
||||
|
||||
CLASSNAME_REGISTER( plParticleGenerator );
|
||||
GETINTERFACE_ANY( plParticleGenerator, plCreatable );
|
||||
|
||||
static const void ComputeDirection(float pitch, float yaw, hsVector3 &direction);
|
||||
static const void ComputePitchYaw(float &pitch, float &yaw, const hsVector3 &dir);
|
||||
static inline float GetRandomVar() { return 2.0f * (float)hsRand() / RAND_MAX - 1; } // returns a num between +/- 1.0
|
||||
};
|
||||
|
||||
class plSimpleParticleGenerator : public plParticleGenerator
|
||||
{
|
||||
public:
|
||||
plSimpleParticleGenerator();
|
||||
~plSimpleParticleGenerator();
|
||||
void Init(hsScalar genLife, hsScalar partLifeMin, hsScalar partLifeMax, hsScalar particlesPerSecond,
|
||||
UInt32 numSources, hsPoint3 *pos, hsScalar *initPitch, hsScalar *initYaw, hsScalar angleRange,
|
||||
hsScalar initVelMin, hsScalar initVelMax, hsScalar xSize, hsScalar ySize,
|
||||
hsScalar scaleMin, hsScalar scaleMax,
|
||||
hsScalar massRange, hsScalar radsPerSecRange);
|
||||
|
||||
CLASSNAME_REGISTER( plSimpleParticleGenerator );
|
||||
GETINTERFACE_ANY( plSimpleParticleGenerator, plParticleGenerator);
|
||||
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced);
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
protected:
|
||||
hsScalar fParticlesPerSecond;
|
||||
UInt32 fNumSources;
|
||||
hsPoint3 *fInitPos;
|
||||
hsScalar *fInitPitch, *fInitYaw;
|
||||
hsScalar fAngleRange;
|
||||
hsScalar fVelMin, fVelMax;
|
||||
hsScalar fXSize, fYSize, fScaleMin, fScaleMax;
|
||||
hsScalar fGenLife; // How long shall we spit out particles from this location? When this time runs out, we stop
|
||||
// spitting particles, but we don't actually die until all of our particles die naturally.
|
||||
// (Even the ones that we feel are suffering needlessly.)
|
||||
|
||||
hsScalar fPartLifeMin; // lifespan for the particles we generate
|
||||
hsScalar fPartLifeMax;
|
||||
|
||||
hsScalar fPartInvMassMin; // Doing a uniform variant over the inverse mass range (instead of over the mass range
|
||||
hsScalar fPartInvMassRange; // and then inverting) will favor the low end of the mass range, but then again,
|
||||
// it's just a freaking game. Note though that fPartInvMassMin == 1.f / massMAX.
|
||||
|
||||
hsScalar fPartRadsPerSecRange; // Zero means no rot, otherwise uniform random between [-range..range]
|
||||
|
||||
hsScalar fParticleSum;
|
||||
|
||||
enum
|
||||
{
|
||||
kImmortal = 0x1,
|
||||
kDisabled = 0x2,
|
||||
};
|
||||
UInt32 fMiscFlags;
|
||||
};
|
||||
|
||||
class plOneTimeParticleGenerator : public plParticleGenerator
|
||||
{
|
||||
public:
|
||||
|
||||
plOneTimeParticleGenerator();
|
||||
~plOneTimeParticleGenerator();
|
||||
void Init(hsScalar count, hsPoint3 *pointArray, hsVector3 *dirArray,
|
||||
hsScalar xSize, hsScalar ySize, hsScalar scaleMin, hsScalar scaleMax, hsScalar radsPerSec);
|
||||
|
||||
CLASSNAME_REGISTER( plOneTimeParticleGenerator );
|
||||
GETINTERFACE_ANY( plOneTimeParticleGenerator, plParticleGenerator);
|
||||
|
||||
virtual hsBool AddAutoParticles(plParticleEmitter *emitter, float dt, UInt32 numForced = 0);
|
||||
virtual void UpdateParam(UInt32 paramID, hsScalar paramValue) {}
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr *mgr);
|
||||
|
||||
protected:
|
||||
hsScalar fCount;
|
||||
hsPoint3 *fPosition;
|
||||
hsVector3 *fDirection;
|
||||
hsScalar fXSize, fYSize, fScaleMin, fScaleMax;
|
||||
hsScalar fPartRadsPerSecRange; // Zero means no rot, otherwise uniform random between [-range..range]
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,76 +1,76 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plParticleSDLMod.h"
|
||||
#include "plParticleSystem.h"
|
||||
|
||||
#include "pnSceneObject/plSceneObject.h"
|
||||
#include "plSDL/plSDL.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
|
||||
// static vars
|
||||
char plParticleSDLMod::kStrNumParticles[]="numParticles";
|
||||
|
||||
void plParticleSDLMod::IPutCurrentStateIn(plStateDataRecord* dstState)
|
||||
{
|
||||
plSceneObject* sobj=GetTarget();
|
||||
if (!sobj)
|
||||
return;
|
||||
|
||||
UInt32 flags = sobj->GetKey()->GetUoid().GetLocation().GetFlags();
|
||||
|
||||
const plParticleSystem *sys = plParticleSystem::ConvertNoRef(sobj->GetModifierByType(plParticleSystem::Index()));
|
||||
if (!sys)
|
||||
return;
|
||||
|
||||
int num = sys->GetNumValidParticles(true);
|
||||
dstState->FindVar(kStrNumParticles)->Set(num);
|
||||
}
|
||||
|
||||
void plParticleSDLMod::ISetCurrentStateFrom(const plStateDataRecord* srcState)
|
||||
{
|
||||
plSceneObject* sobj=GetTarget();
|
||||
if (!sobj)
|
||||
return;
|
||||
|
||||
plParticleSystem *sys = const_cast<plParticleSystem*>(plParticleSystem::ConvertNoRef(sobj->GetModifierByType(plParticleSystem::Index())));
|
||||
if (!sys)
|
||||
return;
|
||||
|
||||
int num;
|
||||
srcState->FindVar(kStrNumParticles)->Get(&num);
|
||||
if (num > sys->GetMaxTotalParticles())
|
||||
num = sys->GetMaxTotalParticles();
|
||||
|
||||
sys->WipeExistingParticles();
|
||||
sys->GenerateParticles(num);
|
||||
}
|
||||
|
||||
UInt32 plParticleSDLMod::IApplyModFlags(UInt32 sendFlags)
|
||||
{
|
||||
if (fAttachedToAvatar)
|
||||
return (sendFlags | plSynchedObject::kDontPersistOnServer | plSynchedObject::kIsAvatarState);
|
||||
return sendFlags;
|
||||
}
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "plParticleSDLMod.h"
|
||||
#include "plParticleSystem.h"
|
||||
|
||||
#include "pnSceneObject/plSceneObject.h"
|
||||
#include "plSDL/plSDL.h"
|
||||
#include "pnKeyedObject/plKey.h"
|
||||
|
||||
// static vars
|
||||
char plParticleSDLMod::kStrNumParticles[]="numParticles";
|
||||
|
||||
void plParticleSDLMod::IPutCurrentStateIn(plStateDataRecord* dstState)
|
||||
{
|
||||
plSceneObject* sobj=GetTarget();
|
||||
if (!sobj)
|
||||
return;
|
||||
|
||||
UInt32 flags = sobj->GetKey()->GetUoid().GetLocation().GetFlags();
|
||||
|
||||
const plParticleSystem *sys = plParticleSystem::ConvertNoRef(sobj->GetModifierByType(plParticleSystem::Index()));
|
||||
if (!sys)
|
||||
return;
|
||||
|
||||
int num = sys->GetNumValidParticles(true);
|
||||
dstState->FindVar(kStrNumParticles)->Set(num);
|
||||
}
|
||||
|
||||
void plParticleSDLMod::ISetCurrentStateFrom(const plStateDataRecord* srcState)
|
||||
{
|
||||
plSceneObject* sobj=GetTarget();
|
||||
if (!sobj)
|
||||
return;
|
||||
|
||||
plParticleSystem *sys = const_cast<plParticleSystem*>(plParticleSystem::ConvertNoRef(sobj->GetModifierByType(plParticleSystem::Index())));
|
||||
if (!sys)
|
||||
return;
|
||||
|
||||
int num;
|
||||
srcState->FindVar(kStrNumParticles)->Get(&num);
|
||||
if (num > sys->GetMaxTotalParticles())
|
||||
num = sys->GetMaxTotalParticles();
|
||||
|
||||
sys->WipeExistingParticles();
|
||||
sys->GenerateParticles(num);
|
||||
}
|
||||
|
||||
UInt32 plParticleSDLMod::IApplyModFlags(UInt32 sendFlags)
|
||||
{
|
||||
if (fAttachedToAvatar)
|
||||
return (sendFlags | plSynchedObject::kDontPersistOnServer | plSynchedObject::kIsAvatarState);
|
||||
return sendFlags;
|
||||
}
|
||||
|
@ -1,60 +1,60 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleSDLMod_inc
|
||||
#define plParticleSDLMod_inc
|
||||
|
||||
#include "plModifier/plSDLModifier.h"
|
||||
|
||||
//
|
||||
// This modifier is responsible for sending and recving
|
||||
// particle system state. Few need it. Little state is needed.
|
||||
//
|
||||
|
||||
class plParticleSDLMod : public plSDLModifier
|
||||
{
|
||||
private:
|
||||
bool fAttachedToAvatar;
|
||||
|
||||
protected:
|
||||
void IPutCurrentStateIn(plStateDataRecord* dstState);
|
||||
void ISetCurrentStateFrom(const plStateDataRecord* srcState);
|
||||
UInt32 IApplyModFlags(UInt32 sendFlags);
|
||||
public:
|
||||
// var labels
|
||||
static char kStrNumParticles[];
|
||||
|
||||
CLASSNAME_REGISTER( plParticleSDLMod );
|
||||
GETINTERFACE_ANY( plParticleSDLMod, plSDLModifier);
|
||||
|
||||
plParticleSDLMod(bool attachedToAvatar = false): fAttachedToAvatar(attachedToAvatar) {}
|
||||
|
||||
void PutCurrentStateIn(plStateDataRecord* dstState);
|
||||
const char* GetSDLName() const { return kSDLParticleSystem; }
|
||||
|
||||
void SetAttachedToAvatar(bool attached) {fAttachedToAvatar = attached;}
|
||||
};
|
||||
|
||||
#endif // plParticleSDLMod_inc
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleSDLMod_inc
|
||||
#define plParticleSDLMod_inc
|
||||
|
||||
#include "plModifier/plSDLModifier.h"
|
||||
|
||||
//
|
||||
// This modifier is responsible for sending and recving
|
||||
// particle system state. Few need it. Little state is needed.
|
||||
//
|
||||
|
||||
class plParticleSDLMod : public plSDLModifier
|
||||
{
|
||||
private:
|
||||
bool fAttachedToAvatar;
|
||||
|
||||
protected:
|
||||
void IPutCurrentStateIn(plStateDataRecord* dstState);
|
||||
void ISetCurrentStateFrom(const plStateDataRecord* srcState);
|
||||
UInt32 IApplyModFlags(UInt32 sendFlags);
|
||||
public:
|
||||
// var labels
|
||||
static char kStrNumParticles[];
|
||||
|
||||
CLASSNAME_REGISTER( plParticleSDLMod );
|
||||
GETINTERFACE_ANY( plParticleSDLMod, plSDLModifier);
|
||||
|
||||
plParticleSDLMod(bool attachedToAvatar = false): fAttachedToAvatar(attachedToAvatar) {}
|
||||
|
||||
void PutCurrentStateIn(plStateDataRecord* dstState);
|
||||
const char* GetSDLName() const { return kSDLParticleSystem; }
|
||||
|
||||
void SetAttachedToAvatar(bool attached) {fAttachedToAvatar = attached;}
|
||||
};
|
||||
|
||||
#endif // plParticleSDLMod_inc
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,185 +1,185 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleSystem_inc
|
||||
#define plParticleSystem_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "pnModifier/plModifier.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plEffectTargetInfo.h"
|
||||
|
||||
class plPipeline;
|
||||
class plParticle;
|
||||
class plParticleGenerator;
|
||||
class plSimpleParticleGenerator;
|
||||
class plParticleEmitter;
|
||||
class plParticleEffect;
|
||||
class plParticleSDLMod;
|
||||
class plController;
|
||||
class hsGMaterial;
|
||||
class plDrawableSpans;
|
||||
class plDrawInterface;
|
||||
class Mtl;
|
||||
|
||||
// This is responsible for creating and maintaining (allocation and update cycle) a related set of particles.
|
||||
// Automatic particle generation is handled by the plParticleEmitters (one for each spawning location).
|
||||
|
||||
class plParticleSystem : public plModifier
|
||||
{
|
||||
friend plParticleEmitter;
|
||||
friend plSimpleParticleGenerator;
|
||||
|
||||
protected:
|
||||
static const hsScalar GRAVITY_ACCEL_FEET_PER_SEC2;
|
||||
plSceneObject *fTarget;
|
||||
|
||||
hsGMaterial *fTexture; // One texture per system (Tiling is your friend!)
|
||||
UInt32 fXTiles, fYTiles; // Width/height of the texture (in tiles) for determining a particle's UVs
|
||||
|
||||
double fCurrTime;
|
||||
double fLastTime;
|
||||
hsVector3 fAccel;
|
||||
hsScalar fPreSim;
|
||||
hsScalar fDrag;
|
||||
hsScalar fWindMult;
|
||||
bool fAttachedToAvatar;
|
||||
|
||||
UInt32 fMaxTotalParticles;
|
||||
UInt32 fMaxTotalParticlesLeft;
|
||||
UInt32 fNumValidEmitters;
|
||||
UInt32 fMaxEmitters;
|
||||
UInt32 fNextEmitterToGo;
|
||||
|
||||
plParticleEmitter **fEmitters; // Various locations we're emitting particles from (the first one is
|
||||
// reserved for particles added explicitly (to keep all the bookkeeping
|
||||
// in the hands of plParticleEmitter).
|
||||
|
||||
hsTArray<plParticleEffect *> fForces; // Global forces (wind/gravity/etc) that affect accelleration.
|
||||
hsTArray<plParticleEffect *> fEffects; // Any other non-constraint effects.
|
||||
hsTArray<plParticleEffect *> fConstraints; // Rigid body, collision, connectivity, etc.
|
||||
plParticleContext fContext; // Rendering context passed to forces/effects/constraints.
|
||||
|
||||
hsTArray<plKey> fPermaLights; // Runtime lights assigned to this system. Currently don't support projected lights on particles.
|
||||
|
||||
// Material related animations, mapped over the course of a particle's life
|
||||
plController *fAmbientCtl;
|
||||
plController *fDiffuseCtl;
|
||||
plController *fOpacityCtl;
|
||||
plController *fWidthCtl;
|
||||
plController *fHeightCtl;
|
||||
|
||||
plParticleSDLMod *fParticleSDLMod;
|
||||
|
||||
hsBool IShouldUpdate(plPipeline* pipe) const;
|
||||
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty); // required by plModifier
|
||||
void IHandleRenderMsg(plPipeline* pipe);
|
||||
plDrawInterface* ICheckDrawInterface();
|
||||
void IAddEffect(plParticleEffect *effect, UInt32 type);
|
||||
void IReadEffectsArray(hsTArray<plParticleEffect *> &effects, UInt32 type, hsStream *s, hsResMgr *mgr);
|
||||
void IPreSim();
|
||||
|
||||
public:
|
||||
plParticleSystem();
|
||||
virtual ~plParticleSystem();
|
||||
void Init(UInt32 xTiles, UInt32 yTiles, UInt32 maxTotalParticles, UInt32 numEmitters,
|
||||
plController *ambientCtl, plController *diffuseCtl, plController *opacityCtl,
|
||||
plController *widthCtl, plController *heightCtl);
|
||||
|
||||
enum effectType
|
||||
{
|
||||
kEffectForce = 0x1,
|
||||
kEffectMisc = 0x2,
|
||||
kEffectConstraint = 0x4,
|
||||
};
|
||||
|
||||
enum miscFlags
|
||||
{
|
||||
kParticleSystemAlwaysUpdate = 0x1
|
||||
};
|
||||
UInt8 fMiscFlags; // Not read/written (could be, but it's not needed yet.)
|
||||
|
||||
// There might not be enough particles available. this function returns the number of maxParticles that
|
||||
// the emitter actually received.
|
||||
UInt32 AddEmitter(UInt32 maxParticles, plParticleGenerator *gen, UInt32 emitterFlags);
|
||||
|
||||
plParticleEmitter* GetAvailEmitter();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleSystem );
|
||||
GETINTERFACE_ANY( plParticleSystem, plModifier);
|
||||
|
||||
// These are just public wrappers to the equivalent plParticleEmitter functions, provided for the purpose
|
||||
// of adding particles to a system explicitly.
|
||||
void AddParticle(hsPoint3 &pos, hsVector3 &velocity, UInt32 tileIndex,
|
||||
hsScalar hSize, hsScalar vSize, hsScalar scale, hsScalar invMass, hsScalar life,
|
||||
hsPoint3 &orientation, UInt32 miscFlags, hsScalar radsPerSec=0.f);
|
||||
void GenerateParticles(UInt32 num, hsScalar dt = 0.f);
|
||||
void WipeExistingParticles(); // Instant nuke
|
||||
void KillParticles(hsScalar num, hsScalar timeToDie, UInt8 flags); // Sets a death timer. They'll get removed on the next update (if time has run out)
|
||||
UInt16 StealParticlesFrom(plParticleSystem *victim, UInt16 num); // Returns the number of particles actually stolen
|
||||
void TranslateAllParticles(hsPoint3 &amount); // Used to recenter the system when linking between ages.
|
||||
|
||||
void DisableGenerators();
|
||||
UInt32 GetNumTiles() const { return fXTiles * fYTiles; }
|
||||
void SetTileIndex(plParticle &particle, UInt32 index); // Sets the UV coordinates appropriate for the current texture
|
||||
UInt32 GetNumValidParticles(hsBool immortalOnly = false) const; // Takes a bit longer if we want a count of immortal particles...
|
||||
UInt32 GetMaxTotalParticles() const { return fMaxTotalParticles; }
|
||||
|
||||
const hsMatrix44 &GetLocalToWorld() const;
|
||||
void SetAccel(const hsVector3& a) { fAccel = GRAVITY_ACCEL_FEET_PER_SEC2 * a; }
|
||||
void SetGravity(hsScalar pct) { fAccel.Set(0, 0, -GRAVITY_ACCEL_FEET_PER_SEC2 * pct); }
|
||||
void SetDrag(hsScalar d) { fDrag = -d; }
|
||||
void SetWindMult(hsScalar m) { fWindMult = m; }
|
||||
void SetPreSim(hsScalar time) { fPreSim = time; }
|
||||
void UpdateGenerator(UInt32 paramID, hsScalar value);
|
||||
plParticleGenerator *GetExportedGenerator() const;
|
||||
|
||||
const hsVector3& GetAccel() const { return fAccel; }
|
||||
hsScalar GetDrag() const { return fDrag; }
|
||||
hsScalar GetWindMult() const { return fWindMult; }
|
||||
plParticleEffect *GetEffect(UInt16 type) const;
|
||||
|
||||
plParticleSDLMod* GetSDLMod() {return fParticleSDLMod;}
|
||||
// Functions related to/required by plModifier
|
||||
virtual int GetNumTargets() const { return fTarget ? 1 : 0; }
|
||||
virtual plSceneObject* GetTarget(int w) const { hsAssert(w < 1, "Bad target"); return fTarget; }
|
||||
virtual void AddTarget(plSceneObject* so);
|
||||
virtual void RemoveTarget(plSceneObject* so);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
void SetAttachedToAvatar(bool attached);
|
||||
|
||||
// Export only functions for building the system. Not supported at runtime.
|
||||
// AddLight allows the particle system to remain in ignorant bliss about runtime lights
|
||||
void AddLight(plKey liKey);
|
||||
};
|
||||
|
||||
#endif
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef plParticleSystem_inc
|
||||
#define plParticleSystem_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "pnModifier/plModifier.h"
|
||||
#include "pnNetCommon/plSynchedValue.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plEffectTargetInfo.h"
|
||||
|
||||
class plPipeline;
|
||||
class plParticle;
|
||||
class plParticleGenerator;
|
||||
class plSimpleParticleGenerator;
|
||||
class plParticleEmitter;
|
||||
class plParticleEffect;
|
||||
class plParticleSDLMod;
|
||||
class plController;
|
||||
class hsGMaterial;
|
||||
class plDrawableSpans;
|
||||
class plDrawInterface;
|
||||
class Mtl;
|
||||
|
||||
// This is responsible for creating and maintaining (allocation and update cycle) a related set of particles.
|
||||
// Automatic particle generation is handled by the plParticleEmitters (one for each spawning location).
|
||||
|
||||
class plParticleSystem : public plModifier
|
||||
{
|
||||
friend plParticleEmitter;
|
||||
friend plSimpleParticleGenerator;
|
||||
|
||||
protected:
|
||||
static const hsScalar GRAVITY_ACCEL_FEET_PER_SEC2;
|
||||
plSceneObject *fTarget;
|
||||
|
||||
hsGMaterial *fTexture; // One texture per system (Tiling is your friend!)
|
||||
UInt32 fXTiles, fYTiles; // Width/height of the texture (in tiles) for determining a particle's UVs
|
||||
|
||||
double fCurrTime;
|
||||
double fLastTime;
|
||||
hsVector3 fAccel;
|
||||
hsScalar fPreSim;
|
||||
hsScalar fDrag;
|
||||
hsScalar fWindMult;
|
||||
bool fAttachedToAvatar;
|
||||
|
||||
UInt32 fMaxTotalParticles;
|
||||
UInt32 fMaxTotalParticlesLeft;
|
||||
UInt32 fNumValidEmitters;
|
||||
UInt32 fMaxEmitters;
|
||||
UInt32 fNextEmitterToGo;
|
||||
|
||||
plParticleEmitter **fEmitters; // Various locations we're emitting particles from (the first one is
|
||||
// reserved for particles added explicitly (to keep all the bookkeeping
|
||||
// in the hands of plParticleEmitter).
|
||||
|
||||
hsTArray<plParticleEffect *> fForces; // Global forces (wind/gravity/etc) that affect accelleration.
|
||||
hsTArray<plParticleEffect *> fEffects; // Any other non-constraint effects.
|
||||
hsTArray<plParticleEffect *> fConstraints; // Rigid body, collision, connectivity, etc.
|
||||
plParticleContext fContext; // Rendering context passed to forces/effects/constraints.
|
||||
|
||||
hsTArray<plKey> fPermaLights; // Runtime lights assigned to this system. Currently don't support projected lights on particles.
|
||||
|
||||
// Material related animations, mapped over the course of a particle's life
|
||||
plController *fAmbientCtl;
|
||||
plController *fDiffuseCtl;
|
||||
plController *fOpacityCtl;
|
||||
plController *fWidthCtl;
|
||||
plController *fHeightCtl;
|
||||
|
||||
plParticleSDLMod *fParticleSDLMod;
|
||||
|
||||
hsBool IShouldUpdate(plPipeline* pipe) const;
|
||||
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty); // required by plModifier
|
||||
void IHandleRenderMsg(plPipeline* pipe);
|
||||
plDrawInterface* ICheckDrawInterface();
|
||||
void IAddEffect(plParticleEffect *effect, UInt32 type);
|
||||
void IReadEffectsArray(hsTArray<plParticleEffect *> &effects, UInt32 type, hsStream *s, hsResMgr *mgr);
|
||||
void IPreSim();
|
||||
|
||||
public:
|
||||
plParticleSystem();
|
||||
virtual ~plParticleSystem();
|
||||
void Init(UInt32 xTiles, UInt32 yTiles, UInt32 maxTotalParticles, UInt32 numEmitters,
|
||||
plController *ambientCtl, plController *diffuseCtl, plController *opacityCtl,
|
||||
plController *widthCtl, plController *heightCtl);
|
||||
|
||||
enum effectType
|
||||
{
|
||||
kEffectForce = 0x1,
|
||||
kEffectMisc = 0x2,
|
||||
kEffectConstraint = 0x4,
|
||||
};
|
||||
|
||||
enum miscFlags
|
||||
{
|
||||
kParticleSystemAlwaysUpdate = 0x1
|
||||
};
|
||||
UInt8 fMiscFlags; // Not read/written (could be, but it's not needed yet.)
|
||||
|
||||
// There might not be enough particles available. this function returns the number of maxParticles that
|
||||
// the emitter actually received.
|
||||
UInt32 AddEmitter(UInt32 maxParticles, plParticleGenerator *gen, UInt32 emitterFlags);
|
||||
|
||||
plParticleEmitter* GetAvailEmitter();
|
||||
|
||||
CLASSNAME_REGISTER( plParticleSystem );
|
||||
GETINTERFACE_ANY( plParticleSystem, plModifier);
|
||||
|
||||
// These are just public wrappers to the equivalent plParticleEmitter functions, provided for the purpose
|
||||
// of adding particles to a system explicitly.
|
||||
void AddParticle(hsPoint3 &pos, hsVector3 &velocity, UInt32 tileIndex,
|
||||
hsScalar hSize, hsScalar vSize, hsScalar scale, hsScalar invMass, hsScalar life,
|
||||
hsPoint3 &orientation, UInt32 miscFlags, hsScalar radsPerSec=0.f);
|
||||
void GenerateParticles(UInt32 num, hsScalar dt = 0.f);
|
||||
void WipeExistingParticles(); // Instant nuke
|
||||
void KillParticles(hsScalar num, hsScalar timeToDie, UInt8 flags); // Sets a death timer. They'll get removed on the next update (if time has run out)
|
||||
UInt16 StealParticlesFrom(plParticleSystem *victim, UInt16 num); // Returns the number of particles actually stolen
|
||||
void TranslateAllParticles(hsPoint3 &amount); // Used to recenter the system when linking between ages.
|
||||
|
||||
void DisableGenerators();
|
||||
UInt32 GetNumTiles() const { return fXTiles * fYTiles; }
|
||||
void SetTileIndex(plParticle &particle, UInt32 index); // Sets the UV coordinates appropriate for the current texture
|
||||
UInt32 GetNumValidParticles(hsBool immortalOnly = false) const; // Takes a bit longer if we want a count of immortal particles...
|
||||
UInt32 GetMaxTotalParticles() const { return fMaxTotalParticles; }
|
||||
|
||||
const hsMatrix44 &GetLocalToWorld() const;
|
||||
void SetAccel(const hsVector3& a) { fAccel = GRAVITY_ACCEL_FEET_PER_SEC2 * a; }
|
||||
void SetGravity(hsScalar pct) { fAccel.Set(0, 0, -GRAVITY_ACCEL_FEET_PER_SEC2 * pct); }
|
||||
void SetDrag(hsScalar d) { fDrag = -d; }
|
||||
void SetWindMult(hsScalar m) { fWindMult = m; }
|
||||
void SetPreSim(hsScalar time) { fPreSim = time; }
|
||||
void UpdateGenerator(UInt32 paramID, hsScalar value);
|
||||
plParticleGenerator *GetExportedGenerator() const;
|
||||
|
||||
const hsVector3& GetAccel() const { return fAccel; }
|
||||
hsScalar GetDrag() const { return fDrag; }
|
||||
hsScalar GetWindMult() const { return fWindMult; }
|
||||
plParticleEffect *GetEffect(UInt16 type) const;
|
||||
|
||||
plParticleSDLMod* GetSDLMod() {return fParticleSDLMod;}
|
||||
// Functions related to/required by plModifier
|
||||
virtual int GetNumTargets() const { return fTarget ? 1 : 0; }
|
||||
virtual plSceneObject* GetTarget(int w) const { hsAssert(w < 1, "Bad target"); return fTarget; }
|
||||
virtual void AddTarget(plSceneObject* so);
|
||||
virtual void RemoveTarget(plSceneObject* so);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
void SetAttachedToAvatar(bool attached);
|
||||
|
||||
// Export only functions for building the system. Not supported at runtime.
|
||||
// AddLight allows the particle system to remain in ignorant bliss about runtime lights
|
||||
void AddLight(plKey liKey);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user