2014-12-16 13:36:27 +00:00
|
|
|
// action_api.cpp
|
|
|
|
//
|
|
|
|
// Copyright 1997-1998 by David K. McAllister
|
|
|
|
//
|
|
|
|
// This file implements the action API calls by creating
|
|
|
|
// action class instances, which are either executed or
|
|
|
|
// added to an action list.
|
|
|
|
|
|
|
|
#include "general.h"
|
|
|
|
|
|
|
|
extern void _pAddActionToList(ParticleAction *S, int size);
|
|
|
|
extern void _pCallActionList(ParticleAction *pa, int num_actions,
|
|
|
|
ParticleGroup *pg);
|
|
|
|
|
|
|
|
// Do not call this function.
|
|
|
|
void _pSendAction(ParticleAction *S, PActionEnum type, int size)
|
|
|
|
{
|
|
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
|
|
|
|
S->type = type;
|
|
|
|
|
|
|
|
if(_ps.in_new_list)
|
|
|
|
{
|
|
|
|
_pAddActionToList(S, size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Immediate mode. Execute it.
|
|
|
|
// This is a hack to give them local access to dt.
|
|
|
|
S->dt = _ps.dt;
|
|
|
|
_pCallActionList(S, 1, _ps.pgrp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pAvoid(float magnitude, float epsilon, float look_ahead,
|
|
|
|
PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PAAvoid S;
|
|
|
|
|
|
|
|
S.position = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.look_ahead = look_ahead;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAAvoidID, sizeof(PAAvoid));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pBounce(float friction, float resilience, float cutoff,
|
|
|
|
PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PABounce S;
|
|
|
|
|
|
|
|
S.position = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
S.oneMinusFriction = 1.0f - friction;
|
|
|
|
S.resilience = resilience;
|
|
|
|
S.cutoffSqr = fsqr(cutoff);
|
|
|
|
|
|
|
|
_pSendAction(&S, PABounceID, sizeof(PABounce));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pCopyVertexB(bool copy_pos, bool copy_vel)
|
|
|
|
{
|
|
|
|
PACopyVertexB S;
|
|
|
|
|
|
|
|
S.copy_pos = copy_pos;
|
|
|
|
S.copy_vel = copy_vel;
|
|
|
|
|
|
|
|
_pSendAction(&S, PACopyVertexBID, sizeof(PACopyVertexB));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pDamping(float damping_x, float damping_y, float damping_z,
|
|
|
|
float vlow, float vhigh)
|
|
|
|
{
|
|
|
|
PADamping S;
|
|
|
|
|
|
|
|
S.damping = pVector(damping_x, damping_y, damping_z);
|
|
|
|
S.vlowSqr = fsqr(vlow);
|
|
|
|
S.vhighSqr = fsqr(vhigh);
|
|
|
|
|
|
|
|
_pSendAction(&S, PADampingID, sizeof(PADamping));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pExplosion(float center_x, float center_y, float center_z, float velocity,
|
|
|
|
float magnitude, float stdev, float epsilon, float age)
|
|
|
|
{
|
|
|
|
PAExplosion S;
|
|
|
|
|
|
|
|
S.center = pVector(center_x, center_y, center_z);
|
|
|
|
S.velocity = velocity;
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.stdev = stdev;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.age = age;
|
|
|
|
|
|
|
|
if(S.epsilon < 0.0f)
|
|
|
|
S.epsilon = P_EPS;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAExplosionID, sizeof(PAExplosion));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pFollow(float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAFollow S;
|
|
|
|
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAFollowID, sizeof(PAFollow));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pGravitate(float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAGravitate S;
|
|
|
|
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAGravitateID, sizeof(PAGravitate));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pGravity(float dir_x, float dir_y, float dir_z)
|
|
|
|
{
|
|
|
|
PAGravity S;
|
|
|
|
|
|
|
|
S.direction = pVector(dir_x, dir_y, dir_z);
|
|
|
|
|
|
|
|
_pSendAction(&S, PAGravityID, sizeof(PAGravity));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pJet(float center_x, float center_y, float center_z,
|
|
|
|
float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
|
|
|
|
PAJet S;
|
|
|
|
|
|
|
|
S.center = pVector(center_x, center_y, center_z);
|
|
|
|
S.acc = _ps.Vel;
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAJetID, sizeof(PAJet));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pKillOld(float age_limit, bool kill_less_than)
|
|
|
|
{
|
|
|
|
PAKillOld S;
|
|
|
|
|
|
|
|
S.age_limit = age_limit;
|
|
|
|
S.kill_less_than = kill_less_than;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAKillOldID, sizeof(PAKillOld));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pMatchVelocity(float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAMatchVelocity S;
|
|
|
|
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAMatchVelocityID, sizeof(PAMatchVelocity));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pMove()
|
|
|
|
{
|
|
|
|
PAMove S;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAMoveID, sizeof(PAMove));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pOrbitLine(float p_x, float p_y, float p_z,
|
|
|
|
float axis_x, float axis_y, float axis_z,
|
|
|
|
float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAOrbitLine S;
|
|
|
|
|
|
|
|
S.p = pVector(p_x, p_y, p_z);
|
|
|
|
S.axis = pVector(axis_x, axis_y, axis_z);
|
|
|
|
S.axis.normalize();
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAOrbitLineID, sizeof(PAOrbitLine));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pOrbitPoint(float center_x, float center_y, float center_z,
|
|
|
|
float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAOrbitPoint S;
|
|
|
|
|
|
|
|
S.center = pVector(center_x, center_y, center_z);
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAOrbitPointID, sizeof(PAOrbitPoint));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pRandomAccel(PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PARandomAccel S;
|
|
|
|
|
|
|
|
S.gen_acc = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
|
|
|
|
_pSendAction(&S, PARandomAccelID, sizeof(PARandomAccel));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pRandomDisplace(PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PARandomDisplace S;
|
|
|
|
|
|
|
|
S.gen_disp = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
|
|
|
|
_pSendAction(&S, PARandomDisplaceID, sizeof(PARandomDisplace));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pRandomVelocity(PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PARandomVelocity S;
|
|
|
|
|
|
|
|
S.gen_vel = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
|
|
|
|
_pSendAction(&S, PARandomVelocityID, sizeof(PARandomVelocity));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pRestore(float time_left)
|
|
|
|
{
|
|
|
|
PARestore S;
|
|
|
|
|
|
|
|
S.time_left = time_left;
|
|
|
|
|
|
|
|
_pSendAction(&S, PARestoreID, sizeof(PARestore));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pSink(bool kill_inside, PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PASink S;
|
|
|
|
|
|
|
|
S.kill_inside = kill_inside;
|
|
|
|
S.position = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
|
|
|
|
_pSendAction(&S, PASinkID, sizeof(PASink));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pSinkVelocity(bool kill_inside, PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
PASinkVelocity S;
|
|
|
|
|
|
|
|
S.kill_inside = kill_inside;
|
|
|
|
S.velocity = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
|
|
|
|
_pSendAction(&S, PASinkVelocityID, sizeof(PASinkVelocity));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pSource(float particle_rate, PDomainEnum dtype,
|
|
|
|
float a0, float a1, float a2,
|
|
|
|
float a3, float a4, float a5,
|
|
|
|
float a6, float a7, float a8)
|
|
|
|
{
|
|
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
|
|
|
|
PASource S;
|
|
|
|
|
|
|
|
S.particle_rate = particle_rate;
|
|
|
|
S.position = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
|
|
S.positionB = _ps.VertexB;
|
|
|
|
S.size = _ps.Size;
|
|
|
|
S.velocity = _ps.Vel;
|
|
|
|
S.color = _ps.Color;
|
|
|
|
S.alpha = _ps.Alpha;
|
|
|
|
S.age = _ps.Age;
|
|
|
|
S.age_sigma = _ps.AgeSigma;
|
|
|
|
S.vertexB_tracks = _ps.vertexB_tracks;
|
|
|
|
|
|
|
|
_pSendAction(&S, PASourceID, sizeof(PASource));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pSpeedLimit(float min_speed, float max_speed)
|
|
|
|
{
|
|
|
|
PASpeedLimit S;
|
|
|
|
|
|
|
|
S.min_speed = min_speed;
|
|
|
|
S.max_speed = max_speed;
|
|
|
|
|
|
|
|
_pSendAction(&S, PASpeedLimitID, sizeof(PASpeedLimit));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pTargetColor(float color_x, float color_y, float color_z,
|
|
|
|
float alpha, float scale)
|
|
|
|
{
|
|
|
|
PATargetColor S;
|
|
|
|
|
|
|
|
S.color = pVector(color_x, color_y, color_z);
|
|
|
|
S.alpha = alpha;
|
|
|
|
S.scale = scale;
|
|
|
|
|
|
|
|
_pSendAction(&S, PATargetColorID, sizeof(PATargetColor));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pTargetSize(float size_x, float size_y, float size_z,
|
|
|
|
float scale_x, float scale_y, float scale_z)
|
|
|
|
{
|
|
|
|
PATargetSize S;
|
|
|
|
|
|
|
|
S.size = pVector(size_x, size_y, size_z);
|
|
|
|
S.scale = pVector(scale_x, scale_y, scale_z);
|
|
|
|
|
|
|
|
_pSendAction(&S, PATargetSizeID, sizeof(PATargetSize));
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pTargetVelocity(float vel_x, float vel_y, float vel_z, float scale)
|
|
|
|
{
|
|
|
|
PATargetVelocity S;
|
|
|
|
|
|
|
|
S.velocity = pVector(vel_x, vel_y, vel_z);
|
|
|
|
S.scale = scale;
|
|
|
|
|
|
|
|
_pSendAction(&S, PATargetVelocityID, sizeof(PATargetVelocity));
|
|
|
|
}
|
|
|
|
|
|
|
|
// If in immediate mode, quickly add a vertex.
|
|
|
|
// If building an action list, call pSource.
|
|
|
|
PARTICLEDLL_API void pVertex(float x, float y, float z)
|
|
|
|
{
|
|
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
|
|
|
|
if(_ps.in_new_list)
|
|
|
|
{
|
|
|
|
pSource(1, PDPoint, x, y, z);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Immediate mode. Quickly add the vertex.
|
|
|
|
if(_ps.pgrp == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pVector pos(x, y, z);
|
|
|
|
pVector siz, vel, col, posB;
|
|
|
|
if(_ps.vertexB_tracks)
|
|
|
|
posB = pos;
|
|
|
|
else
|
|
|
|
_ps.VertexB.Generate(posB);
|
|
|
|
_ps.Size.Generate(siz);
|
|
|
|
_ps.Vel.Generate(vel);
|
|
|
|
_ps.Color.Generate(col);
|
|
|
|
_ps.pgrp->Add(pos, posB, siz, vel, col, _ps.Alpha, _ps.Age);
|
|
|
|
}
|
|
|
|
|
|
|
|
PARTICLEDLL_API void pVortex(float center_x, float center_y, float center_z,
|
|
|
|
float axis_x, float axis_y, float axis_z,
|
|
|
|
float magnitude, float epsilon, float max_radius)
|
|
|
|
{
|
|
|
|
PAVortex S;
|
|
|
|
|
|
|
|
S.center = pVector(center_x, center_y, center_z);
|
|
|
|
S.axis = pVector(axis_x, axis_y, axis_z);
|
|
|
|
S.axis.normalize();
|
|
|
|
S.magnitude = magnitude;
|
|
|
|
S.epsilon = epsilon;
|
|
|
|
S.max_radius = max_radius;
|
|
|
|
|
|
|
|
_pSendAction(&S, PAVortexID, sizeof(PAVortex));
|
|
|
|
}
|