Prevent fatal error in WebXR when 'immersize-ar' loses and regains tracking
This commit is contained in:
parent
dae72fcdd5
commit
5625dc502c
3 changed files with 32 additions and 10 deletions
|
@ -381,6 +381,11 @@ const GodotWebXR = {
|
||||||
gl.deleteTexture(texture);
|
gl.deleteTexture(texture);
|
||||||
}
|
}
|
||||||
GodotWebXR.textures[i] = null;
|
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;
|
GodotWebXR.texture_ids[i] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +466,7 @@ const GodotWebXR = {
|
||||||
godot_webxr_get_external_texture_for_eye__proxy: 'sync',
|
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__sig: 'ii',
|
||||||
godot_webxr_get_external_texture_for_eye: function (p_eye) {
|
godot_webxr_get_external_texture_for_eye: function (p_eye) {
|
||||||
if (!GodotWebXR.session || !GodotWebXR.pose) {
|
if (!GodotWebXR.session) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +475,13 @@ const GodotWebXR = {
|
||||||
return GodotWebXR.texture_ids[view_index];
|
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 glLayer = GodotWebXR.session.renderState.baseLayer;
|
||||||
const view = GodotWebXR.pose.views[view_index];
|
const view = GodotWebXR.pose.views[view_index];
|
||||||
const viewport = glLayer.getViewport(view);
|
const viewport = glLayer.getViewport(view);
|
||||||
|
|
|
@ -80,6 +80,8 @@ void _emwebxr_on_session_failed(char *p_message) {
|
||||||
Ref<ARVRInterface> interface = arvr_server->find_interface("WebXR");
|
Ref<ARVRInterface> interface = arvr_server->find_interface("WebXR");
|
||||||
ERR_FAIL_COND(interface.is_null());
|
ERR_FAIL_COND(interface.is_null());
|
||||||
|
|
||||||
|
interface->uninitialize();
|
||||||
|
|
||||||
String message = String(p_message);
|
String message = String(p_message);
|
||||||
interface->emit_signal("session_failed", message);
|
interface->emit_signal("session_failed", message);
|
||||||
}
|
}
|
||||||
|
@ -226,6 +228,12 @@ bool WebXRInterfaceJS::initialize() {
|
||||||
// make this our primary interface
|
// make this our primary interface
|
||||||
arvr_server->set_primary_interface(this);
|
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;
|
initialized = true;
|
||||||
|
|
||||||
godot_webxr_initialize(
|
godot_webxr_initialize(
|
||||||
|
@ -279,22 +287,24 @@ Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Size2 WebXRInterfaceJS::get_render_targetsize() {
|
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();
|
int *js_size = godot_webxr_get_render_targetsize();
|
||||||
if (!initialized || js_size == nullptr) {
|
if (!initialized || js_size == nullptr) {
|
||||||
// As a default, use half the window size.
|
// As a temporary default (until WebXR is fully initialized), use half the window size.
|
||||||
target_size = OS::get_singleton()->get_window_size();
|
Size2 temp = OS::get_singleton()->get_window_size();
|
||||||
target_size.width /= 2.0;
|
temp.width /= 2.0;
|
||||||
return target_size;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_size.width = js_size[0];
|
render_targetsize.width = js_size[0];
|
||||||
target_size.height = js_size[1];
|
render_targetsize.height = js_size[1];
|
||||||
|
|
||||||
free(js_size);
|
free(js_size);
|
||||||
|
|
||||||
return target_size;
|
return render_targetsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
Transform WebXRInterfaceJS::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
|
Transform WebXRInterfaceJS::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
|
||||||
|
|
|
@ -47,7 +47,6 @@ class WebXRInterfaceJS : public WebXRInterface {
|
||||||
private:
|
private:
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
|
||||||
// @todo Should these really use enums instead of strings?
|
|
||||||
String session_mode;
|
String session_mode;
|
||||||
String required_features;
|
String required_features;
|
||||||
String optional_features;
|
String optional_features;
|
||||||
|
@ -55,6 +54,7 @@ private:
|
||||||
String reference_space_type;
|
String reference_space_type;
|
||||||
|
|
||||||
bool controllers_state[2];
|
bool controllers_state[2];
|
||||||
|
Size2 render_targetsize;
|
||||||
|
|
||||||
Transform _js_matrix_to_transform(float *p_js_matrix);
|
Transform _js_matrix_to_transform(float *p_js_matrix);
|
||||||
void _update_tracker(int p_controller_id);
|
void _update_tracker(int p_controller_id);
|
||||||
|
|
Loading…
Reference in a new issue