本文整理汇总了C++中AABB::GetRadius方法的典型用法代码示例。如果您正苦于以下问题:C++ AABB::GetRadius方法的具体用法?C++ AABB::GetRadius怎么用?C++ AABB::GetRadius使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AABB
的用法示例。
在下文中一共展示了AABB::GetRadius方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RegisterWithAutoAimManager
//------------------------------------------------------------------------
int CScriptBind_Game::RegisterWithAutoAimManager(IFunctionHandler *pH, ScriptHandle entityId, float innerRadiusFactor, float outerRadiusFactor, float snapRadiusFactor)
{
IEntity* pEntity = gEnv->pEntitySystem->GetEntity((EntityId)entityId.n);
if (pEntity)
{
AABB entityBbox;
pEntity->GetWorldBounds(entityBbox);
const float entityRadius = (entityBbox.IsEmpty() == false) ? entityBbox.GetRadius() : 1.0f;
SAutoaimTargetRegisterParams registerParams;
registerParams.fallbackOffset = 0.0f;
registerParams.innerRadius = entityRadius * innerRadiusFactor;
registerParams.outerRadius = entityRadius * outerRadiusFactor;
registerParams.snapRadius = entityRadius * snapRadiusFactor;
registerParams.snapRadiusTagged = entityRadius;
registerParams.primaryBoneId = -1;
registerParams.physicsBoneId = -1;
registerParams.secondaryBoneId = -1;
g_pGame->GetAutoAimManager().RegisterAutoaimTargetObject((EntityId)entityId.n, registerParams);
}
return pH->EndFunction();
}
示例2: Activate
//.........这里部分代码省略.........
if (status.speed > 0.1f)
{
// add angular impulse
pe_action_impulse angImp;
float amount = m_pVehicle->GetMass() * status.speed * Random(0.25f, 0.45f) * -sgn(wheelTM.GetTranslation().x);
angImp.angImpulse = pEntity->GetWorldTM().TransformVector(Vec3(0,0,amount));
pPhysics->Action(&angImp);
}
m_aiImmobilizedTimer = m_pVehicle->SetTimer(-1, AI_IMMOBILIZED_TIME*1000, this);
}
if (!gEnv->pSystem->IsSerializingFile())
{
// add linear impulse
pe_action_impulse imp;
imp.point = pPart->GetWorldTM().GetTranslation();
float amount = m_pVehicle->GetMass() * Random(0.1f, 0.15f);
if (pWheel)
{
amount *= max(0.5f, min(10.f, status.speed));
if (status.speed < 0.1f)
amount = -0.5f*amount;
}
else
amount *= 0.5f;
imp.impulse = pEntity->GetWorldTM().TransformVector(Vec3(0,0,amount));
pPhysics->Action(&imp);
// effect
IParticleEffect* pEffect = gEnv->pParticleManager->FindEffect(TIRE_BLOW_EFFECT);
if (pEffect)
{
int slot = pEntity->LoadParticleEmitter(-1, pEffect);
if (slot > -1)
{
float rotation = pWheel ? 0.5f * gf_PI * -sgn(wheelTM.GetTranslation().x) : gf_PI;
Matrix34 tm = Matrix34::CreateRotationZ(rotation);
tm.SetTranslation(wheelTM.GetTranslation());
pEntity->SetSlotLocalTM(slot, tm);
}
}
// remove affected decals
{
Vec3 pos = pPart->GetWorldTM().GetTranslation();
AABB aabb = pPart->GetLocalBounds();
float radius = aabb.GetRadius();
Vec3 vRadius(radius,radius,radius);
AABB areaBox(pos-vRadius, pos+vRadius);
IRenderNode * pRenderNode = NULL;
if (IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER))
pRenderNode = pRenderProxy->GetRenderNode();
gEnv->p3DEngine->DeleteDecalsInRange(&areaBox, pRenderNode);
}
}
}
else
{
if (pWheel)
{
// restore wheel properties
IPhysicalEntity* pPhysics = m_pVehicle->GetEntity()->GetPhysics();
pe_params_wheel wheelParams;
for (int i=0; i<m_pVehicle->GetWheelCount(); ++i)
{
const pe_cargeomparams* pParams = m_pVehicle->GetWheelPart(i)->GetIWheel()->GetCarGeomParams();
wheelParams.iWheel = i;
wheelParams.bBlocked = 0;
wheelParams.suspLenMax = pParams->lenMax;
wheelParams.bDriving = pParams->bDriving;
wheelParams.minFriction = pParams->minFriction;
wheelParams.maxFriction = pParams->maxFriction;
pPhysics->SetParams(&wheelParams);
}
if (IVehicleMovement* pMovement = m_pVehicle->GetMovement())
{
SVehicleMovementEventParams params;
params.pComponent = pComponent;
params.iValue = pWheel->GetWheelIndex();
// reset the particle status
pMovement->OnEvent(IVehicleMovement::eVME_TireRestored, params);
}
}
m_aiImmobilizedTimer = -1;
}
m_isActive = activate;
}
示例3: Update
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))
//.........这里部分代码省略.........
示例4: ThrowObject
//-----------------------------------------------------
void CThrow::ThrowObject(IEntity *pEntity, IPhysicalEntity *pPE)
{
bool strengthMode = false;
CPlayer *pPlayer = static_cast<CPlayer *>(m_pWeapon->GetOwnerActor());
if (pPlayer)
{
// Report throw to AI system.
if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI())
{
SAIEVENT AIevent;
AIevent.targetId = pEntity->GetId();
pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_THROW, &AIevent);
}
}
Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE);
Vec3 pos = GetFiringPos(hit);
Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread());
Vec3 vel = GetFiringVelocity(dir);
float speed = 12.0f;
if(strengthMode)
{
speed *= m_pShared->throwparams.strenght_scale;
}
speed = max(2.0f, speed);
pe_params_pos ppos;
ppos.pos = pEntity->GetWorldPos();
pPE->SetParams(&ppos);
if(CheckForIntersections(pPE, dir))
{
Matrix34 newTM = pEntity->GetWorldTM();
newTM.SetTranslation(newTM.GetTranslation() - (dir * 0.4f));
pEntity->SetWorldTM(newTM, ENTITY_XFORM_POS);
}
else
{
pe_action_set_velocity asv;
asv.v = (dir * speed) + vel;
AABB box;
pEntity->GetWorldBounds(box);
Vec3 finalW = -gEnv->pSystem->GetViewCamera().GetMatrix().GetColumn0() * (8.0f / max(0.1f, box.GetRadius()));
finalW.x *= Random(0.5f, 1.3f);
finalW.y *= Random(0.5f, 1.3f);
finalW.z *= Random(0.5f, 1.3f);
asv.w = finalW;
//asv.w = Vec3(Random(-4.5f,3.5f),Random(-1.75f,2.5f),Random(-1.5f,2.2f));
pPE->Action(&asv);
}
SEntityEvent entityEvent;
entityEvent.event = ENTITY_EVENT_PICKUP;
entityEvent.nParam[0] = 0;
if (pPlayer)
{
entityEvent.nParam[1] = pPlayer->GetEntityId();
}
entityEvent.fParam[0] = speed;
pEntity->SendEvent( entityEvent );
}
示例5: Draw
void CGame::Draw()
{
Vector vecForward = m_hPlayer->GetGlobalView();
Vector vecUp(0, 1, 0);
// Cross-product http://www.youtube.com/watch?v=FT7MShdqK6w
Vector vecRight = vecUp.Cross(vecForward).Normalized();
CRenderer* pRenderer = GetRenderer();
// Tell the renderer how to set up the camera.
pRenderer->SetCameraPosition(m_hPlayer->GetGlobalOrigin() - vecForward * 6 + vecUp * 3 - vecRight * 0.5f);
pRenderer->SetCameraDirection(vecForward);
pRenderer->SetCameraUp(Vector(0, 1, 0));
pRenderer->SetCameraFOV(90);
pRenderer->SetCameraNear(0.1f);
pRenderer->SetCameraFar(1000);
// This rendering context is a tool for rendering things to the screen.
// All of our drawing commands are part of it.
CRenderingContext r(pRenderer);
// Clear the depth buffer and set a background color.
r.ClearDepth();
r.ClearColor(Color(210, 230, 255));
// CRenderer::StartRendering() - This function sets up OpenGL with the
// camera information that we passed it before.
pRenderer->StartRendering(&r);
m_oFrameFrustum = CFrustum(r.GetProjection() * r.GetView());
// First tell OpenGL what "shader" or "program" to use.
r.UseProgram("model");
// Set the sunlight direction. The y component is -1 so the light is pointing down.
Vector vecSunlight = Vector(1, -1, 1).Normalized();
// Uncomment this code to make the sunlight rotate:
//Vector vecSunlight = Vector(cos(Game()->GetTime()), -1, sin(Game()->GetTime())).Normalized();
r.SetUniform("vecSunlight", vecSunlight);
r.SetUniform("bLighted", false);
r.SetUniform("bDiffuse", false);
// Render the ground.
r.SetUniform("vecColor", Vector4D(0.6f, 0.7f, 0.9f, 1));
r.SetUniform("vecCameraPosition", GetRenderer()->GetCameraPosition());
r.BeginRenderTriFan();
r.Normal(Vector(0, 1, 0));
r.Tangent(Vector(1, 0, 0));
r.Bitangent(Vector(0, 0, 1));
r.TexCoord(Vector2D(0, 1));
r.Vertex(Vector(-30, 0, -30));
r.TexCoord(Vector2D(0, 0));
r.Vertex(Vector(-30, 0, 30));
r.TexCoord(Vector2D(1, 0));
r.Vertex(Vector(30, 0, 30));
r.TexCoord(Vector2D(1, 1));
r.Vertex(Vector(30, 0, -30));
r.EndRender();
r.SetUniform("bLighted", true);
// Prepare a list of entities to render.
m_apRenderOpaqueList.clear();
m_apRenderTransparentList.clear();
for (size_t i = 0; i < MAX_CHARACTERS; i++)
{
CCharacter* pCharacter = GetCharacterIndex(i);
if (!pCharacter)
continue;
// We need to scale the AABB using the character's scale values before we can use it to calculate our center/radius.
AABB aabbSizeWithScaling = pCharacter->m_aabbSize * pCharacter->m_vecScaling;
Vector vecCharacterCenter = pCharacter->GetGlobalOrigin() + aabbSizeWithScaling.GetCenter();
float flCharacterRadius = aabbSizeWithScaling.GetRadius();
// If the entity is outside the viewing frustum then the player can't see it - don't draw it.
// http://youtu.be/4p-E_31XOPM
if (!m_oFrameFrustum.SphereIntersection(vecCharacterCenter, flCharacterRadius))
continue;
if (pCharacter->m_bDrawTransparent)
m_apRenderTransparentList.push_back(pCharacter);
else
m_apRenderOpaqueList.push_back(pCharacter);
}
// Draw all opaque characters first.
DrawCharacters(m_apRenderOpaqueList, false);
for (size_t i = 0; i < MAX_CHARACTERS; i++)
{
CCharacter* pCharacter = GetCharacterIndex(i);
if (!pCharacter)
continue;
//.........这里部分代码省略.........
示例6: UpdateTargetInfo
//.........这里部分代码省略.........
primaryOffset = pTargetActor->GetBoneTransform(aaTarget.primaryBoneId).t;
}
else
{
GameWarning("CAutoAimManager: Character %s missing primary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.primaryBoneId]);
aaTarget.primaryBoneId = -1;
}
}
if (aaTarget.secondaryBoneId >= 0)
{
if (pTargetActor->HasBoneID(aaTarget.secondaryBoneId))
{
secondaryOffset = pTargetActor->GetBoneTransform(aaTarget.secondaryBoneId).t;
}
else
{
GameWarning("CAutoAimManager: Character %s missing secondary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.secondaryBoneId]);
aaTarget.secondaryBoneId = -1;
}
}
aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset);
aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset);
//Update hostility (changes during gameplay)
if (!gEnv->bMultiplayer)
{
uint8 targetFaction = (aaTarget.aiFaction != IFactionMap::InvalidFactionID) ? aaTarget.aiFaction : GetTargetFaction(*pTargetEntity);
if (gEnv->pAISystem->GetFactionMap().GetReaction(GetLocalPlayerFaction(), aaTarget.aiFaction) == IFactionMap::Hostile)
{
aaTarget.SetFlag(eAATF_AIHostile);
}
else
{
aaTarget.RemoveFlag(eAATF_AIHostile);
}
aaTarget.aiFaction = targetFaction;
}
}
else if(aaTarget.hasSkeleton)
{
//Not an actor but has a skeleton (and so can use bone offsets)
ISkeletonPose* pSkeletonPose = pTargetEntity->GetCharacter(0)->GetISkeletonPose();
const Matrix34& characterMat = pTargetEntity->GetWorldTM();
const Vec3 characterPos = characterMat.GetTranslation();
const Quat characterRot(characterMat);
Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset);
Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset);
if (aaTarget.primaryBoneId >= 0)
{
primaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.primaryBoneId).t;
}
if (aaTarget.secondaryBoneId >= 0)
{
secondaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.secondaryBoneId).t;
}
aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset);
aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset);
}
else
{
//Must be an object
const Matrix34& entityWorldTM = pTargetEntity->GetWorldTM();
Vec3 primaryPosition = entityWorldTM.GetTranslation();
Vec3 secondaryPosition = entityWorldTM.TransformPoint(Vec3(0.0f, 0.0f, 0.5f));
AABB entityLocalBBox;
pTargetEntity->GetLocalBounds(entityLocalBBox);
if (!entityLocalBBox.IsEmpty())
{
const Vec3 offset (0.0f, 0.0f, entityLocalBBox.GetRadius() * 0.2f);
const Vec3 objectCenter = entityLocalBBox.GetCenter();
primaryPosition = entityWorldTM.TransformPoint((objectCenter - offset));
secondaryPosition = entityWorldTM.TransformPoint((objectCenter + offset));
}
aaTarget.primaryAimPosition = primaryPosition;
aaTarget.secondaryAimPosition = secondaryPosition;
}
//The physics drags the render proxy and entity behind it. If we auto aim at the render position,
// we will handicap the console players by failing to let them aim ahead of the target.
if(IPhysicalEntity * pPhysicalEntity = pTargetEntity->GetPhysics())
{
pe_status_dynamics dyn;
if(pPhysicalEntity->GetStatus(&dyn))
{
Vec3 lookAhead = (dyn.v * fFrameTime);
aaTarget.primaryAimPosition = aaTarget.primaryAimPosition + lookAhead;
aaTarget.secondaryAimPosition = aaTarget.secondaryAimPosition + lookAhead;
}
}
}
}
示例7: Update
//------------------------------------------------------------------------
bool CTracer::Update(float frameTime, const Vec3 &camera, const float fovScale)
{
frameTime = (float)__fsel(-m_age, 0.002f, frameTime);
const float tracerAge = (float)__fsel(-m_age, 0.002f, m_age+frameTime);
m_age = tracerAge;
if (tracerAge >= m_lifeTime)
return false;
Vec3 currentLimitDestination;
if (gEnv->bMultiplayer)
{
if(m_tracerFlags & kTracerFlag_updateDestFromBullet)
{
IEntity* pBulletEntity = gEnv->pEntitySystem->GetEntity(m_boundToBulletId);
if(pBulletEntity)
{
m_dest = pBulletEntity->GetPos();
}
}
currentLimitDestination = m_dest;
}
else
{
IEntity* pBulletEntity = gEnv->pEntitySystem->GetEntity(m_boundToBulletId);
currentLimitDestination = pBulletEntity ? pBulletEntity->GetPos() : m_dest;
}
const Vec3 maxTravelledDistance = m_dest - m_startingPos;
const float maxTravelledDistanceSqr = maxTravelledDistance.len2();
float dist = sqrt_tpl(maxTravelledDistanceSqr);
if (dist <= 0.001f)
return false;
const Vec3 dir = maxTravelledDistance * (float)__fres(dist);
Vec3 pos = m_pos;
float lengthScale = 1.f;
Vec3 newPos = m_pos;
if (!(m_tracerFlags & kTracerFlag_dontTranslate))
{
const float sqrRadius = GetGameConstCVar(g_tracers_slowDownAtCameraDistance) * GetGameConstCVar(g_tracers_slowDownAtCameraDistance);
const float cameraDistance = (m_pos-camera).len2();
const float speed = m_speed * (float)__fsel(sqrRadius - cameraDistance, 0.35f + (cameraDistance/(sqrRadius*2)), 1.0f); //Slow down tracer when near the player
newPos += dir * min(speed*frameTime, dist);
pos = newPos;
if(m_slideFrac > 0.f)
{
pos += (((2.f * cry_frand()) - 0.5f) * m_slideFrac * speed * frameTime * dir);
}
}
// Now update visuals...
if (IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entityId))
{
AABB tracerBbox;
pEntity->GetWorldBounds(tracerBbox);
float tracerHalfLength = !tracerBbox.IsEmpty() ? tracerBbox.GetRadius() : 0.0f;
const Vec3 frontOfTracerPos = pos + (dir * tracerHalfLength);
if((frontOfTracerPos-m_startingPos).len2() > maxTravelledDistanceSqr)
{
return false;
}
if (!(m_tracerFlags & kTracerFlag_dontTranslate) && tracerHalfLength > 0.f)
{
//Ensure that never goes in front of the bullet
const Vec3 dirFromFrontOfTracerToDestination = currentLimitDestination - frontOfTracerPos;
if (dir.dot(dirFromFrontOfTracerToDestination) < 0)
{
pos += dirFromFrontOfTracerToDestination;
}
// ... and check if back of tracer is behind starting point, so adjust length.
const Vec3 backOfTracerPos = pos - (dir * tracerHalfLength);
const Vec3 dirFromBackOfTracerToStart = m_startingPos - backOfTracerPos;
if (dir.dot(dirFromBackOfTracerToStart) > 0)
{
if(dir.dot((m_startingPos - pos)) > 0)
{
pos = m_startingPos + (dir * cry_frand() * tracerHalfLength);
}
lengthScale = ((pos - m_startingPos).GetLength() / tracerHalfLength);
}
}
m_pos = newPos;
Matrix34 tm(Matrix33::CreateRotationVDir(dir));
tm.AddTranslation(pos);
pEntity->SetWorldTM(tm);
//.........这里部分代码省略.........
示例8: ViewSpectatorTarget
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams)
{
CActor *pTarget = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget);
if(!pTarget)
{
return;
}
Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM();
Vec3 worldPos = worldTM.GetTranslation();
worldPos.z += 1.5f;
Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM));
float rot = worldAngles.z;// + m_rot;
float distance = 3;//(m_defaultDistance != 0) ? m_defaultDistance : m_distance;
if(IVehicle *pVehicle = pTarget->GetLinkedVehicle())
{
AABB vehicleBox;
pVehicle->GetEntity()->GetLocalBounds(vehicleBox);
distance = 2.0f * vehicleBox.GetRadius();
}
Vec3 goal;
float zoom = 1.0f;
goal.x = distance * zoom * cosf(rot + gf_PI * 1.5f) + worldPos.x;
goal.y = distance * zoom * sinf(rot - gf_PI / 2.0f) + worldPos.y;
AABB targetBounds;
pTarget->GetEntity()->GetLocalBounds(targetBounds);
goal.z = targetBounds.max.z;
static float defaultOffset = 0.75f;
float offset = defaultOffset;
if(pTarget->GetLinkedVehicle())
{
offset = 2.0f;
}
goal.z += pTarget->GetEntity()->GetWorldPos().z + offset;
// store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles)
static Vec3 viewOffset(goal - worldPos);
static Vec3 position(goal);
static Vec3 entPos(worldPos);
static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget);
// do a ray cast to check for camera intersection
static ray_hit hit;
IPhysicalEntity *pSkipEntities[10];
int nSkip = 0;
IItem *pItem = pTarget->GetCurrentItem();
if (pItem)
{
CWeapon *pWeapon = (CWeapon *)pItem->GetIWeapon();
if (pWeapon)
{
nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10);
}
}
else if(IVehicle *pVehicle = pTarget->GetLinkedVehicle())
{
// vehicle drivers don't seem to have current items, so need to add the vehicle itself here
nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10);
}
const float wallSafeDistance = 0.2f; // how far to keep camera from walls
Vec3 dir = goal - worldPos;
primitives::sphere sphere;
sphere.center = worldPos;
sphere.r = wallSafeDistance;
geom_contact *pContact = 0;
float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
&pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip);
// even when we have contact, keep the camera the same height above the target
float minHeightDiff = dir.z;
if(hitDist > 0 && pContact)
{
goal = worldPos + (hitDist * dir.GetNormalizedSafe());
if(goal.z - worldPos.z < minHeightDiff)
{
// can't move the camera far enough away from the player in this direction. Try moving it directly up a bit
sphere.center = goal;
// (move back just slightly to avoid colliding with the wall we've already found...)
sphere.center -= dir.GetNormalizedSafe() * 0.05f;
float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0, 0, minHeightDiff), ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
&pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip);
float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance;
if(newHitDist != 0)
{
raiseDist = MIN(minHeightDiff, newHitDist);
}
raiseDist = MAX(0.0f, raiseDist);
goal.z += raiseDist;
worldPos.z += raiseDist * 0.8f;
}
}
//.........这里部分代码省略.........