summaryrefslogtreecommitdiff
path: root/indra/llmessage/partsyspacket.h
blob: 23307f3409ef4b064ce2f53b481d029f54d80493 (plain)
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/**
 * @file partsyspacket.h
 * @brief Object for packing particle system initialization parameters
 * before sending them over the network
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_PARTSYSPACKET_H
#define LL_PARTSYSPACKET_H

#include "lluuid.h"

// Particle system stuff

const U64 PART_SYS_MAX_TIME_IN_USEC = 1000000;  //  1 second, die not quite near instantaneously


// this struct is for particle system initialization parameters
// I'm breaking some rules here, but I need a storage structure to hold initialization data
//  for these things.  Sorry guys, they're not simple enough (yet) to avoid this cleanly
struct LLPartInitData {
    // please do not add functions to this class -- data only!
    //F32 k[18];     // first 9 --> x,y,z  last 9 --> scale, alpha, rot
    //F32 kill_p[6]; // last one is for particles that die when they reach a spherical bounding radius
    //F32 kill_plane[3];
    //F32 bounce_p[5];
    F32 bounce_b; // recently changed
    // no need to store orientation and position here, as they're sent over seperately
    //F32 pos_ranges[6];
    //F32 vel_ranges[6];
    F32 scale_range[4];
    F32 alpha_range[4];
    F32 vel_offset[3];  //new - more understandable!

    F32 mDistBeginFadeout; // for fadeout LOD optimization
    F32 mDistEndFadeout;

    LLUUID mImageUuid;
    //U8 n; // number of particles
    U8 mFlags[8]; // for miscellaneous data --> its interpretation can change at my whim!
    U8 createMe; // do I need to be created? or has the work allready been done?
    //ActionFlag is now mFlags[PART_SYS_ACTION_BYTE]
    //Spawn point is initially object creation center

    F32 diffEqAlpha[3];
    F32 diffEqScale[3];

    U8  maxParticles;
        //How many particles exist at any time within the system?
    U8  initialParticles;
        //How many particles exist when the system is created?
    F32 killPlaneZ;
        //For simplicity assume the XY plane, so this sets an altitude at which to die
    F32 killPlaneNormal[3];
        //Normal if not planar XY
    F32 bouncePlaneZ;
        //For simplicity assume the XY plane, so this sets an altitude at which to bounce
    F32 bouncePlaneNormal[3];
        //Normal if not planar XY
    F32 spawnRange;
        //Range of emission points about the mSpawnPoint
    F32 spawnFrequency;
        //Required if the system is to spawn new particles.
        //This variable determines the time after a particle dies when it is respawned.
    F32 spawnFreqencyRange;
        //Determines the random range of time until a new particle is spawned.
    F32 spawnDirection[3];
        //Direction vector giving the mean direction in which particles are spawned
    F32 spawnDirectionRange;
        //Direction limiting the angular range of emissions about the mean direction. 1.0f means everywhere, 0.0f means uni-directional
    F32 spawnVelocity;
        //The mean speed at which particles are emitted
    F32 spawnVelocityRange;
        //The range of speeds about the mean at which particles are emitted.
    F32 speedLimit;
        //Used to constrain particle maximum velocity
    F32 windWeight;
        //How much of an effect does wind have
    F32 currentGravity[3];
        //Gravity direction used in update calculations
    F32 gravityWeight;
        //How much of an effect does gravity have
    F32 globalLifetime;
        //If particles re-spawn, a system can exist forever.
        //If (ActionFlags & PART_SYS_GLOBAL_DIE) is true this variable is used to determine how long the system lasts.
    F32 individualLifetime;
        //How long does each particle last if nothing else happens to it
    F32 individualLifetimeRange;
        //Range of variation in individual lifetimes
    F32 alphaDecay;
        //By what factor does alpha decrease as the lifetime of a particle is approached.
    F32 scaleDecay;
        //By what factor does scale decrease as the lifetime of a particle is approached.
    F32 distanceDeath;
        //With the increased functionality, particle systems can expand to indefinite size
        //(e.g. wind can chaotically move particles into a wide spread).
        //To avoid particles exceeding normal object size constraints,
        //set the PART_SYS_DISTANCE_DEATH flag, and set a distance value here, representing a radius around the spawn point.
    F32 dampMotionFactor;
        //How much to damp motion
    F32 windDiffusionFactor[3];
        //Change the size and alpha of particles as wind speed increases (scale gets bigger, alpha smaller)
};

// constants for setting flag values
// BYTES are in range 0-8, bits are in range 2^0 - 2^8 and can only be powers of two
const int PART_SYS_NO_Z_BUFFER_BYTE = 0; // option to turn off z-buffer when rendering
const int PART_SYS_NO_Z_BUFFER_BIT = 2;  // particle systems --
// I advise against using this, as it looks bad in every case I've tried

const int PART_SYS_SLOW_ANIM_BYTE = 0; // slow animation down by a factor of 10
const int PART_SYS_SLOW_ANIM_BIT = 1;  // useful for tweaking anims during debugging

const int PART_SYS_FOLLOW_VEL_BYTE = 0; // indicates whether to orient sprites towards
const int PART_SYS_FOLLOW_VEL_BIT = 4;  // their velocity vector -- default is false

const int PART_SYS_IS_LIGHT_BYTE = 0;   // indicates whether a particular particle system
const int PART_SYS_IS_LIGHT_BIT = 8;    // is also a light object -- for andrew
// should deprecate this once there is a general method for setting light properties of objects

const int PART_SYS_SPAWN_COPY_BYTE = 0;   // indicates whether to spawn baby particle systems on
const int PART_SYS_SPAWN_COPY_BIT = 0x10; // particle death -- intended for smoke trails

const int PART_SYS_COPY_VEL_BYTE = 0; // indicates whether baby particle systems inherit parents vel
const int PART_SYS_COPY_VEL_BIT = 0x20; // (by default they don't)

const int PART_SYS_INVISIBLE_BYTE = 0; // optional -- turn off display, just simulate
const int PART_SYS_INVISIBLE_BIT = 0x40; // useful for smoke trails

const int PART_SYS_ADAPT_TO_FRAMERATE_BYTE = 0;    // drop sprites from render call proportionally
const int PART_SYS_ADAPT_TO_FRAMERATE_BIT = 0x80; // to how far we are below 60 fps


// 26 September 2001 - not even big enough to hold all changes, so should enlarge anyway
//const U16 MAX_PART_SYS_PACKET_SIZE = 180;
const U16 MAX_PART_SYS_PACKET_SIZE = 256;

//const U8 PART_SYS_K_MASK              = 0x01;
const U8 PART_SYS_KILL_P_MASK           = 0x02;
const U8 PART_SYS_BOUNCE_P_MASK         = 0x04;
const U8 PART_SYS_BOUNCE_B_MASK         = 0x08;
//const U8 PART_SYS_POS_RANGES_MASK     = 0x10;
//const U8 PART_SYS_VEL_RANGES_MASK     = 0x20;
const U8 PART_SYS_VEL_OFFSET_MASK       = 0x10; //re-use one of the original slots now commented out
const U8 PART_SYS_ALPHA_SCALE_DIFF_MASK = 0x20; //re-use one of the original slots now commented out
const U8 PART_SYS_SCALE_RANGE_MASK      = 0x40;
const U8 PART_SYS_M_IMAGE_UUID_MASK     = 0x80;
const U8 PART_SYS_BYTE_3_ALPHA_MASK     = 0x01; // wrapped around, didn't we?

const U8 PART_SYS_BYTE_SPAWN_MASK       = 0x01;
const U8 PART_SYS_BYTE_ENVIRONMENT_MASK = 0x02;
const U8 PART_SYS_BYTE_LIFESPAN_MASK    = 0x04;
const U8 PART_SYS_BYTE_DECAY_DAMP_MASK  = 0x08;
const U8 PART_SYS_BYTE_WIND_DIFF_MASK   = 0x10;


// 26 September 2001 - new constants for  mActionFlags
const int PART_SYS_ACTION_BYTE = 1;
const U8 PART_SYS_SPAWN                         = 0x01;
const U8 PART_SYS_BOUNCE                        = 0x02;
const U8 PART_SYS_AFFECTED_BY_WIND              = 0x04;
const U8 PART_SYS_AFFECTED_BY_GRAVITY           = 0x08;
const U8 PART_SYS_EVALUATE_WIND_PER_PARTICLE    = 0x10;
const U8 PART_SYS_DAMP_MOTION                   = 0x20;
const U8 PART_SYS_WIND_DIFFUSION                = 0x40;

// 26 September 2001 - new constants for  mKillFlags
const int PART_SYS_KILL_BYTE = 2;
const U8 PART_SYS_KILL_PLANE                    = 0x01;
const U8 PART_SYS_GLOBAL_DIE                    = 0x02;
const U8 PART_SYS_DISTANCE_DEATH                = 0x04;
const U8 PART_SYS_TIME_DEATH                    = 0x08;


// global, because the sim-side also calls it in the LLPartInitDataFactory


void gSetInitDataDefaults(LLPartInitData *setMe);

class LLPartSysCompressedPacket
{
public:
    LLPartSysCompressedPacket();
    ~LLPartSysCompressedPacket();
    bool    fromLLPartInitData(LLPartInitData *in, U32 &bytesUsed);
    bool    toLLPartInitData(LLPartInitData *out, U32 *bytesUsed);
    bool    fromUnsignedBytes(U8 *in, U32 bytesUsed);
    bool    toUnsignedBytes(U8 *out);
    U32     bufferSize();
    U8      *getBytePtr();

protected:
    U8 mData[MAX_PART_SYS_PACKET_SIZE];
    U32 mNumBytes;
    LLPartInitData mDefaults; //  this is intended to hold default LLPartInitData values
    //                            please do not modify it
    LLPartInitData mWorkingCopy; // uncompressed data I'm working with

protected:
    // private functions (used only to break up code)
    void    writeFlagByte(LLPartInitData *in);
    //U32       writeK(LLPartInitData *in, U32 startByte);
    U32     writeKill_p(LLPartInitData *in, U32 startByte);
    U32     writeBounce_p(LLPartInitData *in, U32 startByte);
    U32     writeBounce_b(LLPartInitData *in, U32 startByte);
    //U32       writePos_ranges(LLPartInitData *in, U32 startByte);
    //U32       writeVel_ranges(LLPartInitData *in, U32 startByte);
    U32     writeAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte);
    U32     writeScale_range(LLPartInitData *in, U32 startByte);
    U32     writeAlpha_range(LLPartInitData *in, U32 startByte);
    U32     writeUUID(LLPartInitData *in, U32 startByte);

    U32     writeVelocityOffset(LLPartInitData *in, U32 startByte);
    U32     writeSpawn(LLPartInitData *in, U32 startByte);  //all spawn data
    U32     writeEnvironment(LLPartInitData *in, U32 startByte);    //wind and gravity
    U32     writeLifespan(LLPartInitData *in, U32 startByte);   //lifespan data - individual and global
    U32     writeDecayDamp(LLPartInitData *in, U32 startByte);  //alpha and scale, and motion damp
    U32     writeWindDiffusionFactor(LLPartInitData *in, U32 startByte);


    //U32       readK(LLPartInitData *in, U32 startByte);
    U32     readKill_p(LLPartInitData *in, U32 startByte);
    U32     readBounce_p(LLPartInitData *in, U32 startByte);
    U32     readBounce_b(LLPartInitData *in, U32 startByte);
    //U32       readPos_ranges(LLPartInitData *in, U32 startByte);
    //U32       readVel_ranges(LLPartInitData *in, U32 startByte);
    U32     readAlphaScaleDiffEqn_range(LLPartInitData *in, U32 startByte);
    U32     readScale_range(LLPartInitData *in, U32 startByte);
    U32     readAlpha_range(LLPartInitData *in, U32 startByte);
    U32     readUUID(LLPartInitData *in, U32 startByte);

    U32     readVelocityOffset(LLPartInitData *in, U32 startByte);
    U32     readSpawn(LLPartInitData *in, U32 startByte);   //all spawn data
    U32     readEnvironment(LLPartInitData *in, U32 startByte); //wind and gravity
    U32     readLifespan(LLPartInitData *in, U32 startByte);    //lifespan data - individual and global
    U32     readDecayDamp(LLPartInitData *in, U32 startByte);   //alpha and scale, and motion damp
    U32     readWindDiffusionFactor(LLPartInitData *in, U32 startByte);
};

#endif