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();
}
示例#2
0
文件: Claymore.cpp 项目: RenEvo/dead6
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);
	}
}
示例#3
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();
	}
}