summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gltf/doc_classes/GLTFDocumentExtension.xml6
-rw-r--r--modules/gltf/doc_classes/GLTFState.xml8
-rw-r--r--modules/gltf/gltf_document.cpp42
-rw-r--r--modules/gltf/gltf_document.h2
-rw-r--r--modules/gltf/gltf_document_extension.cpp7
-rw-r--r--modules/gltf/gltf_document_extension.h2
-rw-r--r--modules/gltf/gltf_state.cpp12
-rw-r--r--modules/gltf/gltf_state.h4
-rw-r--r--modules/webxr/config.py2
-rw-r--r--modules/webxr/godot_webxr.h3
-rw-r--r--modules/webxr/native/library_godot_webxr.js191
-rw-r--r--modules/webxr/webxr_interface_js.cpp56
-rw-r--r--modules/webxr/webxr_interface_js.h1
13 files changed, 131 insertions, 205 deletions
diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
index 205f6c0f8f..936794976d 100644
--- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml
+++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
@@ -30,6 +30,12 @@
<description>
</description>
</method>
+ <method name="_get_supported_extensions" qualifiers="virtual">
+ <return type="PackedStringArray" />
+ <description>
+ Returns an array of the GLTF extensions supported by this GLTFDocumentExtension class. This is used to validate if a GLTF file with required extensions can be loaded.
+ </description>
+ </method>
<method name="_import_node" qualifiers="virtual">
<return type="int" />
<param index="0" name="state" type="GLTFState" />
diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml
index 1dbd89aed8..6c2f488c1c 100644
--- a/modules/gltf/doc_classes/GLTFState.xml
+++ b/modules/gltf/doc_classes/GLTFState.xml
@@ -7,6 +7,14 @@
<tutorials>
</tutorials>
<methods>
+ <method name="add_used_extension">
+ <return type="void" />
+ <param index="0" name="extension_name" type="String" />
+ <param index="1" name="required" type="bool" />
+ <description>
+ Appends an extension to the list of extensions used by this GLTF file during serialization. If [param required] is true, the extension will also be added to the list of required extensions. Do not run this in [method GLTFDocumentExtension._export_post], as that stage is too late to add extensions. The final list is sorted alphabetically.
+ </description>
+ </method>
<method name="get_accessors">
<return type="GLTFAccessor[]" />
<description>
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 53cf7285f9..8d2e37be3a 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -198,7 +198,7 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
}
/* STEP SERIALIZE EXTENSIONS */
- err = _serialize_extensions(state);
+ err = _serialize_gltf_extensions(state);
if (err != OK) {
return Error::FAILED;
}
@@ -219,9 +219,9 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
return OK;
}
-Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const {
- Array extensions_used;
- Array extensions_required;
+Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> state) const {
+ Vector<String> extensions_used = state->extensions_used;
+ Vector<String> extensions_required = state->extensions_required;
if (!state->lights.is_empty()) {
extensions_used.push_back("KHR_lights_punctual");
}
@@ -230,9 +230,11 @@ Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const {
extensions_required.push_back("KHR_texture_transform");
}
if (!extensions_used.is_empty()) {
+ extensions_used.sort();
state->json["extensionsUsed"] = extensions_used;
}
if (!extensions_required.is_empty()) {
+ extensions_required.sort();
state->json["extensionsRequired"] = extensions_required;
}
return OK;
@@ -6917,12 +6919,32 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint
Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) {
ERR_FAIL_NULL_V(state, ERR_PARSE_ERROR);
- if (state->json.has("extensionsRequired") && state->json["extensionsRequired"].get_type() == Variant::ARRAY) {
- Array extensions_required = state->json["extensionsRequired"];
- if (extensions_required.find("KHR_draco_mesh_compression") != -1) {
- ERR_PRINT("glTF2 extension KHR_draco_mesh_compression is not supported.");
- return ERR_UNAVAILABLE;
+ if (state->json.has("extensionsUsed")) {
+ Vector<String> ext_array = state->json["extensionsUsed"];
+ state->extensions_used = ext_array;
+ }
+ if (state->json.has("extensionsRequired")) {
+ Vector<String> ext_array = state->json["extensionsRequired"];
+ state->extensions_required = ext_array;
+ }
+ HashSet<String> supported_extensions;
+ supported_extensions.insert("KHR_lights_punctual");
+ supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
+ supported_extensions.insert("KHR_texture_transform");
+ for (int ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
+ Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ ERR_CONTINUE(ext.is_null());
+ Vector<String> ext_supported_extensions = ext->get_supported_extensions();
+ for (int i = 0; i < ext_supported_extensions.size(); ++i) {
+ supported_extensions.insert(ext_supported_extensions[i]);
}
}
- return OK;
+ Error ret = Error::OK;
+ for (int i = 0; i < state->extensions_required.size(); i++) {
+ if (!supported_extensions.has(state->extensions_required[i])) {
+ ERR_PRINT("GLTF: Can't import file '" + state->filename + "', required extension '" + String(state->extensions_required[i]) + "' is not supported. Are you missing a GLTFDocumentExtension plugin?");
+ ret = ERR_UNAVAILABLE;
+ }
+ }
+ return ret;
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index b3ed786a39..750d3d403e 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -265,7 +265,7 @@ private:
Dictionary _serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material);
Error _serialize_version(Ref<GLTFState> state);
Error _serialize_file(Ref<GLTFState> state, const String p_path);
- Error _serialize_extensions(Ref<GLTFState> state) const;
+ Error _serialize_gltf_extensions(Ref<GLTFState> state) const;
public:
// https://www.itu.int/rec/R-REC-BT.601
diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp
index d0bd7651e0..3b952f8246 100644
--- a/modules/gltf/gltf_document_extension.cpp
+++ b/modules/gltf/gltf_document_extension.cpp
@@ -31,6 +31,7 @@
#include "gltf_document_extension.h"
void GLTFDocumentExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_get_supported_extensions);
GDVIRTUAL_BIND(_import_preflight, "state");
GDVIRTUAL_BIND(_import_post_parse, "state");
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
@@ -40,6 +41,12 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_export_post, "state");
}
+Vector<String> GLTFDocumentExtension::get_supported_extensions() {
+ Vector<String> ret;
+ GDVIRTUAL_CALL(_get_supported_extensions, ret);
+ return ret;
+}
+
Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) {
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h
index 0ef9109584..d4bb3993dc 100644
--- a/modules/gltf/gltf_document_extension.h
+++ b/modules/gltf/gltf_document_extension.h
@@ -41,6 +41,7 @@ protected:
static void _bind_methods();
public:
+ virtual Vector<String> get_supported_extensions();
virtual Error import_preflight(Ref<GLTFState> p_state);
virtual Error import_post_parse(Ref<GLTFState> p_state);
virtual Error export_post(Ref<GLTFState> p_state);
@@ -48,6 +49,7 @@ public:
virtual Error export_preflight(Node *p_state);
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
virtual Error export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
+ GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
GDVIRTUAL1R(int, _import_preflight, Ref<GLTFState>);
GDVIRTUAL1R(int, _import_post_parse, Ref<GLTFState>);
GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp
index 85bac446cc..a23fb39503 100644
--- a/modules/gltf/gltf_state.cpp
+++ b/modules/gltf/gltf_state.cpp
@@ -31,6 +31,7 @@
#include "gltf_state.h"
void GLTFState::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_used_extension", "extension_name", "required"), &GLTFState::add_used_extension);
ClassDB::bind_method(D_METHOD("get_json"), &GLTFState::get_json);
ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json);
ClassDB::bind_method(D_METHOD("get_major_version"), &GLTFState::get_major_version);
@@ -112,6 +113,17 @@ void GLTFState::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
}
+void GLTFState::add_used_extension(const String &p_extension_name, bool p_required) {
+ if (!extensions_used.has(p_extension_name)) {
+ extensions_used.push_back(p_extension_name);
+ }
+ if (p_required) {
+ if (!extensions_required.has(p_extension_name)) {
+ extensions_required.push_back(p_extension_name);
+ }
+ }
+}
+
Dictionary GLTFState::get_json() {
return json;
}
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index 6b2d1ca228..791431f376 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -78,6 +78,8 @@ class GLTFState : public Resource {
Vector<int> root_nodes;
Vector<Ref<GLTFTexture>> textures;
Vector<Ref<Texture2D>> images;
+ Vector<String> extensions_used;
+ Vector<String> extensions_required;
Vector<Ref<GLTFSkin>> skins;
Vector<Ref<GLTFCamera>> cameras;
@@ -97,6 +99,8 @@ protected:
static void _bind_methods();
public:
+ void add_used_extension(const String &p_extension, bool p_required = false);
+
Dictionary get_json();
void set_json(Dictionary p_json);
diff --git a/modules/webxr/config.py b/modules/webxr/config.py
index f676ef3483..8d75e7f531 100644
--- a/modules/webxr/config.py
+++ b/modules/webxr/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return not env["disable_3d"]
+ return env["opengl3"] and not env["disable_3d"]
def configure(env):
diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h
index 52104895d4..34d068be3e 100644
--- a/modules/webxr/godot_webxr.h
+++ b/modules/webxr/godot_webxr.h
@@ -65,8 +65,7 @@ extern int godot_webxr_get_view_count();
extern int *godot_webxr_get_render_target_size();
extern float *godot_webxr_get_transform_for_eye(int p_eye);
extern float *godot_webxr_get_projection_for_eye(int p_eye);
-extern int godot_webxr_get_external_texture_for_eye(int p_eye);
-extern void godot_webxr_commit_for_eye(int p_eye);
+extern void godot_webxr_commit_for_eye(int p_eye, unsigned int p_destination_fbo);
extern void godot_webxr_sample_controller_data();
extern int godot_webxr_get_controller_count();
diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js
index c4b21defce..9b75796ee5 100644
--- a/modules/webxr/native/library_godot_webxr.js
+++ b/modules/webxr/native/library_godot_webxr.js
@@ -32,9 +32,6 @@ const GodotWebXR = {
$GodotWebXR: {
gl: null,
- texture_ids: [null, null],
- textures: [null, null],
-
session: null,
space: null,
frame: null,
@@ -77,110 +74,6 @@ const GodotWebXR = {
}, 0);
},
- // Some custom WebGL code for blitting our eye textures to the
- // framebuffer we get from WebXR.
- shaderProgram: null,
- programInfo: null,
- buffer: null,
- // Vertex shader source.
- vsSource: `
- const vec2 scale = vec2(0.5, 0.5);
- attribute vec4 aVertexPosition;
-
- varying highp vec2 vTextureCoord;
-
- void main () {
- gl_Position = aVertexPosition;
- vTextureCoord = aVertexPosition.xy * scale + scale;
- }
- `,
- // Fragment shader source.
- fsSource: `
- varying highp vec2 vTextureCoord;
-
- uniform sampler2D uSampler;
-
- void main() {
- gl_FragColor = texture2D(uSampler, vTextureCoord);
- }
- `,
-
- initShaderProgram: (gl, vsSource, fsSource) => {
- const vertexShader = GodotWebXR.loadShader(gl, gl.VERTEX_SHADER, vsSource);
- const fragmentShader = GodotWebXR.loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
-
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- GodotRuntime.error(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
- return null;
- }
-
- return shaderProgram;
- },
- loadShader: (gl, type, source) => {
- const shader = gl.createShader(type);
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- GodotRuntime.error(`An error occurred compiling the shader: ${gl.getShaderInfoLog(shader)}`);
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
- },
- initBuffer: (gl) => {
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- const positions = [
- -1.0, -1.0,
- 1.0, -1.0,
- -1.0, 1.0,
- 1.0, 1.0,
- ];
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
- return positionBuffer;
- },
- blitTexture: (gl, texture) => {
- if (GodotWebXR.shaderProgram === null) {
- GodotWebXR.shaderProgram = GodotWebXR.initShaderProgram(gl, GodotWebXR.vsSource, GodotWebXR.fsSource);
- GodotWebXR.programInfo = {
- program: GodotWebXR.shaderProgram,
- attribLocations: {
- vertexPosition: gl.getAttribLocation(GodotWebXR.shaderProgram, 'aVertexPosition'),
- },
- uniformLocations: {
- uSampler: gl.getUniformLocation(GodotWebXR.shaderProgram, 'uSampler'),
- },
- };
- GodotWebXR.buffer = GodotWebXR.initBuffer(gl);
- }
-
- const orig_program = gl.getParameter(gl.CURRENT_PROGRAM);
- gl.useProgram(GodotWebXR.shaderProgram);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, GodotWebXR.buffer);
- gl.vertexAttribPointer(GodotWebXR.programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.uniform1i(GodotWebXR.programInfo.uniformLocations.uSampler, 0);
-
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- // Restore state.
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.disableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
- gl.useProgram(orig_program);
- },
-
// Holds the controllers list between function calls.
controllers: [],
@@ -370,22 +263,6 @@ const GodotWebXR = {
.catch((e) => { });
}
- // Clean-up the textures we allocated for each view.
- const gl = GodotWebXR.gl;
- for (let i = 0; i < GodotWebXR.textures.length; i++) {
- const texture = GodotWebXR.textures[i];
- if (texture !== null) {
- 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;
- }
-
GodotWebXR.session = null;
GodotWebXR.space = null;
GodotWebXR.frame = null;
@@ -460,50 +337,9 @@ const GodotWebXR = {
return buf;
},
- 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) {
- return 0;
- }
-
- const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
- if (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 view = GodotWebXR.pose.views[view_index];
- const viewport = glLayer.getViewport(view);
- const gl = GodotWebXR.gl;
-
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.width, viewport.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- gl.bindTexture(gl.TEXTURE_2D, null);
-
- const texture_id = GL.getNewId(GL.textures);
- GL.textures[texture_id] = texture;
- GodotWebXR.textures[view_index] = texture;
- GodotWebXR.texture_ids[view_index] = texture_id;
- return texture_id;
- },
-
godot_webxr_commit_for_eye__proxy: 'sync',
- godot_webxr_commit_for_eye__sig: 'vi',
- godot_webxr_commit_for_eye: function (p_eye) {
+ godot_webxr_commit_for_eye__sig: 'vii',
+ godot_webxr_commit_for_eye: function (p_eye, p_destination_fbo) {
if (!GodotWebXR.session || !GodotWebXR.pose) {
return;
}
@@ -514,18 +350,29 @@ const GodotWebXR = {
const viewport = glLayer.getViewport(view);
const gl = GodotWebXR.gl;
+ const framebuffer = GL.framebuffers[p_destination_fbo];
+
const orig_framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
- const orig_viewport = gl.getParameter(gl.VIEWPORT);
+ const orig_read_framebuffer = gl.getParameter(gl.READ_FRAMEBUFFER_BINDING);
+ const orig_read_buffer = gl.getParameter(gl.READ_BUFFER);
+ const orig_draw_framebuffer = gl.getParameter(gl.DRAW_FRAMEBUFFER_BINDING);
- // Bind to WebXR's framebuffer.
- gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
- gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ // Copy from Godot render target into framebuffer from WebXR.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, glLayer.framebuffer);
- GodotWebXR.blitTexture(gl, GodotWebXR.textures[view_index]);
+ // Flip Y upside down on destination.
+ gl.blitFramebuffer(0, 0, viewport.width, viewport.height,
+ viewport.x, viewport.height, viewport.width, viewport.y,
+ gl.COLOR_BUFFER_BIT, gl.NEAREST);
// Restore state.
gl.bindFramebuffer(gl.FRAMEBUFFER, orig_framebuffer);
- gl.viewport(orig_viewport[0], orig_viewport[1], orig_viewport[2], orig_viewport[3]);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, orig_read_framebuffer);
+ gl.readBuffer(orig_read_buffer);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, orig_draw_framebuffer);
},
godot_webxr_sample_controller_data__proxy: 'sync',
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index 7d97dbfa0b..d0c7484aa1 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -34,9 +34,11 @@
#include "core/input/input.h"
#include "core/os/os.h"
+#include "drivers/gles3/storage/texture_storage.h"
#include "emscripten.h"
#include "godot_webxr.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/rendering_server_globals.h"
#include <stdlib.h>
@@ -232,6 +234,8 @@ bool WebXRInterfaceJS::initialize() {
}
// we must create a tracker for our head
+ head_transform.basis = Basis();
+ head_transform.origin = Vector3();
head_tracker.instantiate();
head_tracker->set_tracker_type(XRServer::TRACKER_HEAD);
head_tracker->set_tracker_name("head");
@@ -334,15 +338,17 @@ Transform3D WebXRInterfaceJS::get_camera_transform() {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, transform_for_eye);
- float *js_matrix = godot_webxr_get_transform_for_eye(0);
- if (!initialized || js_matrix == nullptr) {
- return transform_for_eye;
- }
+ if (initialized) {
+ float world_scale = xr_server->get_world_scale();
- transform_for_eye = _js_matrix_to_transform(js_matrix);
- free(js_matrix);
+ // just scale our origin point of our transform
+ Transform3D _head_transform = head_transform;
+ _head_transform.origin *= world_scale;
+
+ transform_for_eye = (xr_server->get_reference_frame()) * _head_transform;
+ }
- return xr_server->get_reference_frame() * transform_for_eye;
+ return transform_for_eye;
};
Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) {
@@ -360,6 +366,14 @@ Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Tran
transform_for_eye = _js_matrix_to_transform(js_matrix);
free(js_matrix);
+ float world_scale = xr_server->get_world_scale();
+ // Scale only the center point of our eye transform, so we don't scale the
+ // distance between the eyes.
+ Transform3D _head_transform = head_transform;
+ transform_for_eye.origin -= _head_transform.origin;
+ _head_transform.origin *= world_scale;
+ transform_for_eye.origin += _head_transform.origin;
+
return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
};
@@ -394,29 +408,33 @@ Vector<BlitToScreen> WebXRInterfaceJS::post_draw_viewport(RID p_render_target, c
return blit_to_screen;
}
- // @todo Refactor this to be based on "views" rather than "eyes".
- godot_webxr_commit_for_eye(1);
- if (godot_webxr_get_view_count() > 1) {
- godot_webxr_commit_for_eye(2);
+ GLES3::TextureStorage *texture_storage = dynamic_cast<GLES3::TextureStorage *>(RSG::texture_storage);
+ if (!texture_storage) {
+ return blit_to_screen;
}
+ GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
+
+ // @todo Support multiple eyes!
+ godot_webxr_commit_for_eye(1, rt->fbo);
+
return blit_to_screen;
};
void WebXRInterfaceJS::process() {
if (initialized) {
- godot_webxr_sample_controller_data();
-
+ // Get the "head" position.
+ float *js_matrix = godot_webxr_get_transform_for_eye(0);
+ if (js_matrix != nullptr) {
+ head_transform = _js_matrix_to_transform(js_matrix);
+ free(js_matrix);
+ }
if (head_tracker.is_valid()) {
- // TODO set default pose to our head location (i.e. get_camera_transform without world scale and reference frame applied)
- // head_tracker->set_pose("default", head_transform, Vector3(), Vector3());
+ head_tracker->set_pose("default", head_transform, Vector3(), Vector3());
}
+ godot_webxr_sample_controller_data();
int controller_count = godot_webxr_get_controller_count();
- if (controller_count == 0) {
- return;
- }
-
for (int i = 0; i < controller_count; i++) {
_update_tracker(i);
}
diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h
index dbe89dad83..319adc2ac9 100644
--- a/modules/webxr/webxr_interface_js.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -45,6 +45,7 @@ class WebXRInterfaceJS : public WebXRInterface {
private:
bool initialized;
Ref<XRPositionalTracker> head_tracker;
+ Transform3D head_transform;
String session_mode;
String required_features;