Skip to content

Commit

Permalink
Merge pull request #45515 from dsnopek/webxr-ar-lose-tracking
Browse files Browse the repository at this point in the history
[3.2] Prevent fatal error in WebXR when 'immersize-ar' loses and regains tracking
  • Loading branch information
akien-mga authored Jan 28, 2021
2 parents cea561e + 5625dc5 commit bc90bcb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
14 changes: 13 additions & 1 deletion modules/webxr/native/library_godot_webxr.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ const GodotWebXR = {
gl.deleteTexture(texture);
}
GodotWebXR.textures[i] = null;

const texture_id = GodotWebXR.texture_ids[i];
if (texture_id !== null) {
GL.textures[texture_id] = null;
}
GodotWebXR.texture_ids[i] = null;
}

Expand Down Expand Up @@ -461,7 +466,7 @@ const GodotWebXR = {
godot_webxr_get_external_texture_for_eye__proxy: 'sync',
godot_webxr_get_external_texture_for_eye__sig: 'ii',
godot_webxr_get_external_texture_for_eye: function (p_eye) {
if (!GodotWebXR.session || !GodotWebXR.pose) {
if (!GodotWebXR.session) {
return 0;
}

Expand All @@ -470,6 +475,13 @@ const GodotWebXR = {
return GodotWebXR.texture_ids[view_index];
}

// Check pose separately and after returning the cached texture id,
// because we won't get a pose in some cases if we lose tracking, and
// we don't want to return 0 just because tracking was lost.
if (!GodotWebXR.pose) {
return 0;
}

const glLayer = GodotWebXR.session.renderState.baseLayer;
const view = GodotWebXR.pose.views[view_index];
const viewport = glLayer.getViewport(view);
Expand Down
26 changes: 18 additions & 8 deletions modules/webxr/webxr_interface_js.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ void _emwebxr_on_session_failed(char *p_message) {
Ref<ARVRInterface> interface = arvr_server->find_interface("WebXR");
ERR_FAIL_COND(interface.is_null());

interface->uninitialize();

String message = String(p_message);
interface->emit_signal("session_failed", message);
}
Expand Down Expand Up @@ -226,6 +228,12 @@ bool WebXRInterfaceJS::initialize() {
// make this our primary interface
arvr_server->set_primary_interface(this);

// Clear render_targetsize to make sure it gets reset to the new size.
// Clearing in uninitialize() doesn't work because a frame can still be
// rendered after it's called, which will fill render_targetsize again.
render_targetsize.width = 0;
render_targetsize.height = 0;

initialized = true;

godot_webxr_initialize(
Expand Down Expand Up @@ -279,22 +287,24 @@ Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) {
}

Size2 WebXRInterfaceJS::get_render_targetsize() {
Size2 target_size;
if (render_targetsize.width != 0 && render_targetsize.height != 0) {
return render_targetsize;
}

int *js_size = godot_webxr_get_render_targetsize();
if (!initialized || js_size == nullptr) {
// As a default, use half the window size.
target_size = OS::get_singleton()->get_window_size();
target_size.width /= 2.0;
return target_size;
// As a temporary default (until WebXR is fully initialized), use half the window size.
Size2 temp = OS::get_singleton()->get_window_size();
temp.width /= 2.0;
return temp;
}

target_size.width = js_size[0];
target_size.height = js_size[1];
render_targetsize.width = js_size[0];
render_targetsize.height = js_size[1];

free(js_size);

return target_size;
return render_targetsize;
};

Transform WebXRInterfaceJS::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
Expand Down
2 changes: 1 addition & 1 deletion modules/webxr/webxr_interface_js.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ class WebXRInterfaceJS : public WebXRInterface {
private:
bool initialized;

// @todo Should these really use enums instead of strings?
String session_mode;
String required_features;
String optional_features;
String requested_reference_space_types;
String reference_space_type;

bool controllers_state[2];
Size2 render_targetsize;

Transform _js_matrix_to_transform(float *p_js_matrix);
void _update_tracker(int p_controller_id);
Expand Down

0 comments on commit bc90bcb

Please sign in to comment.