forked from HARPLab/DReyeVR
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EgoVehicle.h
277 lines (242 loc) · 12.6 KB
/
EgoVehicle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#pragma once
#include "Camera/CameraComponent.h" // UCameraComponent
#include "Carla/Actor/DReyeVRCustomActor.h" // ADReyeVRCustomActor
#include "Carla/Game/CarlaEpisode.h" // CarlaEpisode
#include "Carla/Sensor/DReyeVRData.h" // DReyeVR namespace
#include "Carla/Vehicle/CarlaWheeledVehicle.h" // ACarlaWheeledVehicle
#include "Carla/Vehicle/WheeledVehicleAIController.h" // AWheeledVehicleAIController
#include "Components/AudioComponent.h" // UAudioComponent
#include "Components/InputComponent.h" // InputComponent
#include "Components/PlanarReflectionComponent.h" // Planar Reflection
#include "Components/SceneComponent.h" // USceneComponent
#include "CoreMinimal.h" // Unreal functions
#include "DReyeVRGameMode.h" // ADReyeVRGameMode
#include "DReyeVRUtils.h" // GeneralParams.Get
#include "EgoSensor.h" // AEgoSensor
#include "FlatHUD.h" // ADReyeVRHUD
#include "ImageUtils.h" // CreateTexture2D
#include "WheeledVehicle.h" // VehicleMovementComponent
#include <stdio.h>
#include <vector>
#include "EgoVehicle.generated.h"
class ADReyeVRGameMode;
class ADReyeVRPawn;
UCLASS()
class CARLAUE4_API AEgoVehicle : public ACarlaWheeledVehicle
{
GENERATED_BODY()
friend class ADReyeVRPawn;
public:
// Sets default values for this pawn's properties
AEgoVehicle(const FObjectInitializer &ObjectInitializer);
void ReadConfigVariables();
virtual void Tick(float DeltaTime) override; // called automatically
// Setters from external classes
void SetGame(ADReyeVRGameMode *Game);
ADReyeVRGameMode *GetGame();
void SetPawn(ADReyeVRPawn *Pawn);
void SetVolume(const float VolumeIn);
// Getters
const FString &GetVehicleType() const;
FVector GetCameraOffset() const;
FVector GetCameraPosn() const;
FVector GetNextCameraPosn(const float DeltaSeconds) const;
FRotator GetCameraRot() const;
const UCameraComponent *GetCamera() const;
UCameraComponent *GetCamera();
const DReyeVR::UserInputs &GetVehicleInputs() const;
const class AEgoSensor *GetSensor() const;
const struct ConfigFile &GetVehicleParams() const;
// autopilot API
void SetAutopilot(const bool AutopilotOn);
bool GetAutopilotStatus() const;
/// TODO: add custom routes for autopilot
// Play sounds
void PlayGearShiftSound(const float DelayBeforePlay = 0.f) const;
void PlayTurnSignalSound(const float DelayBeforePlay = 0.f) const;
// Camera view
size_t GetNumCameraPoses() const; // how many diff poses?
void SetCameraRootPose(const FTransform &Pose); // give arbitrary FTransform
void SetCameraRootPose(const FString &PoseName); // index into named FTransform
void SetCameraRootPose(size_t PoseIdx); // index into ordered FTransform
const FTransform &GetCameraRootPose() const;
void BeginThirdPersonCameraInit();
void NextCameraView();
void PrevCameraView();
protected:
// Called when the game starts (spawned) or ends (destroyed)
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void BeginDestroy() override;
// custom configuration file for vehicle-specific parameters
struct ConfigFile VehicleParams;
// World variables
class UWorld *World;
private:
template <typename T> T *CreateEgoObject(const FString &Name, const FString &Suffix = "");
FString VehicleType; // initially empty (set in GetVehicleType())
private: // camera
UPROPERTY(Category = Camera, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class USceneComponent *VRCameraRoot;
UPROPERTY(Category = Camera, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UCameraComponent *FirstPersonCam;
void ConstructCameraRoot(); // needs to be called in the constructor
FTransform CameraPose, CameraPoseOffset; // camera pose (location & rotation) and manual offset
TMap<FString, FTransform> CameraTransforms; // collection of named transforms from params
TArray<FString> CameraPoseKeys; // to iterate through them
size_t CurrentCameraTransformIdx = 0; // to index in CameraPoseKeys which indexes into CameraTransforms
bool bCameraFollowHMD = true; // disable this (in params) to replay without following the player's HMD (replay-only)
private: // sensor
class AEgoSensor *GetSensor();
void ReplayTick();
void InitSensor();
// custom sensor helper that holds logic for extracting useful data
TWeakObjectPtr<class AEgoSensor> EgoSensor; // EgoVehicle should have exclusive access (TODO: unique ptr?)
void UpdateSensor(const float DeltaTime);
private: // pawn
class ADReyeVRPawn *Pawn = nullptr;
private: // mirrors
void ConstructMirrors();
struct MirrorParams
{
bool Enabled;
FTransform MirrorTransform, ReflectionTransform;
float ScreenPercentage;
FString Name;
void Initialize(class UStaticMeshComponent *SM, class UPlanarReflectionComponent *Reflection,
class USkeletalMeshComponent *VehicleMesh);
};
struct MirrorParams RearMirrorParams, LeftMirrorParams, RightMirrorParams;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent *RightMirrorSM;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UPlanarReflectionComponent *RightReflection;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent *LeftMirrorSM;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UPlanarReflectionComponent *LeftReflection;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent *RearMirrorSM;
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UPlanarReflectionComponent *RearReflection;
// rear mirror chassis (dynamic)
UPROPERTY(Category = Mirrors, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent *RearMirrorChassisSM;
FTransform RearMirrorChassisTransform;
private: // AI controller
class AWheeledVehicleAIController *AI_Player = nullptr;
void InitAIPlayer();
bool bAutopilotEnabled = false;
void TickAutopilot();
private: // inputs
/// NOTE: since there are so many functions here, they are defined in EgoInputs.cpp
struct DReyeVR::UserInputs VehicleInputs; // struct for user inputs
// Vehicle control functions (additive for multiple input modalities (kbd/logi))
void AddSteering(float SteeringInput);
void AddThrottle(float ThrottleInput);
void AddBrake(float BrakeInput);
void TickVehicleInputs();
bool bReverse;
// "button presses" should have both a "Press" and "Release" function
// And, if using the logitech plugin, should also have an "is rising edge" bool so they can only
// be pressed after being released (cant double press w/ no release)
// Reverse toggle
void PressReverse();
void ReleaseReverse();
bool bCanPressReverse = true;
// turn signals
bool bEnableTurnSignalAction = true; // tune with "EnableTurnSignalAction" in config
// left turn signal
void PressTurnSignalL();
void ReleaseTurnSignalL();
float LeftSignalTimeToDie; // how long until the blinkers go out
bool bCanPressTurnSignalL = true;
// right turn signal
void PressTurnSignalR();
void ReleaseTurnSignalR();
float RightSignalTimeToDie; // how long until the blinkers go out
bool bCanPressTurnSignalR = true;
// Camera control functions (offset by some amount)
void CameraPositionAdjust(const FVector &Disp);
void CameraFwd();
void CameraBack();
void CameraLeft();
void CameraRight();
void CameraUp();
void CameraDown();
void CameraPositionAdjust(bool bForward, bool bRight, bool bBackwards, bool bLeft, bool bUp, bool bDown);
// changing camera views
void PressNextCameraView();
void ReleaseNextCameraView();
bool bCanPressNextCameraView = true;
void PressPrevCameraView();
void ReleasePrevCameraView();
bool bCanPressPrevCameraView = true;
// Vehicle parameters
float ScaleSteeringInput;
float ScaleThrottleInput;
float ScaleBrakeInput;
private: // sounds
UPROPERTY(Category = "Audio", EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UAudioComponent *GearShiftSound; // nice for toggling reverse
UPROPERTY(Category = "Audio", EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UAudioComponent *TurnSignalSound; // good for turn signals
UPROPERTY(Category = "Audio", EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UAudioComponent *EgoEngineRevSound; // driver feedback on throttle
UPROPERTY(Category = "Audio", EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UAudioComponent *EgoCrashSound; // crashing with another actor
void ConstructEgoSounds(); // needs to be called in the constructor
virtual void TickSounds(float DeltaSeconds) override;
// manually overriding these from ACarlaWheeledVehicle
void ConstructEgoCollisionHandler(); // needs to be called in the constructor
UFUNCTION()
void OnEgoOverlapBegin(UPrimitiveComponent *OverlappedComp, AActor *OtherActor, UPrimitiveComponent *OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);
private: // gamemode/level
void TickGame(float DeltaSeconds);
class ADReyeVRGameMode *DReyeVRGame;
private: // dashboard
// Text Render components (Like the HUD but part of the mesh and works in VR)
void ConstructDashText(); // needs to be called in the constructor
UPROPERTY(Category = "Dash", EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UTextRenderComponent *Speedometer;
UPROPERTY(Category = "Dash", EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UTextRenderComponent *TurnSignals;
float TurnSignalDuration; // time in seconds
UPROPERTY(Category = "Dash", EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UTextRenderComponent *GearShifter;
UPROPERTY(Category = "Dash", EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true")) // dashboard text(AM)
class UTextRenderComponent* Atext; // dashboard text(AM)
//UPROPERTY(EditAnywhere, Category = "Mesh")
UPROPERTY(Category = "Mesh", EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent* CubeMesh = nullptr;
void UpdateDash();
FVector DashboardLocnInVehicle{ 110, 0, 105 }; // dashboard text(AM)
float SpeedometerScale = CmPerSecondToXPerHour(true); // scale from CM/s to MPH or KPH (default MPH)
private: // steering wheel
UPROPERTY(Category = Steering, EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent *SteeringWheel;
void ConstructSteeringWheel(); // needs to be called in the constructor
void DestroySteeringWheel();
void TickSteeringWheel(const float DeltaTime);
float MaxSteerAngleDeg;
float MaxSteerVelocity;
float SteeringAnimScale;
bool bWheelFollowAutopilot = true; // disable steering during autopilot and follow AI
// wheel face buttons
void InitWheelButtons();
void UpdateWheelButton(ADReyeVRCustomActor *Button, bool bEnabled);
class ADReyeVRCustomActor *Button_ABXY_A, *Button_ABXY_B, *Button_ABXY_X, *Button_ABXY_Y;
class ADReyeVRCustomActor *Button_DPad_Up, *Button_DPad_Down, *Button_DPad_Left, *Button_DPad_Right;
bool bInitializedButtons = false;
const FLinearColor ButtonNeutralCol = 0.2f * FLinearColor::White;
const FLinearColor ButtonPressedCol = 1.5f * FLinearColor::White;
// wheel face autopilot indicator
void InitAutopilotIndicator();
void TickAutopilotIndicator(bool);
class ADReyeVRCustomActor *AutopilotIndicator;
bool bInitializedAutopilotIndicator = false;
private: // other
void DebugLines() const;
bool bDrawDebugEditor = false;
};