//! Prepares a bullet for rendering
	void PelletManager::SetupRendering(Bullet* pBullet, u32 index, VertexBuffer* pVB)
	{
		Vertex3D* pVertices = pVB->GetVertices();
		if(GraphicExtensionHandler::Instance()->HasExtension(GraphicExtensionHandler::E_PointSprite))
		{
			pVertices[index].Pos = pBullet->vPosition;
			pVB->SetNumVertices(index+1);
		}
		else
		{
			const Matrix44& viewInverse = EntityRenderer::Instance()->Get3DCamera()->GetViewMatrixInverse();
			const f32 fHalfSize = pBullet->fRadius;
			const u32 vtx = index*6;
			pVertices[vtx+0].UV = Vector2(0.0f, 1.0f); pVertices[vtx+0].Pos = Vector3::Create(-fHalfSize, -fHalfSize, 0.0f);
			pVertices[vtx+1].UV = Vector2(0.0f, 0.0f); pVertices[vtx+1].Pos = Vector3::Create(-fHalfSize, fHalfSize, 0.0f);
			pVertices[vtx+2].UV = Vector2(1.0f, 0.0f); pVertices[vtx+2].Pos = Vector3::Create(fHalfSize, fHalfSize, 0.0f);
			pVertices[vtx+3].UV = Vector2(0.0f, 1.0f); pVertices[vtx+3].Pos = Vector3::Create(-fHalfSize, -fHalfSize, 0.0f);
			pVertices[vtx+4].UV = Vector2(1.0f, 0.0f); pVertices[vtx+4].Pos = Vector3::Create(fHalfSize, fHalfSize, 0.0f);
			pVertices[vtx+5].UV = Vector2(1.0f, 1.0f); pVertices[vtx+5].Pos = Vector3::Create(fHalfSize, -fHalfSize, 0.0f);
			Matrix44 transform = viewInverse;
			transform.SetTranslation(pBullet->vPosition);
			for(u32 i=0; i<6; ++i)
			{
				pVertices[vtx+i].Pos = transform.TransformVect(pVertices[vtx+i].Pos);				
			}
			pVB->SetNumVertices(vtx+6);
		}		
	}
Esempio n. 2
0
	//! Sets the absolute position
	void Entity2D::SetAbsolutePosition(const Vector2& vAbsPos)
	{
		Vector3 vPos = Vector3::Create(vAbsPos.X, vAbsPos.Y, 0.0f);
		if(Entity2D* pParent = GetAncestor<Entity2D>())
		{
			Matrix44 inverse;
			if(pParent->GetTransformationMatrix().GetInverse(inverse))
			{
				vPos = inverse.TransformVect(vPos);
			}
		}
		SetPosition(Vector2(vPos.X, vPos.Y) + (m_vCenter*m_vScale));
	}
	int ParticleGenerator::TesselateLine(Particle* pParticle, Vertex3D* pVertices, int current, const Vector3& vScale)
	{
		Vector3 vDir = (pParticle->Pos - pParticle->PreviousPos).Normalized();		
		pVertices[current+0].UV = Vector2::Zero; pVertices[current+0].Pos = Vector3::Zero;
		pVertices[current+1].UV = Vector2::One;  pVertices[current+1].Pos = vDir*vScale*m_fSparkFactor;
		pParticle->PreviousPos = pParticle->Pos;

		Matrix44 transform = Matrix44::Identity;
		transform.SetTranslation(m_bApplyWorldTransform ? super::GetWorldTransform().TransformVect(pParticle->Pos) : pParticle->Pos);
		for(int i=0; i<2; ++i)
		{
			pVertices[current+i].Pos = transform.TransformVect(pVertices[current+i].Pos);
			pVertices[current+i].color = Color::Create(m_ParticleColor.R, m_ParticleColor.G, m_ParticleColor.B, pParticle->Alpha);
		}
		return 2;
	}
	int ParticleGenerator::TesselateQuad(Particle* pParticle, Vertex3D* pVertices, int current, const Vector3& vScale)
	{
		auto halfSize = pParticle->Size;
		pVertices[current+0].UV = Vector2::Create(0.0f, 1.0f); pVertices[current+0].Pos = Vector3::Create(-halfSize, -halfSize, 0.0f)*vScale;
		pVertices[current+1].UV = Vector2::Create(0.0f, 0.0f); pVertices[current+1].Pos = Vector3::Create(-halfSize, halfSize, 0.0f)*vScale;
		pVertices[current+2].UV = Vector2::Create(1.0f, 0.0f); pVertices[current+2].Pos = Vector3::Create(halfSize, halfSize, 0.0f)*vScale;
		pVertices[current+3].UV = Vector2::Create(0.0f, 1.0f); pVertices[current+3].Pos = Vector3::Create(-halfSize, -halfSize, 0.0f)*vScale;
		pVertices[current+4].UV = Vector2::Create(1.0f, 0.0f); pVertices[current+4].Pos = Vector3::Create(halfSize, halfSize, 0.0f)*vScale;
		pVertices[current+5].UV = Vector2::Create(1.0f, 1.0f); pVertices[current+5].Pos = Vector3::Create(halfSize, -halfSize, 0.0f)*vScale;
		
		Matrix44 transform = m_ViewInverse;
		transform.SetTranslation(m_bApplyWorldTransform ? super::GetWorldTransform().TransformVect(pParticle->Pos) : pParticle->Pos);
		for(int i=0; i<6; ++i)
		{
			pVertices[current+i].Pos = transform.TransformVect(pVertices[current+i].Pos);
			pVertices[current+i].color = Color::Create(m_ParticleColor.R, m_ParticleColor.G, m_ParticleColor.B, pParticle->Alpha);
		}
		return 6;
	}
Esempio n. 5
0
	//! returns true if the button is touched
	bool Button::IsTouched() const
	{
		Matrix44 transformation = Matrix44::Identity;
		transformation.Translate(-Vector3::Create(m_vCenter.X, m_vCenter.Y, 0.0f));
		transformation.Scale(Vector3::Create(m_vScale.X, m_vScale.Y, 1.0f));
		transformation.Rotate(Vector3::Create(0.0f, 0.0f, m_fRotation*Math::DegToRadFactor));		
		transformation.Translate(Vector3::Create(m_vOriginalPosition.X, m_vOriginalPosition.Y, 0.0f));
		if(Entity2D* p2DEntity = GetAncestor<Entity2D>())
		{
			transformation *= p2DEntity->GetTransformationMatrix();
		}

		Matrix44 inverse;
		if(transformation.GetInverse(inverse))
		{
			Vector2 vTouchPos = InputManager::Instance()->GetTouchState().vPosition;
			Vector3 invTouchPos3D = inverse.TransformVect(Vector3::Create(vTouchPos.X, vTouchPos.Y, 0.0f));
			Vector2 vInvTouchPos(invTouchPos3D.X, invTouchPos3D.Y);
			return GetBoundingBox().Contains(vInvTouchPos);
		}

		return false;
	}
	//! called during the update of the entity
	void ParticleGenerator::Update()
	{
		auto camera = EntityRenderer::Instance()->Get3DCamera();
		if (!camera)
			return;

		// generate new particles
		if(m_bActive)
		{
			m_fNewParticlesCounter += g_fDeltaTime * m_ParticlesPerSecond;
			int numNewParticles = int(m_fNewParticlesCounter);
			if(m_Pool.GetElementCount() + numNewParticles > m_MaxParticles)
				numNewParticles = m_MaxParticles - (int)m_Pool.GetElementCount();

			// determine emission center
			Vector3 vCenter = m_EmitBox.Min()+m_EmitBox.Size()/2.0f;
			if(!m_bApplyWorldTransform)
				vCenter = super::GetWorldTransform().TransformVect(vCenter);

			Matrix44 speedTransform = super::GetWorldTransform();
			speedTransform.SetTranslation(Vector3::Zero);

			// Pre-emit
			void* pEmitData = (this->*m_PreEmitFunctor)();

			for(int i=0; i<numNewParticles; ++i)
			{
				auto pParticle = m_Pool.Alloc();
				if(!pParticle)
					continue;

				pParticle->InitialLife = Random::GetFloat(m_rParticleLife.Min, m_rParticleLife.Max);
				pParticle->Life = pParticle->InitialLife;

				pParticle->Pos = Vector3::Create(Random::GetFloat(m_EmitBox.Min().X, m_EmitBox.Max().X),
					Random::GetFloat(m_EmitBox.Min().Y, m_EmitBox.Max().Y),
					Random::GetFloat(m_EmitBox.Min().Z, m_EmitBox.Max().Z));				

				if(!m_bApplyWorldTransform)				
					pParticle->Pos = super::GetWorldTransform().TransformVect(pParticle->Pos);
				pParticle->PreviousPos = pParticle->Pos;

				// Emit
				(this->*m_EmitFunctor)(pParticle, vCenter, pEmitData);

				if(!m_bApplyWorldTransform)
					pParticle->Speed = speedTransform.TransformVect(pParticle->Speed);				

				pParticle->Alpha = 1.0f;
			}

			m_fNewParticlesCounter -= numNewParticles;
			if(m_fActiveTime >= 0.0f)
			{
				m_fActiveTime -= g_fDeltaTime;
				if(m_fActiveTime < 0.0f)
					m_bActive = false;
			}
		}

		// update particles
		GraphicComponent* pGraphic = GetComponent<GraphicComponent>();
		VertexBuffer* pVB = pGraphic->GetVertexBuffer();
		Vertex3D* pVertices = reinterpret_cast<Vertex3D*>(pVB->GetVertices());
		const Vector3 vScale = GetAbsoluteScale();
		m_ViewInverse = camera->GetViewMatrixInverse();
		m_ParticleColor = pGraphic->GetMaterial() ? pGraphic->GetMaterial()->GetColor() : Color::White;

		int vtx = 0;
		for (size_t i = 0; i < m_Pool.GetCapacity(); ++i)
		{			
			auto particle = m_Pool.GetElement(i);
			if (!particle)
				continue;

			particle->Pos += particle->Speed * g_fDeltaTime;
			particle->Speed += m_vGravity * g_fDeltaTime;
			auto lifeFactor = particle->Life / particle->InitialLife;
			particle->Alpha = lifeFactor*lifeFactor;
			particle->Size = (this->*m_SizeFuncFunctor)(particle);

			// Tesselate
			auto numParticleVertices = (this->*m_TesselateFunctor)(particle, pVertices, vtx, vScale);

			vtx += numParticleVertices;
			particle->Life -= g_fDeltaTime;
			if(particle->Life < 0.0f)			
				m_Pool.Free(particle);			
		}

		pVB->SetNumVertices(vtx);
		pVB->SetDirty(true);
	}
	//! called during the update of the entity	
	void ParticleGenerator::Update()
	{
		// generate new particles
		if(m_bActive)
		{
			m_fNewParticlesCounter += g_fDeltaTime * m_ParticlesPerSecond;
			u32 numNewParticles = u32(m_fNewParticlesCounter);
			if(m_aParticles.size() + numNewParticles > m_MaxParticles)
			{
				numNewParticles = m_MaxParticles-m_aParticles.size();
			}

			for(u32 i=0; i<numNewParticles; ++i)
			{
				if(Particle* pParticle = m_Pool->Alloc<Particle>())
				{
					pParticle->InitialLife = Random::GetFloat(m_rParticleLife.Min, m_rParticleLife.Max);
					pParticle->Life = pParticle->InitialLife;

					pParticle->Position = Vector3::Create(Random::GetFloat(m_EmitBox.Min().X, m_EmitBox.Max().X),
						Random::GetFloat(m_EmitBox.Min().Y, m_EmitBox.Max().Y),
						Random::GetFloat(m_EmitBox.Min().Z, m_EmitBox.Max().Z));

					Vector3 vCenter = m_EmitBox.Min()+m_EmitBox.Size()/2.0f;
					if(!m_bApplyWorldTransform)
					{
						Vector3 vTranslation = GetTransformationMatrix().GetTranslation();
						pParticle->Position += vTranslation;
						vCenter += vTranslation;
					}

					if(m_bExplosive)
					{
						pParticle->Speed = (pParticle->Position-vCenter).Normalize();
						pParticle->Speed *= Random::GetFloat(m_rParticleInitialSpeed.Min, m_rParticleInitialSpeed.Max);
					}
					else
					{
						pParticle->Speed = Vector3::Create(m_vDirection.X * Random::GetFloat(m_rParticleInitialSpeed.Min, m_rParticleInitialSpeed.Max),
							m_vDirection.Y * Random::GetFloat(m_rParticleInitialSpeed.Min, m_rParticleInitialSpeed.Max),
							m_vDirection.Z * Random::GetFloat(m_rParticleInitialSpeed.Min, m_rParticleInitialSpeed.Max));
					}

					pParticle->Alpha = 1.0f;
					m_aParticles.push_back(pParticle);
				}
			}

			m_fNewParticlesCounter -= numNewParticles;
			if(m_fActiveTime >= 0.0f)
			{
				m_fActiveTime -= g_fDeltaTime;
				if(m_fActiveTime < 0.0f)
				{
					m_bActive = false;
				}
			}
		}

		// update particles
		GraphicComponent* pGraphic = GetComponent<GraphicComponent>();
		VertexBuffer* pVertexBuffer = pGraphic->GetVertexBuffer();
		Material* pMaterial = pGraphic->GetMaterial();
		const Matrix44& viewInverse = EntityRenderer::Instance()->Get3DCamera()->GetViewMatrixInverse();
		const f32 fHalfSize = m_fParticleSize/2.0f;
		const bool bPointSprite = GraphicExtensionHandler::Instance()->HasExtension(GraphicExtensionHandler::E_PointSprite);

		u32 vtx = 0;
		for(std::list<Particle*>::iterator it = m_aParticles.begin(); it != m_aParticles.end(); )
		{
			if((*it)->Life > 0.0f)
			{				
				(*it)->Position += (*it)->Speed * g_fDeltaTime;
				(*it)->Speed += m_vGravity * g_fDeltaTime;
				(*it)->Alpha = (*it)->Life / (*it)->InitialLife;
				(*it)->Life -= g_fDeltaTime;

				const Color& color = pMaterial->GetColor();
				Vertex3D* pVertices = pVertexBuffer->GetVertices();
				const Vector3& pos = (*it)->Position;

				if(bPointSprite)
				{
					pVertices[vtx].Pos = pos;
					pVertices[vtx].color = Color(color.R, color.G, color.B, (*it)->Alpha);
					++vtx;
				}
				else
				{
					Vector3 vScale = GetAbsoluteScale();
					pVertices[vtx+0].UV = Vector2(0.0f, 1.0f); pVertices[vtx+0].Pos = Vector3::Create(-fHalfSize, -fHalfSize, 0.0f)*vScale;
					pVertices[vtx+1].UV = Vector2(0.0f, 0.0f); pVertices[vtx+1].Pos = Vector3::Create(-fHalfSize, fHalfSize, 0.0f)*vScale;
					pVertices[vtx+2].UV = Vector2(1.0f, 0.0f); pVertices[vtx+2].Pos = Vector3::Create(fHalfSize, fHalfSize, 0.0f)*vScale;
					pVertices[vtx+3].UV = Vector2(0.0f, 1.0f); pVertices[vtx+3].Pos = Vector3::Create(-fHalfSize, -fHalfSize, 0.0f)*vScale;
					pVertices[vtx+4].UV = Vector2(1.0f, 0.0f); pVertices[vtx+4].Pos = Vector3::Create(fHalfSize, fHalfSize, 0.0f)*vScale;
					pVertices[vtx+5].UV = Vector2(1.0f, 1.0f); pVertices[vtx+5].Pos = Vector3::Create(fHalfSize, -fHalfSize, 0.0f)*vScale;
					Matrix44 transform = viewInverse;
					transform.SetTranslation(super::GetTransformationMatrix().TransformVect(pos));
					for(u32 i=0; i<6; ++i)
					{
						pVertices[vtx+i].Pos = transform.TransformVect(pVertices[vtx+i].Pos);
						pVertices[vtx+i].color = Color(color.R, color.G, color.B, (*it)->Alpha);
					}
					vtx += 6;
				}

				++it;
			}
			else
			{
				// remove particle
				m_Pool->Free((*it));
				it = m_aParticles.erase(it);
			}
		}

		pVertexBuffer->SetNumVertices(vtx);
		pVertexBuffer->SetDirty(true);
	}