void LightCPURenderThread::ConnectToEye(const float u0,
		const BSDF &bsdf, const Point &lensPoint, const Spectrum &flux,
		vector<SampleResult> &sampleResults) {
	LightCPURenderEngine *engine = (LightCPURenderEngine *)renderEngine;
	Scene *scene = engine->renderConfig->scene;

	Vector eyeDir(bsdf.hitPoint - lensPoint);
	const float eyeDistance = eyeDir.Length();
	eyeDir /= eyeDistance;

	BSDFEvent event;
	Spectrum bsdfEval = bsdf.Evaluate(-eyeDir, &event);

	if (!bsdfEval.Black()) {
		const float epsilon = Max(MachineEpsilon::E(lensPoint), MachineEpsilon::E(eyeDistance));
		Ray eyeRay(lensPoint, eyeDir,
				epsilon,
				eyeDistance - epsilon);

		float scrX, scrY;
		if (scene->camera->GetSamplePosition(lensPoint, eyeDir, eyeDistance, &scrX, &scrY)) {
			RayHit eyeRayHit;
			BSDF bsdfConn;
			Spectrum connectionThroughput;
			if (!scene->Intersect(device, true, u0, &eyeRay, &eyeRayHit, &bsdfConn, &connectionThroughput)) {
				// Nothing was hit, the light path vertex is visible

				const float cosToCamera = Dot(bsdf.shadeN, -eyeDir);
				const float cosAtCamera = Dot(scene->camera->GetDir(), eyeDir);

				const float cameraPdfW = 1.f / (cosAtCamera * cosAtCamera * cosAtCamera *
					scene->camera->GetPixelArea());
				const float cameraPdfA = PdfWtoA(cameraPdfW, eyeDistance, cosToCamera);
				const float fluxToRadianceFactor = cameraPdfA;

				const Spectrum radiance = connectionThroughput * flux * fluxToRadianceFactor * bsdfEval;

				AddSampleResult(sampleResults, PER_SCREEN_NORMALIZED, scrX, scrY,
						radiance, 1.f);
			}
		}
	}
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
void CHomingMissile::UpdateControlledMissile(float frameTime)
{
	bool isServer = gEnv->bServer;
	bool isClient = gEnv->bClient;

	CActor *pClientActor=0;
	if (gEnv->bClient)
		pClientActor=static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor());
	bool isOwner = ((!m_ownerId && isServer) || (isClient && pClientActor && (pClientActor->GetEntityId() == m_ownerId) && pClientActor->IsPlayer()));

	IRenderer* pRenderer = gEnv->pRenderer;
	IRenderAuxGeom* pGeom = pRenderer->GetIRenderAuxGeom();
	float color[4] = {1,1,1,1};
	const static float step = 15.f;  
	float y = 20.f;    

	bool bDebug = g_pGameCVars->i_debug_projectiles > 0;

	if (isOwner || isServer)
	{
		//If there's a target, follow the target
		if(isServer)
		{
			if (m_targetId)
			{
				if (m_lockedTimer>0.0f)
					m_lockedTimer=m_lockedTimer-frameTime;
				else
				{
					// If we are here, there's a target
					IEntity* pTarget = gEnv->pEntitySystem->GetEntity(m_targetId);
					if (pTarget)
					{
						AABB box;
						pTarget->GetWorldBounds(box);
						Vec3 finalDes = box.GetCenter();
						SetDestination(finalDes);
						//SetDestination( box.GetCenter() );

						if (bDebug)
							pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName());
					}

					m_lockedTimer+=0.05f;
				}
			}
			else if(m_autoControlled)
				return;
		} 

		if (m_controlled && !m_autoControlled && isOwner && !m_targetId)
		{
			//Check if the weapon is still selected
			CWeapon *pWeapon = GetWeapon();

			if(!pWeapon || !pWeapon->IsSelected())
				return;

			if (m_controlledTimer>0.0f)
				m_controlledTimer=m_controlledTimer-frameTime;
			else if (pClientActor && pClientActor->IsPlayer()) 	//Follow the crosshair
			{
				if (IMovementController *pMC=pClientActor->GetMovementController())
				{
					Vec3 eyePos(ZERO);
					Vec3 eyeDir(ZERO);

					IVehicle* pVehicle = pClientActor->GetLinkedVehicle();
					if(!pVehicle)
					{
						SMovementState state;
						pMC->GetMovementState(state);

						eyePos = state.eyePosition;
						eyeDir = state.eyeDirection;
					}
					else
					{	
						SViewParams viewParams;
						pVehicle->UpdateView(viewParams, pClientActor->GetEntityId());

						eyePos = viewParams.position;
						eyeDir = viewParams.rotation * Vec3(0,1,0);
						//eyeDir = (viewParams.targetPos - viewParams.position).GetNormalizedSafe();
					}

					int pierceability=7;

					if (IPhysicalEntity *pPE=GetEntity()->GetPhysics())
					{
						if (pPE->GetType()==PE_PARTICLE)
						{
							pe_params_particle pp;

							if (pPE->GetParams(&pp))
								pierceability=pp.iPierceability;
						}
					}

					static const int objTypes = ent_all;
					static const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (pierceability & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit);

					IPhysicalWorld* pWorld = gEnv->pPhysicalWorld;
					static IPhysicalEntity* pSkipEnts[10];
					int numSkip = CSingle::GetSkipEntities(pWeapon, pSkipEnts, 10);

					ray_hit hit;
					int hits = 0;

					float range=m_maxTargetDistance;
					hits = pWorld->RayWorldIntersection(eyePos + 1.5f*eyeDir, eyeDir*range, objTypes, flags, &hit, 1, pSkipEnts, numSkip);
					
					while (hits)
					{
						if (gEnv->p3DEngine->RefineRayHit(&hit, eyeDir*range))
							break;

						eyePos = hit.pt+eyeDir*0.003f;
						range -= hit.dist+0.003f;

						hits = pWorld->RayWorldIntersection(eyePos, eyeDir*range, objTypes, flags, &hit, 1, pSkipEnts, numSkip);
					}

					DestinationParams params;

					if(hits)
						params.pt=hit.pt;
					else
						params.pt=(eyePos+m_maxTargetDistance*eyeDir);	//Some point in the sky...

					GetGameObject()->InvokeRMI(SvRequestDestination(), params, eRMI_ToServer);

					if (bDebug)
					{
						pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "PlayerView eye direction: %.3f %.3f %.3f", eyeDir.x, eyeDir.y, eyeDir.z);
						pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "PlayerView Target: %.3f %.3f %.3f", hit.pt.x, hit.pt.y, hit.pt.z);
						pRenderer->GetIRenderAuxGeom()->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255));
					}
				}

				m_controlledTimer+=0.0f;
			}
		}
	}

	//This code is shared by both modes above (auto and controlled)
	if(!m_destination.IsZero())
	{
		pe_status_dynamics status;
		if (!GetEntity()->GetPhysics()->GetStatus(&status))
		{
			CryLogAlways("couldn't get physics status!");
			return;
		}

		pe_status_pos pos;
		if (!GetEntity()->GetPhysics()->GetStatus(&pos))
		{
			CryLogAlways("couldn't get physics pos!");
			return;
		}

		float currentSpeed = status.v.len();

		if (currentSpeed>0.001f)
		{
			Vec3 currentVel = status.v;
			Vec3 currentPos = pos.pos;
			Vec3 goalDir(ZERO);

			assert(!_isnan(currentSpeed));
			assert(!_isnan(currentVel.x) && !_isnan(currentVel.y) && !_isnan(currentVel.z));

			//Just a security check
			if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius))
			{
				Explode(true, true, m_destination, -currentVel.normalized(), currentVel, m_targetId);

				return;
			}

			goalDir = m_destination - currentPos;
			goalDir.Normalize();

			//Turn more slowly...
			currentVel.Normalize();

			if(bDebug)
			{

				pRenderer->Draw2dLabel(50,55,2.0f,color,false, "  Destination: %.3f, %.3f, %.3f",m_destination.x,m_destination.y,m_destination.z);
				pRenderer->Draw2dLabel(50,80,2.0f,color,false, "  Current Dir: %.3f, %.3f, %.3f",currentVel.x,currentVel.y,currentVel.z);
				pRenderer->Draw2dLabel(50,105,2.0f,color,false,"  Goal    Dir: %.3f, %.3f, %.3f",goalDir.x,goalDir.y,goalDir.z);
			}

			float cosine = currentVel.Dot(goalDir);
			cosine = CLAMP(cosine,-1.0f,1.0f);
			float totalAngle = RAD2DEG(cry_acosf(cosine));

			assert(totalAngle>=0);

			if (cosine<0.99)
			{
				float maxAngle = m_turnSpeed*frameTime;
				if (maxAngle>totalAngle)
					maxAngle=totalAngle;
				float t=(maxAngle/totalAngle)*m_lazyness;

				assert(t>=0.0 && t<=1.0);

				goalDir = Vec3::CreateSlerp(currentVel, goalDir, t);
				goalDir.Normalize();
			}

			if(bDebug)
				pRenderer->Draw2dLabel(50,180,2.0f,color,false,"Corrected Dir: %.3f, %.3f, %.3f",goalDir.x,goalDir.y,goalDir.z);

			pe_action_set_velocity action;
			action.v = goalDir * currentSpeed;
			GetEntity()->GetPhysics()->Action(&action);
		}
	}
}