Skip to content

Commit

Permalink
Merge pull request #49 from ErkMkd/main
Browse files Browse the repository at this point in the history
Recorder API
  • Loading branch information
ErkMkd authored Dec 13, 2022
2 parents a8bdd18 + 229e1d6 commit 6ff06b5
Show file tree
Hide file tree
Showing 22 changed files with 1,458 additions and 341 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/source/assets_compiled
/.vscode
/bin_
/source/database.db
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,37 @@ The source code and the graphics assets are made available for studying purpose.
* HTC Vive Pro
* Meta Quest 2 (in Oculus Link mode)


## Record / Replay API overview:

1. Choose the mission you want to record.
2. Type "F9" to open the recorder interface:
![Recorder](screenshots/recorder_02.png)
* `Add user` : You can add a user. Each user has his own list of records.
* `Users` : Use this combo boxe to selected the user.
* `Item`: List of recordable items.
* `Start recording`: Record the simulation.
* `Recording FPS` : Recording frequency (Frame Per Second).
* `Records`: Select record to replay.
* `Enter replay mode`: Replayer.

3. Replay:
![Recorder](screenshots/recorder_03.png)
* Selected the user and record you want to replay.
* Press `Start play`
The items are created. You can pause the replay, and move the Timeline cursor.
![Recorder](screenshots/recorder_04.png)
* `Display selected item`: Display a sight on selected item, to identify the item in 3D view.
* `Prev frame`, `Next frame`: Backward / foreward frame by frame. You can also press `-`, `+` on keyboard.

### Events:
Hits (missiles, machine gun, crashes) are recorded and displayed as circles during replay:
![Recorder](screenshots/recorder_05.png)
Yellow circles : before the event
Red circles : after the event
The maximum size of the circle depends on the power of the collision.


## Network mode overview

The "Network" mode allows you to control the planes from a third party machine.
Expand Down
Binary file added screenshots/recorder_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/recorder_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/recorder_04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/recorder_05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 8 additions & 6 deletions source/HUD.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,18 @@ def update(cls, main, machine):
target = td.get_target()
f = 1 # Main.HSL_postProcess.GetL()
if target is not None:
p2D = main.get_2d_hud(target.get_parent_node().GetTransform().GetPos())
target_pos = target.get_parent_node().GetTransform().GetPos()
target_distance = hg.Len(target_pos - machine.get_parent_node().GetTransform().GetPos())
p2D = main.get_2d_hud(target_pos)
if p2D is not None:
a_pulse = 0.5 if (sin(tps * 20) > 0) else 0.75
if td.target_locked:
c = hg.Color(1., 0.5, 0.5, a_pulse)
msg = "LOCKED - " + str(int(td.target_distance))
msg = "LOCKED - " + str(int(target_distance))
x = (p2D.x / main.resolution.x - 32 / 1600)
a = a_pulse
else:
msg = str(int(td.target_distance))
msg = str(int(target_distance))
x = (p2D.x / main.resolution.x - 12 / 1600)
c = hg.Color(0.5, 1, 0.5, 0.75)

Expand All @@ -261,9 +263,9 @@ def update(cls, main, machine):

c = hg.Color(0, 1, 0, f)

Overlays.add_text2D("Target dist: %d" % (td.target_distance), hg.Vec2(0.05, 0.91), 0.016, c, main.hud_font)
Overlays.add_text2D("Target heading: %d" % (td.target_heading),hg.Vec2(0.05, 0.89), 0.016, c, main.hud_font)
Overlays.add_text2D("Target alt: %d" % (td.target_altitude), hg.Vec2(0.05, 0.87), 0.016, c, main.hud_font)
Overlays.add_text2D("Target dist: %d" % (target_distance), hg.Vec2(0.05, 0.91), 0.016, c, main.hud_font)
Overlays.add_text2D("Target heading: %d" % (target.get_heading()),hg.Vec2(0.05, 0.89), 0.016, c, main.hud_font)
Overlays.add_text2D("Target alt: %d" % (target.get_altitude()), hg.Vec2(0.05, 0.87), 0.016, c, main.hud_font)


class HUD_Aircraft:
Expand Down
83 changes: 49 additions & 34 deletions source/MachineDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def get_landing_vector(self):

class MachineDevice:

framecount = 0 #Updated with Main.framecount
timer = 0

# Start state: activated or not.
def __init__(self, name, machine, start_state=False):
self.activated = start_state
Expand Down Expand Up @@ -231,6 +234,11 @@ def set_target_id(self, tid):
if target.wreck or not target.activated:
self.next_target()

def get_target_name(self):
if self.target_id == 0:
return None
return self.targets[self.target_id-1].name

def set_target_by_name(self, target_name):
tid = 0
for i, tgt in enumerate(self.targets):
Expand Down Expand Up @@ -334,10 +342,10 @@ def __init__(self, name, machine, slots_nodes):
self.flag_hide_fitted_missiles = False

def destroy(self):
if self.missiles is not None:
for missile in self.missiles:
if missile is not None:
missile.destroy()
#if self.missiles is not None:
# for missile in self.missiles:
# if missile is not None:
# missile.destroy()
self.missiles = None
self.num_slots = 0
self.slots_nodes = None
Expand Down Expand Up @@ -510,6 +518,8 @@ def update(self, dts):
break
"""

#Collision using raycast:
rc_len = hg.Len(p1 - pos_fb)
hit = self.scene_physics.RaycastFirstHit(self.scene, pos_fb, p1)
if 0 < hit.t < rc_len:
Expand All @@ -519,7 +529,7 @@ def update(self, dts):
cnds = target.get_collision_nodes()
for nd in cnds:
if nd == hit.node:
target.hit(0.1)
target.hit(0.1, hit.P)
bullet.v_move = target.v_move
self.strike(i)
break
Expand All @@ -537,18 +547,22 @@ def set_num_bullets(self, num):
self.bullets_particles.particles_cnt_max = int(num)
self.bullets_particles.reset()

def fire_machine_gun(self):
def activate(self):
if not self.wreck:
super().activate()
self.bullets_particles.flow = 24 / 2

def stop_machine_gun(self):

def deactivate(self):
super().deactivate()
self.bullets_particles.flow = 0

"""
def is_gun_activated(self):
if self.bullets_particles.flow == 0:
return False
else:
return True
"""

def get_new_bullets_count(self):
return self.bullets_particles.num_new
Expand All @@ -564,6 +578,7 @@ class ControlDevice(MachineDevice):
CM_MOUSE = "Mouse"
CM_LOGITECH_EXTREME_3DPRO = "Logitech extreme 3DPro"
CM_LOGITECH_ATTACK_3 = "Logitech Attack 3"
CM_NONE = "None"

keyboard = None
mouse = None
Expand Down Expand Up @@ -1120,14 +1135,14 @@ def fire_machine_gun_kb(self, value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and not mgd.is_gun_activated():
mgd.fire_machine_gun()
if mgd is not None and not mgd.is_activated():
mgd.activate()
elif ControlDevice.keyboard.Released(value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()

def fire_missile_kb(self, value):
if ControlDevice.keyboard.Pressed(value):
Expand Down Expand Up @@ -1254,14 +1269,14 @@ def fire_machine_gun_la3(self, value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and not mgd.is_gun_activated():
mgd.fire_machine_gun()
if mgd is not None and not mgd.is_activated():
mgd.activate()
elif ControlDevice.generic_controller.Released(value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()


def fire_missile_la3(self, value):
Expand Down Expand Up @@ -1388,14 +1403,14 @@ def fire_machine_gun_gp(self, value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and not mgd.is_gun_activated():
mgd.fire_machine_gun()
if mgd is not None and not mgd.is_activated():
mgd.activate()
elif ControlDevice.gamepad.Released(value):
n = self.machine.get_machinegun_count()
for i in range(n):
mgd = self.machine.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()

def fire_missile_gp(self, value):
if ControlDevice.gamepad.Pressed(value):
Expand Down Expand Up @@ -1758,8 +1773,8 @@ def activate(self):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()

self.IA_flag_go_to_target = False
if aircraft.flag_landed:
Expand All @@ -1784,8 +1799,8 @@ def deactivate(self):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()
self.IA_flag_go_to_target = False
aircraft.set_flaps_level(0)
self.IA_flag_landing_target_found = False
Expand Down Expand Up @@ -1885,8 +1900,8 @@ def update_IA_idle(self, aircraft):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()
autopilot.set_autopilot_altitude(self.IA_cruising_altitude)
autopilot.set_autopilot_heading(0)

Expand Down Expand Up @@ -1916,8 +1931,8 @@ def update_IA_landing(self, aircraft, dts):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()
self.IA_landing_target = self.get_nearest_landing_target(aircraft)
if self.IA_landing_target is not None:
self.IA_flag_landing_target_found = True
Expand Down Expand Up @@ -2059,14 +2074,14 @@ def update_IA_fight(self, aircraft, dts):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and not mgd.is_gun_activated():
mgd.fire_machine_gun()
if mgd is not None and not mgd.is_activated():
mgd.activate()
else:
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()

flag_missiles_ok = False
if md is not None:
Expand All @@ -2086,8 +2101,8 @@ def update_IA_fight(self, aircraft, dts):
n = aircraft.get_machinegun_count()
for i in range(n):
mgd = aircraft.get_device("MachineGunDevice_%02d" % i)
if mgd is not None and mgd.is_gun_activated():
mgd.stop_machine_gun()
if mgd is not None and mgd.is_activated():
mgd.deactivate()
self.IA_flag_landing_target_found = False
self.IA_command = AircraftIAControlDevice.IA_COM_LANDING
# self.set_autopilot_altitude(self.IA_cruising_altitude)
Expand Down
Loading

0 comments on commit 6ff06b5

Please sign in to comment.