mirror of
https://github.com/ENSL/NS.git
synced 2024-11-30 08:20:56 +00:00
dc79b89150
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@220 67975925-1194-0748-b3d5-c16f83f1a3a1
404 lines
10 KiB
C
404 lines
10 KiB
C
// general.h
|
|
//
|
|
// Copyright 1998 by David K. McAllister.
|
|
//
|
|
// This file implements the API calls that are not particle actions.
|
|
|
|
#ifndef general_h
|
|
#define general_h
|
|
|
|
//#include "papi.h"
|
|
#include "p_vector.h"
|
|
#include "particledefs.h"
|
|
|
|
#ifdef _WIN32
|
|
#pragma warning (disable:4244)
|
|
#endif
|
|
|
|
struct pDomain
|
|
{
|
|
PDomainEnum type; // PABoxDomain, PASphereDomain, PAConeDomain...
|
|
pVector p1, p2; // Box vertices, Sphere center, Cylinder/Cone ends
|
|
pVector u, v; // Orthonormal basis vectors for Cylinder/Cone
|
|
float radius1; // Outer radius
|
|
float radius2; // Inner radius
|
|
float radius1Sqr; // Used for fast Within test of spheres,
|
|
float radius2Sqr; // and for mag. of u and v vectors for plane.
|
|
|
|
bool Within(const pVector &) const;
|
|
void Generate(pVector &) const;
|
|
|
|
// This constructor is used when default constructing a
|
|
// ParticleAction that has a pDomain.
|
|
inline pDomain()
|
|
{
|
|
}
|
|
|
|
// Construct a domain in the standard way.
|
|
pDomain(PDomainEnum dtype,
|
|
float a0=0.0f, float a1=0.0f, float a2=0.0f,
|
|
float a3=0.0f, float a4=0.0f, float a5=0.0f,
|
|
float a6=0.0f, float a7=0.0f, float a8=0.0f);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Type codes for all actions
|
|
enum PActionEnum
|
|
{
|
|
PAHeaderID, // The first action in each list.
|
|
PAAvoidID, // Avoid entering the domain of space.
|
|
PABounceID, // Bounce particles off a domain of space.
|
|
PACallActionListID, //
|
|
PACopyVertexBID, // Set the secondary position from current position.
|
|
PADampingID, // Dampen particle velocities.
|
|
PAExplosionID, // An Explosion.
|
|
PAFollowID, // Accelerate toward the previous particle in the group.
|
|
PAGravitateID, // Accelerate each particle toward each other particle.
|
|
PAGravityID, // Acceleration in the given direction.
|
|
PAJetID, //
|
|
PAKillOldID, //
|
|
PAMatchVelocityID, //
|
|
PAMoveID, //
|
|
PAOrbitLineID, //
|
|
PAOrbitPointID, //
|
|
PARandomAccelID, //
|
|
PARandomDisplaceID, //
|
|
PARandomVelocityID, //
|
|
PARestoreID, //
|
|
PASinkID, //
|
|
PASinkVelocityID, //
|
|
PASourceID, //
|
|
PASpeedLimitID, //
|
|
PATargetColorID, //
|
|
PATargetSizeID, //
|
|
PATargetVelocityID, //
|
|
PAVortexID //
|
|
};
|
|
|
|
// This method actually does the particle's action.
|
|
#define ExecMethod void Execute(ParticleGroup *pg);
|
|
|
|
struct ParticleAction
|
|
{
|
|
static float dt; // This is copied to here from global state.
|
|
PActionEnum type; // Type field
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Data types derived from Action.
|
|
|
|
|
|
struct PAHeader : public ParticleAction
|
|
{
|
|
int actions_allocated;
|
|
int count; // Total actions in the list.
|
|
float padding[96]; // This must be the largest action.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAAvoid : public ParticleAction
|
|
{
|
|
pDomain position; // Avoid region
|
|
float look_ahead; // how many time units ahead to look
|
|
float magnitude; // what percent of the way to go each time
|
|
float epsilon; // add to r^2 for softening
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PABounce : public ParticleAction
|
|
{
|
|
pDomain position; // Bounce region
|
|
float oneMinusFriction; // Friction tangent to surface
|
|
float resilience; // Resilence perpendicular to surface
|
|
float cutoffSqr; // cutoff velocity; friction applies iff v > cutoff
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PACallActionList : public ParticleAction
|
|
{
|
|
int action_list_num; // The action list number to call
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PACopyVertexB : public ParticleAction
|
|
{
|
|
bool copy_pos; // True to copy pos to posB.
|
|
bool copy_vel; // True to copy vel to velB.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PADamping : public ParticleAction
|
|
{
|
|
pVector damping; // Damping constant applied to velocity
|
|
float vlowSqr; // Low and high cutoff velocities
|
|
float vhighSqr;
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAExplosion : public ParticleAction
|
|
{
|
|
pVector center; // The center of the explosion
|
|
float velocity; // Of shock wave
|
|
float magnitude; // At unit radius
|
|
float stdev; // Sharpness or width of shock wave
|
|
float age; // How long it's been going on
|
|
float epsilon; // Softening parameter
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAFollow : public ParticleAction
|
|
{
|
|
float magnitude; // The grav of each particle
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAGravitate : public ParticleAction
|
|
{
|
|
float magnitude; // The grav of each particle
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAGravity : public ParticleAction
|
|
{
|
|
pVector direction; // Amount to increment velocity
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAJet : public ParticleAction
|
|
{
|
|
pVector center; // Center of the fan
|
|
pDomain acc; // Acceleration vector domain
|
|
float magnitude; // Scales acceleration
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAKillOld : public ParticleAction
|
|
{
|
|
float age_limit; // Exact age at which to kill particles.
|
|
bool kill_less_than; // True to kill particles less than limit.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAMatchVelocity : public ParticleAction
|
|
{
|
|
float magnitude; // The grav of each particle
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAMove : public ParticleAction
|
|
{
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAOrbitLine : public ParticleAction
|
|
{
|
|
pVector p, axis; // Endpoints of line to which particles are attracted
|
|
float magnitude; // Scales acceleration
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAOrbitPoint : public ParticleAction
|
|
{
|
|
pVector center; // Point to which particles are attracted
|
|
float magnitude; // Scales acceleration
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PARandomAccel : public ParticleAction
|
|
{
|
|
pDomain gen_acc; // The domain of random accelerations.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PARandomDisplace : public ParticleAction
|
|
{
|
|
pDomain gen_disp; // The domain of random displacements.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PARandomVelocity : public ParticleAction
|
|
{
|
|
pDomain gen_vel; // The domain of random velocities.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PARestore : public ParticleAction
|
|
{
|
|
float time_left; // Time remaining until they should be in position.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PASink : public ParticleAction
|
|
{
|
|
bool kill_inside; // True to dispose of particles *inside* domain
|
|
pDomain position; // Disposal region
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PASinkVelocity : public ParticleAction
|
|
{
|
|
bool kill_inside; // True to dispose of particles with vel *inside* domain
|
|
pDomain velocity; // Disposal region
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PASpeedLimit : public ParticleAction
|
|
{
|
|
float min_speed; // Clamp speed to this minimum.
|
|
float max_speed; // Clamp speed to this maximum.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PASource : public ParticleAction
|
|
{
|
|
pDomain position; // Choose a position in this domain.
|
|
pDomain positionB; // Choose a positionB in this domain.
|
|
pDomain size; // Choose a size in this domain.
|
|
pDomain velocity; // Choose a velocity in this domain.
|
|
pDomain color; // Choose a color in this domain.
|
|
float alpha; // Alpha of all generated particles
|
|
float particle_rate; // Particles to generate per unit time
|
|
float age; // Initial age of the particles
|
|
float age_sigma; // St. dev. of initial age of the particles
|
|
bool vertexB_tracks; // True to get positionB from position.
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PATargetColor : public ParticleAction
|
|
{
|
|
pVector color; // Color to shift towards
|
|
float alpha; // Alpha value to shift towards
|
|
float scale; // Amount to shift by (1 == all the way)
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PATargetSize : public ParticleAction
|
|
{
|
|
pVector size; // Size to shift towards
|
|
pVector scale; // Amount to shift by per frame (1 == all the way)
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PATargetVelocity : public ParticleAction
|
|
{
|
|
pVector velocity; // Velocity to shift towards
|
|
float scale; // Amount to shift by (1 == all the way)
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
struct PAVortex : public ParticleAction
|
|
{
|
|
pVector center; // Center of vortex
|
|
pVector axis; // Axis around which vortex is applied
|
|
float magnitude; // Scale for rotation around axis
|
|
float epsilon; // Softening parameter
|
|
float max_radius; // Only influence particles within max_radius
|
|
|
|
ExecMethod
|
|
};
|
|
|
|
// Global state vector
|
|
struct _ParticleState
|
|
{
|
|
float dt;
|
|
bool in_call_list;
|
|
bool in_new_list;
|
|
bool vertexB_tracks;
|
|
|
|
int group_id;
|
|
int list_id;
|
|
ParticleGroup *pgrp;
|
|
PAHeader *pact;
|
|
int tid; // Only used in the MP case, but always define it.
|
|
|
|
// These are static because all threads access the same groups.
|
|
// All accesses to these should be locked.
|
|
static ParticleGroup **group_list;
|
|
static PAHeader **alist_list;
|
|
static int group_count;
|
|
static int alist_count;
|
|
|
|
pDomain Size;
|
|
pDomain Vel;
|
|
pDomain VertexB;
|
|
pDomain Color;
|
|
float Alpha;
|
|
float Age;
|
|
float AgeSigma;
|
|
|
|
_ParticleState();
|
|
|
|
// Return an index into the list of particle groups where
|
|
// p_group_count groups can be added.
|
|
int GenerateGroups(int p_group_count);
|
|
int GenerateLists(int alist_count);
|
|
ParticleGroup *GetGroupPtr(int p_group_num);
|
|
PAHeader *GetListPtr(int action_list_num);
|
|
};
|
|
|
|
#ifdef PARTICLE_MP
|
|
// All entry points call this to get their particle state.
|
|
inline _ParticleState &_GetPState()
|
|
{
|
|
// Returns a reference to the appropriate particle state.
|
|
extern _ParticleState &_GetPStateWithTID();
|
|
|
|
return _GetPStateWithTID();
|
|
}
|
|
|
|
#else
|
|
|
|
// All entry points call this to get their particle state.
|
|
// For the non-MP case this is practically a no-op.
|
|
inline _ParticleState &_GetPState()
|
|
{
|
|
// This is the global state.
|
|
extern _ParticleState __ps;
|
|
|
|
return __ps;
|
|
}
|
|
#endif
|
|
|
|
// Just a silly little function.
|
|
static inline float fsqr(float f) { return f * f; }
|
|
|
|
#endif
|