mirror of
https://github.com/ENSL/NS.git
synced 2025-01-31 13:10:55 +00:00
Adding particle system - probably needs work, should try to get the version from the NS1 svn repository
This commit is contained in:
parent
0ddfe3c35f
commit
c47caa1440
29 changed files with 4366 additions and 49 deletions
|
@ -49,14 +49,20 @@ typedef int BOOL;
|
|||
#define MAX_PATH PATH_MAX
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef PUZL
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef _vsnprintf
|
||||
#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
|
||||
#endif
|
||||
#ifndef _snprintf
|
||||
#define _snprintf(a,b,c,d,e)
|
||||
#endif
|
||||
#endif
|
||||
#endif //_WIN32
|
||||
|
||||
// Misc C-runtime library headers
|
||||
|
|
|
@ -6,18 +6,18 @@
|
|||
|
||||
DLLNAME=ns
|
||||
|
||||
ARCH=i386
|
||||
ARCH=i686
|
||||
|
||||
#make sure this is the correct compiler for your system
|
||||
CC=gcc
|
||||
LD=gcc
|
||||
|
||||
LIBBASE=../../../libraries/current
|
||||
LIBBASE=..
|
||||
|
||||
DLL_SRCDIR=../dlls
|
||||
GAME_SHARED_SRCDIR = ../game_shared
|
||||
MOD_SRCDIR = ../mod
|
||||
PARTICLES_SRCDIR = ../particles
|
||||
PARTICLES_SRCDIR = ../Particle
|
||||
PM_SHARED_SRCDIR=../pm_shared
|
||||
TEXT_SRCDIR = ../textrep
|
||||
UTIL_SRCDIR = ../util
|
||||
|
@ -36,15 +36,15 @@ BASE_CFLAGS=-Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp
|
|||
# -DAVH_SECURE_PRERELEASE_BUILD for CM testing
|
||||
|
||||
#full optimization
|
||||
CFLAGS=$(BASE_CFLAGS) -w -Wall -nostdinc++ -ffor-scope -fPIC -mcpu=i486 -O3 -pipe -funroll-loops -fdelayed-branch -malign-loops=4 -malign-jumps=4 -malign-functions=4
|
||||
CFLAGS=$(BASE_CFLAGS) -w -Wall -nostdinc++ -fpermissive -ffor-scope -fPIC -mtune=$(ARCH) -O3 -pipe -funroll-loops -fdelayed-branch -falign-loops=4 -falign-jumps=4 -falign-functions=4
|
||||
|
||||
#use these when debugging
|
||||
#CFLAGS=$(BASE_CFLAGS) -fPIC -fno-for-scope
|
||||
|
||||
# add base directory (CGC)
|
||||
|
||||
INCLUDEDIRS=-I$(LIBBASE) -I. -I$(LIBBASE)/include -I$(LIBBASE)/include/stlport -I$(LIBBASE)/include/particle -I$(LIBBASE)/include/lua -I../dlls -I../engine -I../common -I../mod -I../game_shared -I../pm_shared -I.. -I/usr/include/c++/3.3/i486-linux -I/usr/include/c++/3.3 -I/usr/include/c++
|
||||
LINKDIRS= -L$(LIBBASE)/release
|
||||
INCLUDEDIRS=-I$(LIBBASE) -I. -I$(LIBBASE)/include -I$(LIBBASE)/include/stlport -I$(LIBBASE)/particle -I$(LIBBASE)/include/lua -I../dlls -I../engine -I../common -I../mod -I../game_shared -I../pm_shared -I.. -I/usr/include/x86_64-linux-gnu/c++/4.8 -I/usr/include/c++/4.8 -I/usr/include/c++
|
||||
LINKDIRS= -L$(LIBBASE)/particle
|
||||
|
||||
SHLIBEXT=so
|
||||
|
||||
|
@ -52,7 +52,7 @@ LDPRELIBS= $(CFLAGS) -shared \
|
|||
-Wl,-Map,ns_map.txt \
|
||||
$(LINKDIRS)
|
||||
|
||||
LDPOSTLIBS= -Wl,-Bstatic -lstlport_gcc -lstdc++ -lsupc++ -llua -llualib -lparticleMP -lcurl \
|
||||
LDPOSTLIBS= -Wl,-Bstatic -lstdc++ -lsupc++ -lparticleMP -lcurl \
|
||||
-Wl,-Bdynamic -lm -lgcc -lgcc_eh
|
||||
# -lgcc -lgcc_eh -lelf
|
||||
DO_CC=$(CC) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $<
|
||||
|
@ -257,18 +257,18 @@ release: $(DLLNAME)_$(ARCH).$(SHLIBEXT)
|
|||
curl:
|
||||
./build-curl.sh
|
||||
neat:
|
||||
-mkdir $(CURL_OBJDIR)
|
||||
-mkdir $(DLL_OBJDIR)
|
||||
-mkdir $(GAME_SHARED_OBJDIR)
|
||||
-mkdir $(MOD_OBJDIR)
|
||||
-mkdir $(PARTICLES_OBJDIR)
|
||||
-mkdir $(PM_SHARED_OBJDIR)
|
||||
-mkdir $(TEXT_OBJDIR)
|
||||
-mkdir $(UTIL_OBJDIR)
|
||||
-mkdir $(OUTPUT_DIR)
|
||||
@-mkdir -p $(CURL_OBJDIR)
|
||||
@-mkdir -p $(DLL_OBJDIR)
|
||||
@-mkdir -p $(GAME_SHARED_OBJDIR)
|
||||
@-mkdir -p $(MOD_OBJDIR)
|
||||
@-mkdir -p $(PARTICLES_OBJDIR)
|
||||
@-mkdir -p $(PM_SHARED_OBJDIR)
|
||||
@-mkdir -p $(TEXT_OBJDIR)
|
||||
@-mkdir -p $(UTIL_OBJDIR)
|
||||
@-mkdir -p $(OUTPUT_DIR)
|
||||
clean:
|
||||
-rm -f $(OBJ)
|
||||
-rm -f $(DLLNAME)_$(ARCH).$(SHLIBEXT)
|
||||
-rm $(OBJ)
|
||||
-rm $(DLLNAME)_$(ARCH).$(SHLIBEXT)
|
||||
spotless: clean
|
||||
-rm -r $(CURL_OBJDIR)
|
||||
-rm -r $(DLL_OBJDIR)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
|
||||
#ifdef AVH_CLIENT
|
||||
|
@ -665,4 +666,4 @@ void NS_GetBoneMatrices(const NS_AnimationData& inAnimationData, float time, NS_
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1211,17 +1211,17 @@ void TriggerPresence::KeyValue(KeyValueData* pkvd)
|
|||
}
|
||||
else if(FStrEq(pkvd->szKeyName, "timebeforeleave"))
|
||||
{
|
||||
this->mTimeBeforeLeave = max(atof(pkvd->szValue), 0.0f);
|
||||
this->mTimeBeforeLeave = max(atof(pkvd->szValue), (double)0.0f);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if(FStrEq(pkvd->szKeyName, "momentaryopentime"))
|
||||
{
|
||||
this->mMomentaryOpenTime = max(atof(pkvd->szValue), 0.01f);
|
||||
this->mMomentaryOpenTime = max(atof(pkvd->szValue), (double)0.01f);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if(FStrEq(pkvd->szKeyName, "momentaryclosetime"))
|
||||
{
|
||||
this->mMomentaryCloseTime = max(atof(pkvd->szValue), 0.01f);
|
||||
this->mMomentaryCloseTime = max(atof(pkvd->szValue), (double)0.01f);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if(FStrEq(pkvd->szKeyName, "spawnflags"))
|
||||
|
|
|
@ -4,20 +4,22 @@
|
|||
using std::string;
|
||||
#include "AvHNexusServer.h"
|
||||
#include "AvHServerUtil.h"
|
||||
bool AvHNexus::send(entvars_t* const pev, const unsigned char* data, const unsigned int length) { return false; }
|
||||
bool AvHNexus::recv(entvars_t* const pev, const char* data, const unsigned int length) { return false; }
|
||||
string AvHNexus::getNetworkID(const edict_t* edict) { return AvHSUGetPlayerAuthIDString((edict_t *)edict); }
|
||||
void AvHNexus::handleUnauthorizedJoinTeamAttempt(const edict_t* edict, const unsigned char team_index) {}
|
||||
void AvHNexus::performSpeedTest(void) {}
|
||||
void AvHNexus::processResponses(void) {}
|
||||
void AvHNexus::setGeneratePerformanceData(const edict_t* edict, const bool generate) {}
|
||||
bool AvHNexus::getGeneratePerformanceData(void) { return false; }
|
||||
bool AvHNexus::isRecordingGame(void) { return false; }
|
||||
void AvHNexus::cancelGame(void) {}
|
||||
void AvHNexus::finishGame(void) {}
|
||||
void AvHNexus::startGame(void) {}
|
||||
void AvHNexus::startup(void) {}
|
||||
void AvHNexus::shutdown(void) {}
|
||||
namespace AvHNexus {
|
||||
bool send(entvars_t* const pev, const unsigned char* data, const unsigned int length) { return false; }
|
||||
bool recv(entvars_t* const pev, const char* data, const unsigned int length) { return false; }
|
||||
string getNetworkID(const edict_t* edict) { return AvHSUGetPlayerAuthIDString((edict_t *)edict); }
|
||||
void handleUnauthorizedJoinTeamAttempt(const edict_t* edict, const unsigned char team_index) {}
|
||||
void performSpeedTest(void) {}
|
||||
void processResponses(void) {}
|
||||
void setGeneratePerformanceData(const edict_t* edict, const bool generate) {}
|
||||
bool getGeneratePerformanceData(void) { return false; }
|
||||
bool isRecordingGame(void) { return false; }
|
||||
void cancelGame(void) {}
|
||||
void finishGame(void) {}
|
||||
void startGame(void) {}
|
||||
void startup(void) {}
|
||||
void shutdown(void) {}
|
||||
}
|
||||
#else
|
||||
#include <NexusServerInterface.h>
|
||||
#include "AvHNexusServer.h"
|
||||
|
|
|
@ -688,9 +688,9 @@ AvHParticleSystem::GenerateParticles(int inNumberParticles)
|
|||
else if(theDomain == PS_Sphere)
|
||||
{
|
||||
float theRadius1 = fabs(this->mGenerationEntityAbsMax[0] - this->mGenerationEntityAbsMin[0])/2.0f;
|
||||
theRadius1 = max(theRadius1 - theEdgeInset, 0);
|
||||
theRadius1 = max(theRadius1 - theEdgeInset, 0.0f);
|
||||
float theRadius2 = this->mGenerationEntityParam;
|
||||
theRadius2 = max(theRadius2 - theEdgeInset, 0);
|
||||
theRadius2 = max(theRadius2 - theEdgeInset, 0.0f);
|
||||
theParams[3] = theRadius1;
|
||||
theParams[4] = theRadius2;
|
||||
}
|
||||
|
|
|
@ -205,4 +205,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef AVH_PSMANAGER_H
|
||||
#define AVH_PSMANAGER_H
|
||||
|
||||
#include <string.h>
|
||||
#include "util/nowarnings.h"
|
||||
#include "types.h"
|
||||
#include "mod/AvHParticleSystem.h"
|
||||
|
@ -169,4 +170,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <string.h>
|
||||
#include "util/nowarnings.h"
|
||||
#include "mod/AvHParticleTemplate.h"
|
||||
#include "common/renderingconst.h"
|
||||
|
|
|
@ -6878,7 +6878,7 @@ void AvHPlayer::InternalMovementThink()
|
|||
float factor = pushbackfactor / (radius / distance);
|
||||
|
||||
float weigthFactor=1.0f;
|
||||
int veriticalLimit=110;
|
||||
float veriticalLimit=110.0f;
|
||||
switch(theEntity->pev->iuser3) {
|
||||
case AVH_USER3_ALIEN_PLAYER4:
|
||||
weigthFactor=0.70f;
|
||||
|
@ -9227,7 +9227,7 @@ bool AvHPlayer::RunClientScript(const string& inScriptName)
|
|||
|
||||
void AvHPlayer::PrintWeaponListToClient(CBaseEntity *theAvHPlayer) {
|
||||
char msg[1024];
|
||||
sprintf(msg, "Weapons for %s:\n", this->GetPlayerName());
|
||||
sprintf(msg, "Weapons for %s:\n", this->GetPlayerName().c_str());
|
||||
ClientPrint(theAvHPlayer->pev, HUD_PRINTNOTIFY, msg);
|
||||
|
||||
for(int i = 0; i < MAX_ITEM_TYPES; i++)
|
||||
|
|
|
@ -46,13 +46,16 @@
|
|||
#include "common/event_api.h"
|
||||
#include "mod/AvHScriptManager.h"
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void DrawScaledHUDSprite(int inSpriteHandle, int inMode, int inRowsInSprite = 1, int inX = 0, int inY = 0, int inWidth = ScreenWidth(), int inHeight = ScreenHeight(), int inForceSpriteFrame = -1, float inStartU = 0.0f, float inStartV = 0.0f, float inEndU = 1.0f, float inEndV = 1.0f, float inRotateUVRadians = 0.0f, bool inUVWrapsOverFrames = false);
|
||||
extern vec3_t v_origin;
|
||||
|
||||
#ifdef USE_LUA
|
||||
static int errormessage(lua_State* inState)
|
||||
{
|
||||
const char *s = lua_tostring(inState, 1);
|
||||
|
@ -93,6 +96,7 @@ static int print(lua_State* inState)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Runs a client command, returns success
|
||||
static int clientCommand(lua_State* inState)
|
||||
{
|
||||
|
@ -438,9 +442,11 @@ static int triFog(lua_State* inState)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AvHScriptInstance::InitClient()
|
||||
{
|
||||
#ifdef USE_LUA
|
||||
//lua_register(this->mState, LUA_ERRORMESSAGE, errormessage);
|
||||
lua_register(this->mState, "print", print);
|
||||
lua_register(this->mState, "clientCommand", clientCommand);
|
||||
|
@ -469,4 +475,5 @@ void AvHScriptInstance::InitClient()
|
|||
|
||||
//lua_register(this->mState, "drawScaledHUDSprite", drawScaledHUDSpriteUV);
|
||||
//lua_register(this->mState, "drawScaledTiledHUDSprite", drawScaledTiledHUDSprite);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -28,17 +28,21 @@
|
|||
#include "util/STLUtil.h"
|
||||
#include "mod/AvHConstants.h"
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
AvHScriptInstance* gRunningScript = NULL;
|
||||
|
||||
AvHScriptInstance::AvHScriptInstance(string inScriptName)
|
||||
{
|
||||
#ifdef USE_LUA
|
||||
this->mState = NULL;
|
||||
#endif
|
||||
|
||||
this->Init();
|
||||
|
||||
|
@ -70,10 +74,12 @@ void AvHScriptInstance::CallSimpleFunction(const string& inFunctionName)
|
|||
{
|
||||
gRunningScript = this;
|
||||
|
||||
#ifdef USE_LUA
|
||||
// Execute callback
|
||||
lua_getglobal(this->mState, inFunctionName.c_str());
|
||||
//lua_pushstring(this->mState, inFunctionName.c_str());
|
||||
lua_call(this->mState, 0, 0);
|
||||
#endif
|
||||
|
||||
gRunningScript = NULL;
|
||||
}
|
||||
|
@ -83,16 +89,21 @@ void AvHScriptInstance::Cleanup()
|
|||
ASSERT(!this->CallbacksPending());
|
||||
ASSERT(this->mState);
|
||||
|
||||
#ifdef USE_LUA
|
||||
lua_close(this->mState);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_LUA
|
||||
lua_State* AvHScriptInstance::GetState()
|
||||
{
|
||||
return this->mState;
|
||||
}
|
||||
#endif
|
||||
|
||||
void AvHScriptInstance::Init()
|
||||
{
|
||||
#ifdef USE_LUA
|
||||
this->mState = lua_open();
|
||||
|
||||
lua_baselibopen(this->mState);
|
||||
|
@ -107,6 +118,7 @@ void AvHScriptInstance::Init()
|
|||
#else
|
||||
this->InitClient();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void AvHScriptInstance::Reset()
|
||||
|
@ -127,7 +139,9 @@ void AvHScriptInstance::Run()
|
|||
// Set global current script so it's accessible statically (needed for setting callbacks)
|
||||
gRunningScript = this;
|
||||
|
||||
#ifdef USE_LUA
|
||||
lua_dofile(this->mState, this->mScriptName.c_str());
|
||||
#endif
|
||||
|
||||
gRunningScript = NULL;
|
||||
}
|
||||
|
@ -235,6 +249,7 @@ void AvHScriptManager::Update(float inTime)
|
|||
#ifdef AVH_CLIENT
|
||||
void AvHScriptManager::ClientUpdate(float inTimePassed)
|
||||
{
|
||||
#ifdef USE_LUA
|
||||
// For all scripts
|
||||
for(AvHScriptInstanceListType::iterator theIter = this->mScriptList.begin(); theIter != this->mScriptList.end(); /* no increment */)
|
||||
{
|
||||
|
@ -269,6 +284,7 @@ void AvHScriptManager::ClientUpdate(float inTimePassed)
|
|||
theIter++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AvHScriptManager::DrawNormal()
|
||||
|
@ -301,6 +317,7 @@ void AvHScriptManager::DrawNoZBuffering()
|
|||
bool AvHScriptManager::GetClientMove(int& outButtonBits, int& outImpulse)
|
||||
{
|
||||
bool theSuccess = false;
|
||||
#ifdef USE_LUA
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
|
@ -335,6 +352,7 @@ bool AvHScriptManager::GetClientMove(int& outButtonBits, int& outImpulse)
|
|||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return theSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
#include "util/Checksum.h"
|
||||
#include "util/STLUtil.h"
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern "C" struct lua_State;
|
||||
#endif
|
||||
|
||||
class AvHScriptInstance
|
||||
{
|
||||
|
@ -38,7 +40,9 @@ public:
|
|||
|
||||
void Cleanup();
|
||||
|
||||
#ifdef USE_LUA
|
||||
lua_State* GetState();
|
||||
#endif
|
||||
|
||||
void Reset();
|
||||
|
||||
|
@ -58,7 +62,9 @@ private:
|
|||
#endif
|
||||
|
||||
// This gets copied around, so make sure elements can be shallow-copied or write a copy constructor
|
||||
#ifdef USE_LUA
|
||||
lua_State* mState;
|
||||
#endif
|
||||
string mScriptName;
|
||||
|
||||
typedef pair<string, float> CallbackType;
|
||||
|
@ -96,4 +102,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "util/Checksum.h"
|
||||
#include "util/STLUtil.h"
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
@ -545,8 +546,11 @@ static int setServerVariable(lua_State* inState)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AvHScriptInstance::InitServer()
|
||||
{
|
||||
#ifdef USE_LUA
|
||||
//lua_register(this->mState, LUA_ERRORMESSAGE, errormessage);
|
||||
|
||||
//lua_register(this->mState, "execute", execute);
|
||||
|
@ -579,4 +583,6 @@ void AvHScriptInstance::InitServer()
|
|||
lua_register(this->mState, "runClientScript", runClientScript);
|
||||
|
||||
lua_register(this->mState, "setServerVariable", setServerVariable);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "mod/AvHSharedUtil.h"
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
@ -93,3 +94,4 @@ void AvHScriptInstance::InitShared()
|
|||
lua_register(this->mState, "getTime", getTime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
43
main/source/particle/Makefile
Normal file
43
main/source/particle/Makefile
Normal file
|
@ -0,0 +1,43 @@
|
|||
######################################################################
|
||||
# Particle System API
|
||||
#
|
||||
# Copyright 1998 by David K. McAllister.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
C++ = g++
|
||||
|
||||
GLUT_HOME =/usr/local/contrib/unmoderated
|
||||
|
||||
MP = #-mp -DPARTICLE_MP
|
||||
|
||||
# Make it real fast on an Origin 2000.
|
||||
#LNO =-LNO:opt=1:fusion=2:fission=2:fusion_peeling_limit=2048:cs1=32K:cs2=8M
|
||||
COPT = $(MP) -O3 $(LNO) -fPIC
|
||||
|
||||
CFLAGS = $(COPT) $(COMPFLAGS) -I. -I.. -I$(GLUT_HOME)/include -I/usr/include/c++/4.8/
|
||||
|
||||
POBJS =action_api.o actions.o opengl.o system.o
|
||||
|
||||
ALL = libparticleMP.a SPDir
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
# following line needed for c++ .cc files
|
||||
.SUFFIXES : .cpp
|
||||
|
||||
.cpp.o:
|
||||
$(C++) $(CFLAGS) -c $<
|
||||
|
||||
libparticleMP.a: $(POBJS)
|
||||
rm -f $@
|
||||
ar clq $@ $(POBJS)
|
||||
|
||||
SPDir:
|
||||
(cd SP ; smake)
|
||||
|
||||
clean:
|
||||
(cd SP ; smake clean)
|
||||
rm -f libpar*
|
||||
rm -f *.o
|
||||
rm -rf *ii_files
|
132
main/source/particle/ParticleDLL.dsp
Normal file
132
main/source/particle/ParticleDLL.dsp
Normal file
|
@ -0,0 +1,132 @@
|
|||
# Microsoft Developer Studio Project File - Name="ParticleDLL" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=ParticleDLL - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ParticleDLL.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ParticleDLL.mak" CFG="ParticleDLL - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ParticleDLL - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "ParticleDLL - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ParticleDLL - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I ".." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PARTICLEDLL_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
|
||||
# SUBTRACT LINK32 /profile
|
||||
|
||||
!ELSEIF "$(CFG)" == "ParticleDLL - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PARTICLEDLL_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ParticleDLL - Win32 Release"
|
||||
# Name "ParticleDLL - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\action_api.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\actions.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\opengl.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\system.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter ".h"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\general.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\p_vector.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\papi.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
4
main/source/particle/Readme.txt
Normal file
4
main/source/particle/Readme.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
For SGI we make a version of the library that's made for
|
||||
multiprocessing in this directory and a version that's made for single
|
||||
processing in the SP directory. Typing make in this directory will make both.
|
||||
|
390
main/source/particle/action_api.cpp
Normal file
390
main/source/particle/action_api.cpp
Normal file
|
@ -0,0 +1,390 @@
|
|||
// 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));
|
||||
}
|
1840
main/source/particle/actions.cpp
Normal file
1840
main/source/particle/actions.cpp
Normal file
File diff suppressed because it is too large
Load diff
452
main/source/particle/general.h
Normal file
452
main/source/particle/general.h
Normal file
|
@ -0,0 +1,452 @@
|
|||
// 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"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning (disable:4244)
|
||||
#endif
|
||||
|
||||
// A single particle
|
||||
struct Particle
|
||||
{
|
||||
pVector pos;
|
||||
pVector posB;
|
||||
pVector size;
|
||||
pVector vel;
|
||||
pVector velB; // Used to compute binormal, normal, etc.
|
||||
pVector color; // Color must be next to alpha so glColor4fv works.
|
||||
float alpha; // This is both cunning and scary.
|
||||
float age;
|
||||
};
|
||||
|
||||
// A group of particles - Info and an array of Particles
|
||||
struct ParticleGroup
|
||||
{
|
||||
int p_count; // Number of particles currently existing.
|
||||
int max_particles; // Max particles allowed in group.
|
||||
int particles_allocated; // Actual allocated size.
|
||||
Particle list[1]; // Actually, num_particles in size
|
||||
|
||||
inline void Remove(int i)
|
||||
{
|
||||
list[i] = list[--p_count];
|
||||
}
|
||||
|
||||
inline bool Add(const pVector &pos, const pVector &posB,
|
||||
const pVector &size, const pVector &vel, const pVector &color,
|
||||
const float alpha = 1.0f,
|
||||
const float age = 0.0f)
|
||||
{
|
||||
if(p_count >= max_particles)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
list[p_count].pos = pos;
|
||||
list[p_count].posB = posB;
|
||||
list[p_count].size = size;
|
||||
list[p_count].vel = vel;
|
||||
list[p_count].velB = vel; // XXX This should be fixed.
|
||||
list[p_count].color = color;
|
||||
list[p_count].alpha = alpha;
|
||||
list[p_count].age = age;
|
||||
p_count++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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
|
BIN
main/source/particle/libparticleMP.a
Normal file
BIN
main/source/particle/libparticleMP.a
Normal file
Binary file not shown.
149
main/source/particle/opengl.cpp
Normal file
149
main/source/particle/opengl.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
// opengl.cpp
|
||||
//
|
||||
// Copyright 1998 by David K. McAllister
|
||||
//
|
||||
// This file implements the API calls that draw particle groups in OpenGL.
|
||||
|
||||
#include "general.h"
|
||||
|
||||
#ifdef WIN32
|
||||
// This is for something in gl.h.
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
// XXX #include <iostream.h>
|
||||
|
||||
// Emit OpenGL calls to draw the particles. These are drawn with
|
||||
// whatever primitive type the user specified(GL_POINTS, for
|
||||
// example). The color and radius are set per primitive, by default.
|
||||
// For GL_LINES, the other vertex of the line is the velocity vector.
|
||||
// XXX const_size is ignored.
|
||||
PARTICLEDLL_API void pDrawGroupp(int primitive, bool const_size, bool const_color)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
// Get a pointer to the particles in gp memory
|
||||
ParticleGroup *pg = _ps.pgrp;
|
||||
|
||||
if(pg == NULL)
|
||||
return; // ERROR
|
||||
|
||||
if(pg->p_count < 1)
|
||||
return;
|
||||
|
||||
if(primitive == GL_POINTS)
|
||||
{
|
||||
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
if(!const_color)
|
||||
{
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(4, GL_FLOAT, sizeof(Particle), &pg->list[0].color);
|
||||
}
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(Particle), &pg->list[0].pos);
|
||||
glDrawArrays((GLenum)primitive, 0, pg->p_count);
|
||||
glPopClientAttrib();
|
||||
// XXX For E&S
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume GL_LINES
|
||||
glBegin((GLenum)primitive);
|
||||
|
||||
if(!const_color)
|
||||
{
|
||||
for(int i = 0; i < pg->p_count; i++)
|
||||
{
|
||||
Particle &m = pg->list[i];
|
||||
|
||||
// Warning: this depends on alpha following color in the Particle struct.
|
||||
glColor4fv((GLfloat *)&m.color);
|
||||
glVertex3fv((GLfloat *)&m.pos);
|
||||
|
||||
// For lines, make a tail with the velocity vector's direction and
|
||||
// a length of radius.
|
||||
pVector tail = m.pos - m.vel;
|
||||
glVertex3fv((GLfloat *)&tail);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < pg->p_count; i++)
|
||||
{
|
||||
Particle &m = pg->list[i];
|
||||
glVertex3fv((GLfloat *)&m.pos);
|
||||
|
||||
// For lines, make a tail with the velocity vector's direction and
|
||||
// a length of radius.
|
||||
pVector tail = m.pos - m.vel;
|
||||
glVertex3fv((GLfloat *)&tail);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pDrawGroupl(int dlist, bool const_size, bool const_color, bool const_rotation)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
// Get a pointer to the particles in gp memory
|
||||
ParticleGroup *pg = _ps.pgrp;
|
||||
if(pg == NULL)
|
||||
return; // ERROR
|
||||
|
||||
if(pg->p_count < 1)
|
||||
return;
|
||||
|
||||
//if(const_color)
|
||||
// glColor4fv((GLfloat *)&pg->list[0].color);
|
||||
|
||||
for(int i = 0; i < pg->p_count; i++)
|
||||
{
|
||||
Particle &m = pg->list[i];
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(m.pos.x, m.pos.y, m.pos.z);
|
||||
|
||||
if(!const_size)
|
||||
glScalef(m.size.x, m.size.y, m.size.z);
|
||||
else
|
||||
glScalef(pg->list[i].size.x, pg->list[i].size.y, pg->list[i].size.z);
|
||||
|
||||
// Expensive! A sqrt, cross prod and acos. Yow.
|
||||
if(!const_rotation)
|
||||
{
|
||||
pVector vN(m.vel);
|
||||
vN.normalize();
|
||||
pVector voN(m.velB);
|
||||
voN.normalize();
|
||||
|
||||
pVector biN;
|
||||
if(voN.x == vN.x && voN.y == vN.y && voN.z == vN.z)
|
||||
biN = pVector(0, 1, 0);
|
||||
else
|
||||
biN = vN ^ voN;
|
||||
biN.normalize();
|
||||
|
||||
pVector N(vN ^ biN);
|
||||
|
||||
double M[16];
|
||||
M[0] = vN.x; M[4] = biN.x; M[8] = N.x; M[12] = 0;
|
||||
M[1] = vN.y; M[5] = biN.y; M[9] = N.y; M[13] = 0;
|
||||
M[2] = vN.z; M[6] = biN.z; M[10] = N.z; M[14] = 0;
|
||||
M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
|
||||
glMultMatrixd(M);
|
||||
}
|
||||
|
||||
// Warning: this depends on alpha following color in the Particle struct.
|
||||
if(!const_color)
|
||||
glColor4fv((GLfloat *)&m.color);
|
||||
|
||||
glCallList(dlist);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
141
main/source/particle/p_vector.h
Normal file
141
main/source/particle/p_vector.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
// p_vector.h - yet another vector class.
|
||||
//
|
||||
// Copyright 1997 by Jonathan P. Leech
|
||||
// Modifications Copyright 1997-1999 by David K. McAllister
|
||||
//
|
||||
// A simple 3D float vector class for internal use by the particle systems.
|
||||
|
||||
#ifndef particle_vector_h
|
||||
#define particle_vector_h
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433f
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define drand48() (((float) rand())/((float) RAND_MAX))
|
||||
#define srand48(x) srand(x)
|
||||
|
||||
// This is because their stupid compiler thinks it's smart.
|
||||
#define inline __forceinline
|
||||
#endif
|
||||
|
||||
class pVector
|
||||
{
|
||||
public:
|
||||
float x, y, z;
|
||||
|
||||
inline pVector(float ax, float ay, float az) : x(ax), y(ay), z(az)
|
||||
{
|
||||
//x = ax; y = ay; z = az;
|
||||
}
|
||||
|
||||
inline pVector() {}
|
||||
|
||||
inline float length() const
|
||||
{
|
||||
return sqrtf(x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
inline float length2() const
|
||||
{
|
||||
return (x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
inline float normalize()
|
||||
{
|
||||
float onel = 1.0f / sqrtf(x*x+y*y+z*z);
|
||||
x *= onel;
|
||||
y *= onel;
|
||||
z *= onel;
|
||||
|
||||
return onel;
|
||||
}
|
||||
|
||||
inline float operator*(const pVector &a) const
|
||||
{
|
||||
return x*a.x + y*a.y + z*a.z;
|
||||
}
|
||||
|
||||
inline pVector operator*(const float s) const
|
||||
{
|
||||
return pVector(x*s, y*s, z*s);
|
||||
}
|
||||
|
||||
inline pVector operator/(const float s) const
|
||||
{
|
||||
float invs = 1.0f / s;
|
||||
return pVector(x*invs, y*invs, z*invs);
|
||||
}
|
||||
|
||||
inline pVector operator+(const pVector& a) const
|
||||
{
|
||||
return pVector(x+a.x, y+a.y, z+a.z);
|
||||
}
|
||||
|
||||
inline pVector operator-(const pVector& a) const
|
||||
{
|
||||
return pVector(x-a.x, y-a.y, z-a.z);
|
||||
}
|
||||
|
||||
inline pVector operator-()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector& operator+=(const pVector& a)
|
||||
{
|
||||
x += a.x;
|
||||
y += a.y;
|
||||
z += a.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector& operator-=(const pVector& a)
|
||||
{
|
||||
x -= a.x;
|
||||
y -= a.y;
|
||||
z -= a.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector& operator*=(const float a)
|
||||
{
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector& operator/=(const float a)
|
||||
{
|
||||
float b = 1.0f / a;
|
||||
x *= b;
|
||||
y *= b;
|
||||
z *= b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector& operator=(const pVector& a)
|
||||
{
|
||||
x = a.x;
|
||||
y = a.y;
|
||||
z = a.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline pVector operator^(const pVector& b) const
|
||||
{
|
||||
return pVector(
|
||||
y*b.z-z*b.y,
|
||||
z*b.x-x*b.z,
|
||||
x*b.y-y*b.x);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
229
main/source/particle/papi.h
Normal file
229
main/source/particle/papi.h
Normal file
|
@ -0,0 +1,229 @@
|
|||
// papi.h
|
||||
//
|
||||
// Copyright 1997-1998 by David K. McAllister
|
||||
// http://www.cs.unc.edu/~davemc/Particle
|
||||
//
|
||||
// Include this file in all applications that use the Particle System API.
|
||||
|
||||
#ifndef _particle_api_h
|
||||
#define _particle_api_h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// This is the major and minor version number of this release of the API.
|
||||
#define P_VERSION 120
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef PARTICLEDLL_EXPORTS
|
||||
#define PARTICLEDLL_API __declspec(dllexport)
|
||||
#else
|
||||
#define PARTICLEDLL_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define PARTICLEDLL_API
|
||||
#endif
|
||||
|
||||
// Actually this must be < sqrt(MAXFLOAT) since we store this value squared.
|
||||
#define P_MAXFLOAT 1.0e16f
|
||||
|
||||
#ifdef MAXINT
|
||||
#define P_MAXINT MAXINT
|
||||
#else
|
||||
#define P_MAXINT 0x7fffffff
|
||||
#endif
|
||||
|
||||
#define P_EPS 1e-3f
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Type codes for domains
|
||||
PARTICLEDLL_API enum PDomainEnum
|
||||
{
|
||||
PDPoint = 0, // Single point
|
||||
PDLine = 1, // Line segment
|
||||
PDTriangle = 2, // Triangle
|
||||
PDPlane = 3, // Arbitrarily-oriented plane
|
||||
PDBox = 4, // Axis-aligned box
|
||||
PDSphere = 5, // Sphere
|
||||
PDCylinder = 6, // Cylinder
|
||||
PDCone = 7, // Cone
|
||||
PDBlob = 8, // Gaussian blob
|
||||
PDDisc = 9, // Arbitrarily-oriented disc
|
||||
PDRectangle = 10 // Rhombus-shaped planar region
|
||||
};
|
||||
|
||||
// State setting calls
|
||||
|
||||
PARTICLEDLL_API void pColor(float red, float green, float blue, float alpha = 1.0f);
|
||||
|
||||
PARTICLEDLL_API void pColorD(float alpha, 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);
|
||||
|
||||
PARTICLEDLL_API void pSize(float size_x, float size_y = 1.0f, float size_z = 1.0f);
|
||||
|
||||
PARTICLEDLL_API void pSizeD(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);
|
||||
|
||||
PARTICLEDLL_API void pStartingAge(float age, float sigma = 1.0f);
|
||||
|
||||
PARTICLEDLL_API void pTimeStep(float new_dt);
|
||||
|
||||
PARTICLEDLL_API void pVelocity(float x, float y, float z);
|
||||
|
||||
PARTICLEDLL_API void pVelocityD(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);
|
||||
|
||||
PARTICLEDLL_API void pVertexB(float x, float y, float z);
|
||||
|
||||
PARTICLEDLL_API void pVertexBD(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);
|
||||
|
||||
PARTICLEDLL_API void pVertexBTracks(bool track_vertex = true);
|
||||
|
||||
|
||||
// Action List Calls
|
||||
|
||||
PARTICLEDLL_API void pCallActionList(int action_list_num);
|
||||
|
||||
PARTICLEDLL_API void pDeleteActionLists(int action_list_num, int action_list_count = 1);
|
||||
|
||||
PARTICLEDLL_API void pEndActionList();
|
||||
|
||||
PARTICLEDLL_API int pGenActionLists(int action_list_count = 1);
|
||||
|
||||
PARTICLEDLL_API void pNewActionList(int action_list_num);
|
||||
|
||||
|
||||
// Particle Group Calls
|
||||
|
||||
PARTICLEDLL_API void pCopyGroup(int p_src_group_num, int index = 0, int copy_count = P_MAXINT);
|
||||
|
||||
PARTICLEDLL_API void pCurrentGroup(int p_group_num);
|
||||
|
||||
PARTICLEDLL_API void pDeleteParticleGroups(int p_group_num, int p_group_count = 1);
|
||||
|
||||
PARTICLEDLL_API void pDrawGroupl(int dlist, bool const_size = false,
|
||||
bool const_color = false, bool const_rotation = false);
|
||||
|
||||
PARTICLEDLL_API void pDrawGroupp(int primitive, bool const_size = false,
|
||||
bool const_color = false);
|
||||
|
||||
PARTICLEDLL_API int pGenParticleGroups(int p_group_count = 1, int max_particles = 0);
|
||||
|
||||
PARTICLEDLL_API int pGetGroupCount();
|
||||
|
||||
PARTICLEDLL_API int pGetParticles(int index, int count, float *position = NULL, float *color = NULL,
|
||||
float *vel = NULL, float *size = NULL, float *age = NULL);
|
||||
|
||||
PARTICLEDLL_API int pSetMaxParticles(int max_count);
|
||||
|
||||
|
||||
// Actions
|
||||
|
||||
PARTICLEDLL_API void pAvoid(float magnitude, float epsilon, float look_ahead,
|
||||
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);
|
||||
|
||||
PARTICLEDLL_API void pBounce(float friction, float resilience, float cutoff,
|
||||
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);
|
||||
|
||||
PARTICLEDLL_API void pCopyVertexB(bool copy_pos = true, bool copy_vel = false);
|
||||
|
||||
PARTICLEDLL_API void pDamping(float damping_x, float damping_y, float damping_z,
|
||||
float vlow = 0.0f, float vhigh = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pExplosion(float center_x, float center_y, float center_z, float velocity,
|
||||
float magnitude, float stdev, float epsilon = P_EPS, float age = 0.0f);
|
||||
|
||||
PARTICLEDLL_API void pFollow(float magnitude = 1.0f, float epsilon = P_EPS, float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pGravitate(float magnitude = 1.0f, float epsilon = P_EPS, float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pGravity(float dir_x, float dir_y, float dir_z);
|
||||
|
||||
PARTICLEDLL_API void pJet(float center_x, float center_y, float center_z, float magnitude = 1.0f,
|
||||
float epsilon = P_EPS, float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pKillOld(float age_limit, bool kill_less_than = false);
|
||||
|
||||
PARTICLEDLL_API void pMatchVelocity(float magnitude = 1.0f, float epsilon = P_EPS,
|
||||
float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pMove();
|
||||
|
||||
PARTICLEDLL_API void pOrbitLine(float p_x, float p_y, float p_z,
|
||||
float axis_x, float axis_y, float axis_z, float magnitude = 1.0f,
|
||||
float epsilon = P_EPS, float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pOrbitPoint(float center_x, float center_y, float center_z,
|
||||
float magnitude = 1.0f, float epsilon = P_EPS,
|
||||
float max_radius = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pRandomAccel(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);
|
||||
|
||||
PARTICLEDLL_API void pRandomDisplace(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);
|
||||
|
||||
PARTICLEDLL_API void pRandomVelocity(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);
|
||||
|
||||
PARTICLEDLL_API void pRestore(float time);
|
||||
|
||||
PARTICLEDLL_API void pShade(float color_x, float color_y, float color_z,
|
||||
float alpha, float scale);
|
||||
|
||||
PARTICLEDLL_API void pSink(bool kill_inside, 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);
|
||||
|
||||
PARTICLEDLL_API void pSinkVelocity(bool kill_inside, 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);
|
||||
|
||||
PARTICLEDLL_API void pSource(float particle_rate, 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);
|
||||
|
||||
PARTICLEDLL_API void pSpeedLimit(float min_speed, float max_speed = P_MAXFLOAT);
|
||||
|
||||
PARTICLEDLL_API void pTargetColor(float color_x, float color_y, float color_z,
|
||||
float alpha, float scale);
|
||||
|
||||
PARTICLEDLL_API void pTargetSize(float size_x, float size_y, float size_z,
|
||||
float scale_x = 0.0f, float scale_y = 0.0f, float scale_z = 0.0f);
|
||||
|
||||
PARTICLEDLL_API void pTargetVelocity(float vel_x, float vel_y, float vel_z, float scale);
|
||||
|
||||
PARTICLEDLL_API void pVertex(float x, float y, float z);
|
||||
|
||||
PARTICLEDLL_API void pVortex(float center_x, float center_y, float center_z,
|
||||
float axis_x, float axis_y, float axis_z,
|
||||
float magnitude = 1.0f, float epsilon = P_EPS,
|
||||
float max_radius = P_MAXFLOAT);
|
||||
|
||||
#endif
|
883
main/source/particle/system.cpp
Normal file
883
main/source/particle/system.cpp
Normal file
|
@ -0,0 +1,883 @@
|
|||
// system.cpp
|
||||
//
|
||||
// Copyright 1998 by David K. McAllister.
|
||||
//
|
||||
// This file implements the API calls that are not particle actions.
|
||||
|
||||
#include "general.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
// XXX
|
||||
#include <iostream>
|
||||
// using namespace std;
|
||||
|
||||
// For Windows DLL.
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
float ParticleAction::dt;
|
||||
|
||||
ParticleGroup **_ParticleState::group_list;
|
||||
PAHeader **_ParticleState::alist_list;
|
||||
int _ParticleState::group_count;
|
||||
int _ParticleState::alist_count;
|
||||
|
||||
// This AutoCall struct allows for static initialization of the above shared variables.
|
||||
struct AutoCall
|
||||
{
|
||||
AutoCall();
|
||||
};
|
||||
|
||||
AutoCall::AutoCall()
|
||||
{
|
||||
// The list of groups, etc.
|
||||
_ParticleState::group_list = new ParticleGroup *[16];
|
||||
_ParticleState::group_count = 16;
|
||||
_ParticleState::alist_list = new PAHeader *[16];
|
||||
_ParticleState::alist_count = 16;
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
_ParticleState::group_list[i] = NULL;
|
||||
_ParticleState::alist_list[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PARTICLE_MP
|
||||
// This code is defined if we are compiling the library to be used on
|
||||
// multiple threads. We need to have each API call figure out which
|
||||
// _ParticleState belongs to it. We hash pointers to contexts in
|
||||
// _CtxHash. Whenever a TID is asked for but doesn't exist we create
|
||||
// it.
|
||||
|
||||
#include <mpc.h>
|
||||
|
||||
// XXX This hard limit should get fixed.
|
||||
int _CtxCount = 151;
|
||||
_ParticleState **_CtxHash = NULL;
|
||||
|
||||
inline int _HashTID(int tid)
|
||||
{
|
||||
return ((tid << 13) ^ ((tid >> 11) ^ tid)) % _CtxCount;
|
||||
}
|
||||
|
||||
// Returns a reference to the appropriate particle state.
|
||||
_ParticleState &_GetPStateWithTID()
|
||||
{
|
||||
int tid = mp_my_threadnum();
|
||||
|
||||
int ind = _HashTID(tid);
|
||||
|
||||
// cerr << tid << "->" << ind << endl;
|
||||
|
||||
// Check through the hash table and find it.
|
||||
for(int i=ind; i<_CtxCount; i++)
|
||||
if(_CtxHash[i] && _CtxHash[i]->tid == tid)
|
||||
{
|
||||
//#pragma critical
|
||||
//cerr << tid << " => " << i << endl;
|
||||
|
||||
return *_CtxHash[i];
|
||||
}
|
||||
|
||||
for(i=0; i<ind; i++)
|
||||
if(_CtxHash[i] && _CtxHash[i]->tid == tid)
|
||||
return *_CtxHash[i];
|
||||
|
||||
// It didn't exist. It's a new context, so create it.
|
||||
_ParticleState *psp = new _ParticleState();
|
||||
psp->tid = tid;
|
||||
|
||||
// Find a place to put it.
|
||||
for(i=ind; i<_CtxCount; i++)
|
||||
if(_CtxHash[i] == NULL)
|
||||
{
|
||||
// #pragma critical
|
||||
// cerr << "Stored " << tid << " at " << i << endl;
|
||||
_CtxHash[i] = psp;
|
||||
return *psp;
|
||||
}
|
||||
|
||||
for(i=0; i<ind; i++)
|
||||
if(_CtxHash[i] == NULL)
|
||||
{
|
||||
_CtxHash[i] = psp;
|
||||
return *psp;
|
||||
}
|
||||
|
||||
// We should never get here. The hash table got full.
|
||||
exit(1);
|
||||
|
||||
// To appease warnings.
|
||||
return *_CtxHash[0];
|
||||
}
|
||||
|
||||
inline void _PLock()
|
||||
{
|
||||
// XXX This implementation is specific to the #pragma parallel directives.
|
||||
// cerr << "Getting lock.\n";
|
||||
// mp_setlock();
|
||||
// cerr << "Got lock.\n";
|
||||
}
|
||||
|
||||
inline void _PUnLock()
|
||||
{
|
||||
// XXX This implementation is specific to the #pragma parallel directives.
|
||||
// cerr << "Giving lock.\n";
|
||||
// mp_unsetlock();
|
||||
// cerr << "Gave lock.\n";
|
||||
}
|
||||
|
||||
#else
|
||||
// This is the global state.
|
||||
_ParticleState __ps;
|
||||
|
||||
inline void _PLock()
|
||||
{
|
||||
}
|
||||
|
||||
inline void _PUnLock()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
_ParticleState::_ParticleState()
|
||||
{
|
||||
in_call_list = false;
|
||||
in_new_list = false;
|
||||
vertexB_tracks = true;
|
||||
|
||||
dt = 1.0f;
|
||||
|
||||
group_id = -1;
|
||||
list_id = -1;
|
||||
pgrp = NULL;
|
||||
pact = NULL;
|
||||
tid = 0; // This will be filled in above if we're MP.
|
||||
|
||||
Size = pDomain(PDPoint, 1.0f, 1.0f, 1.0f);
|
||||
Vel = pDomain(PDPoint, 0.0f, 0.0f, 0.0f);
|
||||
VertexB = pDomain(PDPoint, 0.0f, 0.0f, 0.0f);
|
||||
Color = pDomain(PDPoint, 1.0f, 1.0f, 1.0f);
|
||||
Alpha = 1.0f;
|
||||
Age = 0.0f;
|
||||
AgeSigma = 0.0f;
|
||||
}
|
||||
|
||||
ParticleGroup *_ParticleState::GetGroupPtr(int p_group_num)
|
||||
{
|
||||
if(p_group_num < 0)
|
||||
return NULL; // IERROR
|
||||
|
||||
if(p_group_num >= group_count)
|
||||
return NULL; // IERROR
|
||||
|
||||
return group_list[p_group_num];
|
||||
}
|
||||
|
||||
PAHeader *_ParticleState::GetListPtr(int a_list_num)
|
||||
{
|
||||
if(a_list_num < 0)
|
||||
return NULL; // IERROR
|
||||
|
||||
if(a_list_num >= alist_count)
|
||||
return NULL; // IERROR
|
||||
|
||||
return alist_list[a_list_num];
|
||||
}
|
||||
|
||||
// Return an index into the list of particle groups where
|
||||
// p_group_count groups can be added.
|
||||
int _ParticleState::GenerateGroups(int p_group_count)
|
||||
{
|
||||
int num_empty = 0;
|
||||
int first_empty = -1;
|
||||
|
||||
for(int i=0; i<group_count; i++)
|
||||
{
|
||||
if(group_list[i])
|
||||
{
|
||||
num_empty = 0;
|
||||
first_empty = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(first_empty < 0)
|
||||
first_empty = i;
|
||||
num_empty++;
|
||||
if(num_empty >= p_group_count)
|
||||
return first_empty;
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a big enough gap. Reallocate.
|
||||
int new_count = 16 + group_count + p_group_count;
|
||||
ParticleGroup **glist = new ParticleGroup *[new_count];
|
||||
memcpy(glist, group_list, group_count * sizeof(void*));
|
||||
for(int i=group_count; i<new_count; i++)
|
||||
glist[i] = NULL;
|
||||
delete [] group_list;
|
||||
group_list = glist;
|
||||
group_count = new_count;
|
||||
|
||||
return GenerateGroups(p_group_count);
|
||||
}
|
||||
|
||||
// Return an index into the list of action lists where
|
||||
// list_count lists can be added.
|
||||
int _ParticleState::GenerateLists(int list_count)
|
||||
{
|
||||
int num_empty = 0;
|
||||
int first_empty = -1;
|
||||
|
||||
for(int i=0; i<alist_count; i++)
|
||||
{
|
||||
if(alist_list[i])
|
||||
{
|
||||
num_empty = 0;
|
||||
first_empty = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(first_empty < 0)
|
||||
first_empty = i;
|
||||
num_empty++;
|
||||
if(num_empty >= list_count)
|
||||
return first_empty;
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a big enough gap. Reallocate.
|
||||
int new_count = 16 + alist_count + list_count;
|
||||
PAHeader **new_list = new PAHeader *[new_count];
|
||||
memcpy(new_list, alist_list, alist_count * sizeof(void*));
|
||||
for(int i=list_count; i<new_count; i++)
|
||||
new_list[i] = NULL;
|
||||
delete [] alist_list;
|
||||
alist_list = new_list;
|
||||
alist_count = new_count;
|
||||
|
||||
return GenerateLists(list_count);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Auxiliary calls
|
||||
void _pCallActionList(ParticleAction *apa, int num_actions,
|
||||
ParticleGroup *pg)
|
||||
{
|
||||
// All these require a particle group, so check for it.
|
||||
if(pg == NULL)
|
||||
return;
|
||||
|
||||
PAHeader *pa = (PAHeader *)apa;
|
||||
|
||||
// Step through all the actions in the action list.
|
||||
for(int action = 0; action < num_actions; action++, pa++)
|
||||
{
|
||||
switch(pa->type)
|
||||
{
|
||||
case PAAvoidID:
|
||||
((PAAvoid *)pa)->Execute(pg);
|
||||
break;
|
||||
case PABounceID:
|
||||
((PABounce *)pa)->Execute(pg);
|
||||
break;
|
||||
case PACallActionListID:
|
||||
((PACallActionList *)pa)->Execute(pg);
|
||||
break;
|
||||
case PACopyVertexBID:
|
||||
((PACopyVertexB *)pa)->Execute(pg);
|
||||
break;
|
||||
case PADampingID:
|
||||
((PADamping *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAExplosionID:
|
||||
((PAExplosion *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAFollowID:
|
||||
((PAFollow *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAGravitateID:
|
||||
((PAGravitate *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAGravityID:
|
||||
((PAGravity *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAJetID:
|
||||
((PAJet *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAKillOldID:
|
||||
((PAKillOld *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAMatchVelocityID:
|
||||
((PAMatchVelocity *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAMoveID:
|
||||
((PAMove *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAOrbitLineID:
|
||||
((PAOrbitLine *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAOrbitPointID:
|
||||
((PAOrbitPoint *)pa)->Execute(pg);
|
||||
break;
|
||||
case PARandomAccelID:
|
||||
((PARandomAccel *)pa)->Execute(pg);
|
||||
break;
|
||||
case PARandomDisplaceID:
|
||||
((PARandomDisplace *)pa)->Execute(pg);
|
||||
break;
|
||||
case PARandomVelocityID:
|
||||
((PARandomVelocity *)pa)->Execute(pg);
|
||||
break;
|
||||
case PARestoreID:
|
||||
((PARestore *)pa)->Execute(pg);
|
||||
break;
|
||||
case PASinkID:
|
||||
((PASink *)pa)->Execute(pg);
|
||||
break;
|
||||
case PASinkVelocityID:
|
||||
((PASinkVelocity *)pa)->Execute(pg);
|
||||
break;
|
||||
case PASourceID:
|
||||
((PASource *)pa)->Execute(pg);
|
||||
break;
|
||||
case PASpeedLimitID:
|
||||
((PASpeedLimit *)pa)->Execute(pg);
|
||||
break;
|
||||
case PATargetColorID:
|
||||
((PATargetColor *)pa)->Execute(pg);
|
||||
break;
|
||||
case PATargetSizeID:
|
||||
((PATargetSize *)pa)->Execute(pg);
|
||||
break;
|
||||
case PATargetVelocityID:
|
||||
((PATargetVelocity *)pa)->Execute(pg);
|
||||
break;
|
||||
case PAVortexID:
|
||||
((PAVortex *)pa)->Execute(pg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the incoming action to the end of the current action list.
|
||||
void _pAddActionToList(ParticleAction *S, int size)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(!_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
if(_ps.pact == NULL)
|
||||
return; // ERROR
|
||||
|
||||
if(_ps.list_id < 0)
|
||||
return; // ERROR
|
||||
|
||||
PAHeader *alist = _ps.pact;
|
||||
|
||||
if(alist->actions_allocated <= alist->count)
|
||||
{
|
||||
// Must reallocate.
|
||||
int new_alloc = 16 + alist->actions_allocated;
|
||||
PAHeader *new_alist = new PAHeader[new_alloc];
|
||||
memcpy(new_alist, alist, alist->count * sizeof(PAHeader));
|
||||
|
||||
delete [] alist;
|
||||
_ps.alist_list[_ps.list_id] = _ps.pact = alist = new_alist;
|
||||
|
||||
alist->actions_allocated = new_alloc;
|
||||
}
|
||||
|
||||
// Now add it in.
|
||||
memcpy(&alist[alist->count], S, size);
|
||||
alist->count++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// State setting calls
|
||||
|
||||
PARTICLEDLL_API void pColor(float red, float green, float blue, float alpha)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Alpha = alpha;
|
||||
_ps.Color = pDomain(PDPoint, red, green, blue);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pColorD(float alpha, PDomainEnum dtype,
|
||||
float a0, float a1, float a2,
|
||||
float a3, float a4, float a5,
|
||||
float a6, float a7, float a8)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Alpha = alpha;
|
||||
_ps.Color = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pVelocity(float x, float y, float z)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Vel = pDomain(PDPoint, x, y, z);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pVelocityD(PDomainEnum dtype,
|
||||
float a0, float a1, float a2,
|
||||
float a3, float a4, float a5,
|
||||
float a6, float a7, float a8)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Vel = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pVertexB(float x, float y, float z)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.VertexB = pDomain(PDPoint, x, y, z);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pVertexBD(PDomainEnum dtype,
|
||||
float a0, float a1, float a2,
|
||||
float a3, float a4, float a5,
|
||||
float a6, float a7, float a8)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.VertexB = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
|
||||
|
||||
PARTICLEDLL_API void pVertexBTracks(bool trackVertex)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.vertexB_tracks = trackVertex;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pSize(float size_x, float size_y, float size_z)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Size = pDomain(PDPoint, size_x, size_y, size_z);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pSizeD(PDomainEnum dtype,
|
||||
float a0, float a1, float a2,
|
||||
float a3, float a4, float a5,
|
||||
float a6, float a7, float a8)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Size = pDomain(dtype, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pStartingAge(float age, float sigma)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.Age = age;
|
||||
_ps.AgeSigma = sigma;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pTimeStep(float newDT)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
_ps.dt = newDT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Action List Calls
|
||||
|
||||
PARTICLEDLL_API int pGenActionLists(int action_list_count)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return -1; // ERROR
|
||||
|
||||
_PLock();
|
||||
|
||||
int ind = _ps.GenerateLists(action_list_count);
|
||||
|
||||
for(int i=ind; i<ind+action_list_count; i++)
|
||||
{
|
||||
_ps.alist_list[i] = new PAHeader[8];
|
||||
_ps.alist_list[i]->actions_allocated = 8;
|
||||
_ps.alist_list[i]->type = PAHeaderID;
|
||||
_ps.alist_list[i]->count = 1;
|
||||
}
|
||||
|
||||
_PUnLock();
|
||||
|
||||
return ind;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pNewActionList(int action_list_num)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
_ps.pact = _ps.GetListPtr(action_list_num);
|
||||
|
||||
if(_ps.pact == NULL)
|
||||
return; // ERROR
|
||||
|
||||
_ps.list_id = action_list_num;
|
||||
_ps.in_new_list = true;
|
||||
|
||||
// Remove whatever used to be in the list.
|
||||
_ps.pact->count = 1;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pEndActionList()
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(!_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
_ps.in_new_list = false;
|
||||
|
||||
_ps.pact = NULL;
|
||||
_ps.list_id = -1;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pDeleteActionLists(int action_list_num, int action_list_count)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
if(action_list_num < 0)
|
||||
return; // ERROR
|
||||
|
||||
if(action_list_num + action_list_count > _ps.alist_count)
|
||||
return; // ERROR
|
||||
|
||||
_PLock();
|
||||
|
||||
for(int i = action_list_num; i < action_list_num + action_list_count; i++)
|
||||
{
|
||||
if(_ps.alist_list[i])
|
||||
{
|
||||
delete [] _ps.alist_list[i];
|
||||
_ps.alist_list[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_PUnLock();
|
||||
return; // ERROR
|
||||
}
|
||||
}
|
||||
|
||||
_PUnLock();
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pCallActionList(int action_list_num)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
{
|
||||
// Add this call as an action to the current list.
|
||||
extern void _pSendAction(ParticleAction *S, PActionEnum type, int size);
|
||||
|
||||
PACallActionList S;
|
||||
S.action_list_num = action_list_num;
|
||||
|
||||
_pSendAction(&S, PACallActionListID, sizeof(PACallActionList));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Execute the specified action list.
|
||||
PAHeader *pa = _ps.GetListPtr(action_list_num);
|
||||
|
||||
if(pa == NULL)
|
||||
return; // ERRROR
|
||||
|
||||
// XXX A temporary hack.
|
||||
pa->dt = _ps.dt;
|
||||
|
||||
_ps.in_call_list = true;
|
||||
|
||||
_pCallActionList(pa+1, pa->count-1, _ps.pgrp);
|
||||
|
||||
_ps.in_call_list = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Particle Group Calls
|
||||
|
||||
// Create particle groups, each with max_particles allocated.
|
||||
PARTICLEDLL_API int pGenParticleGroups(int p_group_count, int max_particles)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return -1; // ERROR
|
||||
|
||||
_PLock();
|
||||
// cerr << "Generating pg " << _ps.tid << " cnt= " << max_particles << endl;
|
||||
|
||||
int ind = _ps.GenerateGroups(p_group_count);
|
||||
|
||||
for(int i=ind; i<ind+p_group_count; i++)
|
||||
{
|
||||
_ps.group_list[i] = (ParticleGroup *)new
|
||||
Particle[max_particles + 2];
|
||||
_ps.group_list[i]->max_particles = max_particles;
|
||||
_ps.group_list[i]->particles_allocated = max_particles;
|
||||
_ps.group_list[i]->p_count = 0;
|
||||
}
|
||||
|
||||
_PUnLock();
|
||||
|
||||
return ind;
|
||||
}
|
||||
|
||||
PARTICLEDLL_API void pDeleteParticleGroups(int p_group_num, int p_group_count)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(p_group_num < 0)
|
||||
return; // ERROR
|
||||
|
||||
if(p_group_num + p_group_count > _ps.group_count)
|
||||
return; // ERROR
|
||||
|
||||
_PLock();
|
||||
|
||||
for(int i = p_group_num; i < p_group_num + p_group_count; i++)
|
||||
{
|
||||
if(_ps.group_list[i])
|
||||
{
|
||||
delete [] _ps.group_list[i];
|
||||
_ps.group_list[i] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_PUnLock();
|
||||
return; // ERROR
|
||||
}
|
||||
}
|
||||
|
||||
_PUnLock();
|
||||
}
|
||||
|
||||
// Change which group is current.
|
||||
PARTICLEDLL_API void pCurrentGroup(int p_group_num)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
_ps.pgrp = _ps.GetGroupPtr(p_group_num);
|
||||
if(_ps.pgrp)
|
||||
_ps.group_id = p_group_num;
|
||||
else
|
||||
_ps.group_id = -1;
|
||||
}
|
||||
|
||||
// Change the maximum number of particles in the current group.
|
||||
PARTICLEDLL_API int pSetMaxParticles(int max_count)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return 0; // ERROR
|
||||
|
||||
ParticleGroup *pg = _ps.pgrp;
|
||||
if(pg == NULL)
|
||||
return 0; // ERROR
|
||||
|
||||
if(max_count < 0)
|
||||
return 0; // ERROR
|
||||
|
||||
// Reducing max.
|
||||
if(pg->particles_allocated >= max_count)
|
||||
{
|
||||
pg->max_particles = max_count;
|
||||
|
||||
// May have to kill particles.
|
||||
if(pg->p_count > pg->max_particles)
|
||||
pg->p_count = pg->max_particles;
|
||||
|
||||
return max_count;
|
||||
}
|
||||
|
||||
_PLock();
|
||||
|
||||
// Allocate particles.
|
||||
ParticleGroup *pg2 =(ParticleGroup *)new Particle[max_count + 2];
|
||||
if(pg2 == NULL)
|
||||
{
|
||||
// Not enough memory. Just give all we've got.
|
||||
// ERROR
|
||||
pg->max_particles = pg->particles_allocated;
|
||||
|
||||
_PUnLock();
|
||||
|
||||
return pg->max_particles;
|
||||
}
|
||||
|
||||
memcpy(pg2, pg, (pg->p_count + 2) * sizeof(Particle));
|
||||
|
||||
delete [] pg;
|
||||
|
||||
_ps.group_list[_ps.group_id] = _ps.pgrp = pg2;
|
||||
pg2->max_particles = max_count;
|
||||
pg2->particles_allocated = max_count;
|
||||
|
||||
_PUnLock();
|
||||
|
||||
return max_count;
|
||||
}
|
||||
|
||||
// Copy from the specified group to the current group.
|
||||
PARTICLEDLL_API void pCopyGroup(int p_src_group_num, int index, int copy_count)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return; // ERROR
|
||||
|
||||
ParticleGroup *srcgrp = _ps.GetGroupPtr(p_src_group_num);
|
||||
if(srcgrp == NULL)
|
||||
return; // ERROR
|
||||
|
||||
ParticleGroup *destgrp = _ps.pgrp;
|
||||
if(destgrp == NULL)
|
||||
return; // ERROR
|
||||
|
||||
// Find out exactly how many to copy.
|
||||
int ccount = copy_count;
|
||||
if(ccount > srcgrp->p_count - index)
|
||||
ccount = srcgrp->p_count - index;
|
||||
if(ccount > destgrp->max_particles - destgrp->p_count)
|
||||
ccount = destgrp->max_particles - destgrp->p_count;
|
||||
|
||||
// #pragma critical
|
||||
// cerr << p_src_group_num << ": " << ccount << " " << srcgrp->p_count << " " << index << endl;
|
||||
|
||||
if(ccount<0)
|
||||
ccount = 0;
|
||||
|
||||
// Directly copy the particles to the current list.
|
||||
for(int i=0; i<ccount; i++)
|
||||
{
|
||||
destgrp->list[destgrp->p_count+i] =
|
||||
srcgrp->list[index+i];
|
||||
}
|
||||
destgrp->p_count += ccount;
|
||||
}
|
||||
|
||||
// Copy from the current group to application memory.
|
||||
PARTICLEDLL_API int pGetParticles(int index, int count, float *verts,
|
||||
float *color, float *vel, float *size, float *age)
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
// XXX I should think about whether color means color3, color4, or what.
|
||||
// For now, it means color4.
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return -1; // ERROR
|
||||
|
||||
ParticleGroup *pg = _ps.pgrp;
|
||||
if(pg == NULL)
|
||||
return -2; // ERROR
|
||||
|
||||
if(index < 0 || count < 0)
|
||||
return -3; // ERROR
|
||||
|
||||
if(index + count > pg->p_count)
|
||||
{
|
||||
count = pg->p_count - index;
|
||||
if(count <= 0)
|
||||
return -4; // ERROR index out of bounds.
|
||||
}
|
||||
|
||||
int vi = 0, ci = 0, li = 0, si = 0, ai = 0;
|
||||
|
||||
// This could be optimized.
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
Particle &m = pg->list[index + i];
|
||||
|
||||
if(verts)
|
||||
{
|
||||
verts[vi++] = m.pos.x;
|
||||
verts[vi++] = m.pos.y;
|
||||
verts[vi++] = m.pos.z;
|
||||
}
|
||||
|
||||
if(color)
|
||||
{
|
||||
color[ci++] = m.color.x;
|
||||
color[ci++] = m.color.y;
|
||||
color[ci++] = m.color.z;
|
||||
color[ci++] = m.alpha;
|
||||
}
|
||||
|
||||
if(vel)
|
||||
{
|
||||
vel[li++] = m.vel.x;
|
||||
vel[li++] = m.vel.y;
|
||||
vel[li++] = m.vel.z;
|
||||
}
|
||||
|
||||
if(size)
|
||||
{
|
||||
size[si++] = m.size.x;
|
||||
size[si++] = m.size.y;
|
||||
size[si++] = m.size.z;
|
||||
}
|
||||
|
||||
if(age)
|
||||
{
|
||||
age[ai++] = m.age;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Returns the number of particles currently in the group.
|
||||
PARTICLEDLL_API int pGetGroupCount()
|
||||
{
|
||||
_ParticleState &_ps = _GetPState();
|
||||
|
||||
if(_ps.in_new_list)
|
||||
return 0; // ERROR
|
||||
|
||||
if(_ps.pgrp == NULL)
|
||||
return 0; // ERROR
|
||||
|
||||
return _ps.pgrp->p_count;
|
||||
}
|
|
@ -9,6 +9,8 @@
|
|||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "Balance.h"
|
||||
|
||||
using std::auto_ptr;
|
||||
|
@ -1054,4 +1056,4 @@ bool FileValueContainer::save(void)
|
|||
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define C_STRING_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using std::string;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#ifndef STL_UTIL_H
|
||||
#define STL_UTIL_H
|
||||
|
||||
#include <string.h>
|
||||
#include "util/nowarnings.h"
|
||||
#include "util/CString.h"
|
||||
#include "types.h"
|
||||
|
@ -53,4 +54,4 @@ bool MakeHexPairsFromBytes(const unsigned char* inBytes, string& ioHex, int numB
|
|||
|
||||
extern int32 sprintf(string& inOutput, const char* inPattern, ...);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue