00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llvoclouds.h"
00035
00036 #include "lldrawpoolalpha.h"
00037
00038 #include "llviewercontrol.h"
00039
00040 #include "llagent.h"
00041 #include "lldrawable.h"
00042 #include "llface.h"
00043 #include "llprimitive.h"
00044 #include "llsky.h"
00045 #include "llviewercamera.h"
00046 #include "llviewerimagelist.h"
00047 #include "llviewerobjectlist.h"
00048 #include "llviewerregion.h"
00049 #include "llvosky.h"
00050 #include "llworld.h"
00051 #include "pipeline.h"
00052 #include "llspatialpartition.h"
00053
00054 LLUUID gCloudTextureID = IMG_CLOUD_POOF;
00055
00056
00057 LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00058 : LLAlphaObject(id, LL_VO_CLOUDS, regionp)
00059 {
00060 mCloudGroupp = NULL;
00061 mbCanSelect = FALSE;
00062 setNumTEs(1);
00063 LLViewerImage* image = gImageList.getImage(gCloudTextureID);
00064 image->setBoostLevel(LLViewerImage::BOOST_CLOUDS);
00065 setTEImage(0, image);
00066 }
00067
00068
00069 LLVOClouds::~LLVOClouds()
00070 {
00071 }
00072
00073
00074 BOOL LLVOClouds::isActive() const
00075 {
00076 return TRUE;
00077 }
00078
00079
00080 BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
00081 {
00082 if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)))
00083 {
00084 return TRUE;
00085 }
00086
00087
00088 if (mDrawable)
00089 {
00090 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
00091 }
00092
00093 return TRUE;
00094 }
00095
00096
00097 void LLVOClouds::setPixelAreaAndAngle(LLAgent &agent)
00098 {
00099 mAppAngle = 50;
00100 mPixelArea = 1500*100;
00101 }
00102
00103 void LLVOClouds::updateTextures(LLAgent &agent)
00104 {
00105 getTEImage(0)->addTextureStats(mPixelArea);
00106 }
00107
00108 LLDrawable* LLVOClouds::createDrawable(LLPipeline *pipeline)
00109 {
00110 pipeline->allocDrawable(this);
00111 mDrawable->setLit(FALSE);
00112 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
00113
00114 return mDrawable;
00115 }
00116
00117 BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
00118 {
00119 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS);
00120 if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)))
00121 {
00122 return TRUE;
00123 }
00124
00125 dirtySpatialGroup();
00126
00127 LLFace *facep;
00128
00129 S32 num_faces = mCloudGroupp->getNumPuffs();
00130
00131 if (num_faces > drawable->getNumFaces())
00132 {
00133 drawable->setNumFacesFast(num_faces, NULL, getTEImage(0));
00134 }
00135
00136 mDepth = (getPositionAgent()-LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();
00137
00138 S32 face_indx = 0;
00139 for ( ; face_indx < num_faces; face_indx++)
00140 {
00141 facep = drawable->getFace(face_indx);
00142 if (!facep)
00143 {
00144 llwarns << "No facep for index " << face_indx << llendl;
00145 continue;
00146 }
00147
00148 facep->setSize(4, 6);
00149
00150 facep->setTEOffset(face_indx);
00151 facep->setTexture(getTEImage(0));
00152 const LLCloudPuff &puff = mCloudGroupp->getPuff(face_indx);
00153 const LLVector3 puff_pos_agent = gAgent.getPosAgentFromGlobal(puff.getPositionGlobal());
00154 facep->mCenterLocal = puff_pos_agent;
00156 LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha());
00157 facep->setFaceColor(float_color);
00158 }
00159 for ( ; face_indx < drawable->getNumFaces(); face_indx++)
00160 {
00161 facep = drawable->getFace(face_indx);
00162 if (!facep)
00163 {
00164 llwarns << "No facep for index " << face_indx << llendl;
00165 continue;
00166 }
00167
00168 facep->setTEOffset(face_indx);
00169 facep->setSize(0,0);
00170 }
00171
00172 drawable->movePartition();
00173
00174 return TRUE;
00175 }
00176
00177 F32 LLVOClouds::getPartSize(S32 idx)
00178 {
00179 return (CLOUD_PUFF_HEIGHT+CLOUD_PUFF_WIDTH)*0.5f;
00180 }
00181
00182 void LLVOClouds::getGeometry(S32 te,
00183 LLStrider<LLVector3>& verticesp,
00184 LLStrider<LLVector3>& normalsp,
00185 LLStrider<LLVector2>& texcoordsp,
00186 LLStrider<LLColor4U>& colorsp,
00187 LLStrider<U16>& indicesp)
00188 {
00189
00190 if (te >= mCloudGroupp->getNumPuffs())
00191 {
00192 return;
00193 }
00194
00195 LLDrawable* drawable = mDrawable;
00196 LLFace *facep = drawable->getFace(te);
00197
00198 if (!facep->hasGeometry())
00199 {
00200 return;
00201 }
00202
00203 LLVector3 normal(0.f,0.f,-1.f);
00204
00205 const LLCloudPuff &puff = mCloudGroupp->getPuff(te);
00206 S32 index_offset = facep->getGeomIndex();
00207 LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha());
00208 LLColor4U color;
00209 color.setVec(float_color);
00210 facep->setFaceColor(float_color);
00211
00212
00213 LLVector3 up;
00214 LLVector3 right;
00215 LLVector3 at;
00216
00217 const LLVector3& puff_pos_agent = facep->mCenterLocal;
00218 LLVector2 uvs[4];
00219
00220 uvs[0].setVec(0.f, 1.f);
00221 uvs[1].setVec(0.f, 0.f);
00222 uvs[2].setVec(1.f, 1.f);
00223 uvs[3].setVec(1.f, 0.f);
00224
00225 LLVector3 vtx[4];
00226
00227 at = LLViewerCamera::getInstance()->getAtAxis();
00228 right = at % LLVector3(0.f, 0.f, 1.f);
00229 right.normVec();
00230 up = right % at;
00231 up.normVec();
00232 right *= 0.5f*CLOUD_PUFF_WIDTH;
00233 up *= 0.5f*CLOUD_PUFF_HEIGHT;;
00234
00235 *colorsp++ = color;
00236 *colorsp++ = color;
00237 *colorsp++ = color;
00238 *colorsp++ = color;
00239
00240 vtx[0] = puff_pos_agent - right + up;
00241 vtx[1] = puff_pos_agent - right - up;
00242 vtx[2] = puff_pos_agent + right + up;
00243 vtx[3] = puff_pos_agent + right - up;
00244
00245 *verticesp++ = vtx[0];
00246 *verticesp++ = vtx[1];
00247 *verticesp++ = vtx[2];
00248 *verticesp++ = vtx[3];
00249
00250 *texcoordsp++ = uvs[0];
00251 *texcoordsp++ = uvs[1];
00252 *texcoordsp++ = uvs[2];
00253 *texcoordsp++ = uvs[3];
00254
00255 *normalsp++ = normal;
00256 *normalsp++ = normal;
00257 *normalsp++ = normal;
00258 *normalsp++ = normal;
00259
00260 *indicesp++ = index_offset + 0;
00261 *indicesp++ = index_offset + 1;
00262 *indicesp++ = index_offset + 2;
00263
00264 *indicesp++ = index_offset + 1;
00265 *indicesp++ = index_offset + 3;
00266 *indicesp++ = index_offset + 2;
00267 }
00268
00269 U32 LLVOClouds::getPartitionType() const
00270 {
00271 return LLViewerRegion::PARTITION_CLOUD;
00272 }
00273
00274
00275 void LLVOClouds::updateDrawable(BOOL force_damped)
00276 {
00277
00278 if (mDrawable.notNull())
00279 {
00280 mDrawable->updateXform(TRUE);
00281 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00282 }
00283 clearChanged(SHIFTED);
00284 }
00285
00286 LLCloudPartition::LLCloudPartition()
00287 {
00288 mDrawableType = LLPipeline::RENDER_TYPE_CLOUDS;
00289 mPartitionType = LLViewerRegion::PARTITION_CLOUD;
00290 }
00291