File: particle.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (177 lines) | stat: -rw-r--r-- 7,049 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * Copyright (C) Volition, Inc. 1999.  All rights reserved.
 *
 * All source code herein is the property of Volition, Inc. You may not sell 
 * or otherwise commercially exploit the source or things you created based on the 
 * source.
 *
*/



#ifndef _PARTICLE_H
#define _PARTICLE_H

#include "globalincs/pstypes.h"
#include "object/object.h"

#include <memory>

extern bool Randomize_particle_rotation;

namespace particle
{
	//============================================================================
	//==================== PARTICLE SYSTEM GAME SEQUENCING CODE ==================
	//============================================================================

	// Resets particle system.  Call between levels.
	void init();

	// called at game exit to cleanup any used resources
	void close();

	// Moves the particles for each frame
	void move_all(float frametime);

	// Renders all the particles
	void render_all();

	// kill all active particles
	void kill_all();


	//============================================================================
	//=============== LOW-LEVEL SINGLE PARTICLE CREATION CODE ====================
	//============================================================================

	/**
	 * The different types of particles
	 */
	enum ParticleType
	{
		PARTICLE_DEBUG, //!< A simple sphere; optional data provides the color which defaults to red
		PARTICLE_BITMAP, //!< A bitmap, optional data is the bitmap number.  If bitmap is an animation, lifetime is calculated by the number of frames and fps.
		PARTICLE_FIRE, //!< The vclip used for explosions, optional means nothing
		PARTICLE_SMOKE, //!< The vclip used for smoke, optional means nothing
		PARTICLE_SMOKE2, //!< The vclip used for smoke, optional means nothing
		PARTICLE_BITMAP_PERSISTENT, //!< A bitmap, optional data is the bitmap number.  If bitmap is an animation, lifetime is calculated by the number of frames and fps.

		NUM_PARTICLE_TYPES,
		INVALID_TYPE
	};

	// particle creation stuff
	typedef struct particle_info {
		// old-style particle info
		vec3d pos = vmd_zero_vector;
		vec3d vel = vmd_zero_vector;
		float lifetime = -1.0f;
		float rad = -1.0f;
		ParticleType type = INVALID_TYPE;
		int optional_data = -1;

		// new-style particle info
		int attached_objnum = -1;				// if these are set, the pos is relative to the pos of the origin of the attached object
		int attached_sig = -1;					// to make sure the object hasn't changed or died. velocity is ignored in this case
		bool reverse = false;					// play any animations in reverse
		bool lifetime_from_animation = true;	// if the particle plays an animation then use the anim length for the particle life
		float length = 0.f;						// if set, makes the particle render like a laser, oriented along its path
		bool use_angle = Randomize_particle_rotation;	// whether particles created from this will use angles (i.e. can be rotated)
														// (the field is initialized to the game_settings variable here because not all particle creation goes through ParticleProperties::createParticle)
		int size_lifetime_curve = -1;			// a curve idx for size over lifetime, if applicable
		int vel_lifetime_curve = -1;			// a curve idx for velocity over lifetime, if applicable
	} particle_info;

	typedef struct particle {
		// old style data
		vec3d	pos;				// position
		vec3d	velocity;			// velocity
		float	age;				// How long it's been alive
		float	max_life;			// How much life we had
		bool    looping;            // If the particle will loop its animation at the end of its life instead of expiring
		float	radius;				// radius
		int		type;				// type										// -1 = None
		int		optional_data;		// depends on type
		int		nframes;			// If an ani, how many frames?	

		// new style data
		int		attached_objnum;	// if this is set, pos is relative to the attached object. velocity is ignored
		int		attached_sig;		// to check for dead/nonexistent objects
		bool	reverse;			// play any animations in reverse
		float   length;				// the length of the particle for laser-style rendering
		float	angle;
		bool	use_angle;			// whether this particle can be rotated
		int		size_lifetime_curve;// a curve idx for size over lifetime, if applicable
		int		vel_lifetime_curve;		// a curve idx for velocity over lifetime, if applicable
	} particle;

	typedef std::weak_ptr<particle> WeakParticlePtr;
	typedef std::shared_ptr<particle> ParticlePtr;

	/**
	 * @brief Creates a non-persistent particle
	 *
	 * A non-persistent particle will be managed more efficiently than a persistent particle but it will not be possible
	 * to keep a reference to the particle. This should be used whenever the a particle handle is not required (which
	 * should be the case for most usages).
	 *
	 * @param pinfo A structure containg information about how the particle should be created
	 */
	void create(particle_info* pinfo);

	/**
	 * @brief Convenience function for creating a non-persistent particle without explicitly creating a particle_info
	 * structure.
	 * @return The particle handle
	 *
	 * @see particle::create(particle_info* pinfo)
	 */
	void create(vec3d* pos,
				vec3d* vel,
				float lifetime,
				float rad,
				ParticleType type,
				int optional_data = -1,
				object* objp = NULL,
				bool reverse = false);

	/**
	 * @brief Creates a persistent particle
	 *
	 * A persistent particle is handled differently from a standard particle. It is possible to hold a weak or strong
	 * reference to a persistent particle which allows to track where the particle is and also allows to change particle
	 * properties after it has been created.
	 *
	 * @param pinfo A structure containg information about how the particle should be created
	 * @return A weak reference to the particle
	 */
    WeakParticlePtr createPersistent(particle_info* pinfo);

	//============================================================================
	//============== HIGH-LEVEL PARTICLE SYSTEM CREATION CODE ====================
	//============================================================================

	// Use a structure rather than pass a ton of parameters to particle_emit
	typedef struct particle_emitter {
		int		num_low;			// Lowest number of particles to create
		int		num_high;			// Highest number of particles to create
		vec3d	pos;				// Where the particles emit from
		vec3d	vel;				// Initial velocity of all the particles
		float	min_life;			// How long the particles live
		float	max_life;			// How long the particles live
		vec3d	normal;				// What normal the particle emit arond
		float	normal_variance;	// How close they stick to that normal 0=good, 1=360 degree
		float	min_vel;			// How fast the slowest particle can move
		float	max_vel;			// How fast the fastest particle can move
		float	min_rad;			// Min radius
		float	max_rad;			// Max radius
	} particle_emitter;

	// Creates a bunch of particles. You pass a structure
	// rather than a bunch of parameters.
	void emit(particle_emitter *pe, ParticleType type, int optional_data, float range = 1.0);
}

#endif // _PARTICLE_H