Exemplo n.º 1
0
//====================================================================
// DebugDrawWireFOVCone
//====================================================================
void CAIDebugRenderer::DrawWireFOVCone(const Vec3& vPos, const Vec3& vDir, float fRadius, float fFOV, const ColorB& color)
{
	const unsigned int npts = 32;
	const unsigned int npts2 = 16;
	Vec3	points[npts];
	Vec3	pointsx[npts2];
	Vec3	pointsy[npts2];

	Matrix33	base;
	base.SetRotationVDir(vDir);

	float coneRadius = sinf(fFOV) * fRadius;
	float coneHeight = cosf(fFOV) * fRadius;

	for (unsigned int i = 0; i < npts; i++)
	{
		float	a = ((float)i / (float)npts) * gf_PI2;
		float rx = cosf(a) * coneRadius;
		float ry = sinf(a) * coneRadius;
		points[i] = vPos + base.TransformVector(Vec3(rx, coneHeight, ry));
	}

	for (unsigned int i = 0; i < npts2; i++)
	{
		float	a = -fFOV + ((float)i / (float)(npts2-1)) * (fFOV*2);
		float rx = sinf(a) * fRadius;
		float ry = cosf(a) * fRadius;
		pointsx[i] = vPos + base.TransformVector(Vec3(rx, ry, 0));
		pointsy[i] = vPos + base.TransformVector(Vec3(0, ry, rx));
	}

	DrawPolyline(points, npts, true, color);
	DrawPolyline(pointsx, npts2, false, color);
	DrawPolyline(pointsy, npts2, false, color);

	DrawLine(points[0], color, vPos, color);
	DrawLine(points[npts/4], color, vPos, color);
	DrawLine(points[npts/2], color, vPos, color);
	DrawLine(points[npts/2+npts/4], color, vPos, color);
}
void CCameraInputHelper::UpdateCameraInput(Ang3 &deltaRotation, const float frameTimeClamped, const float frameTimeNormalised)
{
	// Use new control scheme,
	// or, if we're just entering/leaving it then adjust camera/character orientations as appropriate.

	//--- Translate left stick into a deltaRotation.z (and a move direction)

	Vec3 vcStick=Vec3(m_pHeroInput->m_moveStickLR, m_pHeroInput->m_moveStickUD,0);	// Stick vector in view space	// -m_moveStickLR removes flicker, but inverses direction..

	static Vec3 vcStickPrev=Vec3(0,1,0);

	float stickMag=vcStick.len();

	if(stickMag>0.001f)
		vcStick*=1/stickMag;
	else
		vcStick=vcStickPrev;	// should hold previous value/direction unless we're in transition.

	vcStickPrev=vcStick;

	Matrix33 camViewMtx = m_pHero->m_camViewMtxFinal;
	//in flight mode the actual camera matrix changes
	//the mtxFinal itself stays untouched, so that the camera can move back after the flight
	if(CCameraFlight::GetInstance()->IsCameraFlightActive())
	{
		Vec3 vCamDir = CCameraFlight::GetInstance()->GetLookingDirection();
		camViewMtx.SetRotationVDir(vCamDir, 0.0f);
	}
	
	const Matrix34& entityWorldTM = m_pHero->GetEntity()->GetWorldTM();
	Vec3 vwEntPos = entityWorldTM.GetTranslation();
	Vec3 vwDrawFrom = vwEntPos+Vec3(0,0,0.8f);
	Vec3 vwEntityFront = entityWorldTM.GetColumn1();
	Vec3 vwEntityRight = entityWorldTM.GetColumn0();
	Vec3 vCamRef = camViewMtx*Vec3(0,1,0);
	Vec3 vwStick = camViewMtx*vcStick;	// Stick vector in world space
	Vec3 vwfStick = Vec3FlattenXY(vwStick);

	Vec3 vwfEntityFront=Vec3FlattenXY(vwEntityFront);
	Vec3 vwfEntityRight=Vec3FlattenXY(vwEntityRight);
	float dotRight=vwfStick.Dot(vwfEntityRight);
	float dotFront=vwfStick.Dot(vwfEntityFront);
	dotFront = clamp(dotFront,-1.0f,1.0f);

	bool enteredNavFromCombat = false; //(m_bNavCombatModeChanged && !bIsCombatMode);

	//--- Just moved into nav mode from combat
	if(enteredNavFromCombat)
	{
		// so set directions appropriately.

		float dotFront2=(vCamRef).Dot(Vec3(0,1,0));
		float dotRight2=(camViewMtx*Vec3(1,0,0)).Dot(Vec3(0,1,0));
		float yaw = 0.0f;

		dotFront2 = clamp(dotFront2,-1.0f,1.0f);
		if(dotRight2>=0)
		{
			yaw=-cry_acosf(dotFront2);
		}
		else
		{
			yaw=cry_acosf(dotFront2);
		}

		m_fYaw = yaw;
	}

	//this is the actual entity rotation (yaw movement)
	CCameraOverrides *pCamOverride = g_pGame->GetCameraManager()->GetCamOverrides();
	int eCamOverrideMode = pCamOverride->GetCameraOverride();

	//the ECO_LOWCOVER fading is a hack, causing problems when inputs are changed during the fade
	//in combat mode all inputs have to be passed through to synchronize the camera direction in other modes
	if((stickMag>0.01f && eCamOverrideMode != ECO_LOWCOVER))
	{
		if(dotRight>=0)
		{
			deltaRotation.z=-cry_acosf(dotFront);
		}
		else
		{
			deltaRotation.z=cry_acosf(dotFront);
		}
	}
	else
		deltaRotation.z=0;

	float maxDeltaRot = 7.85f; // safety value //g_pGameCVars->cl_nav_SprintMaxTurnRate;
	Limit( maxDeltaRot, 0.f, gf_PI * 10.f ); // limit to 3600 degrees per second, i.e. 'pretty fast'
	maxDeltaRot *= frameTimeClamped;	

	// In Nav mode movement is always in the characters forward direction.
	UpdatePitchYawDriver(stickMag, frameTimeNormalised);

	m_bNavCombatModeChanged=false;
}
Exemplo n.º 3
0
//------------------------------------------------------------------
void CLam::UpdateTPLaser(float frameTime, CItem* parent)
{
    FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

    const int frameId = gEnv->pRenderer->GetFrameID();

    if (s_lastUpdateFrameId != frameId)
    {
        // Check how many LAMs to update this frame.
        float dt = frameTime; // + s_laserUpdateTimeError;

        const int n = s_lasers.size();

        int nActive = 0;
        for (int i = 0; i < n; ++i)
        {
            if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated())
                continue;
            nActive++;
        }

        float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError;
        int updateCount = (int)floorf(updatedPerSecond * dt);
        if(dt==0.0f)
            s_laserUpdateTimeError = 0.0f;
        else
            s_laserUpdateTimeError = updatedPerSecond - updateCount/dt;

        s_curLaser %= n;
        for (int i = 0, j = 0; i < n && j < updateCount ; ++i)
        {
            s_curLaser = (s_curLaser + 1) % n;
            if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated())
                continue;
            s_lasers[s_curLaser]->SetAllowUpdate();
            ++j;
        }

        s_lastUpdateFrameId = frameId;
    }

    IEntity* pRootEnt = GetEntity();
    if (!pRootEnt)
        return;

    IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId);
//	if(!pLaserEntity)
//		return;

    const CCamera& camera = gEnv->pRenderer->GetCamera();

    Vec3   lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos();
    Vec3   dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1();

    bool charNotVisible = false;

    float  dsg1Scale = 1.0f;

    //If character not visible, laser is not correctly updated
    if(parent)
    {
        if(CActor* pOwner = parent->GetOwnerActor())
        {
            ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0);
            if(pCharacter && !pCharacter->IsCharacterVisible())
                charNotVisible = true;
        }
        if(parent->GetEntity()->GetClass()==CItem::sDSG1Class)
            dsg1Scale = 3.0f;
    }

//	if (!pLaserEntity->GetParent())
//		return;

    Vec3 hitPos(0,0,0);
    float laserLength = 0.0f;

    // HACK??: Use player movement controller locations, or else the laser
    // pops all over the place when character out of the screen.
    CActor *pActor = parent->GetOwnerActor();
    if (pActor && (!pActor->IsPlayer() || charNotVisible))
    {
        if (IMovementController* pMC = pActor->GetMovementController())
        {
            SMovementState state;
            pMC->GetMovementState(state);
            if(!charNotVisible)
                lamPos = state.weaponPosition;
            else
            {
                float oldZPos = lamPos.z;
                lamPos = state.weaponPosition;
                if(m_lastZPos>0.0f)
                    lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate)
                else
                    lamPos.z = oldZPos;
            }
            const float angleMin = DEG2RAD(3.0f);
            const float angleMax = DEG2RAD(7.0f);
            const float thr = cosf(angleMax);
            float dot = dir.Dot(state.aimDirection);
            if (dot > thr)
            {
                float a = acos_tpl(dot);
                float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f);
                dir = dir + u * (state.aimDirection - dir);
                dir.Normalize();
            }
        }
    }

    if(!charNotVisible)
        m_lastZPos = lamPos.z;

    lamPos += (dir*0.10f);

    if (m_allowUpdate)
    {
        m_allowUpdate = false;

        IPhysicalEntity* pSkipEntity = NULL;
        if(parent->GetOwner())
            pSkipEntity = parent->GetOwner()->GetPhysics();

        const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale;

        // Use the same flags as the AI system uses for visbility.
        const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living;
        const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit);

        ray_hit hit;
        if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*range, objects, flags,
                &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0))
        {
            laserLength = hit.dist;
            m_lastLaserHitPt = hit.pt;
            m_lastLaserHitSolid = true;
        }
        else
        {
            m_lastLaserHitSolid = false;
            m_lastLaserHitPt = lamPos + dir * range;
            laserLength = range + 0.1f;
        }

        // Hit near plane
        if (dir.Dot(camera.GetViewdir()) < 0.0f)
        {
            Plane nearPlane;
            nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition());
            nearPlane.d -= camera.GetNearPlane()+0.15f;
            Ray ray(lamPos, dir);
            Vec3 out;
            m_lastLaserHitViewPlane = false;
            if (Intersect::Ray_Plane(ray, nearPlane, out))
            {
                float dist = Distance::Point_Point(lamPos, out);
                if (dist < laserLength)
                {
                    laserLength = dist;
                    m_lastLaserHitPt = out;
                    m_lastLaserHitSolid = true;
                    m_lastLaserHitViewPlane = true;
                }
            }
        }

        hitPos = m_lastLaserHitPt;
    }
    else
    {
        laserLength = Distance::Point_Point(m_lastLaserHitPt, lamPos);
        hitPos = lamPos + dir * laserLength;
    }

    if (m_smoothLaserLength < 0.0f)
        m_smoothLaserLength = laserLength;
    else
    {
        if (laserLength < m_smoothLaserLength)
            m_smoothLaserLength = laserLength;
        else
            m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime);
    }

    float laserAIRange = 0.0f;
    if (m_laserActivated && pLaserEntity)
    {
        // Orient the laser towards the point point.
        Matrix34 parentTMInv;
        parentTMInv = pRootEnt->GetWorldTM().GetInverted();

        Vec3 localDir = parentTMInv.TransformPoint(hitPos);
        float finalLaserLen = localDir.NormalizeSafe();
        Matrix33 rot;
        rot.SetIdentity();
        rot.SetRotationVDir(localDir);
        pLaserEntity->SetLocalTM(rot);

        laserAIRange = finalLaserLen;

        const float assetLength = 2.0f;
        finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale);
        float scale = finalLaserLen / assetLength;

        // Scale the laser based on the distance.
        if (m_laserEffectSlot >= 0)
        {
            Matrix33 scl;
            scl.SetIdentity();
            scl.SetScale(Vec3(1,scale,1));
            pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl);
        }

        if (m_dotEffectSlot >= 0)
        {
            if (m_lastLaserHitSolid)
            {
                Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0));
                if(m_lastLaserHitViewPlane)
                    mt.Scale(Vec3(0.2f,0.2f,0.2f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt);
            }
            else
            {
                Matrix34 scaleMatrix;
                scaleMatrix.SetIdentity();
                scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix);
            }
        }
    }

    float lightAIRange = 0.0f;
    if (m_lightActivated)
    {
        float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]);
        lightAIRange = range * 1.5f;

        if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f)
        {
            CItem* pLightEffect = this;
            if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
                pLightEffect = (CItem *)pOwnerItem;
            pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]);
        }
    }


    if (laserAIRange > 0.0001f || lightAIRange > 0.0001f)
        UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange);

}
Exemplo n.º 4
0
void CVehicleWeaponControlled::Update(SEntityUpdateContext& ctx, int update)
{
	IVehicle *pVehicle = m_vehicleId ? gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) : NULL; 
  if (!m_vehicleId && GetEntity()->GetParent())
  {
    IEntity *entity = GetEntity();
    
    if (entity)
    {
      IEntity *parent = entity->GetParent();
      if (parent)
      {
				m_vehicleId = parent->GetId();
        pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(parent->GetId());
      }
    }
  }



  if (pVehicle)
  {
		IVehiclePart *pPart = pVehicle->GetWeaponParentPart(GetEntityId());
		if(pPart)
		{
			if(IVehiclePart *pParentPart = pPart->GetParent())
			{
				CRY_ASSERT(pVehicle->GetEntity());

				if(ICharacterInstance *characterInst = pVehicle->GetEntity()->GetCharacter(pParentPart->GetSlot()))
				{
					if(ISkeletonPose* pose = characterInst->GetISkeletonPose())
					{
						IDefaultSkeleton& rIDefaultSkeleton = characterInst->GetIDefaultSkeleton();
						int16 joint = rIDefaultSkeleton.GetJointIDByName(pPart->GetName());
						const QuatT &jQuat = pose->GetAbsJointByID(joint);

						Matrix34 localT(jQuat);
						localT.SetTranslation(jQuat.t/* - Vec3(0.0f, 0.75f, 0.0f)*/);

						Matrix34 vehicleWorldTm = pVehicle->GetEntity()->GetWorldTM();
						Matrix34 mat = vehicleWorldTm * localT;
						Vec3 vehicleSide2 = pPart->GetParent()->GetLocalTM(true, true).GetTranslation();

						CPlayer *pl = this->GetOwnerPlayer();

						Matrix33 mat2;
						if (!m_destination.IsEquivalent(ZERO))
						{
							Vec3 diff = GetDestination() - mat.GetTranslation(); //pPart->GetWorldTM().GetTranslation();
							diff.Normalize();

							Matrix33 loc(mat);
							loc.Invert();

							Vec3 diffLocal = loc.TransformVector(diff);

							Matrix33 desMat;
							desMat.SetRotationVDir(diffLocal, 0.0f);

							Vec3 test = GetEntity()->GetLocalTM().GetColumn0();

							Ang3 testTM(desMat);

							float za = testTM.x - m_Angles.x;
							za = (za < 0.0f) ? -gf_PI : gf_PI;
							za *= 0.05f * ctx.fFrameTime;

							m_Angles.x += za;
							Limit(m_Angles.x, -gf_PI * 0.33f, gf_PI * 0.33f);

							if (testTM.z > m_Angles.z + 0.05f)
							{
								m_Angles.z += gf_PI * factor1 * ctx.fFrameTime;        
							}
							else if (testTM.z < m_Angles.z - 0.05f)
							{
								m_Angles.z -= gf_PI * factor1 * ctx.fFrameTime;        
							}
							else
							{
								m_Angles.z = testTM.z;
							}

							Limit(m_Angles.z, -gf_PI * 0.33f, gf_PI * 0.33f);
							mat2.SetRotationXYZ(m_Angles);
						}
						else
						{
							if (!m_FireBlocked)
							{
								m_Angles.x = m_Angles.x - ctx.fFrameTime * factor2 * m_Angles.x;
								m_Angles.z = m_Angles.z - ctx.fFrameTime * factor2 * m_Angles.z;
							}
							mat2.SetRotationXYZ(m_Angles);
						}

						mat = mat * mat2; 


						GetEntity()->SetWorldTM(mat);


						if (pl)
						{
							Matrix34 worldGunMat = vehicleWorldTm * localT;

							if (!pl->IsDead())
							{

								Vec3 trans = worldGunMat.GetTranslation() - worldGunMat.GetColumn2() * 0.7f;
								worldGunMat.SetTranslation(trans);

								pl->GetEntity()->SetWorldTM(worldGunMat);


								float dot = mat.GetColumn1().dot(worldGunMat.GetColumn0());
								Update3PAnim(pl, 0.5f - dot * 0.5f, ctx.fFrameTime, mat);
							}
							else
							{

								ICharacterInstance* pCharacter = pl->GetEntity()->GetCharacter(0);
								int boneId = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName("Spine03") : 7;

								pl->LinkToMountedWeapon(0);
								if (IVehicleSeat* seat = pVehicle->GetSeatForPassenger(pl->GetEntityId()))
								{
									seat->Exit(false, true);
								}

								Matrix33 rot(worldGunMat);
								Vec3 offset(0.0f, 0.0f, 0.70f);
								Vec3 transformedOff = rot.TransformVector(offset);
								Vec3 trans = worldGunMat.GetTranslation();
								trans -= transformedOff;
								worldGunMat.SetTranslation(trans);
								pl->GetEntity()->SetWorldTM(worldGunMat);
								pl->GetEntity()->SetPos(worldGunMat.GetTranslation()); //worldGunMat.GetTranslation());
								pl->RagDollize(true);

								if (boneId > -1)
								{
									IPhysicalEntity *physEnt = pl->GetEntity()->GetPhysics();
									if (physEnt)
									{
										pe_simulation_params simulationParams;
										physEnt->GetParams(&simulationParams);

										pe_params_pos pos;
										pos.pos = GetEntity()->GetPos();
										physEnt->SetParams(&pos);

										pe_action_impulse impulse;
										impulse.ipart = boneId;
										impulse.angImpulse = Vec3(0.0f, 0.0f, 1.0f);
										impulse.impulse = worldGunMat.GetColumn1() * -1.5f * simulationParams.mass;
										physEnt->Action(&impulse);
									}
								}

								StopUse(GetOwnerId());

								SetOwnerId(0);
								StopFire();

								m_FireBlocked = true;
							} // IsDead
						} // pl
					} // pose
				} // characterInst
			} // pParentPart
		} // pPart
	} // pVehicle

  Base::Update(ctx, update);
  RequireUpdate(eIUS_General);
}