You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
579 lines
15 KiB
579 lines
15 KiB
4 years ago
|
/*==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/>.
|
||
|
|
||
|
Additional permissions under GNU GPL version 3 section 7
|
||
|
|
||
|
If you modify this Program, or any covered work, by linking or
|
||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||
|
(or a modified version of those libraries),
|
||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||
|
licensors of this Program grant you additional
|
||
|
permission to convey the resulting work. Corresponding Source for a
|
||
|
non-source form of such a combination shall include the source code for
|
||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||
|
work.
|
||
|
|
||
|
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==*/
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// plSpanTypes Class Functions //
|
||
|
// //
|
||
|
//// Version History /////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// 5.3.2001 mcn - Created. //
|
||
|
// //
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "hsTypes.h"
|
||
|
#include "plSpanTypes.h"
|
||
|
#include "hsStream.h"
|
||
|
#include "../pnKeyedObject/plKey.h"
|
||
|
#include "../plPipeline/plGBufferGroup.h"
|
||
|
#include "../plPipeline/hsGDeviceRef.h"
|
||
|
#include "../plGLight/plLightInfo.h"
|
||
|
#include "plDrawable.h"
|
||
|
#include "plAuxSpan.h"
|
||
|
#include "plAccessSnapShot.h"
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//// plSpan Functions ////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//// Read ////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plSpan::Read( hsStream *stream )
|
||
|
{
|
||
|
fSubType = (UInt16)(stream->ReadSwap32());
|
||
|
fFogEnvironment = nil;
|
||
|
|
||
|
fMaterialIdx = stream->ReadSwap32();
|
||
|
fLocalToWorld.Read( stream );
|
||
|
fWorldToLocal.Read( stream );
|
||
|
fProps = stream->ReadSwap32();
|
||
|
fLocalBounds.Read( stream );
|
||
|
fWorldBounds.Read( stream );
|
||
|
|
||
|
fNumMatrices = (UInt8)(stream->ReadSwap32());
|
||
|
fBaseMatrix = stream->ReadSwap32();
|
||
|
|
||
|
fLocalUVWChans = stream->ReadSwap16();
|
||
|
fMaxBoneIdx = stream->ReadSwap16();
|
||
|
fPenBoneIdx = stream->ReadSwap16();
|
||
|
|
||
|
fMinDist = stream->ReadSwapScalar();
|
||
|
fMaxDist = stream->ReadSwapScalar();
|
||
|
|
||
|
if( fProps & kWaterHeight )
|
||
|
fWaterHeight = stream->ReadSwapScalar();
|
||
|
|
||
|
#ifdef HS_DEBUGGING
|
||
|
fOwnerKey = nil;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//// Write ///////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plSpan::Write( hsStream *stream )
|
||
|
{
|
||
|
stream->WriteSwap32(fSubType);
|
||
|
|
||
|
stream->WriteSwap32( fMaterialIdx );
|
||
|
|
||
|
fLocalToWorld.Write( stream );
|
||
|
fWorldToLocal.Write( stream );
|
||
|
stream->WriteSwap32( fProps );
|
||
|
fLocalBounds.Write( stream );
|
||
|
fWorldBounds.Write( stream );
|
||
|
|
||
|
stream->WriteSwap32( fNumMatrices );
|
||
|
stream->WriteSwap32( fBaseMatrix );
|
||
|
|
||
|
stream->WriteSwap16( fLocalUVWChans );
|
||
|
stream->WriteSwap16( fMaxBoneIdx );
|
||
|
stream->WriteSwap16( fPenBoneIdx );
|
||
|
|
||
|
stream->WriteSwapScalar( fMinDist );
|
||
|
stream->WriteSwapScalar( fMaxDist );
|
||
|
|
||
|
if( fProps & kWaterHeight )
|
||
|
stream->WriteSwapScalar(fWaterHeight);
|
||
|
}
|
||
|
|
||
|
void plSpan::RemoveAuxSpan(plAuxSpan* aux)
|
||
|
{
|
||
|
int i = fAuxSpans.Find(aux);
|
||
|
int newCount = fAuxSpans.GetCount()-1;
|
||
|
if( i < newCount )
|
||
|
{
|
||
|
fAuxSpans[i] = fAuxSpans[fAuxSpans.GetCount()-1];
|
||
|
}
|
||
|
fAuxSpans.SetCount(newCount);
|
||
|
}
|
||
|
|
||
|
void plSpan::AddAuxSpan(plAuxSpan* aux)
|
||
|
{
|
||
|
fAuxSpans.Append(aux);
|
||
|
}
|
||
|
|
||
|
// AddPermaLight ////////////////////////////////////////////////////////////////
|
||
|
// PermaLights are permanently assigned to a set of spans. There's no checking
|
||
|
// for in range or anything, they are just on.
|
||
|
|
||
|
void plSpan::AddPermaLight(plLightInfo* li, hsBool proj)
|
||
|
{
|
||
|
if( li )
|
||
|
{
|
||
|
hsTArray<plLightInfo*>& lights = proj ? fPermaProjs : fPermaLights;
|
||
|
int idx = lights.Find(li);
|
||
|
if( lights.kMissingIndex == idx )
|
||
|
lights.Append(li);
|
||
|
if( lights.GetCount() )
|
||
|
fProps |= proj ? kPropHasPermaProjs : kPropHasPermaLights;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void plSpan::RemovePermaLight(plLightInfo* li, hsBool proj)
|
||
|
{
|
||
|
hsTArray<plLightInfo*>& lights = proj ? fPermaProjs : fPermaLights;
|
||
|
int idx = lights.Find(li);
|
||
|
if( lights.kMissingIndex != idx )
|
||
|
{
|
||
|
lights.Remove(idx);
|
||
|
if( !lights.GetCount() )
|
||
|
fProps &= ~(proj ? kPropHasPermaProjs : kPropHasPermaLights);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//// AddLight ////////////////////////////////////////////////////////////////
|
||
|
// Smart function for maintaining the sorted list of lights for a plSpan.
|
||
|
|
||
|
void plSpan::AddLight( plLightInfo *li, hsScalar strength, hsScalar scale, hsBool proj ) const
|
||
|
{
|
||
|
hsTArray<plLightInfo*>& lights = proj ? fProjectors : fLights;
|
||
|
hsTArray<hsScalar>& strengths = proj ? fProjStrengths : fLightStrengths;
|
||
|
hsTArray<hsScalar>& scales = proj ? fProjScales : fLightScales;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for( i = 0; i < lights.GetCount(); i++ )
|
||
|
{
|
||
|
if( strengths[ i ] < strength )
|
||
|
break;
|
||
|
}
|
||
|
lights.Insert(i, li);
|
||
|
strengths.Insert(i, strength);
|
||
|
scales.Insert(i, hsScalar(UInt32(scale * 127.9f)) / 127.f);
|
||
|
}
|
||
|
|
||
|
void plSpan::ClearLights() const
|
||
|
{
|
||
|
fLights.SetCount(0);
|
||
|
fLightStrengths.SetCount(0);
|
||
|
fLightScales.SetCount(0);
|
||
|
fProjectors.SetCount(0);
|
||
|
fProjStrengths.SetCount(0);
|
||
|
fProjScales.SetCount(0);
|
||
|
|
||
|
int i;
|
||
|
for( i = 0; i < fPermaLights.GetCount(); i++ )
|
||
|
{
|
||
|
if( !(fPermaLights[i]->IsIdle() || fPermaLights[i]->GetProperty(plLightInfo::kLPShadowOnly)) )
|
||
|
{
|
||
|
fLights.Append(fPermaLights[i]);
|
||
|
fLightStrengths.Append(2.f);
|
||
|
fLightScales.Append(1.f);
|
||
|
}
|
||
|
}
|
||
|
for( i = 0; i < fPermaProjs.GetCount(); i++ )
|
||
|
{
|
||
|
if( !(fPermaProjs[i]->IsIdle() || fPermaProjs[i]->GetProperty(plLightInfo::kLPShadowOnly)) )
|
||
|
{
|
||
|
fProjectors.Append(fPermaProjs[i]);
|
||
|
fProjStrengths.Append(2.f);
|
||
|
fProjScales.Append(1.f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fShadowSlaveBits.Clear();
|
||
|
}
|
||
|
|
||
|
//// CanMergeInto ////////////////////////////////////////////////////////////
|
||
|
|
||
|
hsBool plSpan::CanMergeInto( plSpan *other )
|
||
|
{
|
||
|
if( fTypeMask ^ other->fTypeMask )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Make sure lighting equations match
|
||
|
if( ( ( fProps ^ other->fProps ) & kLiteMask ) != 0 )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if( fNumMatrices != other->fNumMatrices )
|
||
|
return false;
|
||
|
if( fBaseMatrix != other->fBaseMatrix )
|
||
|
return false;
|
||
|
|
||
|
if( fMaterialIdx != other->fMaterialIdx )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if( fFogEnvironment != other->fFogEnvironment )
|
||
|
return false;
|
||
|
|
||
|
// Don't bother checking for having exactly the same matrix elements.
|
||
|
// Either they are both ident, or they are inequal.
|
||
|
if( fLocalToWorld != other->fLocalToWorld )
|
||
|
// if( !(fLocalToWorld.fFlags & other->fLocalToWorld.fFlags & hsMatrix44::kIsIdent) )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if( fLights.GetCount() != other->fLights.GetCount() )
|
||
|
return false;
|
||
|
if( fProjectors.GetCount() != other->fProjectors.GetCount() )
|
||
|
return false;
|
||
|
|
||
|
if( fLights.GetCount() )
|
||
|
{
|
||
|
if( !HSMemory::EqualBlocks(fLights.AcquireArray(), other->fLights.AcquireArray(), fLights.GetCount() * sizeof(plLightInfo*)) )
|
||
|
return false;
|
||
|
if( !HSMemory::EqualBlocks(fLightScales.AcquireArray(), other->fLightScales.AcquireArray(), fLights.GetCount() * sizeof(hsScalar)) )
|
||
|
return false;
|
||
|
}
|
||
|
if( fProjectors.GetCount() )
|
||
|
{
|
||
|
if( !HSMemory::EqualBlocks(fProjectors.AcquireArray(), other->fProjectors.AcquireArray(), fProjectors.GetCount() * sizeof(plLightInfo*)) )
|
||
|
return false;
|
||
|
if( !HSMemory::EqualBlocks(fProjScales.AcquireArray(), other->fProjScales.AcquireArray(), fProjectors.GetCount() * sizeof(hsScalar)) )
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if( fShadowSlaveBits != other->fShadowSlaveBits )
|
||
|
return false;
|
||
|
|
||
|
if( fSubType ^ other->fSubType )
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//// MergeInto ///////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plSpan::MergeInto( plSpan *other )
|
||
|
{
|
||
|
int i;
|
||
|
for( i = 0; i < GetNumAuxSpans(); i++ )
|
||
|
other->fAuxSpans.Append(GetAuxSpan(i));
|
||
|
}
|
||
|
|
||
|
//// Constructor & Destructor ////////////////////////////////////////////////
|
||
|
|
||
|
plSpan::plSpan()
|
||
|
{
|
||
|
fTypeMask = kSpan;
|
||
|
fSubType = plDrawable::kSubNormal;
|
||
|
fMaterialIdx = (UInt32)-1;
|
||
|
fFogEnvironment = nil;
|
||
|
fProps = 0;
|
||
|
|
||
|
fSnapShot = nil;
|
||
|
|
||
|
ClearLights();
|
||
|
fVisSet.SetBit(0);
|
||
|
|
||
|
fNumMatrices = 0;
|
||
|
fBaseMatrix = 0;
|
||
|
fLocalUVWChans = 0;
|
||
|
fMaxBoneIdx = 0;
|
||
|
fPenBoneIdx = 0;
|
||
|
|
||
|
fMinDist = fMaxDist = -1.f;
|
||
|
|
||
|
fWaterHeight = 0;
|
||
|
|
||
|
#ifdef HS_DEBUGGING
|
||
|
fOwnerKey = nil;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void plSpan::Destroy()
|
||
|
{
|
||
|
if( fSnapShot )
|
||
|
{
|
||
|
fSnapShot->Destroy();
|
||
|
delete fSnapShot;
|
||
|
}
|
||
|
|
||
|
int i;
|
||
|
for( i = 0; i < fAuxSpans.GetCount(); i++ )
|
||
|
fAuxSpans[i]->fDrawable = nil;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//// plVertexSpan Functions //////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
plVertexSpan::plVertexSpan()
|
||
|
{
|
||
|
fTypeMask |= kVertexSpan;
|
||
|
fGroupIdx = (UInt32)-1;
|
||
|
fVBufferIdx = (UInt32)-1;
|
||
|
fCellIdx = (UInt32)-1;
|
||
|
fCellOffset = (UInt32)-1;
|
||
|
}
|
||
|
|
||
|
void plVertexSpan::Read( hsStream* stream )
|
||
|
{
|
||
|
plSpan:: Read( stream );
|
||
|
|
||
|
fGroupIdx = stream->ReadSwap32();
|
||
|
fVBufferIdx = stream->ReadSwap32();
|
||
|
fCellIdx = stream->ReadSwap32();
|
||
|
fCellOffset = stream->ReadSwap32();
|
||
|
fVStartIdx = stream->ReadSwap32();
|
||
|
fVLength = stream->ReadSwap32();
|
||
|
}
|
||
|
|
||
|
void plVertexSpan::Write( hsStream* stream )
|
||
|
{
|
||
|
plSpan::Write( stream );
|
||
|
|
||
|
stream->WriteSwap32( fGroupIdx );
|
||
|
stream->WriteSwap32( fVBufferIdx );
|
||
|
stream->WriteSwap32( fCellIdx );
|
||
|
stream->WriteSwap32( fCellOffset );
|
||
|
stream->WriteSwap32( fVStartIdx );
|
||
|
stream->WriteSwap32( fVLength );
|
||
|
}
|
||
|
|
||
|
hsBool plVertexSpan::CanMergeInto( plSpan *other )
|
||
|
{
|
||
|
if( !plSpan::CanMergeInto( other ) )
|
||
|
return false;
|
||
|
|
||
|
plVertexSpan *otherSpan = (plVertexSpan*)other;
|
||
|
|
||
|
if( fGroupIdx != otherSpan->fGroupIdx ||
|
||
|
fVBufferIdx != otherSpan->fVBufferIdx ||
|
||
|
fCellIdx != otherSpan->fCellIdx )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void plVertexSpan::MergeInto( plSpan *other )
|
||
|
{
|
||
|
plSpan::MergeInto( other );
|
||
|
|
||
|
plVertexSpan* otherIce = (plVertexSpan*)other;
|
||
|
int min, max;
|
||
|
|
||
|
|
||
|
min = fVStartIdx;
|
||
|
max = min + fVLength - 1;
|
||
|
if( otherIce->fVStartIdx < min )
|
||
|
min = otherIce->fVStartIdx;
|
||
|
if( otherIce->fVStartIdx + otherIce->fVLength - 1 > max )
|
||
|
max = otherIce->fVStartIdx + otherIce->fVLength - 1;
|
||
|
|
||
|
otherIce->fVStartIdx = min;
|
||
|
otherIce->fVLength = max - min + 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//// plIcicle Functions //////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//// Read ////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plIcicle::Read( hsStream *stream )
|
||
|
{
|
||
|
plVertexSpan::Read( stream );
|
||
|
|
||
|
fIBufferIdx = stream->ReadSwap32();
|
||
|
fIPackedIdx = fIStartIdx = stream->ReadSwap32();
|
||
|
fILength = stream->ReadSwap32();
|
||
|
|
||
|
if( fProps & kPropFacesSortable )
|
||
|
{
|
||
|
/// Read in sorting data
|
||
|
int i;
|
||
|
|
||
|
|
||
|
fSortData = TRACKED_NEW plGBufferTriangle[ fILength / 3 ];
|
||
|
for( i = 0; i < fILength / 3; i++ )
|
||
|
fSortData[ i ].Read( stream );
|
||
|
}
|
||
|
else
|
||
|
fSortData = nil;
|
||
|
}
|
||
|
|
||
|
//// Write ///////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plIcicle::Write( hsStream *stream )
|
||
|
{
|
||
|
plVertexSpan::Write( stream );
|
||
|
|
||
|
stream->WriteSwap32( fIBufferIdx );
|
||
|
stream->WriteSwap32( fIStartIdx );
|
||
|
stream->WriteSwap32( fILength );
|
||
|
|
||
|
if( fProps & kPropFacesSortable )
|
||
|
{
|
||
|
/// Write out sorting data
|
||
|
int i;
|
||
|
for( i = 0; i < fILength / 3; i++ )
|
||
|
fSortData[ i ].Write( stream );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//// Destroy /////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plIcicle::Destroy( void )
|
||
|
{
|
||
|
plSpan::Destroy();
|
||
|
delete [] fSortData;
|
||
|
fSortData = nil;
|
||
|
}
|
||
|
|
||
|
//// CanMergeInto ////////////////////////////////////////////////////////////
|
||
|
|
||
|
hsBool plIcicle::CanMergeInto( plSpan *other )
|
||
|
{
|
||
|
if( !plVertexSpan::CanMergeInto( other ) )
|
||
|
return false;
|
||
|
|
||
|
plIcicle *otherIce = (plIcicle *)other;
|
||
|
|
||
|
if( fIBufferIdx != otherIce->fIBufferIdx )
|
||
|
return false;
|
||
|
|
||
|
if( (fNumMatrices != otherIce->fNumMatrices)
|
||
|
||(fBaseMatrix != otherIce->fBaseMatrix) )
|
||
|
return false;
|
||
|
|
||
|
if( fIPackedIdx != otherIce->fIPackedIdx + otherIce->fILength )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//// MergeInto ///////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plIcicle::MergeInto( plSpan *other )
|
||
|
{
|
||
|
plVertexSpan::MergeInto( other );
|
||
|
|
||
|
plIcicle *otherIce = (plIcicle *)other;
|
||
|
|
||
|
otherIce->fILength += fILength;
|
||
|
}
|
||
|
|
||
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
||
|
|
||
|
plIcicle::plIcicle()
|
||
|
{
|
||
|
fTypeMask |= kIcicleSpan;
|
||
|
|
||
|
fSortData = nil;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//// plParticleSpan Functions ////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//// Constructor /////////////////////////////////////////////////////////////
|
||
|
|
||
|
plParticleSpan::plParticleSpan() : plIcicle()
|
||
|
{
|
||
|
fTypeMask |= kParticleSpan;
|
||
|
|
||
|
fProps |= kPropProjAsVtx;
|
||
|
|
||
|
fSource = nil;
|
||
|
fSortCount = 0;
|
||
|
}
|
||
|
|
||
|
//// CanMergeInto ////////////////////////////////////////////////////////////
|
||
|
|
||
|
hsBool plParticleSpan::CanMergeInto( plSpan *other )
|
||
|
{
|
||
|
return plIcicle::CanMergeInto( other );
|
||
|
}
|
||
|
|
||
|
//// MergeInto ///////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plParticleSpan::MergeInto( plSpan *other )
|
||
|
{
|
||
|
plIcicle::MergeInto( other );
|
||
|
}
|
||
|
|
||
|
//// Destroy /////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void plParticleSpan::Destroy( void )
|
||
|
{
|
||
|
plIcicle::Destroy();
|
||
|
fSource = nil;
|
||
|
if( fParentSet != nil )
|
||
|
{
|
||
|
fParentSet->fRefCount--;
|
||
|
if( fParentSet->fRefCount == 0 )
|
||
|
delete fParentSet;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//// plParticleSet Functions /////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//// Constructor /////////////////////////////////////////////////////////////
|
||
|
|
||
|
plParticleSet::plParticleSet()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//// Destructor //////////////////////////////////////////////////////////////
|
||
|
|
||
|
plParticleSet::~plParticleSet()
|
||
|
{
|
||
|
fVLength = 0; // Flag as empty
|
||
|
}
|
||
|
|
||
|
|
||
|
|