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
|
/**
* @file llcloud.h
* @brief Description of viewer LLCloudLayer class
*
* Copyright (c) 2001-2007, Linden Research, Inc.
*
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
*/
#ifndef LL_LLCLOUD_H
#define LL_LLCLOUD_H
// Some ideas on how clouds should work
//
// Each region has a cloud layer
// Each cloud layer has pre-allocated space for N clouds
// The LLSky class knows the max number of clouds to render M.
// All clouds use the same texture, but the tex-coords can take on 8 configurations
// (four rotations, front and back)
//
// The sky's part
// --------------
// The sky knows that A clouds have been assigned to regions and there are B left over.
// Divide B by number of active regions to get C.
// Ask each region to add C more clouds and return total number D.
// Add up all the D's to get a new A.
//
// The cloud layer's part
// ----------------------
// The cloud layer is a grid of possibility. Each grid's value represents the probablility
// (0.0 to 1.0) that a cloud placement query will succeed.
//
// The sky asks the region to add C more clouds.
// The cloud layer tries a total of E times to place clouds and returns total cloud count.
//
// Clouds move according to local wind velocity.
// If a cloud moves out of region then it's location is sent to neighbor region
// or it is allowed to drift and decay.
//
// The clouds in non-visible regions do not propagate every frame.
// Each frame one non-visible region is allowed to propagate it's clouds
// (might have to check to see if incoming cloud was already visible or not).
//
//
#include "llmath.h"
//#include "vmath.h"
#include "v3math.h"
#include "v3dmath.h"
#include "v4math.h"
#include "v4color.h"
#include "llmemory.h"
#include "lldarray.h"
#include "llframetimer.h"
const U32 CLOUD_GRIDS_PER_EDGE = 16;
const F32 CLOUD_PUFF_WIDTH = 64.f;
const F32 CLOUD_PUFF_HEIGHT = 48.f;
class LLWind;
class LLVOClouds;
class LLViewerRegion;
class LLCloudLayer;
class LLBitPack;
class LLGroupHeader;
const S32 CLOUD_GROUPS_PER_EDGE = 4;
class LLCloudPuff
{
public:
LLCloudPuff();
const LLVector3d &getPositionGlobal() const { return mPositionGlobal; }
friend class LLCloudGroup;
void updatePuffs(const F32 dt);
void updatePuffOwnership();
F32 getAlpha() const { return mAlpha; }
U32 getLifeState() const { return mLifeState; }
void setLifeState(const U32 state) { mLifeState = state; }
BOOL isDead() const { return mAlpha <= 0.f; }
static S32 sPuffCount;
protected:
F32 mAlpha;
F32 mRate;
LLVector3d mPositionGlobal;
BOOL mLifeState;
};
class LLCloudGroup
{
public:
LLCloudGroup();
void cleanup();
void setCloudLayerp(LLCloudLayer *clp) { mCloudLayerp = clp; }
void setCenterRegion(const LLVector3 ¢er);
void updatePuffs(const F32 dt);
void updatePuffOwnership();
void updatePuffCount();
BOOL inGroup(const LLCloudPuff &puff) const;
F32 getDensity() const { return mDensity; }
S32 getNumPuffs() const { return mCloudPuffs.count(); }
const LLCloudPuff &getPuff(const S32 i) { return mCloudPuffs[i]; }
protected:
LLCloudLayer *mCloudLayerp;
LLVector3 mCenterRegion;
F32 mDensity;
S32 mTargetPuffCount;
LLDynamicArray<LLCloudPuff> mCloudPuffs;
LLPointer<LLVOClouds> mVOCloudsp;
};
class LLCloudLayer
{
public:
LLCloudLayer();
~LLCloudLayer();
void create(LLViewerRegion *regionp);
void destroy();
void reset(); // Clears all active cloud puffs
void updatePuffs(const F32 dt);
void updatePuffOwnership();
void updatePuffCount();
LLCloudGroup *findCloudGroup(const LLCloudPuff &puff);
void setRegion(LLViewerRegion *regionp);
LLViewerRegion* getRegion() const { return mRegionp; }
void setWindPointer(LLWind *windp);
void setOriginGlobal(const LLVector3d &origin_global) { mOriginGlobal = origin_global; }
void setWidth(F32 width);
void setBrightness(F32 brightness);
void setSunColor(const LLColor4 &color);
F32 getDensityRegion(const LLVector3 &pos_region); // "position" is in local coordinates
void renderDensityField();
void decompress(LLBitPack &bitpack, LLGroupHeader *group_header);
LLCloudLayer* getNeighbor(const S32 n) const { return mNeighbors[n]; }
void connectNeighbor(LLCloudLayer *cloudp, U32 direction);
void disconnectNeighbor(U32 direction);
void disconnectAllNeighbors();
public:
LLVector3d mOriginGlobal;
F32 mMetersPerEdge;
F32 mMetersPerGrid;
F32 mMaxAlpha; // The max cloud puff _render_ alpha
protected:
LLCloudLayer *mNeighbors[4];
LLWind *mWindp;
LLViewerRegion *mRegionp;
F32 *mDensityp; // the probability density grid
LLCloudGroup mCloudGroups[CLOUD_GROUPS_PER_EDGE][CLOUD_GROUPS_PER_EDGE];
};
#endif
|