00001 00032 #ifndef LL_LLCLOUD_H 00033 #define LL_LLCLOUD_H 00034 00035 // Some ideas on how clouds should work 00036 // 00037 // Each region has a cloud layer 00038 // Each cloud layer has pre-allocated space for N clouds 00039 // The LLSky class knows the max number of clouds to render M. 00040 // All clouds use the same texture, but the tex-coords can take on 8 configurations 00041 // (four rotations, front and back) 00042 // 00043 // The sky's part 00044 // -------------- 00045 // The sky knows that A clouds have been assigned to regions and there are B left over. 00046 // Divide B by number of active regions to get C. 00047 // Ask each region to add C more clouds and return total number D. 00048 // Add up all the D's to get a new A. 00049 // 00050 // The cloud layer's part 00051 // ---------------------- 00052 // The cloud layer is a grid of possibility. Each grid's value represents the probablility 00053 // (0.0 to 1.0) that a cloud placement query will succeed. 00054 // 00055 // The sky asks the region to add C more clouds. 00056 // The cloud layer tries a total of E times to place clouds and returns total cloud count. 00057 // 00058 // Clouds move according to local wind velocity. 00059 // If a cloud moves out of region then it's location is sent to neighbor region 00060 // or it is allowed to drift and decay. 00061 // 00062 // The clouds in non-visible regions do not propagate every frame. 00063 // Each frame one non-visible region is allowed to propagate it's clouds 00064 // (might have to check to see if incoming cloud was already visible or not). 00065 // 00066 // 00067 00068 #include "llmath.h" 00069 //#include "vmath.h" 00070 #include "v3math.h" 00071 #include "v3dmath.h" 00072 #include "v4math.h" 00073 #include "v4color.h" 00074 #include "llmemory.h" 00075 #include "lldarray.h" 00076 00077 #include "llframetimer.h" 00078 00079 const U32 CLOUD_GRIDS_PER_EDGE = 16; 00080 00081 const F32 CLOUD_PUFF_WIDTH = 64.f; 00082 const F32 CLOUD_PUFF_HEIGHT = 48.f; 00083 00084 class LLWind; 00085 class LLVOClouds; 00086 class LLViewerRegion; 00087 class LLCloudLayer; 00088 class LLBitPack; 00089 class LLGroupHeader; 00090 00091 const S32 CLOUD_GROUPS_PER_EDGE = 4; 00092 00093 class LLCloudPuff 00094 { 00095 public: 00096 LLCloudPuff(); 00097 00098 const LLVector3d &getPositionGlobal() const { return mPositionGlobal; } 00099 friend class LLCloudGroup; 00100 00101 void updatePuffs(const F32 dt); 00102 void updatePuffOwnership(); 00103 00104 F32 getAlpha() const { return mAlpha; } 00105 U32 getLifeState() const { return mLifeState; } 00106 void setLifeState(const U32 state) { mLifeState = state; } 00107 BOOL isDead() const { return mAlpha <= 0.f; } 00108 00109 00110 static S32 sPuffCount; 00111 protected: 00112 F32 mAlpha; 00113 F32 mRate; 00114 LLVector3d mPositionGlobal; 00115 00116 BOOL mLifeState; 00117 }; 00118 00119 class LLCloudGroup 00120 { 00121 public: 00122 LLCloudGroup(); 00123 00124 void cleanup(); 00125 00126 void setCloudLayerp(LLCloudLayer *clp) { mCloudLayerp = clp; } 00127 void setCenterRegion(const LLVector3 ¢er); 00128 00129 void updatePuffs(const F32 dt); 00130 void updatePuffOwnership(); 00131 void updatePuffCount(); 00132 00133 BOOL inGroup(const LLCloudPuff &puff) const; 00134 00135 F32 getDensity() const { return mDensity; } 00136 S32 getNumPuffs() const { return (S32) mCloudPuffs.size(); } 00137 const LLCloudPuff &getPuff(const S32 i) { return mCloudPuffs[i]; } 00138 protected: 00139 LLCloudLayer *mCloudLayerp; 00140 LLVector3 mCenterRegion; 00141 F32 mDensity; 00142 S32 mTargetPuffCount; 00143 00144 std::vector<LLCloudPuff> mCloudPuffs; 00145 LLPointer<LLVOClouds> mVOCloudsp; 00146 }; 00147 00148 00149 class LLCloudLayer 00150 { 00151 public: 00152 LLCloudLayer(); 00153 ~LLCloudLayer(); 00154 00155 void create(LLViewerRegion *regionp); 00156 void destroy(); 00157 00158 void reset(); // Clears all active cloud puffs 00159 00160 00161 void updatePuffs(const F32 dt); 00162 void updatePuffOwnership(); 00163 void updatePuffCount(); 00164 00165 LLCloudGroup *findCloudGroup(const LLCloudPuff &puff); 00166 00167 void setRegion(LLViewerRegion *regionp); 00168 LLViewerRegion* getRegion() const { return mRegionp; } 00169 void setWindPointer(LLWind *windp); 00170 void setOriginGlobal(const LLVector3d &origin_global) { mOriginGlobal = origin_global; } 00171 void setWidth(F32 width); 00172 00173 void setBrightness(F32 brightness); 00174 void setSunColor(const LLColor4 &color); 00175 00176 F32 getDensityRegion(const LLVector3 &pos_region); // "position" is in local coordinates 00177 00178 void renderDensityField(); 00179 void decompress(LLBitPack &bitpack, LLGroupHeader *group_header); 00180 00181 LLCloudLayer* getNeighbor(const S32 n) const { return mNeighbors[n]; } 00182 00183 void connectNeighbor(LLCloudLayer *cloudp, U32 direction); 00184 void disconnectNeighbor(U32 direction); 00185 void disconnectAllNeighbors(); 00186 00187 public: 00188 LLVector3d mOriginGlobal; 00189 F32 mMetersPerEdge; 00190 F32 mMetersPerGrid; 00191 00192 00193 F32 mMaxAlpha; // The max cloud puff _render_ alpha 00194 00195 protected: 00196 LLCloudLayer *mNeighbors[4]; 00197 LLWind *mWindp; 00198 LLViewerRegion *mRegionp; 00199 F32 *mDensityp; // the probability density grid 00200 00201 LLCloudGroup mCloudGroups[CLOUD_GROUPS_PER_EDGE][CLOUD_GROUPS_PER_EDGE]; 00202 }; 00203 00204 00205 #endif