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