aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvopartgroup.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llvopartgroup.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llvopartgroup.cpp')
-rw-r--r--linden/indra/newview/llvopartgroup.cpp285
1 files changed, 285 insertions, 0 deletions
diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp
new file mode 100644
index 0000000..10a765d
--- /dev/null
+++ b/linden/indra/newview/llvopartgroup.cpp
@@ -0,0 +1,285 @@
1/**
2 * @file llvopartgroup.cpp
3 * @brief Group of particle systems
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llvopartgroup.h"
31
32#include "llfasttimer.h"
33#include "message.h"
34#include "v2math.h"
35
36#include "llagent.h"
37#include "lldrawable.h"
38#include "llface.h"
39#include "llsky.h"
40#include "llviewercamera.h"
41#include "llviewerpartsim.h"
42#include "llviewerregion.h"
43#include "pipeline.h"
44
45const F32 MAX_PART_LIFETIME = 120.f;
46
47extern U64 gFrameTime;
48
49LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
50 : LLViewerObject(id, pcode, regionp),
51 mViewerPartGroupp(NULL)
52{
53 setNumTEs(1);
54 setTETexture(0, LLUUID::null);
55 mbCanSelect = FALSE; // users can't select particle systems
56 mDebugColor = LLColor4(frand(1.f), frand(1.f), frand(1.f), 1.f);
57}
58
59
60LLVOPartGroup::~LLVOPartGroup()
61{
62}
63
64BOOL LLVOPartGroup::isActive() const
65{
66 return TRUE;
67}
68
69BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
70{
71 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))
72 {
73 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
74 }
75
76 // Particle groups don't need any of default idleUpdate velocity interpolation stuff.
77 //LLViewerObject::idleUpdate(agent, world, time);
78 return TRUE;
79}
80
81
82void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent)
83{
84 // mPixelArea is calculated during render
85
86 LLVector3 viewer_pos_agent = agent.getCameraPositionAgent();
87 LLVector3 pos_agent = getRenderPosition();
88
89 F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
90 F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
91 F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
92
93 F32 mid_scale = getMidScale();
94 F32 range = sqrt(dx*dx + dy*dy + dz*dz);
95
96 if (range < 0.001f || isHUDAttachment()) // range == zero
97 {
98 mAppAngle = 180.f;
99 }
100 else
101 {
102 mAppAngle = (F32) atan2( mid_scale, range) * RAD_TO_DEG;
103 }
104}
105
106void LLVOPartGroup::updateTextures(LLAgent &agent)
107{
108 // Texture stats for particles will need to be updated in a different way...
109}
110
111
112LLDrawable* LLVOPartGroup::createDrawable(LLPipeline *pipeline)
113{
114 pipeline->allocDrawable(this);
115 mDrawable->setLit(FALSE);
116 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
117
118 LLDrawPool *pool = gPipeline.getPool(LLDrawPool::POOL_ALPHA);
119 mDrawable->setNumFaces(mViewerPartGroupp->getCount(), pool, getTEImage(0));
120 return mDrawable;
121}
122
123 const F32 MAX_PARTICLE_AREA_SCALE = 0.02f; // some tuned constant, limits on how much particle area to draw
124
125BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
126{
127 LLFastTimer t(LLFastTimer::FTM_UPDATE_PARTICLES);
128
129 LLVector3 at;
130 LLVector3 up;
131 LLVector3 right;
132 LLVector3 position_agent;
133 LLVector3 camera_agent = gAgent.getCameraPositionAgent();
134 LLVector2 uvs[4];
135
136 uvs[0].setVec(0.f, 1.f);
137 uvs[1].setVec(0.f, 0.f);
138 uvs[2].setVec(1.f, 1.f);
139 uvs[3].setVec(1.f, 0.f);
140
141 LLDrawPool *drawpool = gPipeline.getPool(LLDrawPool::POOL_ALPHA);
142 S32 num_parts = mViewerPartGroupp->getCount();
143 LLFace *facep;
144
145 if (!num_parts)
146 {
147 drawable->setNumFaces(0, drawpool, getTEImage(0));
148 LLPipeline::sCompiles++;
149 return TRUE;
150 }
151
152 if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
153 {
154 return TRUE;
155 }
156
157// drawable->setNumFaces(num_parts, drawpool, getTEImage(0));
158 drawable->setNumFacesFast(num_parts, drawpool, getTEImage(0));
159
160 LLVector3 normal(-gCamera->getXAxis()); // make point agent face camera
161
162 LLStrider<LLVector3> verticesp;
163 LLStrider<LLVector3> normalsp;
164 LLStrider<LLVector2> texCoordsp;
165 U32 *indicesp = 0;
166
167 S32 vert_offset;
168 F32 tot_area = 0;
169 F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE;
170
171 S32 count=0;
172 for (S32 i = 0; i < num_parts; i++)
173 {
174 const LLViewerPart &part = mViewerPartGroupp->mParticles[i];
175
176 LLVector3 part_pos_agent(part.mPosAgent);
177 at = part_pos_agent - camera_agent;
178
179 //F32 invcamdist = 1.0f / at.magVec();
180 //area += (part.mScale.mV[0]*invcamdist)*(part.mScale.mV[1]*invcamdist);
181 F32 camera_dist_squared = at.magVecSquared();
182 F32 inv_camera_dist_squared;
183 if (camera_dist_squared > 1.f)
184 inv_camera_dist_squared = 1.f / camera_dist_squared;
185 else
186 inv_camera_dist_squared = 1.f;
187 F32 area = part.mScale.mV[0] * part.mScale.mV[1] * inv_camera_dist_squared;
188 tot_area += area;
189 if (tot_area > max_area)
190 {
191 break;
192 }
193
194 count++;
195
196 facep = drawable->getFace(i);
197 const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera
198 const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera
199 if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
200 {
201 facep->setSize(0, 0);
202 continue;
203 }
204 facep->setSize(4, 6);
205 facep->mCenterAgent = part_pos_agent;
206 vert_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
207 if (-1 == vert_offset)
208 {
209 return TRUE;
210 }
211
212 right = at % LLVector3(0.f, 0.f, 1.f);
213 right.normVec();
214 up = right % at;
215 up.normVec();
216
217 if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
218 {
219 LLVector3 normvel = part.mVelocity;
220 normvel.normVec();
221 LLVector2 up_fracs;
222 up_fracs.mV[0] = normvel*right;
223 up_fracs.mV[1] = normvel*up;
224 up_fracs.normVec();
225
226 LLVector3 new_up;
227 LLVector3 new_right;
228 new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
229 new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
230 up = new_up;
231 right = new_right;
232 up.normVec();
233 right.normVec();
234 }
235
236 right *= 0.5f*part.mScale.mV[0];
237 up *= 0.5f*part.mScale.mV[1];
238
239 *verticesp++ = part_pos_agent + up - right;
240 *verticesp++ = part_pos_agent - up - right;
241 *verticesp++ = part_pos_agent + up + right;
242 *verticesp++ = part_pos_agent - up + right;
243
244 *texCoordsp++ = uvs[0];
245 *texCoordsp++ = uvs[1];
246 *texCoordsp++ = uvs[2];
247 *texCoordsp++ = uvs[3];
248
249 *normalsp++ = normal;
250 *normalsp++ = normal;
251 *normalsp++ = normal;
252 *normalsp++ = normal;
253
254 if (part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
255 {
256 facep->setState(LLFace::FULLBRIGHT);
257 }
258 else
259 {
260 facep->clearState(LLFace::FULLBRIGHT);
261 }
262 facep->setFaceColor(part.mColor);
263
264 *indicesp++ = vert_offset + 0;
265 *indicesp++ = vert_offset + 1;
266 *indicesp++ = vert_offset + 2;
267
268 *indicesp++ = vert_offset + 1;
269 *indicesp++ = vert_offset + 3;
270 *indicesp++ = vert_offset + 2;
271 }
272 for (S32 j = count; j < drawable->getNumFaces(); j++)
273 {
274 drawable->getFace(j)->setSize(0,0);
275 }
276
277 mPixelArea = tot_area * gCamera->getPixelMeterRatio() * gCamera->getPixelMeterRatio();
278 const F32 area_scale = 10.f; // scale area to increase priority a bit
279 getTEImage(0)->addTextureStats(mPixelArea * area_scale);
280
281 LLPipeline::sCompiles++;
282
283 return TRUE;
284}
285