Exemple #1
0
void CAICorpseManager::DebugDraw()
{
	if(g_pGameCVars->g_aiCorpses_DebugDraw == 0)
		return;

	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();

	gEnv->pRenderer->Draw2dLabel( 50.0f, 50.0f, 1.5f, Col_White, false, "Corpse count %" PRISIZE_T " - Max %d", m_corpsesArray.size(), m_maxCorpses );

	for(size_t i = 0; i < m_corpsesArray.size(); ++i)
	{
		CorpseInfo& corpse = m_corpsesArray[i];

		CAICorpse* pCorpse = corpse.GetCorpse();
		if(pCorpse != NULL)
		{
			AABB corpseBbox;
			pCorpse->GetEntity()->GetWorldBounds(corpseBbox);
			const Vec3 refPosition = corpseBbox.IsEmpty() ? pCorpse->GetEntity()->GetWorldPos() : corpseBbox.GetCenter();

			gEnv->pRenderer->DrawLabel( refPosition, 1.5f, "%s\nPriority %d\n%s\n%s", 
				pCorpse->GetEntity()->GetName(), pCorpse->GetPriority(),
				corpse.flags.AreAnyFlagsActive( CorpseInfo::eFlag_FarAway ) ? "Far away, remove when not visible" : "Not far away",
				corpse.flags.AreAllFlagsActive( CorpseInfo::eFlag_PhysicsDisabled) ? "Physics disabled" : "Physics enabled" );
			pRenderAux->DrawCone( refPosition + Vec3(0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, -1.0f), 0.3f, 0.8f, Col_Red );
		}
	}
}
Exemple #2
0
void CAIDebugRenderer::SetDepthWrite(bool bOn)
{
	IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom();
	SAuxGeomRenderFlags	flags = pRenderAuxGeom->GetRenderFlags();
	flags.SetDepthWriteFlag(bOn ? e_DepthWriteOn : e_DepthWriteOff);
	pRenderAuxGeom->SetRenderFlags(flags);
}
Exemple #3
0
void CAIDebugRenderer::SetAlphaBlended(bool bOn)
{
	IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom();
	SAuxGeomRenderFlags	flags = pRenderAuxGeom->GetRenderFlags();
	flags.SetAlphaBlendMode(bOn ? e_AlphaBlended : e_AlphaNone);
	pRenderAuxGeom->SetRenderFlags(flags);
}
Exemple #4
0
void CAIDebugRenderer::SetBackFaceCulling(bool bOn)
{
	IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom();
	SAuxGeomRenderFlags	flags = pRenderAuxGeom->GetRenderFlags();
	flags.SetCullMode(bOn ? e_CullModeBack : e_CullModeNone);
	pRenderAuxGeom->SetRenderFlags(flags);
}
Exemple #5
0
void CAIDebugRenderer::SetDrawInFront(bool bOn)
{
	IRenderAuxGeom* pRenderAuxGeom = m_pRenderer->GetIRenderAuxGeom();
	SAuxGeomRenderFlags	flags = pRenderAuxGeom->GetRenderFlags();
	flags.SetDrawInFrontMode(bOn ? e_DrawInFrontOn : e_DrawInFrontOff);
	pRenderAuxGeom->SetRenderFlags(flags);
}
void CGameVolume_Water::DebugDrawVolume()
{
	IGameVolumes::VolumeInfo volumeInfo;
	if (GetVolumeInfoForEntity(GetEntityId(), volumeInfo) == false)
		return;

	if (volumeInfo.verticesCount < 3)
		return;

	const Matrix34 worldTM = GetEntity()->GetWorldTM();
	const Vec3 depthOffset = worldTM.GetColumn2().GetNormalized() * - m_volumeDepth;

	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();
	for (uint32 i = 0; i < volumeInfo.verticesCount - 1; ++i)
	{
		const Vec3 point1 = worldTM.TransformPoint(volumeInfo.pVertices[i]);
		const Vec3 point2 = worldTM.TransformPoint(volumeInfo.pVertices[i + 1]);

		pRenderAux->DrawLine( point1, Col_SlateBlue, point1 + depthOffset, Col_SlateBlue, 2.0f );
		pRenderAux->DrawLine( point1 + depthOffset, Col_SlateBlue, point2 + depthOffset, Col_SlateBlue, 2.0f );
	}

	const Vec3 firstPoint = worldTM.TransformPoint(volumeInfo.pVertices[0]);
	const Vec3 lastPoint = worldTM.TransformPoint(volumeInfo.pVertices[volumeInfo.verticesCount - 1]);

	pRenderAux->DrawLine( lastPoint, Col_SlateBlue, lastPoint + depthOffset, Col_SlateBlue, 2.0f );
	pRenderAux->DrawLine( lastPoint + depthOffset, Col_SlateBlue, firstPoint + depthOffset, Col_SlateBlue, 2.0f );
}
	void OnUpdate( SActivationInfo* pActInfo )
	{
		const Vec3 positionOffsetLocal = GetPortVec3( pActInfo, PORT_IN_POSITION_OFFSET_LOCAL );
		const float maxDistance = max( 0.f, GetPortFloat( pActInfo, PORT_IN_MAX_LENGTH ) );

		const CCamera& camera = GetISystem()->GetViewCamera();
		
		const Vec3 cameraDirection = camera.GetViewdir();
		const Vec3 cameraPositionWorld = camera.GetPosition();
		const Matrix33 cameraOrientation = Matrix33::CreateRotationVDir( cameraDirection );
		const Vec3 positionOffsetWorld = cameraOrientation * positionOffsetLocal;

		const Vec3 rayOriginWorld = cameraPositionWorld + positionOffsetWorld;
		const Vec3 raySegment = cameraDirection * maxDistance;


		IPhysicalWorld* pWorld = gEnv->pPhysicalWorld;

		const int objectTypes = ent_all;
		const unsigned int raycastFlags = rwi_stop_at_pierceable | rwi_colltype_any;

		ray_hit hit;
		const int hitCount = pWorld->RayWorldIntersection( rayOriginWorld, raySegment, objectTypes, raycastFlags, &hit, 1 );
		
		float hitDistance = maxDistance;
		if ( 0 < hitCount )
		{
			hitDistance = hit.dist;
		}

		const float timeDelta = 0.1f;
		const float smoothTime = max( 0.f, GetPortFloat( pActInfo, PORT_IN_SMOOTH_TIME ) );
		SmoothCD( m_smoothedHitDistance, m_hitDistanceChangeRate, timeDelta, hitDistance, smoothTime );
		
		ActivateOutput( pActInfo, PORT_OUT_FOCUS_DISTANCE, m_smoothedHitDistance );

		const float focusRangeFactor = max( 0.f, GetPortFloat( pActInfo, PORT_IN_FOCUS_RANGE_FACTOR ) );
		const float focusRange = focusRangeFactor * m_smoothedHitDistance;

		ActivateOutput( pActInfo, PORT_OUT_FOCUS_RANGE, focusRange );


		const bool drawDebugInfo = GetPortBool( pActInfo, PORT_IN_DEBUG_ENABLED );
		if ( ! drawDebugInfo )
		{
			return;
		}

		IRenderer* pRenderer = gEnv->pRenderer;
		IRenderAuxGeom* pRenderAuxGeom = pRenderer->GetIRenderAuxGeom();

		ColorB rayColor = ( 0 < hitCount ) ? ColorB( 255, 255, 0 ) : ColorB( 255, 0, 0 );
		pRenderAuxGeom->DrawSphere( hit.pt, 0.1f, rayColor );
		pRenderAuxGeom->DrawLine( rayOriginWorld, rayColor, hit.pt, rayColor );

	}
Exemple #8
0
//------------------------------------------------------------------------
//chr safe to remove?
bool CGunTurret::IsTargetCloaked(IActor *pActor) const
{
	// cloak check
	if(m_turretparams.find_cloaked)
		return false;

	bool cloaked = false;

	// if destinationId assigned, target can always be found
	if(m_destinationId && pActor->GetEntityId() == m_destinationId)
		return false;

	if(cloaked && m_turretparams.light_fov != 0.f)
	{
		// if cloaked, target can only be found with searchlight
		// check if target inside light cone
		const Matrix34 &weaponTM = GetEntity()->GetSlotWorldTM(eIGS_ThirdPerson);
		Vec3 wpos(weaponTM.GetTranslation());
		Vec3 wdir(weaponTM.GetColumn1());
		Vec3 tpos(GetTargetPos(pActor->GetEntity()));

		float epsilon = 0.8f;
		Quat rot = Quat::CreateRotationAA(epsilon*0.5f*DEG2RAD(m_turretparams.light_fov), weaponTM.GetColumn2());
		Vec3 a = wpos + m_turretparams.mg_range*(wdir*rot);
		Vec3 b = wpos + m_turretparams.mg_range*(wdir*rot.GetInverted());
		bool inside = Overlap::PointInTriangle(tpos, wpos, a, b, weaponTM.GetColumn2());

		if(inside)
		{
			rot = Quat::CreateRotationAA(0.5f*DEG2RAD(m_turretparams.light_fov), weaponTM.GetColumn0());
			a = wpos + m_turretparams.mg_range*(wdir*rot);
			b = wpos + m_turretparams.mg_range*(wdir*rot.GetInverted());
			inside = Overlap::PointInTriangle(tpos, wpos, a, b, weaponTM.GetColumn0());
		}

		cloaked = !inside;

		if(g_pGameCVars->i_debug_turrets == eGTD_Search)
		{
			IRenderAuxGeom *pGeom = gEnv->pRenderer->GetIRenderAuxGeom();
			pGeom->SetRenderFlags(e_Def3DPublicRenderflags);
			float color[] = {1,1,1,1};
			Vec3 points[] = {wpos, a, b};
			pGeom->DrawPolyline(points, 3, true, ColorB(0,255,0,255));

			if(inside)
				gEnv->pRenderer->Draw2dLabel(200,200,1.4f,color,false,"target inside cone");
		}
	}

	return cloaked;
}
//------------------------------------------------------------------------
void CVehicleMovementStdBoat::DrawImpulse(const pe_action_impulse& action, const Vec3& offset, float scale, const ColorB& col)
{
  if (!is_unused(action.impulse) && action.impulse.len2()>0)
  {
    IRenderAuxGeom* pGeom = gEnv->pRenderer->GetIRenderAuxGeom();
    Vec3 start = action.point + offset;
    Vec3 end = start - (action.impulse*scale/m_pVehicle->GetMass());
    Vec3 dir = (start-end).GetNormalizedSafe();
    pGeom->DrawCone(start-1.f*dir, dir, 0.5f, 1.f, col);
    pGeom->DrawLine(start, col, end, col);
    pGeom->DrawSphere(end, 0.25f, col);
  }  
}
void DebugDrawLocation(const QuatT &location, ColorB colorPos, ColorB colorX, ColorB colorY, ColorB colorZ)
{
	IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();

	const float thickness = 7.0f;
	const Vec3  pushUp(0.0f, 0.03f, 0.0f);

	pAuxGeom->DrawLine(location.t + pushUp, colorX, location.t + pushUp + location.q.GetColumn0(), colorX, thickness);
	pAuxGeom->DrawLine(location.t + pushUp, colorY, location.t + pushUp + location.q.GetColumn1(), colorY, thickness);
	pAuxGeom->DrawLine(location.t + pushUp, colorZ, location.t + pushUp + location.q.GetColumn2(), colorZ, thickness);

	const float radius = 0.06f;
	pAuxGeom->DrawSphere(location.t + pushUp, radius, colorPos);
}
void CPlayerVisTableDebugDraw::Update()
{
	const float currentTime = gEnv->pTimer->GetCurrTime();
	const float maxDebugLifeTime = 1.0f;

	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();
	const ColorB visibleColor(0, 255, 0, 128);
	const ColorB hiddenColor(255, 0, 0, 128);
	const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};

	SAuxGeomRenderFlags oldRenderFlags = pRenderAux->GetRenderFlags();
	SAuxGeomRenderFlags newRenderFlags = e_Def3DPublicRenderflags;
	newRenderFlags.SetAlphaBlendMode(e_AlphaBlended);
	newRenderFlags.SetDepthTestFlag(e_DepthTestOff);
	newRenderFlags.SetCullMode(e_CullModeNone); 
	pRenderAux->SetRenderFlags(newRenderFlags);

	TDebugTargets::iterator targetIt = m_debugTargets.begin();
	while (targetIt != m_debugTargets.end())
	{
		SDebugInfo& targetInfo = *targetIt;

		const float lastUpdateAge = (currentTime - targetInfo.m_lastUpdatedTime);
		const bool remove = (lastUpdateAge > maxDebugLifeTime);

		if (!remove)
		{
			IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(targetInfo.m_targetId);
			if (pTargetEntity)
			{
				const ColorB& color = targetInfo.m_visible ? visibleColor : hiddenColor;
				const Vec3 worldRefPosition = pTargetEntity->GetWorldTM().TransformPoint(targetInfo.m_localTargetPos);

				const Vec3 offset(0.0f, 0.0f, 0.4f);
				pRenderAux->DrawCone(worldRefPosition + offset, -Vec3Constants<float>::fVec3_OneZ, 0.125f, offset.z, color);
				gEnv->pRenderer->DrawLabelEx(worldRefPosition, 1.5f, white, true, false, "%.2f", lastUpdateAge);
			}
			++targetIt;
		}
		else
		{
			TDebugTargets::iterator nextElement = m_debugTargets.erase(targetIt);
			targetIt = nextElement;
		}
	}

	pRenderAux->SetRenderFlags(oldRenderFlags);
}
//------------------------------------------------------------------------
void CVehicleMovementTank::Update(const float deltaTime)
{
	CVehicleMovementStdWheeled::Update(deltaTime); 

#if ENABLE_VEHICLE_DEBUG
	if (IsProfilingMovement())
	{
		if (m_steeringImpulseMin > 0.f && m_wheelContactsLeft != 0 && m_wheelContactsRight != 0)
		{  
			const Matrix34& worldTM = m_pVehicle->GetEntity()->GetWorldTM();   
			Vec3 localVel = worldTM.GetInvertedFast().TransformVector(m_statusDyn.v);
			Vec3 localW = worldTM.GetInvertedFast().TransformVector(m_statusDyn.w);
			float speed = m_statusDyn.v.len();
			float speedRatio = min(1.f, speed/m_maxSpeed);

			const float maxW = 0.3f*gf_PI;
			float steer = abs(m_currSteer)>0.001f ? m_currSteer : 0.f;    
			float desired = steer * maxW; 
			float curr = -localW.z;
			float err = desired - curr; // err>0 means correction to right 
			Limit(err, -maxW, maxW);

			if (abs(err) > 0.01f)
			{ 
				float amount = m_steeringImpulseMin + speedRatio*(m_steeringImpulseMax-m_steeringImpulseMin);

				float corr = -err * amount * m_statusDyn.mass * deltaTime;

				pe_action_impulse imp;
				imp.iApplyTime = 1;      
				imp.angImpulse = worldTM.GetColumn2() * corr;

				float color[] = {1,1,1,1};
				gEnv->pRenderer->Draw2dLabel(300,300,1.5f,color,false,"err: %.2f ", err);
				gEnv->pRenderer->Draw2dLabel(300,320,1.5f,color,false,"corr: %.3f", corr/m_statusDyn.mass);

				IRenderAuxGeom* pGeom = gEnv->pRenderer->GetIRenderAuxGeom();
				float len = 4.f * imp.angImpulse.len() / deltaTime / m_statusDyn.mass;
				Vec3 dir = (float)-sgn(corr) * worldTM.GetColumn0(); //imp.angImpulse.GetNormalized();
				pGeom->DrawCone(worldTM.GetTranslation()+Vec3(0,0,5)-(dir*len), dir, 0.5f, len, ColorB(128,0,0,255));        
			}
		}
	}    

	DebugDrawMovement(deltaTime);
#endif
}
int CScriptBind_Game::DebugDrawCone( IFunctionHandler *pH, float x, float y, float z, float radius, float height, int r, int g, int b, int a )
{
	IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
	if (pRenderAuxGeom)
	{
		SAuxGeomRenderFlags oldFlags = pRenderAuxGeom->GetRenderFlags();
		SAuxGeomRenderFlags newFlags = oldFlags;

		newFlags.SetCullMode(e_CullModeNone);
		newFlags.SetAlphaBlendMode(e_AlphaBlended);
		pRenderAuxGeom->SetRenderFlags(newFlags);

		pRenderAuxGeom->DrawCone(Vec3(x,y,z), Vec3(0.f, 0.f, 1.f), radius, height, ColorB(r,g,b,a));
		
		pRenderAuxGeom->SetRenderFlags(oldFlags);
	}
	return pH->EndFunction();
}
int CScriptBind_Game::DebugDrawAABB( IFunctionHandler *pH, float x, float y, float z, float x2, float y2, float z2, int r, int g, int b, int a )
{
	IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
	if (pRenderAuxGeom)
	{
		SAuxGeomRenderFlags oldFlags = pRenderAuxGeom->GetRenderFlags();
		SAuxGeomRenderFlags newFlags = oldFlags;

		newFlags.SetCullMode(e_CullModeNone);
		newFlags.SetAlphaBlendMode(e_AlphaBlended);
		pRenderAuxGeom->SetRenderFlags(newFlags);

		AABB bbox(Vec3(x, y, z), Vec3(x2, y2, z2));
		pRenderAuxGeom->DrawAABB(bbox, true, ColorB(r, g, b, a), eBBD_Faceted);

		pRenderAuxGeom->SetRenderFlags(oldFlags);
	}
	return pH->EndFunction();
}
//------------------------------------------------------------------------
void CGameRulesHoldObjectiveBase::DebugDrawCylinder(SHoldEntityDetails *pDetails)
{
	// Draw debug cylinder
	if(g_pGameCVars->g_holdObjectiveDebug == eHOB_Debug_Draw_Sphere)
	{
		IEntity *pHoldEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id);
		if (pHoldEntity)
		{

			IRenderAuxGeom* pAuxRenderer = gEnv->pRenderer->GetIRenderAuxGeom();
			SAuxGeomRenderFlags renderFlags = pAuxRenderer->GetRenderFlags();
			renderFlags.SetAlphaBlendMode(e_AlphaBlended);
			pAuxRenderer->SetRenderFlags(renderFlags);

			pAuxRenderer->DrawCylinder(	pHoldEntity->GetPos()+Vec3(0.f,0.f,pDetails->m_controlOffsetZ+(pDetails->m_controlHeight*0.5f)),
																	Vec3(0.0f,0.0f,1.0f),
																	pDetails->m_controlRadius,
																	pDetails->m_controlHeight,
																	ColorB(255,255,0,128));
		}
	}
}
void CHeavyMountedWeapon::Update( SEntityUpdateContext& ctx, int slot )
{
	BaseClass::Update(ctx, slot);
	
	if (m_rotatingSoundID!=INVALID_SOUNDID)
	{
		if (m_RotationSoundTimeOut>0)
		{
			m_RotationSoundTimeOut -= ctx.fFrameTime;
			RequireUpdate( eIUS_General );
		}
		else
		{
			StopSound(m_rotatingSoundID);
			m_rotatingSoundID = INVALID_SOUNDID;
		}
	}

	// Helper for editor placing
	if (gEnv->IsEditing())
	{
		// If host id is not 0, it means it is mounted to a vehicle, so don't render the helper in that case
		if (!GetHostId())
		{
			IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();

			const Matrix34& weaponTM = GetEntity()->GetWorldTM();
			const Vec3 point1 = weaponTM.GetTranslation();
			const Vec3 point2 = point1 - (m_sharedparams->pMountParams->ground_distance * weaponTM.GetColumn2());
			const Vec3 point3 = point2 - (m_sharedparams->pMountParams->body_distance * weaponTM.GetColumn1());

			pRenderAux->DrawLine(point1, ColorB(0, 192, 0), point2, ColorB(0, 192, 0), 3.0f);
			pRenderAux->DrawLine(point2, ColorB(0, 192, 0), point3, ColorB(0, 192, 0), 3.0f);
			pRenderAux->DrawSphere(point3, 0.15f, ColorB(192, 0, 0));

			RequireUpdate(eIUS_General);
		}
	}
}
void SearchSpot::DebugDraw(float searchTimeOut)
{
	ColorB spotColor;

	switch (m_status)
	{
	case NotSearchedYet:
		spotColor = ColorB(0, 0, 255);
		break;
	case BeingSearchedRightAboutNow:
		spotColor = ColorB(255, 255, 0);
		break;
	case Searched:
		spotColor = ColorB(0, 255, 0);
		break;
	case Unreachable:
		spotColor = ColorB(255, 0, 0);
		break;
	case SearchedTimingOut:
		if(searchTimeOut)
		{
			uint8 green = (uint8)(255 * clamp_tpl( (m_searchTimeoutLeft / (searchTimeOut / 2.0f)), 0.0f, 1.0f));
			uint8 blue = (uint8)(255 * clamp_tpl(((searchTimeOut - m_searchTimeoutLeft) / (searchTimeOut / 2.0f)), 0.0f, 1.0f));
			spotColor = ColorB(0, green, blue);
		}
		break;
	}

	IRenderAuxGeom* pDebugRenderer = gEnv->pRenderer->GetIRenderAuxGeom();
	pDebugRenderer->DrawSphere(m_pos, 0.3f, spotColor);

	if (m_assigneeID)
	{
		Agent agent(m_assigneeID);
		if (agent)
			pDebugRenderer->DrawLine(agent.GetPos(), ColorB(255, 255, 0), m_pos, ColorB(255, 255, 0), 2.0f);
	}
}
void SDebugCannonBallPenetration::Update(float frameTime)
{
	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();

	SAuxGeomRenderFlags oldFlags = pRenderAux->GetRenderFlags();
	SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags;
	newFlags.SetAlphaBlendMode(e_AlphaBlended);
	newFlags.SetDepthTestFlag(e_DepthTestOff);
	newFlags.SetCullMode(e_CullModeNone); 
	pRenderAux->SetRenderFlags(newFlags);

	const float baseDebugTimeOut = (g_pGameCVars->g_bulletPenetrationDebugTimeout > 0.0f) ? g_pGameCVars->g_bulletPenetrationDebugTimeout : DEFAULT_DEBUG_CannonBall_HIT_LIFETIME;

	for (int i = 0; i < MAX_DEBUG_CannonBall_HITS; ++i)
	{
		SDebugCannonBallHit& currentHit = m_hitsList[i];

		if (currentHit.lifeTime <= 0.0f)
		{
			continue;
		}

		currentHit.lifeTime -= frameTime;

		//const float alpha = powf((currentHit.lifeTime / baseDebugTimeOut), 4.0f);
		// avoid powf whenever possible, for such simple cases, can do with 2 muls
		float alpha = (currentHit.lifeTime / baseDebugTimeOut);
		alpha *= alpha;
		alpha *= alpha;

		const ColorB red(255, 0, 0, (uint8)(192 * alpha)), green(0, 255, 0, (uint8)(192 * alpha));
		const ColorB& hitColor = currentHit.stoppedCannonBall ? red : green;
		const Vec3 coneBase = currentHit.isBackFaceHit ? (currentHit.hitPosition + (currentHit.CannonBallDirection * 0.3f)) : (currentHit.hitPosition - (currentHit.CannonBallDirection * 0.2f)) ;
		const Vec3 lineEnd = (coneBase - (currentHit.CannonBallDirection * 0.3f));
		pRenderAux->DrawCone(coneBase, currentHit.CannonBallDirection, 0.12f, 0.2f, hitColor);
		pRenderAux->DrawLine(coneBase, hitColor, lineEnd, hitColor, 3.0f);

		const Vec3 baseText = (currentHit.isBackFaceHit) ? coneBase + (0.2f * currentHit.CannonBallDirection)  : lineEnd - (0.3f * currentHit.CannonBallDirection);
		const Vec3 textLineOffset(0.0f, 0.0f, 0.14f);
		const float textColor[4] = {1.0f, 1.0f, 1.0f, alpha};

		gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 2.0f), 1.25f, textColor, true, false, "Damage: %.1f", currentHit.damage);
		gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 3.0f), 1.25f, textColor, true, false, "Pierceability: %d", currentHit.surfacePierceability);
		gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 4.0f), 1.25f, textColor, true, false, "%s", GetPenetrationLevelByPierceability(currentHit.surfacePierceability));
		gEnv->pRenderer->DrawLabelEx(baseText - (textLineOffset * 5.0f), 1.25f, textColor, true, false, currentHit.tooThick ? "Too thick!" : "------");

	}

	pRenderAux->SetRenderFlags(oldFlags);
}
Exemple #19
0
void CAutoAimManager::DebugDraw()
{
	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();
	const int numAutoaimTargets = m_autoaimTargets.size();

	const Vec3 viewPos = gEnv->pSystem->GetViewCamera().GetPosition();

	SAuxGeomRenderFlags oldFlags = pRenderAux->GetRenderFlags();
	SAuxGeomRenderFlags newFlags = e_Def3DPublicRenderflags;
	newFlags.SetAlphaBlendMode(e_AlphaBlended);
	newFlags.SetDepthTestFlag(e_DepthTestOff);
	newFlags.SetCullMode(e_CullModeNone); 
	pRenderAux->SetRenderFlags(newFlags);

	const ColorB enemyColor(255,0,0,128);
	const ColorB friendlyColor(0,255,0,128);
	const ColorB followColorInner(255,255,0,64);
	const ColorB followColorOuter(255,255,0,0);
	const ColorB snapColor(255,255,255,64);

	for(int i = 0; i < numAutoaimTargets; i++)
	{
		const SAutoaimTarget& aaTarget = m_autoaimTargets[i];

		Vec3 dirToTarget = aaTarget.primaryAimPosition - viewPos;
		dirToTarget.NormalizeSafe();
		
		const float snapRadius = aaTarget.HasFlagSet(eAATF_AIRadarTagged) ?	aaTarget.snapRadiusTagged * g_pGameCVars->aim_assistSnapRadiusTaggedScale : 
																			aaTarget.snapRadius * g_pGameCVars->aim_assistSnapRadiusScale;

		pRenderAux->DrawSphere(aaTarget.primaryAimPosition, aaTarget.innerRadius, aaTarget.HasFlagSet(eAATF_AIHostile) ? enemyColor : friendlyColor);
		pRenderAux->DrawSphere(aaTarget.secondaryAimPosition, 0.2f, aaTarget.HasFlagSet(eAATF_AIHostile) ? enemyColor : friendlyColor);
		DrawDisc(aaTarget.primaryAimPosition, dirToTarget, aaTarget.innerRadius, aaTarget.outerRadius, followColorInner, followColorOuter);
		DrawDisc(aaTarget.primaryAimPosition, dirToTarget, aaTarget.outerRadius, snapRadius, followColorOuter, snapColor);
	}

	pRenderAux->SetRenderFlags(oldFlags);

	const float white[4] = {1.0f, 1.0f, 1.0f, 0.75f};
	gEnv->pRenderer->Draw2dLabel(50.0f, 50.0f, 1.5f, white, false, "Number of targets: %d", numAutoaimTargets);
}
void SearchGroup::Update()
{
	IVisionMap& visionMap = *gEnv->pAISystem->GetVisionMap();

	// Update vision
	{
		std::vector<SearchActor>::iterator actorIt = m_actors.begin();
		std::vector<SearchActor>::iterator actorEnd = m_actors.end();

		for ( ; actorIt != actorEnd; ++actorIt)
		{
			SearchActor& actor = (*actorIt);

			Agent agent(actor.entityID);
			if(!agent.IsValid())
				continue;

			ObserverParams observerParams;
			observerParams.eyePosition = agent.GetPos();
			observerParams.eyeDirection = agent.GetViewDir();

			visionMap.ObserverChanged(actor.visionID, observerParams, eChangedPosition | eChangedOrientation);
		}
	}

	// Debug draw target pos
	if (g_pGameCVars->ai_DebugSearch)
	{
		IRenderAuxGeom* pDebugRenderer = gEnv->pRenderer->GetIRenderAuxGeom();
		pDebugRenderer->DrawSphere(m_targetPos, 0.6f, ColorB(255, 255, 255, 128));
	}

	const float frameTime = gEnv->pTimer->GetFrameTime();

	std::vector<SearchSpot>::iterator spotIt = m_searchSpots.begin();
	std::vector<SearchSpot>::iterator spotEnd = m_searchSpots.end();

	for ( ; spotIt != spotEnd; ++spotIt)
	{
		SearchSpot& searchSpot = (*spotIt);

		if (g_pGameCVars->ai_DebugSearch)
			searchSpot.DebugDraw(m_searchSpotTimeout);

		if(searchSpot.IsTimingOut())
			searchSpot.UpdateSearchedTimeout(frameTime);

		if (searchSpot.HasBeenSearched())
			continue;

		// Naive Implementation!
		// Go through all the actors and see
		// if they see any of the search spots.
		// Later on, use a callback for this!

		SearchActorIter actorIt = m_actors.begin();
		std::vector<SearchActor>::iterator actorEnd = m_actors.end();

		for ( ; actorIt != actorEnd; ++actorIt)
		{
			SearchActor& actor = *actorIt;
			if (visionMap.IsVisible(actor.visionID, searchSpot))
			{
				searchSpot.MarkAsSearchedBy(actor, m_searchSpotTimeout);
				break;
			}
		}
	}
}
//------------------------------------------------------------------------
void CVehicleMovementStdBoat::Update(const float deltaTime)
{
	CVehicleMovementBase::Update(deltaTime);

	SetAnimationSpeed(eVMA_Engine, abs(m_rpmScaleSgn));
	if (m_inWater)
	{ 
		SetSoundParam(eSID_Run, "slip", 0.2f*abs(m_localSpeed.x)); 
	}

#if ENABLE_VEHICLE_DEBUG
	if (IsProfilingMovement() && g_pGameCVars->v_profileMovement != 2)
	{
		IEntity* pEntity = m_pVehicle->GetEntity();
		const Matrix34& wTM = pEntity->GetWorldTM();  
		Matrix34 wTMInv = wTM.GetInvertedFast();
		
		const SVehiclePhysicsStatus* physStatus = &m_physStatus[k_mainThread];
		Vec3 localW = physStatus->q * physStatus->w;

		float speed = physStatus->v.len2() > 0.001f ? physStatus->v.len() : 0.f;    
		float speedRatio = min(1.f, speed/(m_maxSpeed*m_factorMaxSpeed));  
		float absPedal = abs(m_movementAction.power);
		float absSteer = abs(m_movementAction.rotateYaw);
		
		static const float fSubmergedMin = 0.01f;
		static const float fWaterLevelMaxDiff = 0.15f; // max allowed height difference between propeller center and water level

		Vec3 worldPropPos = wTM * m_pushOffset;  
		float waterLevelWorld = gEnv->p3DEngine->GetWaterLevel( &worldPropPos );
		float fWaterLevelDiff = worldPropPos.z - waterLevelWorld;  

		// wave stuff 
		float waveFreq = 1.f;
		waveFreq += 3.f*speedRatio;

		float kx = m_waveIdleStrength.x*(m_waveRandomMult+0.3f) * (1.f-speedRatio + m_waveSpeedMult*speedRatio);
		float ky = m_waveIdleStrength.y * (1.f - 0.5f*absPedal - 0.5f*absSteer);
		Vec3 waveLoc = m_massOffset;
		waveLoc.y += speedRatio*min(0.f, m_pushOffset.y-m_massOffset.y);
		waveLoc = wTM * waveLoc;

		IRenderer* pRenderer = gEnv->pRenderer;
		static float color[4] = {1,1,1,1};    
		float colorRed[4] = {1,0,0,1};
		float colorGreen[4] = {0,1,0,1};
		float y=50.f, step1=15.f, step2=20.f, size1=1.3f, size2=1.5f;

		pRenderer->Draw2dLabel(5.0f,   y, size2, color, false, "Boat movement");
		pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, color, false, "Speed: %.1f (%.1f km/h)", speed, speed*3.6f);
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "LocalW.z norm: %.2f", abs(localW.z)/m_turnRateMax);
		if (m_velLift > 0.f)
		{
			pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, m_lifted ? colorGreen : color, false, m_lifted ? "Lifted" : "not lifted");
			//pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, color, false, "Impulse lift: %.0f", liftImp.impulse.len());               
		}    
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, physStatus->submergedFraction > fSubmergedMin ? color : colorRed, false, "Submerged: %.2f", physStatus->submergedFraction);
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, fWaterLevelDiff < fWaterLevelMaxDiff ? color : colorRed, false, "WaterLevel: %.2f (max: %.2f)", fWaterLevelDiff, fWaterLevelMaxDiff);

		pRenderer->Draw2dLabel(5.0f,  y+=step2, size2, color, false, "Driver input");
		pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, color, false, "power: %.2f", m_movementAction.power);
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "steer: %.2f", m_movementAction.rotateYaw); 

		pRenderer->Draw2dLabel(5.0f,  y+=step2, size2, color, false, "Propelling");
		//pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, color, false, "turnAccel (norm/real): %.2f / %.2f", turnAccelNorm, turnAccel);         
		//pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "Impulse acc: %.0f", linearImp.impulse.len());         
		//pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "Impulse steer/damp: %.0f", angularImp.angImpulse.len()); 
		//pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "Impulse corner: %.0f", dampImp.impulse.len());

		pRenderer->Draw2dLabel(5.0f,  y+=step2, size2, color, false, "Waves");
		pRenderer->Draw2dLabel(5.0f,  y+=step2, size1, color, false, "timer: %.1f", m_waveTimer); 
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "frequency: %.2f", waveFreq); 
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "random: %.2f", m_waveRandomMult); 
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "kX: %.2f", kx);     
		pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "kY: %.2f", ky); 

		if (Boosting())
			pRenderer->Draw2dLabel(5.0f,  y+=step1, size1, color, false, "Boost: %.2f", m_boostCounter);

		IRenderAuxGeom* pGeom = pRenderer->GetIRenderAuxGeom();
		ColorB colorB(0,255,0,255);

		pRenderer->DrawLabel(worldPropPos, 1.3f, "WL: %.2f", waterLevelWorld);

		pGeom->DrawSphere(worldPropPos, 0.15f, colorB);
		pGeom->DrawSphere(waveLoc, 0.25f, colorB);
		pGeom->DrawLine(waveLoc, colorB, waveLoc+Vec3(0,0,2), colorB);

		// impulses
		//DrawImpulse(linearImp, Vec3(0,0,1), 3.f/deltaTime, ColorB(255,0,0,255));
		//DrawImpulse(angularImp, Vec3(0,0,1), 2.f/deltaTime, ColorB(128,0,0,255));          
		//DrawImpulse(liftImp, Vec3(0,0,6), 2.f/deltaTime, ColorB(0,0,255,255));
	}
#endif
}
//------------------------------------------------------------------------
void CDebugGun::Update( SEntityUpdateContext& ctx, int update)
{ 
  if (!IsSelected())
    return;
  
  static float drawColor[4] = {1,1,1,1};
  static const int dx = 5; 
  static const int dy = 15;
  static const float font = 1.2f;
  static const float fontLarge = 1.4f;

  IRenderer* pRenderer = gEnv->pRenderer;
  IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom();
  pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);

  pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second);      

  ray_hit rayhit;
  int hits = 0;
  
  unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
  if (m_fireModes[m_fireMode].first == "pierceability")
  { 
    flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask;
  }
  
  // use cam, no need for firing pos/dir
  CCamera& cam = GetISystem()->GetViewCamera();

  if (hits = gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1))
  {
    IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager();
    IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
    IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
    
    int x = (int)(pRenderer->GetWidth() *0.5f) + dx;
    int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy;

    // draw normal
    ColorB colNormal(200,0,0,128);
    Vec3 end = rayhit.pt + 0.75f*rayhit.n;
    pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal);
    pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal);

    IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
    if(pEntity)
    {  
      pRenderer->Draw2dLabel(x, y+=dy, fontLarge, drawColor, false, pEntity->GetName());      
    }
    
    // material
    const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName();

    if (matName[0])      
      pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx);

    pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f m", rayhit.dist);

    if (pEntity)
    {
      IScriptTable* pScriptTable = pEntity->GetScriptTable();

      // physics 
      if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics())
      {
        pe_status_dynamics status;
        if (pPhysEnt->GetStatus(&status))
        {        
          if (status.mass > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f kg", status.mass);

          pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "pe_type: %i", pPhysEnt->GetType());                

          if (status.submergedFraction > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f submerged", status.submergedFraction);

          if (status.v.len2() > 0.0001f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f m/s", status.v.len());
        }   
      }  

      if (pScriptTable)
      {
        HSCRIPTFUNCTION func = 0;
        if (pScriptTable->GetValue("GetFrozenAmount", func) && func)
        {
          float frozen = 0.f;
          Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, frozen);
					gEnv->pScriptSystem->ReleaseFunc(func);
          
          if (frozen > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Frozen: %.2f", frozen); 
        }
      }
     
      // class-specific stuff
      if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId()))
      {
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i health", pActor->GetHealth());
      }
      else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId()))
      {
        const SVehicleStatus& status = pVehicle->GetStatus();
        
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f%% health", 100.f*status.health);
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i passengers", status.passengerCount);
        
        if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered())
        {
          pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Running");
        }
      }
      else
      {
        if (pScriptTable)
        {
          HSCRIPTFUNCTION func = 0;
          if (pScriptTable->GetValue("GetHealth", func) && func)
          {
            float health = 0.f;
            if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health))
            {
              pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f health", health);
            }
						gEnv->pScriptSystem->ReleaseFunc(func);
          }
        }
      }
    }    
  }  
}
Exemple #23
0
//----------------------------------------------------------------------------
void CHomingMissile::UpdateCruiseMissile(float frameTime)
{

	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 (m_targetId)
	{
		IEntity* pTarget = gEnv->pEntitySystem->GetEntity(m_targetId);
		if (pTarget)
		{
			AABB box;
			pTarget->GetWorldBounds(box);
			SetDestination( box.GetCenter() );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName());
		}    
	}
	else 
	{
		// update destination pos from weapon
		static IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
		IItem* pItem = pItemSystem->GetItem(m_weaponId);
		if (pItem && pItem->GetIWeapon())
		{
			const Vec3& dest = pItem->GetIWeapon()->GetDestination();
			SetDestination( dest );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Weapon Destination: (%.1f %.1f %.1f)", dest.x, dest.y, dest.z);
		}
	}

	pe_status_dynamics status;
	if (!GetEntity()->GetPhysics()->GetStatus(&status))
		return;

	float currentSpeed = status.v.len();
	Vec3 currentPos = GetEntity()->GetWorldPos();
	Vec3 goalDir(ZERO);

	if (!m_destination.IsZero())
	{

		if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius))
		{
			Explode(true, true, m_destination, -status.v.normalized(), status.v, m_targetId);
			return;
		}

		if (bDebug)
			pGeom->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255));

		float heightDiff = (m_cruiseAltitude-m_alignAltitude) - currentPos.z;

		if (!m_isCruising && heightDiff * sgn(status.v.z) > 0.f)
		{
			// if heading towards align altitude (but not yet reached) accelerate to max speed    
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step,   1.5f, color, false, "[HomingMissile] accelerating (%.1f / %.1f)", currentSpeed, m_maxSpeed);    
		}
		else if (!m_isCruising && heightDiff * sgnnz(status.v.z) < 0.f && (status.v.z<0 || status.v.z>0.25f))
		{
			// align to cruise
			if (currentSpeed != 0)
			{
				goalDir = status.v;
				goalDir.z = 0;
				goalDir.normalize();
			}    

			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] aligning"); 
		}
		else
		{
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] cruising..."); 

			// cruise
			m_isCruising = true;

			if (!m_destination.IsZero())
			{
				float groundDistSq = m_destination.GetSquaredDistance2D(currentPos);
				float distSq = m_destination.GetSquaredDistance(currentPos);
				float descendDistSq = sqr(m_descendDistance);

				if (m_isDescending || groundDistSq <= descendDistSq)
				{
					if (bDebug)
						pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] descending!"); 

					if (distSq != 0)
						goalDir = (m_destination - currentPos).normalized();
					else 
						goalDir.zero();

					m_isDescending = true;
				}              
				else
				{
					Vec3 airPos = m_destination;
					airPos.z = currentPos.z;          
					goalDir = airPos - currentPos;
					if (goalDir.len2() != 0)
						goalDir.Normalize();
				}    
			}
		}
	}  

	float desiredSpeed = currentSpeed;
	if (currentSpeed < m_maxSpeed-0.1f)
	{
		desiredSpeed = min(m_maxSpeed, desiredSpeed + m_accel*frameTime);
	}

	Vec3 currentDir = status.v.GetNormalizedSafe(FORWARD_DIRECTION);
	Vec3 dir = currentDir;

	if (!goalDir.IsZero())
	{ 
		float cosine = max(min(currentDir.Dot(goalDir), 0.999f), -0.999f);
		float goalAngle = RAD2DEG(acos_tpl(cosine));
		float maxAngle = m_turnSpeed * frameTime;

		if (bDebug)
		{ 
			pGeom->DrawCone( currentPos, goalDir, 0.4f, 12.f, ColorB(255,0,0,255) );
			pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] goalAngle: %.2f", goalAngle); 

		}

		if (goalAngle > maxAngle+0.05f)    
			dir = (Vec3::CreateSlerp(currentDir, goalDir, maxAngle/goalAngle)).normalize();
		else //if (goalAngle < 0.005f)
			dir = goalDir;
	}

	pe_action_set_velocity action;
	action.v = dir * desiredSpeed;
	GetEntity()->GetPhysics()->Action(&action);

	if (bDebug)
	{
		pGeom->DrawCone( currentPos, dir, 0.4f, 12.f, ColorB(128,128,0,255) );  
		pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] currentSpeed: %.1f (max: %.1f)", currentSpeed, m_maxSpeed); 
	}
}
Exemple #24
0
//------------------------------------------------------------------------
Vec3 CGunTurret::GetSweepPos(IEntity *pTarget, const Vec3 &shootPos)
{
	pTarget=ResolveTarget(pTarget);

	// sweep on ground
	int nhints = m_fireparams.hints.size();
	float sweepTime = m_turretparams.sweep_time / (float)nhints;
	float timeFiring = max(0.f, GetBurstTime() - sweepTime*(m_fireHint-1));
	float sweepRelTime = min(1.f, timeFiring/sweepTime);

	if(sweepRelTime == 1.f && m_fireHint == nhints)
		return shootPos;

	Vec3 wpos(GetWeaponPos());
	Vec3 dir = shootPos - wpos;
	Vec3 dir2d(dir.x, dir.y, 0.f);
	float dist2d = dir2d.GetLength();

	if(dist2d < 2.f*m_fireparams.hints[0].y)
		return shootPos; // don't sweep when target too close

	dir2d /= dist2d;
	Vec3 right = Vec3(0,0,-1) % dir2d;
	Vec3 zoffset(0,0,0);

	if(IPhysicalEntity *pPE = pTarget->GetPhysics())
	{
		pe_status_pos ppos;

		if(pPE->GetStatus(&ppos))
			zoffset=Vec3(0,0,-0.5f*(ppos.BBox[1].z-ppos.BBox[0].z));
	}

	Vec3 lastHintPos(shootPos);
	const Vec2 &lastHint = m_fireparams.hints[m_fireHint-1];
	lastHintPos += lastHint.y*-dir2d + lastHint.x*right + zoffset;

	Vec3 nextHintPos(shootPos);

	if(m_fireHint < nhints)
	{
		const Vec2 &nextHint = m_fireparams.hints[m_fireHint];
		nextHintPos += nextHint.y*-dir2d + nextHint.x*right + zoffset;
	}

	Vec3 currPos = Vec3::CreateLerp(lastHintPos, nextHintPos, sweepRelTime);

	if(sweepRelTime == 1.f && m_fireHint < nhints)
		++m_fireHint;

	if(g_pGameCVars->i_debug_turrets == eGTD_Sweep)
	{
		IRenderAuxGeom *pGeom = gEnv->pRenderer->GetIRenderAuxGeom();
		pGeom->SetRenderFlags(e_Def3DPublicRenderflags);
		ColorB col(0,255,255,128);
		pGeom->DrawSphere(currPos, 0.3f, col);
		pGeom->DrawSphere(lastHintPos, 0.3f, col);
		pGeom->DrawSphere(nextHintPos, 0.3f, col);
		pGeom->DrawLine(lastHintPos, col, nextHintPos, col);
		gEnv->pRenderer->DrawLabel(currPos, 1.4f, "sweep, hint %i, ratio %.2f)", m_fireHint, sweepRelTime);
	}

	return currPos;
}
Exemple #25
0
	void Draw()
	{
		IRenderAuxGeom* pRender = gEnv->pRenderer->GetIRenderAuxGeom();
		SAuxGeomRenderFlags flags = pRender->GetRenderFlags();
		SAuxGeomRenderFlags oldFlags = pRender->GetRenderFlags();
		flags.SetDepthWriteFlag(e_DepthWriteOff);
		flags.SetDepthTestFlag(e_DepthTestOff);
		pRender->SetRenderFlags(flags);
	
		m_timer += gEnv->pTimer->GetFrameTime();
		if (m_timer>30.f) m_timer = 0.f;
		float time = gEnv->pTimer->GetCurrTime();
		float dt = (1.f/50.f);
		Vec3 offset = Vec3(0.f, 0.f, 0.025f + 0.003f*sinf(8.f*m_timer));
		Vec3 offset2 = Vec3(0.f, 0.f, 0.035f + 0.003f*sinf(5.f*m_timer));

		ColorB desiredColour = ColorB(255,0,0,255);  // Red
		ColorB desiredVelColour = ColorB(255,(int)(128.f+127.f*sinf(8.f*m_timer)),0,255);  // Yellow/Red
		ColorB actualPosColour = ColorB(0,255,0,255);  // Green
		ColorB actualVelColour = ColorB(0,0,(int)(128.f+127.f*sinf(5.f*m_timer)),255);  // blue/black
		ColorB snapPosColour = ColorB(255,255,255,255); // White
		ColorB lerpErrorColour = ColorB(255,0,0,255); // Red
		
		// Draw the desired positions
		for (unsigned int i=0; i<m_desired.size(); i++)
		{
			Desired &d = m_desired[i];
			pRender->DrawSphere(d.pos + offset, 0.025f, desiredColour);
			pRender->DrawLine(d.pos + offset, desiredVelColour, d.pos + offset + d.vel*dt, desiredVelColour);
		}

		if(g_pGameCVars->pl_debugInterpolation == 1) // Show entity position + velocity
		{
			for (unsigned int i=0; i<m_actual.size(); i++)
			{
				Actual &a = m_actual[i];
				pRender->DrawSphere(a.pos + offset2, 0.025f, a.snapped ? snapPosColour : actualPosColour);
				pRender->DrawLine(a.pos + offset2, actualVelColour, a.pos + offset2 + a.vel*dt, actualVelColour);
			}
		}

		if(g_pGameCVars->pl_debugInterpolation == 2) // Show entity position + lerpError
		{
			for (unsigned int i=0; i<m_actual.size(); i++)
			{
				Actual &a = m_actual[i];
				pRender->DrawSphere(a.pos + offset2, 0.025f, a.snapped ? snapPosColour : actualPosColour);
				pRender->DrawLine(a.pos + offset2, lerpErrorColour, a.pos + offset2 + a.lerpError, lerpErrorColour);
			}
		}
		
		pRender->SetRenderFlags(oldFlags);
	}
Exemple #26
0
void CClaymore::Update(SEntityUpdateContext &ctx, int updateSlot)
{
	CProjectile::Update(ctx, updateSlot);

	bool debug = (g_pGameCVars->g_debugMines != 0);

	if(gEnv->bServer)
	{
		if(m_armed)
		{
			CGameRules* pGR = g_pGame->GetGameRules();
			if(pGR)
			{
				for(std::list<EntityId>::iterator it = m_targetList.begin(); it != m_targetList.end(); ++it)
				{
					IEntity* pEntity = gEnv->pEntitySystem->GetEntity(*it);
					if(!pEntity) continue;
						
					// if this is a team game, claymores aren't set off by their own team...
					if(pGR->GetTeamCount() > 0 && (m_teamId != 0 && pGR->GetTeam(pEntity->GetId()) == m_teamId))
						continue;

					// otherwise, not set off by the player who dropped them.
					if(pGR->GetTeamCount() == 0 && m_ownerId == pEntity->GetId())
						continue;
					
					IPhysicalEntity *pPhysics = pEntity->GetPhysics();
					if(pPhysics)
					{
						pe_status_dynamics physStatus;
						if(0 != pPhysics->GetStatus(&physStatus) && physStatus.v.GetLengthSquared() > 0.01f)
						{
							// now check angle between this claymore and approaching object
							//	to see if it is within the angular range m_triggerAngle.
							//	If it is, then check distance is less than m_triggerRange,
							//	and also check line-of-sight between the two entities.
							IRenderAuxGeom * pRAG = gEnv->pRenderer->GetIRenderAuxGeom();
							pRAG->SetRenderFlags( e_Mode3D | e_AlphaBlended | e_DrawInFrontOff | e_FillModeSolid | e_CullModeNone );

							AABB entityBBox;	
							pEntity->GetWorldBounds(entityBBox);

							if(debug)
							{
								pRAG->DrawAABB( entityBBox, true, ColorF(1,0,0,0.4f), eBBD_Faceted );
							}

							Vec3 enemyDir = entityBBox.GetCenter() - GetEntity()->GetPos();
							Vec3 checkDir = enemyDir; 
							checkDir.z = 0;
							float distanceSq = enemyDir.GetLengthSquared();

							// for players a simple distance check is fine, but for vehicles use a better intersection check
							//	so any corner of the vehicle going inside the zone sets off the claymore.
							static float playerRadius = 2.5f;
							bool inside = false;
							if(entityBBox.GetRadius() < playerRadius)
							{
								inside = (distanceSq < (m_triggerRadius * m_triggerRadius));
							}
							else
							{							
								static ray_hit hit;
								if(gEnv->pPhysicalWorld->CollideEntityWithBeam(pEntity->GetPhysics(), GetEntity()->GetWorldPos(), enemyDir, m_triggerRadius, &hit))
								{
									inside = true;
									enemyDir = hit.pt - GetEntity()->GetWorldPos();
								}
							}

							if(inside)
							{
								enemyDir.NormalizeSafe();
								checkDir.NormalizeSafe();
								float dotProd = checkDir.Dot(m_triggerDirection);

								if(debug)
								{
									pRAG->DrawLine(GetEntity()->GetPos(), ColorF(1,0,0,1), GetEntity()->GetPos() + Matrix33::CreateRotationZ(m_triggerAngle/2.0f)*m_triggerDirection*m_triggerRadius, ColorF(1,0,0,1), 5.0f);
									pRAG->DrawLine(GetEntity()->GetPos(), ColorF(1,0,0,1), GetEntity()->GetPos() + Matrix33::CreateRotationZ(-m_triggerAngle/2.0f)*m_triggerDirection*m_triggerRadius, ColorF(1,0,0,1), 5.0f);

									ColorF clr;
									clr.a = 0.3f;
									clr.b = 0.4f;
									clr.g = 0.1f;
									clr.r = 1.0f;
									pRAG->DrawLine(GetEntity()->GetPos(), clr, GetEntity()->GetPos() + (enemyDir * m_triggerRadius), clr, 5.0f);
								}

								if(dotProd > cry_cosf(m_triggerAngle/2.0f))
								{
									static const int objTypes = ent_all&(~ent_terrain);   
									static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
									ray_hit hit;
									int col = gEnv->pPhysicalWorld->RayWorldIntersection(GetEntity()->GetPos(), (enemyDir * m_triggerRadius * 1.5f), objTypes, flags, &hit, 1, GetEntity()->GetPhysics());

									bool bang = false;
									if (!col)
										bang = true;
									else if (entityBBox.IsContainPoint(hit.pt))
										bang = true;
									else if (hit.pt.GetSquaredDistance(GetEntity()->GetWorldPos()) >= distanceSq)
										bang = true;
									if (bang)
									{
										// pass in the explosion normal, which is -m_triggerDirection
										Explode(true, false, Vec3(0,0,0), -m_triggerDirection);

										if(debug)
										{
											ColorF clr;
											clr.a = 0.3f;
											clr.g = 0.1f;
											clr.r = 1.0f;
											clr.b = 1.0f;
											pRAG->DrawLine(GetEntity()->GetPos(), clr, GetEntity()->GetPos() + (enemyDir * m_triggerRadius), clr, 5.0f);
										}
									}
								}
							}
						}
					}
				}
			}
		}
		else
		{
			m_timeToArm -= gEnv->pTimer->GetFrameTime();
			if(m_timeToArm <= 0.0f)
			{
				m_armed = true;

				IEntityTriggerProxy *pTriggerProxy = (IEntityTriggerProxy*)(GetEntity()->GetProxy(ENTITY_PROXY_TRIGGER));

				if (!pTriggerProxy)
				{
					GetEntity()->CreateProxy(ENTITY_PROXY_TRIGGER);
					pTriggerProxy = (IEntityTriggerProxy*)GetEntity()->GetProxy(ENTITY_PROXY_TRIGGER);
				}

				if(pTriggerProxy)
				{
					// create a trigger volume a couple of metres bigger than we need, to ensure we catch vehicles.
					//	Checks above will still make sure the entity is within the radius before detonating though.
					float radius = m_triggerRadius + 2.0f;
					AABB boundingBox = AABB(Vec3(-radius,-radius,-radius), Vec3(radius,radius,radius));
					pTriggerProxy->SetTriggerBounds(boundingBox);
				}
			}
		}
	}

	if(debug && m_armed)
	{
		IRenderAuxGeom * pRAG = gEnv->pRenderer->GetIRenderAuxGeom();
		ColorF clr;
		clr.a = 0.3f;
		clr.b = 0.4f;
		clr.g = 0.1f;
		clr.r = 1.0f;
		pRAG->SetRenderFlags( e_Mode3D | e_AlphaBlended | e_DrawInFrontOff | e_FillModeSolid | e_CullModeNone );
		pRAG->DrawCylinder(GetEntity()->GetPos(), Vec3(0, 0, 1), m_triggerRadius, m_triggerRadius * 2.0f, clr);
		Vec3 size(m_triggerRadius + 2.0f, m_triggerRadius + 2.0f, m_triggerRadius + 2.0f);
		AABB box(GetEntity()->GetPos() - size, GetEntity()->GetPos() + size);
		pRAG->DrawAABB(box, false, ColorF(0.1f, 0.1f, 0.1f, 0.1f), eBBD_Faceted);
		pRAG->DrawLine(GetEntity()->GetPos(), clr, GetEntity()->GetPos() + m_triggerDirection, clr, 5.0f);
	}
}
Exemple #27
0
void CNetPlayerInput::UpdateInterpolation()
{
	Vec3 desiredPosition = m_curInput.position;

	Vec3 entPos = m_pPlayer->GetEntity()->GetPos();
	Vec3 displacement = desiredPosition - entPos;
	displacement.z = 0.0f;
	float dist = displacement.len();

	CTimeValue	curTime=gEnv->pTimer->GetFrameStartTime();
	Vec3 desiredVelocity = m_curInput.deltaMovement * g_pGameCVars->pl_netSerialiseMaxSpeed;
	m_netDesiredSpeed = desiredVelocity.GetLength2D();

	if (m_newInterpolation)
	{
		InitialiseInterpolation(dist, displacement, desiredVelocity, curTime);
	}

	float dt = curTime.GetDifferenceInSeconds(m_netLastUpdate) + k_lerpTargetTime;
	dt = min(dt, k_maxPredictTime);
	m_predictedPosition = desiredPosition + (desiredVelocity * dt);

	Vec3 predOffset = m_predictedPosition - entPos;
	float predDist = predOffset.GetLength2D();

	float lerpSpeed = (predDist/k_lerpTargetTime);
	lerpSpeed=clamp(lerpSpeed, k_minInterpolateSpeed, k_maxInterpolateSpeed);

	m_netLerpSpeed = lerpSpeed;

	UpdateErrorSnap(entPos, desiredPosition, dist, displacement, curTime);

	if (!m_passedNetPos && (m_initialDir.Dot(displacement) < 0.0f))
	{
		m_passedNetPos = true;
	}
	Vec3 maxPrediction = desiredPosition + (desiredVelocity * k_maxPredictTime);
	if (m_passedNetPos && !m_passedPredictionPos && (m_initialDir.Dot(maxPrediction - entPos) < 0.0f))
	{
		m_passedPredictionPos = true;
	}

#if !defined(_RELEASE)

	if (g_pGameCVars->pl_debugInterpolation)
	{
		CryWatch("Cur: (%f, %f, %f) Des: (%f, %f, %f) Pred: (%f, %f, %f) ", entPos.x, entPos.y, entPos.z, desiredPosition.x, desiredPosition.y, desiredPosition.z, m_predictedPosition.x, m_predictedPosition.y, m_predictedPosition.z);
		CryWatch("BlockTime: (%f) PredictTime (%f) LastNetTime (%f) CurTime (%f)", m_blockedTime, dt, m_netLastUpdate.GetSeconds(), curTime.GetSeconds());
		CryWatch("Lerp Speed: (%f) Passed pred pos (%d) Passed net pos (%d)", m_netLerpSpeed, m_passedPredictionPos, m_passedNetPos);
		CryWatch("InputSpeed: (%f, %f, %f) ", desiredVelocity.x, desiredVelocity.y, desiredVelocity.z);

		IRenderAuxGeom* pRender = gEnv->pRenderer->GetIRenderAuxGeom();

		SAuxGeomRenderFlags flags = pRender->GetRenderFlags();
		SAuxGeomRenderFlags oldFlags = pRender->GetRenderFlags();
		flags.SetDepthWriteFlag(e_DepthWriteOff);
		flags.SetDepthTestFlag(e_DepthTestOff);
		pRender->SetRenderFlags(flags);
		pRender->DrawSphere(desiredPosition + Vec3(0.0f, 0.0f, 0.035f), 0.07f, ColorB(255,0,0,255));
		pRender->DrawSphere(m_predictedPosition + Vec3(0.0f, 0.0f, 0.025f), 0.05f, ColorB(255,255,255,255));
		pRender->SetRenderFlags(oldFlags);

		ColorF ballCol = m_passedPredictionPos ? ColorF(1.0f,1.0f,0.0f,0.75f) : (m_passedNetPos ? ColorF(1.0f,1.0f,1.0f,0.75f) : ColorF(0.0f,1.0f,0.0f,0.75f));

		g_pGame->GetIGameFramework()->GetIPersistantDebug()->Begin("INTERPOLATION TRAIL", false);
		g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(desiredPosition + Vec3(0.0f, 0.0f, 0.1f),  0.04f, ColorF(1.0f,0.0f,0.0f,0.75f), 30.f);
		g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(m_predictedPosition + Vec3(0.0f, 0.0f, 0.1f),  0.03f, ColorF(0.0f,0.0f,1.0f,0.8f), 30.f);

		ballCol.a = 1.0f;
		g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddSphere(entPos + Vec3(0.0f, 0.0f, 0.1f),  0.02f, ballCol, 30.f);
		g_pGame->GetIGameFramework()->GetIPersistantDebug()->AddLine(entPos + Vec3(0.0f, 0.0f, 0.1f), m_predictedPosition + Vec3(0.0f, 0.0f, 0.1f), ballCol, 30.f);
	}

#endif //!_RELEASE
}
void CVehiclePartSuspensionPart::Update(const float frameTime)
{
	inherited::Update(frameTime);

	const Matrix34& parentTm = m_pParentPart->GetLocalTM(false);
	const Matrix34& targetTm = m_targetPart->GetLocalTM(false);

	Vec3 pos = parentTm * m_pos0;
 	Vec3 targetPos = (m_ikFlags&k_flagIgnoreTargetRotation) ? (targetTm.GetColumn3() + m_targetOffset) : (targetTm * m_targetOffset);
 	Vec3 dir = targetPos - pos;
	float length = dir.GetLength();
	if (length > 1e-2f)
	{
		Matrix33 rot = Matrix33::CreateRotationV0V1(m_direction0, dir*(1.f/length));
		Matrix33 partRot = rot*Matrix33(m_initialRot);

		if (m_mode==k_modeRotate || m_mode==k_modeSnapToEF)
		{
			if (m_mode==k_modeSnapToEF)
			{
				pos = targetPos - rot * m_direction0;
			}
			Matrix34 tm(partRot, pos);
			SetLocalTM(tm);
		}
		else if (m_mode==k_modeStretch)
		{
			const float scale = length * m_invLength0;
			const Vec3 z = m_direction0;
			const Vec3 sz = m_direction0*(scale-1.f);
			Matrix33 scaleM;
			scaleM.m00 = 1.f+sz.x*z.x; scaleM.m01 =  sz.y*z.x    ; scaleM.m02 =  sz.z*z.x;
			scaleM.m10 = sz.x*z.y    ; scaleM.m11 =  1.f+sz.y*z.y; scaleM.m12 =  sz.z*z.y;
			scaleM.m20 = sz.x*z.z    ; scaleM.m21 =  sz.y*z.z    ; scaleM.m22 =  1.f+sz.z*z.z;
			Matrix34 tm(partRot * scaleM, pos);
			SetLocalTM(tm);
		}
	}

#if !defined(_RELEASE)
	if (VehicleCVars().v_debugSuspensionIK)
	{
		IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
		SAuxGeomRenderFlags flags = pAuxGeom->GetRenderFlags();
		SAuxGeomRenderFlags oldFlags = pAuxGeom->GetRenderFlags();
		flags.SetDepthWriteFlag(e_DepthWriteOff);
		flags.SetDepthTestFlag(e_DepthTestOff);
		pAuxGeom->SetRenderFlags(flags);
	
		ColorB colRed(255,0,0,255);
		ColorB colBlue(0,0,255,255);
		ColorB colWhite(255,255,255,255);
		ColorB colGreen(0,255,0,255);

		pos = m_pVehicle->GetEntity()->GetWorldTM() * pos;
		targetPos = m_pVehicle->GetEntity()->GetWorldTM() * targetPos;
		pAuxGeom->DrawSphere(pos, 0.02f, colGreen);
		pAuxGeom->DrawSphere(targetPos, 0.02f, colBlue);
		pAuxGeom->DrawLine(pos, colWhite, targetPos, colWhite);
	}
#endif
}
Exemple #29
0
void CPersistantDebug::Update( float frameTime )
{
	if (m_objects.empty())
		return;

	IRenderAuxGeom * pAux = gEnv->pRenderer->GetIRenderAuxGeom();
	static const int flags3D = e_Mode3D | e_AlphaBlended | e_DrawInFrontOff | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn;
	static const int flags2D = e_Mode2D | e_AlphaBlended;

	std::vector<ListObj::iterator> toClear;
	std::vector<MapListObj::iterator> toClearMap;
	for (MapListObj::iterator iterMap = m_objects.begin(); iterMap != m_objects.end(); ++iterMap)
	{
		toClear.resize(0);
		for (ListObj::iterator iterList = iterMap->second.begin(); iterList != iterMap->second.end(); ++iterList)
		{
			iterList->timeRemaining -= frameTime;
			if (iterList->timeRemaining <= 0.0f && !(iterList->obj == eOT_EntityTag && iterList->columns.size() > 1))
				toClear.push_back(iterList);
			else
			{
				ColorF clr = iterList->clr;
				clr.a *= iterList->timeRemaining / iterList->totalTime;
				switch (iterList->obj)
				{
				case eOT_Sphere:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawSphere( iterList->pos, iterList->radius, clr );
					break;
				case eOT_Quat:
					pAux->SetRenderFlags( flags3D );
					{
						float r = iterList->radius;
						Vec3 x = r * iterList->q.GetColumn0();
						Vec3 y = r * iterList->q.GetColumn1();
						Vec3 z = r * iterList->q.GetColumn2();
						Vec3 p = iterList->pos;
						OBB obb = OBB::CreateOBB( Matrix33::CreateIdentity(), Vec3(0.05f,0.05f,0.05f), ZERO );
						pAux->DrawOBB( obb, p, false, clr, eBBD_Extremes_Color_Encoded );
						pAux->DrawLine( p, ColorF(1,0,0,clr.a), p+x, ColorF(1,0,0,clr.a) );
						pAux->DrawLine( p, ColorF(0,1,0,clr.a), p+y, ColorF(0,1,0,clr.a) );
						pAux->DrawLine( p, ColorF(0,0,1,clr.a), p+z, ColorF(0,0,1,clr.a) );
					}
					break;
				case eOT_Arrow:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawLine( iterList->pos - iterList->dir * iterList->radius, clr, iterList->pos + iterList->dir * iterList->radius, clr );
					pAux->DrawCone( iterList->pos + iterList->dir * iterList->radius, iterList->dir, 0.1f * iterList->radius, 0.3f * iterList->radius, clr );
					break;
				case eOT_Line:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawLine( iterList->pos, clr, iterList->pos + iterList->dir, clr );
					break;
				case eOT_Cone:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawCone( iterList->pos, iterList->dir, iterList->radius, iterList->radius2, clr );
					break;
				case eOT_Cylinder:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawCylinder( iterList->pos, iterList->dir, iterList->radius, iterList->radius2, clr );
					break;
				case eOT_AABB:
					pAux->SetRenderFlags( flags3D );
					pAux->DrawAABB( AABB(iterList->pos,iterList->dir), Matrix34(IDENTITY), false, clr, eBBD_Faceted );
					break;
				case eOT_Line2D:
					pAux->SetRenderFlags( flags2D );
					pAux->DrawLine( iterList->pos, clr, iterList->dir, clr );
					break;
				case eOT_Text:
					{
						float clrAry[4] = {clr.r, clr.g, clr.b, clr.a};
						gEnv->pRenderer->Draw2dLabel( iterList->pos.x, iterList->pos.y, iterList->radius, clrAry, false, "%s", iterList->text.c_str() );
					}
					break;
				case eOT_Disc:
					{
						pAux->SetRenderFlags( flags3D );
						vtx_idx indTriQuad[ 6 ] = 
						{
							0, 2, 1, 
							0, 3, 2
						};	
						vtx_idx indTriTri[ 3 ] = 
						{
							0, 1, 2
						};	

						int steps = (int)(10 * iterList->radius2);
						steps = std::max(steps, 10);
						float angStep = gf_PI2 / steps;
						for (int i=0; i<steps; i++)
						{
							float a0 = angStep*i;
							float a1 = angStep*(i+1);
							float c0 = cosf( a0 );
							float c1 = cosf( a1 );
							float s0 = sinf( a0 );
							float s1 = sinf( a1 );
							Vec3 pts[4];
							int n, n2;
							vtx_idx * indTri;
							if (iterList->radius)
							{
								n = 4;
								n2 = 6;
								pts[0] = iterList->pos + iterList->radius * Vec3( c0, s0, 0 );
								pts[1] = iterList->pos + iterList->radius * Vec3( c1, s1, 0 );
								pts[2] = iterList->pos + iterList->radius2 * Vec3( c1, s1, 0 );
								pts[3] = iterList->pos + iterList->radius2 * Vec3( c0, s0, 0 );
								indTri = indTriQuad;
							}
							else
							{
								n = 3;
								n2 = 3;
								pts[0] = iterList->pos;
								pts[1] = pts[0] + iterList->radius2 * Vec3( c0, s0, 0 );
								pts[2] = pts[0] + iterList->radius2 * Vec3( c1, s1, 0 );
								indTri = indTriTri;
							}
							pAux->DrawTriangles( pts, n, indTri, n2, clr );
						}
					}
					break;
				case eOT_EntityTag:
					{
						UpdateTags(frameTime, *iterList);
					}
					break;
				}
			}
		}
		while (!toClear.empty())
		{
			iterMap->second.erase(toClear.back());
			toClear.pop_back();
		}
		if (iterMap->second.empty())
			toClearMap.push_back(iterMap);
	}
	while (!toClearMap.empty())
	{
		m_objects.erase(toClearMap.back());
		toClearMap.pop_back();
	}
}
//------------------------------------------------------------------------
void CVehicleMovementStdBoat::UpdateSurfaceEffects(const float deltaTime)
{
  FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

  if (0 == g_pGameCVars->v_pa_surface)
  {
    ResetParticles();
    return;
  }
  
  IEntity* pEntity = m_pVehicle->GetEntity();
  const Matrix34& worldTM = pEntity->GetWorldTM();
  
  float distSq = worldTM.GetTranslation().GetSquaredDistance(gEnv->pRenderer->GetCamera().GetPosition());
  if (distSq > sqr(300.f) || (distSq > sqr(50.f) && !m_pVehicle->GetGameObject()->IsProbablyVisible()))
    return;

  Matrix34 worldTMInv = worldTM.GetInverted();
  const SVehicleStatus& status = m_pVehicle->GetStatus();    
  float velDot = status.vel * worldTM.GetColumn1();  
  float powerNorm = min(abs(m_movementAction.power), 1.f);

  SEnvironmentParticles* envParams = m_pPaParams->GetEnvironmentParticles();

  SEnvParticleStatus::TEnvEmitters::iterator end = m_paStats.envStats.emitters.end();
  for (SEnvParticleStatus::TEnvEmitters::iterator emitterIt = m_paStats.envStats.emitters.begin(); emitterIt!=end; ++emitterIt)  
  { 
    if (emitterIt->layer < 0)
    {
      assert(0);
      continue;
    }

    const SEnvironmentLayer& layer = envParams->GetLayer(emitterIt->layer);
    
    SEntitySlotInfo info;        
    info.pParticleEmitter = 0;
    pEntity->GetSlotInfo(emitterIt->slot, info);        

    float countScale = 1.f;
    float sizeScale = 1.f;
		float speedScale = 1.f;
    float speed = 0.f;

    // check if helper position is beneath water level      
                
    Vec3 emitterWorldPos = worldTM * emitterIt->quatT.t;
    float waterLevel = gEnv->p3DEngine->GetWaterLevel(&emitterWorldPos);
    int matId = 0;
    
    if (emitterWorldPos.z <= waterLevel+0.1f && m_physStatus[k_mainThread].submergedFraction<0.999f)
    {
      matId = gEnv->pPhysicalWorld->GetWaterMat();
      speed = status.speed;

      bool spray = !strcmp(layer.GetName(), "spray");        
      
      if (spray)
      {
        // slip based          
        speed -= abs(velDot);
      }

      GetParticleScale(layer, speed, powerNorm, countScale, sizeScale, speedScale);
    }
    else
    {
      countScale = 0.f;
    }
    
    if (matId && matId != emitterIt->matId)
    {
      // change effect       
      IParticleEffect* pEff = 0;                
      const char* effect = GetEffectByIndex( matId, layer.GetName() );

      if (effect && (pEff = gEnv->pParticleManager->FindEffect(effect)))
      {  
#if ENABLE_VEHICLE_DEBUG
        if (DebugParticles())              
					CryLog("%s changes water sfx to %s (slot %i)", pEntity->GetName(), effect, emitterIt->slot);
#endif

        if (info.pParticleEmitter)
        {
          info.pParticleEmitter->Activate(false);
          pEntity->FreeSlot(emitterIt->slot);                  
        }

        emitterIt->slot = pEntity->LoadParticleEmitter(emitterIt->slot, pEff);

        if (emitterIt->slot != -1)
          pEntity->SetSlotLocalTM(emitterIt->slot, Matrix34(emitterIt->quatT));

        info.pParticleEmitter = 0;
        pEntity->GetSlotInfo(emitterIt->slot, info);
      }
      else
        countScale = 0.f;
    }

    if (matId)
      emitterIt->matId = matId;

    if (info.pParticleEmitter)
    {
      SpawnParams sp;
      sp.fSizeScale = sizeScale;
      sp.fCountScale = countScale;    
			sp.fSpeedScale = speedScale;
      info.pParticleEmitter->SetSpawnParams(sp);

      if (layer.alignToWater && countScale > 0.f)
      {          
        Vec3 worldPos(emitterWorldPos.x, emitterWorldPos.y, waterLevel+0.05f);

        Matrix34 localTM(emitterIt->quatT);
        localTM.SetTranslation(worldTMInv * worldPos);
        pEntity->SetSlotLocalTM(emitterIt->slot, localTM);           
      }
    }

#if ENABLE_VEHICLE_DEBUG
    if (DebugParticles() && m_pVehicle->IsPlayerDriving())
    {          
      float color[] = {1,1,1,1};
      ColorB red(255,0,0,255);
      IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
      
      const char* effect = info.pParticleEmitter ? info.pParticleEmitter->GetName() : "";
      const Matrix34& slotTM = m_pEntity->GetSlotWorldTM(emitterIt->slot);
      Vec3 ppos = slotTM.GetTranslation();
      
      pAuxGeom->DrawSphere(ppos, 0.2f, red);
      pAuxGeom->DrawCone(ppos, slotTM.GetColumn1(), 0.1f, 0.5f, red);
      gEnv->pRenderer->Draw2dLabel(50.f, (float)(400+10*emitterIt->slot), 1.2f, color, false, "<%s> water fx: slot %i [%s], speed %.1f, sizeScale %.2f, countScale %.2f (pos %.0f,%0.f,%0.f)", pEntity->GetName(), emitterIt->slot, effect, speed, sizeScale, countScale, ppos.x, ppos.y, ppos.z);        
    }  
#endif
  }

  // generate water splashes
	Vec3 wakePos;
	if(m_pSplashPos)
	{
		wakePos = m_pSplashPos->GetWorldSpaceTranslation();
	}
	else
	{
		wakePos = worldTM.GetTranslation();
	}
  float wakeWaterLevel = gEnv->p3DEngine->GetWaterLevel(&wakePos);

  const Vec3& localW = m_localSpeed;
  if (localW.x >= 0.f)
    m_diving = false;
      
  if (!m_diving && localW.x < -0.03f && status.speed > 10.f && wakePos.z < m_lastWakePos.z && wakeWaterLevel+0.1f >= wakePos.z)
  {
    float speedRatio = min(1.f, status.speed/(m_maxSpeed*m_factorMaxSpeed)); 
    m_diving = true;              
    
    if (m_pWaveEffect)
    {
      if (IParticleEmitter* pEmitter = pEntity->GetParticleEmitter(m_wakeSlot))
      {
        pEmitter->Activate(false);
        pEntity->FreeSlot(m_wakeSlot);
        m_wakeSlot = -1;
      }

      SpawnParams spawnParams;
      spawnParams.fSizeScale = spawnParams.fCountScale = 0.5f + 0.25f*speedRatio;
      spawnParams.fSizeScale  += 0.4f*m_waveRandomMult;
      spawnParams.fCountScale += cry_random(0.0f, 0.4f);

      m_wakeSlot = pEntity->LoadParticleEmitter(m_wakeSlot, m_pWaveEffect, &spawnParams);        
    }

    // handle splash sound  
    ExecuteTrigger(eSID_Splash);
    SetSoundParam(eSID_Splash, "intensity", 0.2f*speedRatio + 0.5f*m_waveRandomMult);     

    if (m_rpmPitchDir == 0)
    {
      m_rpmPitchDir = -1;
      m_waveSoundPitch = 0.f;
      m_waveSoundAmount = 0.02f + m_waveRandomMult*0.08f;
    }      
  }  

  if (m_wakeSlot != -1)
  { 
    // update emitter local pos to short above waterlevel
    Matrix34 tm;
		if(m_pSplashPos)
			m_pSplashPos->GetVehicleTM(tm);
		else
			tm.SetIdentity();

    Vec3 pos = tm.GetTranslation();
    pos.z = worldTMInv.TransformPoint(Vec3(wakePos.x,wakePos.y,wakeWaterLevel)).z + 0.2f;
    tm.SetTranslation(pos);
    pEntity->SetSlotLocalTM(m_wakeSlot, tm);

#if ENABLE_VEHICLE_DEBUG
    if (IsProfilingMovement())
    {
      Vec3 wPos = worldTM * tm.GetTranslation();
      ColorB col(128, 128, 0, 200);
      gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(wPos, 0.4f, col);
      gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(wPos, col, wPos+Vec3(0,0,1.5f), col);
    }          
#endif
  } 

  m_lastWakePos = wakePos;
}