示例#1
0
文件: Melee.cpp 项目: RenEvo/dead6
//------------------------------------------------------------------------
bool CMelee::PerformCylinderTest(const Vec3 &pos, const Vec3 &dir, float strength, bool remote)
{
	IEntity *pOwner = m_pWeapon->GetOwner();
	IPhysicalEntity *pIgnore = pOwner?pOwner->GetPhysics():0;
	IEntity *pHeldObject = NULL;

	if(m_ignoredEntity)
		pHeldObject = gEnv->pEntitySystem->GetEntity(m_ignoredEntity);
		
	primitives::cylinder cyl;
	cyl.r = 0.25f;
	cyl.axis = dir;
	cyl.hh = m_meleeparams.range/2.0f;
	cyl.center = pos + dir.normalized()*cyl.hh;
	
	float n = 0.0f;
	geom_contact *contacts;
	intersection_params params;
	params.bStopAtFirstTri = false;
	params.bNoBorder = true;
	params.bNoAreaContacts = true;
	n = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::cylinder::type, &cyl, Vec3(ZERO), 
		ent_rigid|ent_sleeping_rigid|ent_independent|ent_static|ent_terrain|ent_water, &contacts, 0,
		geom_colltype0|geom_colltype_foliage|geom_colltype_player, &params, 0, 0, &pIgnore, pIgnore?1:0);

	int ret = (int)n;

	float closestdSq = 9999.0f;
	geom_contact *closestc = 0;
	geom_contact *currentc = contacts;

	for (int i=0; i<ret; i++)
	{
		geom_contact *contact = currentc;
		if (contact)
		{
			IPhysicalEntity *pCollider = gEnv->pPhysicalWorld->GetPhysicalEntityById(contact->iPrim[0]);
			if (pCollider)
			{
				IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider);
				if (pEntity)
				{
					if ((pEntity == pOwner)||(pHeldObject && (pEntity == pHeldObject)))
					{
						++currentc;
						continue;
					}
				}

				float distSq = (pos-currentc->pt).len2();
				if (distSq < closestdSq)
				{
					closestdSq = distSq;
					closestc = contact;
				}
			}
		}
		++currentc;
	}

	if (ret)
	{
		WriteLockCond lockColl(*params.plock, 0);
		lockColl.SetActive(1);
	}

  
	if (closestc)
	{
		IPhysicalEntity *pCollider = gEnv->pPhysicalWorld->GetPhysicalEntityById(closestc->iPrim[0]);

		Hit(closestc, dir, strength, remote);
		Impulse(closestc->pt, dir, closestc->n, pCollider, closestc->iPrim[1], 0, closestc->id[1], strength);
	}

	return closestc!=0;
}
示例#2
0
void CPlayerRotation::GetStanceAngleLimits(float & minAngle,float & maxAngle)
{
	EStance stance = m_player.GetStance();

	switch(stance)
	{
	default:
	case STANCE_CROUCH:
	case STANCE_STAND:
		minAngle = -80.0f;
		maxAngle = 80.0f;
		break;
	case STANCE_PRONE:
		minAngle = -35.0f;
		maxAngle = 45.0f;
		break;
	}

	//Limit camera rotation on ladders(to prevent clipping)
	if(m_player.m_stats.isOnLadder)
	{
		minAngle = -40.0f;
		maxAngle = 80.0f;
	}
	if(m_stats.grabbedHeavyEntity!=0)
	{
		minAngle = -35.0f;  //Limit angle to prevent clipping, throw objects at feet, etc...
	}

	// SNH: additional restriction based on weapon type if prone.
	if(m_player.GetStance() == STANCE_PRONE && g_pGameCVars->g_proneAimAngleRestrict_Enable != 0)
	{
		float dist = 0.0f;
		CItem* pItem = (CItem*)(m_player.GetCurrentItem());
		if(pItem)
			dist = pItem->GetParams().raise_distance;

		SMovementState movestate;
		m_player.m_pMovementController->GetMovementState(movestate);
	
		// try a cylinder intersection test
		IPhysicalEntity* pIgnore[2];
		pIgnore[0] = m_player.GetEntity()->GetPhysics();
		pIgnore[1] = pItem ? pItem->GetEntity()->GetPhysics() : NULL;

		primitives::cylinder cyl;
		cyl.r = 0.05f;
		cyl.axis = movestate.aimDirection;
		cyl.hh = dist;
		cyl.center = movestate.weaponPosition + movestate.aimDirection*cyl.hh;

		//gEnv->pRenderer->GetIRenderAuxGeom()->DrawCylinder(cyl.center, cyl.axis, cyl.r, cyl.hh, ColorF(0.4f,1.0f,0.6f, 0.2f));

		float n = 0.0f;
		geom_contact *contacts;
		intersection_params params;
		params.bStopAtFirstTri = false;
		params.bSweepTest = false;
		params.bNoBorder = true;
		params.bNoAreaContacts = true;
		n = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::cylinder::type, &cyl, Vec3(0,0,2), 
			ent_static|ent_terrain, &contacts, 0,
			geom_colltype_player, &params, 0, 0, pIgnore, pIgnore[1]?2:1);
		int ret = (int)n;
		
		geom_contact *currentc = contacts;
		for (int i=0; i<ret; i++)
		{
			geom_contact *contact = currentc;
			if (contact && (fabs_tpl(contact->n.z)>0.2f))
			{
				Vec3 dir = contact->pt - movestate.weaponPosition;
				dir.NormalizeSafe();
				Vec3 horiz = dir;
				horiz.z = 0.0f;
				horiz.NormalizeSafe();
				float cosangle = dir.Dot(horiz);
				Limit(cosangle, -1.0f, 1.0f);
				float newMin = acos_tpl(cosangle);
				newMin = -newMin * 180.0f / gf_PI;
				//float col[] = {1,1,1,1};
				//gEnv->pRenderer->Draw2dLabel(100,100, 1.0f, col, false, "minangle: %.2f", newMin);
				//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(contact->pt, 0.03f, ColorF(1,0,0,1));
				minAngle = MAX(newMin, minAngle);
			}
			++currentc;
		}
	
		if (ret)
		{
			WriteLockCond lockColl(*params.plock, 0);
			lockColl.SetActive(1);
		}

	}

	minAngle *= gf_PI/180.0f;
	maxAngle *= gf_PI/180.0f;
}