Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 598 vs 599 for /trunk/Source Code/Dynamics/Entities/Particles/ParticleEmitter.cpp

Diff revisions: vs.
  @@ -21,7 +21,6 @@
21 21 ParticleEmitter::ParticleEmitter()
22 22 : SceneNode(SceneNodeType::TYPE_PARTICLE_EMITTER),
23 23 _drawImpostor(false),
24 - _updateParticleEmitterBB(true),
25 24 _particleStateBlockHash(0),
26 25 _enabled(false),
27 26 _uploaded(false),
  @@ -71,20 +70,18 @@
71 70 particleRenderState.setZFunc(ComparisonFunction::LEQUAL);
72 71 _particleStateBlockHash = particleRenderState.getHash();
73 72
74 - ResourceDescriptor particleShaderDescriptor("particles");
73 + bool useTexture = _particleTexture != nullptr;
74 + ResourceDescriptor particleShaderDescriptor(useTexture ? "particles.WithTexture" : "particles.NoTexture");
75 + if (useTexture){
76 + particleShaderDescriptor.setPropertyList("HAS_TEXTURE");
77 + }
75 78 _particleShader = CreateResource<ShaderProgram>(particleShaderDescriptor);
76 - _particleShader->Uniform("hasTexture", _particleTexture != nullptr);
77 79 REGISTER_TRACKED_DEPENDENCY(_particleShader);
78 80
79 81 ResourceDescriptor particleDepthShaderDescriptor("particles.Depth");
80 82 _particleDepthShader = CreateResource<ShaderProgram>(particleDepthShaderDescriptor);
81 83 REGISTER_TRACKED_DEPENDENCY(_particleDepthShader);
82 84
83 - _impostor =
84 - CreateResource<ImpostorBox>(ResourceDescriptor(_name + "_impostor"));
85 - _impostor->renderState().setDrawState(false);
86 - _impostor->getMaterialTpl()->setDiffuse(vec4<F32>(0.0f, 0.0f, 1.0f, 1.0f));
87 -
88 85 //_renderState.addToDrawExclusionMask(RenderStage::SHADOW);
89 86
90 87 return (_particleShader != nullptr);
  @@ -159,9 +156,6 @@
159 156 }
160 157
161 158 void ParticleEmitter::postLoad(SceneGraphNode& sgn) {
162 - sgn.addNode(*_impostor)->setActive(false);
163 -
164 -
165 159 Framebuffer* depthBuffer = GFX_DEVICE.getRenderTarget(GFXDevice::RenderTarget::DEPTH);
166 160 Texture* depthTexture = depthBuffer->getAttachment(TextureDescriptor::AttachmentType::Depth);
167 161 TextureData depthBufferData = depthTexture->getData();
  @@ -185,43 +179,11 @@
185 179 Attorney::RenderingCompSceneNode::getDrawPackage(*renderable, static_cast<RenderStage>(i));
186 180 pkg._drawCommands.push_back(cmd);
187 181 }
182 + sgn.lockBBTransforms(true);
188 183
189 184 SceneNode::postLoad(sgn);
190 185 }
191 186
192 - bool ParticleEmitter::computeBoundingBox(SceneGraphNode& sgn) {
193 - if (!_enabled) {
194 - return false;
195 - }
196 -
197 - DIVIDE_ASSERT(_particles.get() != nullptr,
198 - "ParticleEmitter::computeBoundingBox error: BoundingBox "
199 - "calculation requested without valid particle data "
200 - "available!");
201 - _updateParticleEmitterBB = true;
202 - BoundingBox& bb = sgn.getBoundingBox();
203 - if (_particles->_renderingPositions.size() > 2) {
204 - bb.reset();
205 - bb.add(_particles->_renderingPositions.front());
206 - bb.add(_particles->_renderingPositions.back());
207 - }
208 - return SceneNode::computeBoundingBox(sgn);
209 - }
210 -
211 - bool ParticleEmitter::isInView(const SceneRenderState& sceneRenderState,
212 - const SceneGraphNode& sgn,
213 - Frustum::FrustCollision& collisionType,
214 - const bool distanceCheck) const {
215 - bool visible = false;
216 - if (_enabled && _impostor) {
217 - visible = _impostor->isInView(sceneRenderState, sgn, collisionType, distanceCheck);
218 - }
219 -
220 - collisionType = visible ? Frustum::FrustCollision::FRUSTUM_IN
221 - : Frustum::FrustCollision::FRUSTUM_OUT;
222 -
223 - return visible;
224 - }
225 187
226 188 void ParticleEmitter::onCameraUpdate(SceneGraphNode& sgn, Camera& camera) {
227 189
  @@ -271,8 +233,6 @@
271 233 if (_uploaded || getAliveParticleCount() == 0) {
272 234 return;
273 235 }
274 -
275 - _particles->sort();
276 236
277 237 U32 writeOffset = _writeOffset * to_uint(_particles->totalCount());
278 238 U32 readOffset = _readOffset * to_uint(_particles->totalCount());
  @@ -298,7 +258,6 @@
298 258 RenderStage currentStage) {
299 259 if (_enabled) {
300 260 uploadToGPU();
301 - sgn.getBoundingBox().setComputed(false);
302 261 return true;
303 262 }
304 263
  @@ -318,22 +277,21 @@
318 277
319 278 _uploaded = false;
320 279
321 - PhysicsComponent* const transform = sgn.getComponent<PhysicsComponent>();
322 - if (_updateParticleEmitterBB) {
323 - sgn.updateBoundingBoxTransform(transform->getWorldMatrix());
324 - _updateParticleEmitterBB = false;
325 - }
326 -
280 + PhysicsComponent* transform = sgn.getComponent<PhysicsComponent>();
327 281 const vec3<F32>& eyePos = sceneState.renderState().getCameraConst().getEye();
328 282
329 283 const vec3<F32>& pos = transform->getPosition();
330 284 const Quaternion<F32>& rot = transform->getOrientation();
331 285
286 + F32 averageEmitRate = 0;
332 287 for (std::shared_ptr<ParticleSource>& source : _sources) {
333 288 source->updateTransform(pos, rot);
334 289 source->emit(deltaTime, _particles);
290 + averageEmitRate += source->emitRate();
335 291 }
336 -
292 +
293 + averageEmitRate /= _sources.size();
294 +
337 295 U32 count = _particles->totalCount();
338 296 for (U32 i = 0; i < count; ++i) {
339 297 _particles->_misc[i].w = _particles->_position[i].xyz().distanceSquared(eyePos);
  @@ -348,6 +306,18 @@
348 306 // const vec3<F32>& origin = transform->getPosition();
349 307 // const Quaternion<F32>& orientation = transform->getOrientation();
350 308
309 + _particles->sort();
310 +
311 + BoundingBox& bb = sgn.getBoundingBox();
312 + bb.reset();
313 + U32 aliveCount = _particles->aliveCount();
314 + for (U32 i = 0; i < aliveCount; i += to_uint(averageEmitRate) / 4) {
315 + bb.add(_particles->_position[i]);
316 + }
317 +
318 + bb.setComputed(true);
319 + sgn.setInitialBoundingBox(bb);
320 +
351 321 SceneNode::sceneUpdate(deltaTime, sgn, sceneState);
352 322 }
353 323