394 lines
11 KiB
C++
394 lines
11 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef NL_PS_ZONE_H
|
|
#define NL_PS_ZONE_H
|
|
|
|
#include "nel/misc/types_nl.h"
|
|
#include "nel/misc/stream.h"
|
|
#include "nel/3d/ps_force.h"
|
|
#include "nel/3d/ps_edit.h"
|
|
#include "nel/3d/ps_attrib.h"
|
|
#include "nel/3d/ps_plane_basis.h"
|
|
|
|
|
|
namespace NL3D {
|
|
|
|
|
|
/** This epsilon is in meter and give a thickness to surfaces for tests. It must be above above 0
|
|
* for the system to work correctly
|
|
*/
|
|
const float PSCollideEpsilon = 10E-3f;
|
|
|
|
|
|
|
|
/**
|
|
* This class hold any entity that has an effect over located : a sink , a bouncing zone etc
|
|
* This is a kind a specialized force, and it has an attached list of the targets
|
|
* Not sharable accross systems.
|
|
*
|
|
* \author Nicolas Vizerie
|
|
* \author Nevrax France
|
|
* \date 2001
|
|
*/
|
|
class CPSZone : public CPSTargetLocatedBindable
|
|
{
|
|
public:
|
|
|
|
/// behaviour when a collision occurs
|
|
|
|
enum TCollisionBehaviour { bounce = 0, destroy = 1 };
|
|
|
|
/// Constructor
|
|
CPSZone();
|
|
|
|
/**
|
|
* Gives the type for this bindable.
|
|
*/
|
|
virtual uint32 getType(void) const { return PSZone; }
|
|
|
|
/**
|
|
* Get the priority of the bindable
|
|
* The more high it is, the earlier it is dealt with
|
|
*/
|
|
virtual uint32 getPriority(void) const { return 3500; }
|
|
|
|
/**
|
|
* Process one pass for the zone
|
|
* The default behaviour call performMotion or show depending on the pass being processed
|
|
*/
|
|
virtual void step(TPSProcessPass pass);
|
|
|
|
|
|
/// Show the zone (edition mode).
|
|
virtual void show() = 0;
|
|
|
|
|
|
/// Add a new type of located for this zone to apply on. nlassert if already present
|
|
virtual void attachTarget(CPSLocated *ptr);
|
|
|
|
|
|
/// serialization, DERIVER must override this, and call the parent version
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
|
|
/** Inherited from CPSTargetLocatedBindable. It's called when one of the targets has been detroyed or detached
|
|
* The default behaviour, release collision infos from the located
|
|
*/
|
|
|
|
virtual void releaseTargetRsc(CPSLocated *target);
|
|
|
|
|
|
/// set the bounce factor. It has meaning only if the behaviour is set to bounce...
|
|
void setBounceFactor(float bounceFactor) { _BounceFactor = bounceFactor; }
|
|
|
|
/// get the bounce factor. It has meaning only if the behaviour is set to bounce...
|
|
float getBounceFactor(void) const { return _BounceFactor; }
|
|
|
|
|
|
void setCollisionBehaviour(TCollisionBehaviour behaviour) { _CollisionBehaviour = behaviour; }
|
|
|
|
TCollisionBehaviour getCollisionBehaviour(void) const { return _CollisionBehaviour; }
|
|
|
|
/** Compute collisions for the given target. This will update the collisions infos.
|
|
* The caller must provide pointer to arrays positions before and after time step.
|
|
*/
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter) = 0;
|
|
|
|
protected:
|
|
|
|
|
|
// the bounce factor. 1.f mean no energy loss
|
|
float _BounceFactor;
|
|
|
|
|
|
TCollisionBehaviour _CollisionBehaviour;
|
|
|
|
/**
|
|
* This set speed of a located so that it looks like bouncing on a surface
|
|
* \param locatedIndex the index
|
|
* \param bouncePoint the position where the collision occured
|
|
* \param surfNormal the normal of the surface at the collision point (this must be a unit vector)
|
|
* \elasticity 1 = full bounce, 0 = no bounce (contact)
|
|
* \ellapsedTime the time ellapsed
|
|
*/
|
|
|
|
// void bounce(uint32 locatedIndex, const NLMISC::CVector &bouncePoint, const NLMISC::CVector &surfNormal, float elasticity, float ellapsedTime);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
/** A plane over which particles bounce
|
|
* It has an interface to move each plane individually
|
|
*/
|
|
|
|
class CPSZonePlane : public CPSZone, public IPSMover
|
|
{
|
|
public:
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
|
|
virtual void show();
|
|
|
|
|
|
NLMISC_DECLARE_CLASS(CPSZonePlane);
|
|
|
|
|
|
|
|
virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m);
|
|
virtual NLMISC::CMatrix getMatrix(uint32 index) const;
|
|
virtual bool onlyStoreNormal(void) const { return true; }
|
|
virtual NLMISC::CVector getNormal(uint32 index);
|
|
virtual void setNormal(uint32 index, NLMISC::CVector n);
|
|
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
protected:
|
|
TPSAttribVector _Normal;
|
|
NLMISC::CMatrix buildBasis(uint32 index) const;
|
|
|
|
virtual void resize(uint32 size);
|
|
|
|
virtual void newElement(const CPSEmitterInfo &info);
|
|
|
|
virtual void deleteElement(uint32 index);
|
|
};
|
|
|
|
|
|
|
|
|
|
/// a radius and its suare in the same struct
|
|
struct CRadiusPair
|
|
{
|
|
// the adius, and the square radius
|
|
float R, R2;
|
|
void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
|
{
|
|
f.serial(R, R2);
|
|
}
|
|
};
|
|
|
|
|
|
typedef CPSAttrib<CRadiusPair> TPSAttribRadiusPair;
|
|
|
|
/** A sphere
|
|
*/
|
|
|
|
|
|
class CPSZoneSphere : public CPSZone, public IPSMover
|
|
{
|
|
public:
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
|
|
virtual void show();
|
|
|
|
|
|
NLMISC_DECLARE_CLASS(CPSZoneSphere);
|
|
|
|
CPSZoneSphere()
|
|
{
|
|
if (CParticleSystem::getSerializeIdentifierFlag()) _Name = std::string("ZoneSphere");
|
|
}
|
|
|
|
|
|
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
|
|
// inherited from IPSMover
|
|
virtual bool supportUniformScaling(void) const { return true; }
|
|
virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m);
|
|
virtual NLMISC::CMatrix getMatrix(uint32 index) const;
|
|
virtual void setScale(uint32 k, float scale);
|
|
virtual NLMISC::CVector getScale(uint32 k) const;
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
TPSAttribRadiusPair _Radius;
|
|
|
|
NLMISC::CMatrix buildBasis(uint32 index) const;
|
|
|
|
virtual void resize(uint32 size);
|
|
|
|
virtual void newElement(const CPSEmitterInfo &info);
|
|
|
|
virtual void deleteElement(uint32 index);
|
|
};
|
|
|
|
/// a disc
|
|
|
|
class CPSZoneDisc : public CPSZone, public IPSMover
|
|
{
|
|
public:
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
|
|
virtual void show();
|
|
|
|
CPSZoneDisc()
|
|
{
|
|
if (CParticleSystem::getSerializeIdentifierFlag()) _Name = std::string("ZoneDisc");
|
|
}
|
|
|
|
NLMISC_DECLARE_CLASS(CPSZoneDisc);
|
|
|
|
|
|
// inherited from IPSMover
|
|
virtual bool supportUniformScaling(void) const { return true; }
|
|
virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m);
|
|
virtual NLMISC::CMatrix getMatrix(uint32 index) const;
|
|
virtual void setScale(uint32 k, float scale);
|
|
virtual NLMISC::CVector getScale(uint32 k) const;
|
|
virtual bool onlyStoreNormal(void) const { return true; }
|
|
virtual NLMISC::CVector getNormal(uint32 index);
|
|
virtual void setNormal(uint32 index, NLMISC::CVector n);
|
|
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
|
|
|
|
protected:
|
|
TPSAttribVector _Normal;
|
|
TPSAttribRadiusPair _Radius;
|
|
|
|
NLMISC::CMatrix buildBasis(uint32 index) const;
|
|
|
|
virtual void resize(uint32 size);
|
|
|
|
virtual void newElement(const CPSEmitterInfo &info);
|
|
|
|
virtual void deleteElement(uint32 index);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// a caped cylinder
|
|
|
|
|
|
class CPSZoneCylinder : public CPSZone, public IPSMover
|
|
{
|
|
public:
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
|
|
virtual void show();
|
|
|
|
CPSZoneCylinder()
|
|
{
|
|
if (CParticleSystem::getSerializeIdentifierFlag()) _Name = std::string("ZoneCylinder");
|
|
}
|
|
|
|
NLMISC_DECLARE_CLASS(CPSZoneCylinder);
|
|
|
|
// inherited from IPSMover
|
|
virtual bool supportUniformScaling(void) const { return true; }
|
|
virtual bool supportNonUniformScaling(void) const { return true; }
|
|
virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m);
|
|
virtual NLMISC::CMatrix getMatrix(uint32 index) const;
|
|
virtual void setScale(uint32 k, float scale);
|
|
virtual void setScale(uint32 k, const NLMISC::CVector &s);
|
|
virtual NLMISC::CVector getScale(uint32 k) const;
|
|
|
|
// serialization
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// the I and J vector of the cylinder
|
|
CPSAttrib<CPlaneBasis> _Basis;
|
|
|
|
// dimension of cylinder in each direction, encoded in a vector
|
|
TPSAttribVector _Dim;
|
|
|
|
NLMISC::CMatrix buildBasis(uint32 index) const;
|
|
|
|
virtual void resize(uint32 size);
|
|
|
|
virtual void newElement(const CPSEmitterInfo &info);
|
|
|
|
virtual void deleteElement(uint32 index);
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* The same as a plane, but with a rectangle. We don't encode the plane by its normal, however...
|
|
*/
|
|
|
|
class CPSZoneRectangle : public CPSZone, public IPSMover
|
|
{
|
|
public:
|
|
virtual void computeCollisions(CPSLocated &target, uint firstInstanceIndex, const NLMISC::CVector *posBefore, const NLMISC::CVector *posAfter);
|
|
virtual void show();
|
|
|
|
CPSZoneRectangle()
|
|
{
|
|
if (CParticleSystem::getSerializeIdentifierFlag()) _Name = std::string("CPSZoneRectangle");
|
|
}
|
|
|
|
NLMISC_DECLARE_CLASS(CPSZoneRectangle);
|
|
|
|
|
|
|
|
|
|
|
|
// serialization
|
|
virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
// inherited from IPSMover
|
|
virtual bool supportUniformScaling(void) const { return true; }
|
|
virtual bool supportNonUniformScaling(void) const { return true; }
|
|
virtual void setMatrix(uint32 index, const NLMISC::CMatrix &m);
|
|
virtual NLMISC::CMatrix getMatrix(uint32 index) const;
|
|
virtual void setScale(uint32 index, float scale);
|
|
virtual void setScale(uint32 index, const NLMISC::CVector &s);
|
|
virtual NLMISC::CVector getScale(uint32 index) const;
|
|
|
|
protected:
|
|
|
|
|
|
CPSAttrib<CPlaneBasis> _Basis;
|
|
|
|
// width
|
|
TPSAttribFloat _Width;
|
|
|
|
// Height
|
|
TPSAttribFloat _Height;
|
|
|
|
|
|
NLMISC::CMatrix buildBasis(uint32 index) const;
|
|
|
|
virtual void resize(uint32 size);
|
|
|
|
virtual void newElement(const CPSEmitterInfo &info);
|
|
|
|
virtual void deleteElement(uint32 index);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // NL3D
|
|
|
|
|
|
#endif // NL_PS_ZONE_H
|
|
|
|
/* End of ps_zone.h */
|