Aircraft_script - Outerra/anteworld GitHub Wiki
Models imported as aircraft can be bound to a particular JSBSim FDM and given a script to handle the animation of their parts according to the corresponding JSBSim properties. The assignment is done in the model's objdef file by adding the following lines:
"physics" : "jsbsim/c172r",
"script" : "c172.aircraft.js",
- "physics" - refers to the JSBSim configuration file, found in the program directory under the jsbsim folder.
- "script" - refers to a custom javascript file in the model directory that will be handling model animations, sounds and binding of the inputs to the underlying JSBSim model.
Aircraft script, referenced from .objdef file of a model, is used to define the link between the JSBSim model, 3D model and the input system.
The script should define two functions that are invoked internally: initialize(reload) and update_frame(dt). Initialize() with reload=false is called before any other call to the script. It's expected that the script global variables are set up here. The update_frame() event is called each frame to handle the internal state of the model instance.
When these events are invoked, their this parameter is actually a reference to Outerra's internal aircraft interface, that provides several methods that can be invoked via this.method() call.
The aircraft interface defines the following methods and events:
Type | Name | Parameters | Parameter Description | Returns | Description |
---|---|---|---|---|---|
method | get_objdef_params | - | - | return: objdef parameters | Get the objdef parameters associated with the vehicle. |
method | resolve_path | ot::path_rel_to ref const coid::token& path ifc_out coid::charstr& dst |
ref: The reference path path: The relative path dst: The resolved path |
return: false on argument error | Resolve relative path. |
method | get_geomob | int id (default: 0) | id: Object ID | return: geomob object | Get geomob. |
method | get_objdef_info | ifc_out ot::pkginfo::obj& info | info: Object definition information | return: objdef information | Get objdef information. |
method | get_objdef_param | const coid::token& key const coid::token& group (default: coid::token()) |
key: Key of the parameter group: Group of the parameter |
return: parameter value | Get parameter from objdef. |
method | get_collision_group | ifc_out uint* mask | mask: Optional mask value | return: collision group | Get the collision group. |
method | set_collision_group | uint group uint mask |
group: Collision group ID mask: Collision mask |
- | Set the collision group. |
method | fade | const coid::token& text | text: Message to post to the fading log | - | Posts a message to the fading log. |
method | get_camera_mode | - | - | return: camera mode | Get the camera mode. |
method | get_custom_data_value | - | - | return: custom data value | Get the custom data value. |
method | heading_pitch_roll | - | - | return: float3 | Get heading/pitch/roll angles of the object in radians. |
method | extra_force | const float3& mpos const float3& force bool worldspace (default: false) |
mpos: Model-space position to act on force: Model or world-space force vector worldspace: True for world-space force vector |
- | Add extra force to be applied to the object. |
method | extra_impulse | const float3& mpos const float3& impulse bool worldspace (default: false) |
mpos: Model-space position to act on impulse: Model or world-space force impulse vector worldspace: True for world-space force vector |
- | Apply extra force impulse (force * dt), one-time impulse, non-persistent. |
method | get_joint_id | const coid::token& name | name: Bone name | return: joint/bone id or -1 if doesn't exist | Get joint/bone id for given bone name. |
method | get_mesh_id | const coid::token& name uint8 lod_group (default: 0xff) uint8 mat_group (default: 0xff) |
name: Mesh name lod_group: LOD group for given base name mat_group: Material group for given base name |
return: mesh id for given params or -1 if doesn't exist | Get mesh id for given params or -1 if doesn't exist. |
method | fire | const float3& pos const float3& dir float speed float caliber const float3& color uint joint (default: pkg::InvalidBoneId) |
pos: Model-space launch position dir: Model-space launch direction speed: Firing velocity in m/s caliber: Diameter of the ray [m] color: Plasma color joint: Bone id to attach to |
- | Fire a colored plasma thing. |
method | explode_ground | const ot::ground_explosion& ge | ge: Explosion parameters | - | Explode ground at model position. |
method | elevation_test | const float3& pos float maxdist float negdist (default: -FLT_MIN) uint joint (default: pkg::InvalidBoneId) |
pos: Model-space position maxdist: Max distance/height to check negdist: Max negative distance to test joint: Bone id to be relative to |
return: height above terrrain or >= maxdist if no hit, <= negdist if under terrain | Elevation test. |
method | elevation_test_ext | const float3& pos float maxdist float negdist (default: -FLT_MIN) ifc_out ot::hitpoint* hp (default: 0) ot::hit_flags hpflags (default: {.hit = true, .normal = true}) uint joint (default: pkg::InvalidBoneId) |
pos: Model-space position maxdist: Max distance/height to check negdist: Max negative distance to test hp: Hitpoint result hpflags: Query flags joint: Bone id to be relative to |
return: height above terrrain or >= maxdist if no hit, <= negdist if under terrain | Elevation test with extended info. |
method | ray_test | const float3& pos const float3& dir float maxdist float negdist (default: -FLT_MIN) ifc_out ot::hitpoint* hp (default: 0) ot::hit_flags hpflags (default: {.hit = true, .normal = true}) uint joint (default: pkg::InvalidBoneId) |
pos: Model-space (or bone-space) position dir: Model-space (or bone-space) ray direction maxdist: Max distance/height to check negdist: Max negative distance to test hp: Hitpoint result hpflags: Query flags joint: Bone id to be relative to |
return: intersection distance or >= maxdist if no hit, <= negdist if under terrain | Test if ray from model intersects with terrain. |
method | object_test | const float3& pos const float3& dir float maxdist ifc_out ot::hitpoint* hp (default: 0) ot::hit_flags hpflags (default: {.hit = true, .normal = true, .objects = true, .dynamic = true, .selftest = false}) uint joint (default: pkg::InvalidBoneId) |
pos: Model-space (or bone-space) position dir: Model-space (or bone-space) ray direction maxdist: Max ray distance to check hp: Hitpoint result hpflags: Query flags joint: Bone id to be relative to |
return: object hit | Test if ray from model hits an object. |
method | attach_object | const irefot::object& obj uint joint_id const float3& pos const quat& rot uint custom_id |
obj: Object to attach joint_id: Bone id pos: Relative attachment offset rot: Relative attachment rotation custom_id: ID to identify the attached object when detaching |
- | Attach object. |
method | detach_object | uint custom_id bool activate |
custom_id: ID set previously by attach_geom activate: Activate object (if it's not a static one) |
return: detached object, if found | Detach specified object. |
method | detach_ot_object | const irefot::object& object bool activate |
object: Attached object activate: Activate object (if it's not a static one) |
return: true if successful | Detach specified object. |
method | set_fps_camera_pos | const float3& pos uint joint_id (default: UMAX32) ot::EJointRotationMode joint_rotation (default: ot::JointRotModeEnable) |
pos: Model space position joint_id: Joint ID joint_rotation: Joint rotation mode |
- | Set model space position for FPS camera. |
method | set_fps_camera_rot | const quat& rot ot::ERotationMode mouse_rotation |
rot: Model space rotation mouse_rotation: Mouse rotation mode: 0 freeze, 1 reset & disable, 2 enable, 3 reset & enable |
- | Set model space rotation frame. |
method | set_fps_camera_fov | float hfov float vfov (default: 0) |
hfov: Horizontal FOV in degrees, 0 to reset to the default one vfov: Optional vertical FOV in degrees, otherwise computed from aspect ratio |
- | Set FOV to chassis FPS preset and current camera if vehicle is entered and FPS camera is active. |
method | get_fps_camera_pos | - | - | return: current FPS camera position | Get current FPS camera position. |
method | get_fps_camera_rot | bool base (default: false) | base: True for the base orientation frame, false for current camera orientation as altered by mouse | return: current FPS camera rotation in model space | Get current FPS camera rotation in model space. |
method | get_fps_camera_fov | - | - | return: FPS camera preset FOV for this chassis | Get FPS camera preset FOV for this chassis. |
method | set_fps_camera_ypr | float yaw float pitch float roll ot::ERotationMode mouse_rotation |
yaw: Yaw angle in radians, positive values to the right pitch: Pitch angle in radians, positive up roll: Roll angle in radians, positive clockwise mouse_rotation: Mouse rotation mode: 0 freeze, 1 reset & disable, 2 enable, 3 reset & enable |
- | Set model space orientation for FPS camera. |
method | get_fps_camera_ypr | bool base (default: false) | base: True for the base orientation frame, false for current camera orientation as altered by mouse | return: current yaw/pitch/roll angles of the camera in model space in radians | Get current yaw/pitch/roll angles of the camera in model space. |
method | set_fps_camera_tracking_point | const double3& target bool level_horizon |
target: ECEF coordinates of the point level_horizon: Keep horizon level (roll the camera) |
true if tracking was enabled, false if center wasn't on terrain or the current camera mode is not FPS | Enable tracking of world point. |
method | set_fps_camera_tracking | bool level_horizon | level_horizon: Keep horizon level (roll the camera) | true if tracking was enabled, false if center wasn't on terrain or the current camera mode is not FPS | Enable tracking of the current world point (in screen center). |
method | set_fps_camera_tracking_off | - | - | - | Disable tracking. |
method | sound | - | - | return: of::snd_group interface | Get sound interface. |
method | register_handler_ext | const coid::token& name uint group (default: 0) |
name: Hierarchic action name, file/group/action group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register action handler for an existing knob. |
method | register_event_ext | const coid::token& name bool release_event uint group (default: 0) |
name: Hierarchic action name, file/group/action release_event: True if handler should also receive release events (if bound to key) group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register event action handler. |
method | register_axis_ext | const coid::token& name const ot::ramp_params& ramp uint group (default: 0) |
name: Hierarchic action name, file/group/action ramp: Value limiter parameters (ignored for buttons) group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register axis action handler. |
method | register_handler | const coid::token& name ot::fn_event_action&& handler int handler_id (default: 0) uint group (default: 0) |
name: Hierarchic action name handler: Handler for changed value handler_id: Optional extra data for the handler group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register input action for an existing knob, create new using def_ramp if doesn't exist. |
method | register_handler_default | const coid::token& name ot::fn_event_action&& handler const ot::ramp_params& def_ramp int handler_id (default: 0) const float* def_val (default: nullptr) uint group (default: 0) |
name: Hierarchic action name handler: Handler for changed value def_ramp: Action options to use if knob wasn't found, if nullptr do not create handler_id: Optional extra data for the handler def_val: Optional default action value group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register input action for an existing knob, if doesn't exist create new if def_ramp. |
method | register_axis_handler | const coid::token& name ot::fn_axis_action&& handler const ot::ramp_params& ramp int handler_id (default: 0) const float* def_val (default: nullptr) uint group (default: 0) |
name: Hierarchic action name handler: Optional handler for changed value handler_id: Optional extra data for the handler def_val: Optional default action value ramp: Value limiter parameters group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register input action sending events on value change (full state button and axis). |
method | register_event_handler | const coid::token& name ot::fn_event_action&& handler int handler_id (default: 0) uint group (default: 0) uint extra_channels (default: 0) |
name: Hierarchic action name handler: Optional handler for changed value handler_id: Optional extra data for the handler extra_channels: Number of extra channels that are handled (multiple engines etc) group: Activation group where the action is assigned (can be enabled/disabled together) |
return: slot id or -1 on fail | Register input action sending events on button press (value > 0). |
method | action_group | uint group bool activate |
group: Group ID activate: Activate/deactivate the group |
- | Activate or deactivate given action group. |
method | set_center_value | int action float center |
action: Action ID center: Center value, will be clamped to minval..maxval range |
- | Set the value to center to, default 0. |
method | set_action_value | int action float value bool hold |
action: Action ID value: Action value, will be clamped to minval..maxval range hold: True if the value should be held (disabled centering) |
- | Set action value. |
method | set_instant_action_value | int action float value bool notify |
action: Action ID value: Action value, will be clamped to minval..maxval range notify: Invoke/don't invoke the handler |
- | Set action value. |
method | add_spot_light | const float3& offset const float3& dir const ot::light_params& lp const coid::token& joint (default: coid::token()) |
offset: Model-space offset relative to the bone or model pivot dir: Light direction lp: Light parameters joint: Joint name to attach the light to |
return: light emitter id | Define circular spotlight source. Can be called only from within init_chassis. |
method | add_point_light | const float3& offset const ot::light_params& lp const coid::token& joint (default: coid::token()) |
offset: Model-space offset relative to the bone or model pivot lp: Light parameters joint: Joint name to attach the light to |
return: light emitter id | Define point light source. Can be called only from within init_chassis. |
method | light | uint id bool on |
id: Light ID on: Turn light on/off |
- | Turn light on/off. |
method | light_mask | uint mask bool on uint offset (default: 0) |
mask: Light mask on: Turn light on/off offset: Offset |
- | Turn light on/off using mask. |
method | light_toggle | uint id | id: Light ID | - | Toggle light. |
method | light_toggle_mask | uint mask uint offset (default: 0) |
mask: Light mask offset: Offset |
- | Toggle lights by bit mask. |
method | light_color | uint id const float4& color float range (default: 0) |
id: Light ID color: Light color range: Light range |
- | Set light color/intensity. |
method | lights_off | bool instant (default: false) | instant: Turn off lights instantly or not | - | All lights off. |
method | solar_time | ifc_out double& time ifc_out float& sun_coef |
time: Solar time at vehicle location, in milliseconds sun_coef: Sun position relative to horizon: 0 sun at horizon, 1 sun at zenith, -1 sun at anti-zenith |
- | Return current solar time and cosine of sun-zenith angle. |
method | add_display | float width float height const coid::token& mesh_name |
width: Width of the display height: Height of the display mesh_name: Name of the display's mesh in geomob |
return: id of the display | Add new display. |
method | get_display_canvas | uint display_id | display_id: Display ID | return: display canvas | Get display canvas. |
method | get_display_names | - | - | return: display names | Get display names. |
method | add_smoke_emitter | const coid::token& joint const coid::token& texture const ot::particle_emitter_params& params |
joint: Name of the joint emitter will be attached to texture: Relative path of the texture to use as particle billboard (must be in RGBA8 dds format) params: Emitter parameters |
return: smoke emitter id | Add smoke emitter. |
method | add_dust_emitter | const coid::token& joint const coid::token& texture |
joint: Name of the joint emitter will be attached to texture: Relative path of the texture to use |
return: dust emitter id | Add dust emitter. |
method | set_emitter_color | uint emitter ot::color color |
emitter: Emitter ID color: Particle color |
- | Set overall emitter alpha. |
method | pause_emitter | uint emitter bool pause |
emitter: Handle of emitter pause: Pause/resume |
- | Pause emitter. |
method | load_sound | const coid::token& filename | filename: Sound file name | return: sound buffer id | Load sound buffer. |
method | add_sound_emitter | const coid::token& joint int type (default: 0) float ref_distance (default: 0) |
joint: Bone name to attach to type: Sound type: -1 interior only, 0 universal, 1 exterior only ref_distance: Reference distance (saturated volume distance) |
return: sound emitter id | Attach sound emitter to a model joint. |
method | add_sound_emitter_id | uint joint_id int type (default: 0) float ref_distance (default: 0) |
joint_id: Bone ID to attach to type: Sound type: -1 interior only, 0 universal, 1 exterior only ref_distance: Reference distance (saturated volume distance) |
return: sound emitter id | Attach sound emitter to a model joint by ID. |
method | set_interior_sound_attenuation | float att | att: Attenuation value | - | Set attenuation for sounds coming from outside. |
method | fetch_controls | coid::dynarray32& buf bool append |
buf: Buffer to fetch controls into append: Append to existing buffer or not |
- | Fetch controls. |
method | apply_controls | const int32* cmd uint ncmds |
cmd: Commands array ncmds: Number of commands |
- | Apply controls. |
method | open | int openid ot::kbd_modifier modifiers |
openid: ID of the openable part (script specific) modifiers: Keyboard modifiers (LSHIFT=1, RSHIFT=2, LCTRL=4, RCTRL=8) |
- | Insert an open door command. |
method | get_animator | - | - | return: animator component | Get animator component. |
method | jsb | - | - | return: ot::jsb interface | Get ot::jsb interface to JSBSim instance. |
method | get_aircraft_data | - | - | return: aircraft data | Get aircraft data. |
method | reset_ic | - | - | - | Reset simulation. |
method | initialize_ic | - | - | - | Initialize simulation from initial conditions. |
method | engine_running | - | - | return: true if running | Check if engine is running. |
method | activate_event_group | const coid::token& name | name: Event group name | - | Activate event group. |
method | has_animator | - | - | return: true if exists | Check if animator component exists. |
method | get_animator_input_index | const coid::token& input_name | input_name: Name of the input defined in animation graph | return: input index | Get index of input by name. |
method | get_animator_input_float | uint input_index | input_index: Input index | return: float value | Get current input index value as float. |
method | get_animator_input_bool | uint input_index | input_index: Input index | return: boolean value | Get current input index value as boolean. |
method | get_animator_input_int | uint input_index | input_index: Input index | return: integer value | Get current input index value as integer. |
method | set_animator_input_float | uint input_index float value |
input_index: Input index value: Value to set |
- | Set current input index value as float. |
method | set_animator_input_bool | uint input_index bool value |
input_index: Input index value: Value to set |
- | Set current input index value as boolean. |
method | set_animator_input_int | uint input_index int value |
input_index: Input index value: Value to set |
- | Set current input index value as integer. |
event | init_chassis | const coid::charstr& params | params: Custom parameters from objdef | return: chassis parameters | Initialize chassis (shared across all aircraft instances of the same type). |
event | init_chassis_script | const coid::charstr& params | params: Custom parameters from objdef | return: chassis parameters | Initialize chassis using script (shared across all aircraft instances of the same type). |
event | update_actions_script | float dt const coid::range& actbuf |
dt: Time step for the update actbuf: Range of action buffers |
- | Interface event for handling aircraft state before rendering (inputs, animating joints etc). |
event | engine | bool start | start: Flag indicating whether to start or stop the engine | - | Start/stop engine. |
event | ext_param | const coid::token& name const float* value |
name: Parameter name value: Value to set, null means requesting value |
return: new/existing param value | Set/get externally provided parameter. |
event | initialize | bool reload | reload: True if object is being reloaded | - | Interface event for initialization and script reload. |
event | update_frame | float dt | dt: Time step for the update | - | Interface event for handling aircraft state before rendering (inputs, animating joints etc). |
event | force_bind_script_events | - | - | - | Force bind script events. |
let Rotor_main_id,
Rotor_tail_id;
// cockpit stuff
const PI = 3.14159265358979323846;
const TWO_PI = 6.28318530717958647692;
const DEG2RAD = 180.0 / PI;
function initialize(reload)
{
this.Geom = this.get_geomob(0); // get first geometry instance
this.JSB = this.jsb(); // get JSBSim interface
Rotor_main_id = this.Geom.get_joint('rotor_main');
Rotor_tail_id = this.Geom.get_joint('rotor_tail');
this.set_fps_camera_pos(this.Geom.get_joint_local_pos(this.Geom.get_joint('camera_pilot')));
this.activate_event_group("heli");
}
function deg2rad(angle_deg) { return (PI / 180.0) * angle_deg; }
function update_frame(dt)
{
let val;// = 300 * (1.0 / 60.0) * dt * TWO_PI;
// main / tail rotor
val = this.JSB['propulsion/engine[0]/rotor-rpm'] * (1.0 / 60.0) * dt * TWO_PI;
this.Geom.rotate_joint(Rotor_main_id, val, {x:0,y:0,z:1});
this.Geom.rotate_joint(Rotor_tail_id, val * 4.525, {x:1,y:0,z:0});
}