summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gltf/doc_classes/GLTFCamera.xml13
-rw-r--r--modules/gltf/gltf_document.cpp87
-rw-r--r--modules/gltf/structures/gltf_camera.cpp15
-rw-r--r--modules/gltf/structures/gltf_camera.h27
4 files changed, 80 insertions, 62 deletions
diff --git a/modules/gltf/doc_classes/GLTFCamera.xml b/modules/gltf/doc_classes/GLTFCamera.xml
index 9b9eff6141..b90abd105d 100644
--- a/modules/gltf/doc_classes/GLTFCamera.xml
+++ b/modules/gltf/doc_classes/GLTFCamera.xml
@@ -1,19 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFCamera" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
+ Represents a GLTF camera.
</brief_description>
<description>
+ Represents a camera as defined by the base GLTF spec.
</description>
<tutorials>
+ <link title="GLTF camera detailed specification">https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-camera</link>
+ <link title="GLTF camera spec and example file">https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_015_SimpleCameras.md</link>
</tutorials>
<members>
<member name="depth_far" type="float" setter="set_depth_far" getter="get_depth_far" default="4000.0">
+ The distance to the far culling boundary for this camera relative to its local Z axis, in meters. This maps to GLTF's [code]zfar[/code] property.
</member>
<member name="depth_near" type="float" setter="set_depth_near" getter="get_depth_near" default="0.05">
+ The distance to the near culling boundary for this camera relative to its local Z axis, in meters. This maps to GLTF's [code]znear[/code] property.
</member>
- <member name="fov_size" type="float" setter="set_fov_size" getter="get_fov_size" default="75.0">
+ <member name="fov" type="float" setter="set_fov" getter="get_fov" default="1.309">
+ The FOV of the camera. This class and GLTF define the camera FOV in radians, while Godot uses degrees. This maps to GLTF's [code]yfov[/code] property. This value is only used for perspective cameras, when [member perspective] is true.
</member>
<member name="perspective" type="bool" setter="set_perspective" getter="get_perspective" default="true">
+ Whether or not the camera is in perspective mode. If false, the camera is in orthographic/orthogonal mode. This maps to GLTF's camera [code]type[/code] property. See [member Camera3D.projection] and the GLTF spec for more information.
+ </member>
+ <member name="size_mag" type="float" setter="set_size_mag" getter="get_size_mag" default="0.5">
+ The size of the camera. This class and GLTF define the camera size magnitude as a radius in meters, while Godot defines it as a diameter in meters. This maps to GLTF's [code]ymag[/code] property. This value is only used for orthographic/orthogonal cameras, when [member perspective] is false.
</member>
</members>
</class>
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 6a6de40fbb..b913a771e1 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -50,7 +50,6 @@
#include "core/version.h"
#include "drivers/png/png_driver_common.h"
#include "scene/2d/node_2d.h"
-#include "scene/3d/camera_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/multimesh_instance_3d.h"
#include "scene/3d/node_3d.h"
@@ -4582,22 +4581,21 @@ Error GLTFDocument::_serialize_cameras(Ref<GLTFState> state) {
Ref<GLTFCamera> camera = state->cameras[i];
- if (camera->get_perspective() == false) {
- Dictionary og;
- og["ymag"] = Math::deg2rad(camera->get_fov_size());
- og["xmag"] = Math::deg2rad(camera->get_fov_size());
- og["zfar"] = camera->get_depth_far();
- og["znear"] = camera->get_depth_near();
- d["orthographic"] = og;
- d["type"] = "orthographic";
- } else if (camera->get_perspective()) {
- Dictionary ppt;
- // GLTF spec is in radians, Godot's camera is in degrees.
- ppt["yfov"] = Math::deg2rad(camera->get_fov_size());
- ppt["zfar"] = camera->get_depth_far();
- ppt["znear"] = camera->get_depth_near();
- d["perspective"] = ppt;
+ if (camera->get_perspective()) {
+ Dictionary persp;
+ persp["yfov"] = camera->get_fov();
+ persp["zfar"] = camera->get_depth_far();
+ persp["znear"] = camera->get_depth_near();
+ d["perspective"] = persp;
d["type"] = "perspective";
+ } else {
+ Dictionary ortho;
+ ortho["ymag"] = camera->get_size_mag();
+ ortho["xmag"] = camera->get_size_mag();
+ ortho["zfar"] = camera->get_depth_far();
+ ortho["znear"] = camera->get_depth_near();
+ d["orthographic"] = ortho;
+ d["type"] = "orthographic";
}
cameras[i] = d;
}
@@ -4680,27 +4678,23 @@ Error GLTFDocument::_parse_cameras(Ref<GLTFState> state) {
camera.instantiate();
ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
const String &type = d["type"];
- if (type == "orthographic") {
- camera->set_perspective(false);
- if (d.has("orthographic")) {
- const Dictionary &og = d["orthographic"];
- // GLTF spec is in radians, Godot's camera is in degrees.
- camera->set_fov_size(Math::rad2deg(real_t(og["ymag"])));
- camera->set_depth_far(og["zfar"]);
- camera->set_depth_near(og["znear"]);
- } else {
- camera->set_fov_size(10);
- }
- } else if (type == "perspective") {
+ if (type == "perspective") {
camera->set_perspective(true);
if (d.has("perspective")) {
- const Dictionary &ppt = d["perspective"];
- // GLTF spec is in radians, Godot's camera is in degrees.
- camera->set_fov_size(Math::rad2deg(real_t(ppt["yfov"])));
- camera->set_depth_far(ppt["zfar"]);
- camera->set_depth_near(ppt["znear"]);
- } else {
- camera->set_fov_size(10);
+ const Dictionary &persp = d["perspective"];
+ camera->set_fov(persp["yfov"]);
+ if (persp.has("zfar")) {
+ camera->set_depth_far(persp["zfar"]);
+ }
+ camera->set_depth_near(persp["znear"]);
+ }
+ } else if (type == "orthographic") {
+ camera->set_perspective(false);
+ if (d.has("orthographic")) {
+ const Dictionary &ortho = d["orthographic"];
+ camera->set_size_mag(ortho["ymag"]);
+ camera->set_depth_far(ortho["zfar"]);
+ camera->set_depth_near(ortho["znear"]);
}
} else {
ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "Camera3D should be in 'orthographic' or 'perspective'");
@@ -5204,12 +5198,13 @@ Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, const GLTFNodeInd
print_verbose("glTF: Creating camera for: " + gltf_node->get_name());
Ref<GLTFCamera> c = state->cameras[gltf_node->camera];
- if (c->get_perspective()) {
- camera->set_perspective(c->get_fov_size(), c->get_depth_near(), c->get_depth_far());
- } else {
- camera->set_orthogonal(c->get_fov_size(), c->get_depth_near(), c->get_depth_far());
- }
-
+ camera->set_projection(c->get_perspective() ? Camera3D::PROJECTION_PERSPECTIVE : Camera3D::PROJECTION_ORTHOGONAL);
+ // GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
+ camera->set_fov(Math::rad2deg(c->get_fov()));
+ // GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
+ camera->set_size(c->get_size_mag() * 2.0f);
+ camera->set_near(c->get_depth_near());
+ camera->set_far(c->get_depth_far());
return camera;
}
@@ -5218,11 +5213,11 @@ GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_
Ref<GLTFCamera> c;
c.instantiate();
-
- if (p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE) {
- c->set_perspective(true);
- }
- c->set_fov_size(p_camera->get_fov());
+ c->set_perspective(p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE);
+ // GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
+ c->set_fov(Math::deg2rad(p_camera->get_fov()));
+ // GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
+ c->set_size_mag(p_camera->get_size() * 0.5f);
c->set_depth_far(p_camera->get_far());
c->set_depth_near(p_camera->get_near());
GLTFCameraIndex camera_index = state->cameras.size();
diff --git a/modules/gltf/structures/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp
index f3ea6a1c4c..c492913ea7 100644
--- a/modules/gltf/structures/gltf_camera.cpp
+++ b/modules/gltf/structures/gltf_camera.cpp
@@ -33,15 +33,18 @@
void GLTFCamera::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_perspective"), &GLTFCamera::get_perspective);
ClassDB::bind_method(D_METHOD("set_perspective", "perspective"), &GLTFCamera::set_perspective);
- ClassDB::bind_method(D_METHOD("get_fov_size"), &GLTFCamera::get_fov_size);
- ClassDB::bind_method(D_METHOD("set_fov_size", "fov_size"), &GLTFCamera::set_fov_size);
+ ClassDB::bind_method(D_METHOD("get_fov"), &GLTFCamera::get_fov);
+ ClassDB::bind_method(D_METHOD("set_fov", "fov"), &GLTFCamera::set_fov);
+ ClassDB::bind_method(D_METHOD("get_size_mag"), &GLTFCamera::get_size_mag);
+ ClassDB::bind_method(D_METHOD("set_size_mag", "size_mag"), &GLTFCamera::set_size_mag);
ClassDB::bind_method(D_METHOD("get_depth_far"), &GLTFCamera::get_depth_far);
ClassDB::bind_method(D_METHOD("set_depth_far", "zdepth_far"), &GLTFCamera::set_depth_far);
ClassDB::bind_method(D_METHOD("get_depth_near"), &GLTFCamera::get_depth_near);
ClassDB::bind_method(D_METHOD("set_depth_near", "zdepth_near"), &GLTFCamera::set_depth_near);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "perspective"), "set_perspective", "get_perspective"); // bool
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov_size"), "set_fov_size", "get_fov_size"); // float
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_far"), "set_depth_far", "get_depth_far"); // float
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_near"), "set_depth_near", "get_depth_near"); // float
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "perspective"), "set_perspective", "get_perspective");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov"), "set_fov", "get_fov");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_mag"), "set_size_mag", "get_size_mag");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_far"), "set_depth_far", "get_depth_far");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_near"), "set_depth_near", "get_depth_near");
}
diff --git a/modules/gltf/structures/gltf_camera.h b/modules/gltf/structures/gltf_camera.h
index b7df741825..714ec21693 100644
--- a/modules/gltf/structures/gltf_camera.h
+++ b/modules/gltf/structures/gltf_camera.h
@@ -32,15 +32,22 @@
#define GLTF_CAMERA_H
#include "core/io/resource.h"
+#include "scene/3d/camera_3d.h"
+
+// Reference and test file:
+// https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_015_SimpleCameras.md
class GLTFCamera : public Resource {
GDCLASS(GLTFCamera, Resource);
private:
+ // GLTF has no default camera values, they should always be specified in
+ // the GLTF file. Here we default to Godot's default camera settings.
bool perspective = true;
- float fov_size = 75.0;
- float depth_far = 4000.0;
- float depth_near = 0.05;
+ real_t fov = Math::deg2rad(75.0);
+ real_t size_mag = 0.5;
+ real_t depth_far = 4000.0;
+ real_t depth_near = 0.05;
protected:
static void _bind_methods();
@@ -48,12 +55,14 @@ protected:
public:
bool get_perspective() const { return perspective; }
void set_perspective(bool p_val) { perspective = p_val; }
- float get_fov_size() const { return fov_size; }
- void set_fov_size(float p_val) { fov_size = p_val; }
- float get_depth_far() const { return depth_far; }
- void set_depth_far(float p_val) { depth_far = p_val; }
- float get_depth_near() const { return depth_near; }
- void set_depth_near(float p_val) { depth_near = p_val; }
+ real_t get_fov() const { return fov; }
+ void set_fov(real_t p_val) { fov = p_val; }
+ real_t get_size_mag() const { return size_mag; }
+ void set_size_mag(real_t p_val) { size_mag = p_val; }
+ real_t get_depth_far() const { return depth_far; }
+ void set_depth_far(real_t p_val) { depth_far = p_val; }
+ real_t get_depth_near() const { return depth_near; }
+ void set_depth_near(real_t p_val) { depth_near = p_val; }
};
#endif // GLTF_CAMERA_H