Esempio n. 1
0
	void Camera::SetDirection(const Vector3<float>& aDirection)
	{
		Matrix44<float> newOrientation = Matrix44<float>::CreateMatrixFromForwardVector(aDirection);
		newOrientation.SetTranslation(myOrientation.GetTranslation());
		myOrientation = newOrientation;
		myFrustum.Update(myOrientation, myWidthAndHeight.myY / myWidthAndHeight.myX, myFov);
	}
	//! 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. 3
0
// 获取旋转平移矩阵
Matrix44 Camera::GetModelViewMatrix(void)
{
    Matrix33 rotate = ori_.GetMatrix33();
    Matrix44 m = Matrix44::CreateIdentity();
    m.SetMatrix33(rotate);
    m.SetTranslation(-pos_.x, -pos_.y, -pos_.z);
    return m;
}
	void ParticleSystemData::Load(const std::string& aFilePath)
	{
		myEmitterData.Init(4);
		myOrientations.Init(4);
		myTimeStamps.Init(4);

		XMLReader xmlDoc;
		xmlDoc.OpenDocument(aFilePath);

		XMLElement emitterElement = xmlDoc.FindFirstChild();

		emitterElement = emitterElement->FirstChildElement("Emitter");

		while (emitterElement != nullptr)
		{
			XMLElement dataElement = emitterElement->FirstChildElement("Name");

			std::string emitterName = dataElement->GetText();

			dataElement = emitterElement->FirstChildElement("Time");

			float time;
			dataElement->QueryFloatText(&time);

			dataElement = emitterElement->FirstChildElement("Position");

			Vector3<float> position;

			position.x = dataElement->FloatAttribute("x");
			position.y = dataElement->FloatAttribute("y");
			position.z = dataElement->FloatAttribute("z");

			dataElement = emitterElement->FirstChildElement("Rotation");

			Vector3<float> rotation;

			rotation.x = dataElement->FloatAttribute("x");
			rotation.y = dataElement->FloatAttribute("y");
			rotation.z = dataElement->FloatAttribute("z");

			Matrix44<float> orientation;

			orientation *= Matrix44<float>::CreateRotateAroundX(rotation.x);
			orientation *= Matrix44<float>::CreateRotateAroundY(rotation.y);
			orientation *= Matrix44<float>::CreateRotateAroundZ(rotation.z);

			orientation.SetTranslation(position);

			myEmitterData.Add(emitterName);
			myOrientations.Add(orientation);
			myTimeStamps.Add(time);

			emitterElement = emitterElement->NextSiblingElement("Emitter");
		}
	}
	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;
	}
	//! 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);
	}