BVB Source Codes

CRYENGINE Show VehicleViewActionThirdPerson.cpp Source code

Return Download CRYENGINE: download VehicleViewActionThirdPerson.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.    Description: Implements a third person view for vehicles
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 02:05:2005: Created by Mathieu Pinard
  12.  
  13. *************************************************************************/
  14. #include "StdAfx.h"
  15.  
  16. #include "IViewSystem.h"
  17. #include "IVehicleSystem.h"
  18. #include "VehicleSeat.h"
  19. #include "VehicleViewActionThirdPerson.h"
  20. #include "VehicleCVars.h"
  21. #include "Vehicle.h"
  22.  
  23. #include <CryMath/Cry_GeoIntersect.h>
  24. #include <CryMath/Cry_GeoDistance.h>
  25.  
  26. #if ENABLE_VEHICLE_DEBUG
  27.         #define DEBUG_CAMERA(x) x
  28. #else
  29.         #define DEBUG_CAMERA(x)
  30. #endif
  31.  
  32. const char* CVehicleViewActionThirdPerson::m_name = "ActionThirdPerson";
  33. static float cameraRadius = 0.42f;
  34.  
  35. //------------------------------------------------------------------------
  36. CVehicleViewActionThirdPerson::CVehicleViewActionThirdPerson()
  37.         : m_heightAboveWater(0.0f)
  38. {
  39.         m_pAimPart = NULL;
  40.         m_zoom = 1.0f;
  41.         m_actionZoom = 0.0f;
  42.         m_zoomTarget = 1.f;
  43.         m_lagSpeed = 1.f;
  44.         m_extraLag.zero();
  45.         m_worldViewPos.zero();
  46.         m_worldCameraPos.zero();
  47.         m_worldCameraAim.zero();
  48.         m_localCameraPos.zero();
  49.         m_localCameraAim.zero();
  50.         m_velocityMult.Set(1.f, 1.f, 1.f);
  51.         m_cameraOffset.zero();
  52.         m_verticalFilter = 0.2f;
  53.         m_verticalFilterOffset = 0.f;
  54. }
  55.  
  56. //------------------------------------------------------------------------
  57. CVehicleViewActionThirdPerson::~CVehicleViewActionThirdPerson()
  58. {
  59. }
  60.  
  61. //------------------------------------------------------------------------
  62. bool CVehicleViewActionThirdPerson::Init(IVehicleSeat* pSeat, const CVehicleParams& table)
  63. {
  64.         if (!CVehicleViewBase::Init(pSeat, table))
  65.                 return false;
  66.  
  67.         m_pSeat = static_cast<CVehicleSeat*>(pSeat);
  68.         m_pVehicle = m_pSeat->GetVehicle();
  69.         m_pAimPart = m_pSeat->GetAimPart();
  70.  
  71.         if (CVehicleParams paramsTable = table.findChild(m_name))
  72.         {
  73.                 paramsTable.getAttr("heightAboveWater", m_heightAboveWater);
  74.  
  75.                 float heightOffset = 1.5f; // default offset (suggested by designers)
  76.                 paramsTable.getAttr("heightOffset", heightOffset);
  77.  
  78.                 AABB bounds;
  79.                 if (m_pAimPart)
  80.                 {
  81.                         bounds = m_pAimPart->GetLocalBounds();
  82.                         if (bounds.IsReset())
  83.                         {
  84.                                 bounds.min.zero();
  85.                                 bounds.max.zero();
  86.                         }
  87.                         bounds.SetTransformedAABB(m_pAimPart->GetLocalTM(false).GetInverted(), bounds);
  88.                 }
  89.                 else
  90.                         m_pVehicle->GetEntity()->GetLocalBounds(bounds);
  91.  
  92.                 m_localCameraPos.Set(0.0f, bounds.min.y, bounds.max.z + heightOffset);
  93.                 m_localCameraAim.Set(0.0f, bounds.max.y, bounds.max.z * 0.5f);
  94.  
  95.                 Vec3 offset;
  96.  
  97.                 if (paramsTable.getAttr("cameraAimOffset", offset))
  98.                         m_localCameraAim += offset;
  99.  
  100.                 if (paramsTable.getAttr("cameraPosOffset", offset))
  101.                         m_localCameraPos += offset;
  102.  
  103.                 paramsTable.getAttr("lagSpeed", m_lagSpeed);
  104.                 paramsTable.getAttr("velocityMult", m_velocityMult);
  105.                 paramsTable.getAttr("verticalFilter", m_verticalFilter);
  106.                 paramsTable.getAttr("verticalFilterOffset", m_verticalFilterOffset);
  107.                 m_verticalFilter = clamp_tpl(m_verticalFilter, 0.f, 1.f);
  108.         }
  109.  
  110.         Reset();
  111.         return (true);
  112. }
  113.  
  114. //------------------------------------------------------------------------
  115. void CVehicleViewActionThirdPerson::Reset()
  116. {
  117.         CVehicleViewBase::Reset();
  118.  
  119.         m_actionZoom = 0.0f;
  120.         m_zoomTarget = 1.0f;
  121.         m_zoom = 1.0f;
  122.  
  123.         m_extraLag.zero();
  124. }
  125.  
  126. //------------------------------------------------------------------------
  127. void CVehicleViewActionThirdPerson::OnStartUsing(EntityId passengerId)
  128. {
  129.         CVehicleViewBase::OnStartUsing(passengerId);
  130.  
  131.         Vec3 worldPos = m_pVehicle->GetEntity()->GetWorldPos();
  132.  
  133.         m_worldCameraPos = gEnv->pSystem->GetViewCamera().GetPosition();
  134.         m_worldViewPos = m_worldCameraPos;
  135.         m_worldCameraAim = worldPos;
  136.         m_cameraOffset = m_worldCameraPos - worldPos;
  137.  
  138.         CryLog("Entity position=%.2f %.2f %.2f, initial camera position=%.2f %.2f %.2f, offset=%.2f %.2f %.2f", worldPos.x, worldPos.y, worldPos.z, m_worldViewPos.x, m_worldViewPos.y, m_worldViewPos.z, m_cameraOffset.x, m_cameraOffset.y, m_cameraOffset.z);
  139.  
  140.         m_zoomTarget = 1.0f;
  141.         m_zoom = 1.0f;
  142. }
  143.  
  144. //------------------------------------------------------------------------
  145. void CVehicleViewActionThirdPerson::OnAction(const TVehicleActionId actionId, int activationMode, float value)
  146. {
  147.         CVehicleViewBase::OnAction(actionId, activationMode, value);
  148.  
  149.         if (actionId == eVAI_ZoomIn)
  150.                 m_actionZoom -= value;
  151.         else if (actionId == eVAI_ZoomOut)
  152.                 m_actionZoom += value;
  153. }
  154.  
  155. //------------------------------------------------------------------------
  156. void CVehicleViewActionThirdPerson::Update(float frameTimeIn)
  157. {
  158.         // Use the physics frame time, but only if non zero!
  159.         const float physFrameTime = static_cast<CVehicle*>(m_pVehicle)->GetPhysicsFrameTime();
  160.         const float frameTime = (physFrameTime > 0.f) ? min(physFrameTime, frameTimeIn) : frameTimeIn;
  161.  
  162.         CVehicleViewBase::Update(frameTime);
  163.  
  164. #if ENABLE_VEHICLE_DEBUG
  165.         Vec3 debugAim0, debugAim1, debugAim2, debugAim3;
  166. #endif
  167.  
  168.         // apply any zoom changes
  169.         m_zoomTarget += m_actionZoom;
  170.         m_zoomTarget = clamp_tpl(m_zoomTarget, 0.5f, 5.0f);
  171.         Interpolate(m_zoom, m_zoomTarget, 2.5f, frameTime);
  172.         m_actionZoom = 0.0f;
  173.  
  174.         // compute extra camera pos lag
  175.         const SVehicleStatus& status = m_pVehicle->GetStatus();
  176.  
  177.         Vec3 localVel = m_pVehicle->GetEntity()->GetWorldRotation().GetInverted() * status.vel;
  178.  
  179.         Interpolate(m_extraLag.x, localVel.x * m_velocityMult.x, m_lagSpeed, frameTime);
  180.         Interpolate(m_extraLag.y, localVel.y * m_velocityMult.y, m_lagSpeed, frameTime);
  181.         Interpolate(m_extraLag.z, localVel.z * m_velocityMult.z, m_lagSpeed, frameTime);
  182.  
  183.         Matrix34 worldTM;
  184.  
  185.         if (m_pAimPart)
  186.                 worldTM = m_pAimPart->GetWorldTM();
  187.         else
  188.                 worldTM = m_pVehicle->GetEntity()->GetWorldTM();
  189.  
  190.         Matrix34 lagTM;
  191.         lagTM.SetIdentity();
  192.         lagTM.SetTranslation(m_extraLag);
  193.  
  194.         // update both aim pos and camera pos
  195.  
  196.         Ang3 worldAngles(worldTM);
  197.         float rot = worldAngles.z + m_rotation.z;
  198.  
  199.         m_worldCameraPos = (worldTM * lagTM) * m_localCameraPos;
  200.  
  201.         Vec3 camWorldPos = m_worldCameraPos;
  202.  
  203.         float distance = Vec3(m_localCameraPos - m_localCameraAim).GetLength();
  204.         distance *= 0.5f;
  205.  
  206.         Vec3 localCameraAim = m_localCameraAim;
  207.         localCameraAim.z = m_verticalFilterOffset;
  208.  
  209.         // Straight-forwrard aim position, transformed to world
  210.         Vec3 worldCameraAim1 = worldTM * m_localCameraAim;
  211.         DEBUG_CAMERA(debugAim0 = worldCameraAim1);
  212.  
  213.         // Aim position, taken vertically from the entity's zero z offset
  214.         Vec3 worldCameraAim2 = worldTM * localCameraAim;
  215.         DEBUG_CAMERA(debugAim1 = worldCameraAim2);
  216.         worldCameraAim2.z += m_localCameraAim.z - m_verticalFilterOffset;
  217.         DEBUG_CAMERA(debugAim2 = worldCameraAim2);
  218.  
  219.         // Interpolated final world aim pos
  220.         m_worldCameraAim = worldCameraAim1 + (worldCameraAim2 - worldCameraAim1) * m_verticalFilter;
  221.         DEBUG_CAMERA(debugAim3 = worldCameraAim2);
  222.  
  223.         float cosPitch = cosf(-m_rotation.x);
  224.         camWorldPos.x = cosPitch * distance * m_zoom * cosf(rot - gf_PI * 0.5f) + camWorldPos.x;
  225.         camWorldPos.y = cosPitch * distance * m_zoom * sinf(rot - gf_PI * 0.5f) + camWorldPos.y;
  226.         camWorldPos.z += distance * m_zoom * sinf(-m_rotation.x);
  227.  
  228.         if (!iszero(m_heightAboveWater))
  229.         {
  230.                 float waterLevel = gEnv->p3DEngine->GetWaterLevel(&camWorldPos);
  231.                 camWorldPos.z = max(waterLevel + m_heightAboveWater, camWorldPos.z);
  232.         }
  233.  
  234.         m_worldCameraPos = camWorldPos;
  235.         Vec3 newPos = m_worldCameraPos;
  236.  
  237.         AABB bounds;
  238.         m_pVehicle->GetEntity()->GetWorldBounds(bounds);
  239.  
  240.         Vec3 center = worldTM.GetTranslation();
  241.         center.z += 1.0f;
  242.  
  243.         IPhysicalEntity* pSkipEntities[10];
  244.         int nSkip = 0;
  245.         if (m_pVehicle)
  246.         {
  247.                 nSkip = m_pVehicle->GetSkipEntities(pSkipEntities, 10);
  248.         }
  249.  
  250.         primitives::sphere sphere;
  251.         sphere.center = center;
  252.         sphere.r = cameraRadius;
  253.         Vec3 dir = newPos - center;
  254.  
  255.         geom_contact* pContact = 0;
  256.         float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
  257.                                                                          &pContact, 0, (geom_colltype_player << rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip);
  258.         if (hitDist > 0.0f)
  259.         {
  260.                 newPos = center + hitDist * dir.GetNormalizedSafe();
  261.         }
  262.  
  263.         // check new pos is outside the vehicle bounds...
  264.         bounds.Expand(Vec3(cameraRadius, cameraRadius, 0.0f));
  265.         if (bounds.IsContainPoint(newPos))
  266.         {
  267.                 // nope, still inside.
  268.                 // Take the height of the aim pos and sweep a sphere downwards to the requested pos. Places the camera
  269.                 //      on top of the vehicle.
  270.                 ray_hit hit;
  271.                 sphere.center = newPos;
  272.                 sphere.center.z = center.z + 3.0f;
  273.                 Vec3 newdir = Vec3(0, 0, -5);
  274.                 if (gEnv->pPhysicalWorld->CollideEntityWithPrimitive(m_pVehicle->GetEntity()->GetPhysics(), sphere.type, &sphere, newdir, &hit))
  275.                 {
  276.                         newPos = hit.pt;
  277.                         newPos.z += cameraRadius;
  278.                 }
  279.         }
  280.  
  281.         // interpolate the offset, not the camera position (ensures camera moves with vehicle - reduces perceived jitter)
  282.         static float interpSpeed = 5.0f;
  283.         Interpolate(m_cameraOffset, newPos - center, interpSpeed, frameTime);
  284.         m_worldViewPos = center + m_cameraOffset;
  285.  
  286. #if ENABLE_VEHICLE_DEBUG
  287.         if (m_isDebugView)
  288.         {
  289.                 IRenderer* pRenderer = gEnv->pRenderer;
  290.                 IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
  291.                 SAuxGeomRenderFlags flags = pAuxGeom->GetRenderFlags();
  292.                 SAuxGeomRenderFlags oldFlags = pAuxGeom->GetRenderFlags();
  293.                 flags.SetDepthWriteFlag(e_DepthWriteOff);
  294.                 flags.SetDepthTestFlag(e_DepthTestOff);
  295.                 pAuxGeom->SetRenderFlags(flags);
  296.                 pAuxGeom->DrawSphere(debugAim0, 0.06f, ColorB(255, 255, 255, 255));
  297.                 pAuxGeom->DrawSphere(debugAim1, 0.06f, ColorB(0, 255, 0, 255));
  298.                 pAuxGeom->DrawLine(debugAim1, ColorB(0, 255, 0, 255), debugAim2, ColorB(0, 255, 0, 255));
  299.                 pAuxGeom->DrawSphere(debugAim2, 0.06f, ColorB(0, 255, 0, 255));
  300.                 pAuxGeom->DrawSphere(debugAim3, 0.06f, ColorB(0, 0, 255, 255));
  301.         }
  302. #endif
  303. }
  304.  
  305. //------------------------------------------------------------------------
  306. void CVehicleViewActionThirdPerson::UpdateView(SViewParams& viewParams, EntityId playerId)
  307. {
  308.         Matrix33 cameraTM = Matrix33::CreateRotationVDir((m_worldCameraAim - m_worldViewPos).GetNormalizedSafe());
  309.  
  310.         viewParams.rotation = Quat(cameraTM);
  311.  
  312.         // set view direction on actor
  313.         IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(playerId);
  314.         if (pActor && pActor->IsClient())
  315.         {
  316.                 pActor->SetViewInVehicle(viewParams.rotation);
  317.         }
  318.  
  319.         viewParams.position = m_worldViewPos;
  320.         viewParams.nearplane = cameraRadius + 0.1f;
  321. }
  322.  
  323. //------------------------------------------------------------------------
  324. void CVehicleViewActionThirdPerson::Serialize(TSerialize serialize, EEntityAspects aspects)
  325. {
  326.         CVehicleViewBase::Serialize(serialize, aspects);
  327.  
  328.         if (serialize.GetSerializationTarget() != eST_Network)
  329.         {
  330.                 serialize.Value("zoom", m_zoom);
  331.         }
  332. }
  333.  
  334. //------------------------------------------------------------------------
  335. void CVehicleViewActionThirdPerson::OffsetPosition(const Vec3& delta)
  336. {
  337. #ifdef SEG_WORLD
  338.         m_worldViewPos += delta;
  339.         m_worldCameraPos += delta;
  340. #endif
  341. }
  342.  
  343. DEFINE_VEHICLEOBJECT(CVehicleViewActionThirdPerson);
  344.  
downloadVehicleViewActionThirdPerson.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top