Panagiotis Christopoulos Charitos 13 سال پیش
والد
کامیت
2a7e3030b7
5فایلهای تغییر یافته به همراه81 افزوده شده و 39 حذف شده
  1. 24 4
      include/anki/scene/ParticleEmitter.h
  2. 2 2
      include/anki/scene/Renderable.h
  3. 1 1
      src/physics/RigidBody.cpp
  4. 52 30
      src/scene/ParticleEmitter.cpp
  5. 2 2
      src/scene/Renderable.cpp

+ 24 - 4
include/anki/scene/ParticleEmitter.h

@@ -107,11 +107,23 @@ public:
 	/// Implements  Renderable::getMaterial
 	const Material& getRenderableMaterial() const;
 
-	/// Overrides Renderable::getRenderableWorldTransform
-	const Transform* getRenderableWorldTransform() const
+	/// Overrides Renderable::getRenderableInstancingTranslations
+	virtual const Vec3* getRenderableInstancingTranslations() const
 	{
-		return nullptr;
+		return &instancintPositions[0];
 	}
+
+	virtual U32 getRenderableInstancesCount() const
+	{
+		return instancesCount;
+	}
+	/// @}
+
+	/// @name Movable virtuals
+	/// @{
+
+	/// Overrides Movable::movableUpdate. Calculates an optimization
+	void movableUpdate();
 	/// @}
 
 private:
@@ -122,7 +134,15 @@ private:
 	/// The resource
 	Aabb aabb;
 
-	void init(const char* filename);
+	// Opt: We dont have to make extra calculations if the ParticleEmitter's
+	// rotation is the identity
+	Bool identityRotation = true;
+
+	U32 instancesCount; ///< AKA alive
+
+	Vector<Vec3> instancintPositions;
+
+	void init(const char* filename, Scene* scene);
 
 	static F32 getRandom(F32 initial, F32 deviation);
 	static Vec3 getRandom(const Vec3& initial, const Vec3& deviation);

+ 2 - 2
include/anki/scene/Renderable.h

@@ -83,12 +83,12 @@ public:
 	/// @name Instancing methods
 	/// @{
 
-	virtual Vec3* getRenderableInstancingTranslations() const
+	virtual const Vec3* getRenderableInstancingTranslations() const
 	{
 		return nullptr;
 	}
 
-	virtual Transform* getRenderableInstancingWorldTransforms() const
+	virtual const Transform* getRenderableInstancingWorldTransforms() const
 	{
 		return nullptr;
 	}

+ 1 - 1
src/physics/RigidBody.cpp

@@ -15,7 +15,7 @@ RigidBody::RigidBody(PhysWorld* masterContainer_, const Initializer& init,
 	ANKI_ASSERT(init.shape != nullptr 
 		&& init.shape->getShapeType() != INVALID_SHAPE_PROXYTYPE);
 
-	movable = (movable != nullptr) : movable ? init.movable;
+	movable = (movable != nullptr) ? movable : init.movable;
 
 	Bool isDynamic = (init.mass != 0.0);
 

+ 52 - 30
src/scene/ParticleEmitter.cpp

@@ -1,6 +1,9 @@
 #include "anki/scene/ParticleEmitter.h"
+#include "anki/scene/Scene.h"
 #include "anki/resource/Model.h"
 #include "anki/util/Functions.h"
+#include "anki/physics/PhysWorld.h"
+#include <limits>
 
 namespace anki {
 
@@ -40,7 +43,7 @@ ParticleEmitter::ParticleEmitter(
 		Movable(movableFlags, movParent, *this)
 {
 	Renderable::init(*this);
-	init(filename);
+	init(filename, scene);
 }
 
 //==============================================================================
@@ -85,6 +88,13 @@ const Material& ParticleEmitter::getRenderableMaterial() const
 		particleEmitterResource->getModel().getModelPatches()[0]->getMaterial();
 }
 
+//==============================================================================
+void ParticleEmitter::movableUpdate()
+{
+	identityRotation =
+		getWorldTransform().getRotation() == Mat3::getIdentity();
+}
+
 //==============================================================================
 void ParticleEmitter::init(const char* filename, Scene* scene)
 {
@@ -101,21 +111,21 @@ void ParticleEmitter::init(const char* filename, Scene* scene)
 	RigidBody::Initializer binit;
 	binit.shape = collShape.get();
 	binit.group = PhysWorld::CG_PARTICLE;
-	binit.mask = PhysWorld::CG_WORD;
+	binit.mask = PhysWorld::CG_MAP;
 
 	for(U i = 0; i < maxNumOfParticles; i++)
 	{
-		init.mass = getRandom(particleMass, particleMassDeviation);
+		binit.mass = getRandom(particleMass, particleMassDeviation);
 
 		Particle* particle = new Particle(
 			-1.0, 
-			(getName() + std::to_string(i)).c_str, scene,
+			(getName() + std::to_string(i)).c_str(), scene,
 			Movable::MF_NONE, nullptr,
 			&scene->getPhysics(), binit);
 
 		particles.push_back(particle);
 
-		body->forceActivationState(DISABLE_SIMULATION);
+		particle->forceActivationState(DISABLE_SIMULATION);
 	}
 
 	timeLeftForNextEmission = 0.0;
@@ -126,33 +136,45 @@ void ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
 {
 	SceneNode::frameUpdate(prevUpdateTime, crntTime, frame);
 
-	// Opt: We dont have to make extra calculations if the ParticleEmitter's
-	// rotation is the identity
-	Bool identRot = getWorldTransform().getRotation() == Mat3::getIdentity();
-
-	// deactivate the dead particles
+	// - Deactivate the dead particles
+	// - Calc the AABB
+	// - Calc the instancing stuff
+	//
+	Vec3 aabbmin(std::numeric_limits<F32>::max());
+	Vec3 aabbmax(std::numeric_limits<F32>::min());
+	instancesCount = 0;
+	instancintPositions.clear();
 	for(Particle* p : particles)
 	{
-		if(p->isDead()) // its already dead so dont deactivate it again
-		{
-			continue;
-		}
-
-		if(p->getTimeOfDeath() < crntTime)
+		// if its already dead so dont deactivate it again
+		if(!p->isDead() && p->getTimeOfDeath() < crntTime)
 		{
 			//cout << "Killing " << i << " " << p.timeOfDeath << endl;
 			p->setActivationState(DISABLE_SIMULATION);
 			p->setTimeOfDeath(-1.0);
+
+			const Vec3& origin = p->Movable::getWorldTransform().getOrigin();
+			for(U i = 0; i < 3; i++)
+			{
+				aabbmin[i] = std::min(aabbmin[i], origin[i]);
+				aabbmax[i] = std::max(aabbmax[i], origin[i]);
+			}
+
+			++instancesCount;
+			instancintPositions.push_back(origin);
 		}
 	}
 
+	aabb = Aabb(aabbmin, aabbmax);
+	spatialMarkUpdated();
+
 	// pre calculate
 	Bool forceFlag = particleEmitterResource->hasForce();
 	Bool worldGravFlag = particleEmitterResource->usingWorldGravity();
 
 	if(timeLeftForNextEmission <= 0.0)
 	{
-		U partNum = 0;
+		U particlesCount = 0; // How many particles I am allowed to emmit
 		for(Particle* pp : particles)
 		{
 			Particle& p = *pp;
@@ -162,11 +184,11 @@ void ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
 				continue;
 			}
 
-			RigidBody& body = p.getRigidBody();
+			RigidBody& body = p;
 
 			// life
-			p.setTimeOfDeath(getRandom(crntTime + particleLife,
-				particleLifeDeviation));
+			p.setTimeOfDeath(
+				getRandom(crntTime + particleLife, particleLifeDeviation));
 
 			//cout << "Time of death " << p.timeOfDeath << endl;
 			//cout << "Particle life " << p.timeOfDeath - crntTime << endl;
@@ -183,18 +205,18 @@ void ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
 			// force
 			if(forceFlag)
 			{
-				Vec3 forceDir = getRandom(
-					forceDirection, forceDirectionDeviation);
+				Vec3 forceDir =
+					getRandom(forceDirection, forceDirectionDeviation);
 				forceDir.normalize();
 
-				if(!identRot)
+				if(!identityRotation)
 				{
 					// the forceDir depends on the particle emitter rotation
 					forceDir = getWorldTransform().getRotation() * forceDir;
 				}
 
-				float forceMag = getRandom(forceMagnitude,
-					forceMagnitudeDeviation);
+				F32 forceMag =
+					getRandom(forceMagnitude, forceMagnitudeDeviation);
 
 				body.applyCentralForce(toBt(forceDir * forceMag));
 			}
@@ -208,7 +230,7 @@ void ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
 			// Starting pos. In local space
 			Vec3 pos = getRandom(startingPos, startingPosDeviation);
 
-			if(identRot)
+			if(identityRotation)
 			{
 				pos += getWorldTransform().getOrigin();
 			}
@@ -217,13 +239,13 @@ void ParticleEmitter::frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
 				pos.transform(getWorldTransform());
 			}
 
-			btTransform trf(toBt(Transform(pos,
-				getWorldTransform().getRotation(), 1.0)));
+			btTransform trf(
+				toBt(Transform(pos, getWorldTransform().getRotation(), 1.0)));
 			body.setWorldTransform(trf);
 
 			// do the rest
-			++partNum;
-			if(partNum >= particlesPerEmittion)
+			++particlesCount;
+			if(particlesCount >= particlesPerEmittion)
 			{
 				break;
 			}

+ 2 - 2
src/scene/Renderable.cpp

@@ -108,8 +108,8 @@ void Renderable::init(PropertyMap& pmap)
 	U32 instancesCount = getRenderableInstancesCount();
 	if(instancesCount > 0)
 	{
-		Vec3* translations;
-		Transform* transforms;
+		const Vec3* translations;
+		const Transform* transforms;
 		U32 size = 0;
 
 		if((translations = getRenderableInstancingTranslations()) != 0)