summaryrefslogtreecommitdiffstats
path: root/modules/gltf/structures
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gltf/structures')
-rw-r--r--modules/gltf/structures/gltf_accessor.cpp17
-rw-r--r--modules/gltf/structures/gltf_accessor.h20
-rw-r--r--modules/gltf/structures/gltf_animation.cpp40
-rw-r--r--modules/gltf/structures/gltf_animation.h26
-rw-r--r--modules/gltf/structures/gltf_camera.cpp16
-rw-r--r--modules/gltf/structures/gltf_camera.h3
-rw-r--r--modules/gltf/structures/gltf_node.cpp45
-rw-r--r--modules/gltf/structures/gltf_node.h3
-rw-r--r--modules/gltf/structures/gltf_object_model_property.cpp173
-rw-r--r--modules/gltf/structures/gltf_object_model_property.h104
10 files changed, 432 insertions, 15 deletions
diff --git a/modules/gltf/structures/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp
index 1ebc00a514..300fce09ff 100644
--- a/modules/gltf/structures/gltf_accessor.cpp
+++ b/modules/gltf/structures/gltf_accessor.cpp
@@ -39,6 +39,19 @@ void GLTFAccessor::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_MAT3);
BIND_ENUM_CONSTANT(TYPE_MAT4);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_NONE);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_BYTE);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_BYTE);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_SHORT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_SHORT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_INT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_INT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_SINGLE_FLOAT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_DOUBLE_FLOAT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_HALF_FLOAT);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_SIGNED_LONG);
+ BIND_ENUM_CONSTANT(COMPONENT_TYPE_UNSIGNED_LONG);
+
ClassDB::bind_method(D_METHOD("get_buffer_view"), &GLTFAccessor::get_buffer_view);
ClassDB::bind_method(D_METHOD("set_buffer_view", "buffer_view"), &GLTFAccessor::set_buffer_view);
ClassDB::bind_method(D_METHOD("get_byte_offset"), &GLTFAccessor::get_byte_offset);
@@ -108,7 +121,7 @@ int GLTFAccessor::get_component_type() {
}
void GLTFAccessor::set_component_type(int p_component_type) {
- component_type = p_component_type;
+ component_type = (GLTFComponentType)p_component_type;
}
bool GLTFAccessor::get_normalized() {
@@ -188,7 +201,7 @@ int GLTFAccessor::get_sparse_indices_component_type() {
}
void GLTFAccessor::set_sparse_indices_component_type(int p_sparse_indices_component_type) {
- sparse_indices_component_type = p_sparse_indices_component_type;
+ sparse_indices_component_type = (GLTFComponentType)p_sparse_indices_component_type;
}
int GLTFAccessor::get_sparse_values_buffer_view() {
diff --git a/modules/gltf/structures/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h
index 1a3a2cb494..b00e6a0f92 100644
--- a/modules/gltf/structures/gltf_accessor.h
+++ b/modules/gltf/structures/gltf_accessor.h
@@ -50,10 +50,25 @@ public:
TYPE_MAT4,
};
+ enum GLTFComponentType {
+ COMPONENT_TYPE_NONE = 0,
+ COMPONENT_TYPE_SIGNED_BYTE = 5120,
+ COMPONENT_TYPE_UNSIGNED_BYTE = 5121,
+ COMPONENT_TYPE_SIGNED_SHORT = 5122,
+ COMPONENT_TYPE_UNSIGNED_SHORT = 5123,
+ COMPONENT_TYPE_SIGNED_INT = 5124,
+ COMPONENT_TYPE_UNSIGNED_INT = 5125,
+ COMPONENT_TYPE_SINGLE_FLOAT = 5126,
+ COMPONENT_TYPE_DOUBLE_FLOAT = 5130,
+ COMPONENT_TYPE_HALF_FLOAT = 5131,
+ COMPONENT_TYPE_SIGNED_LONG = 5134,
+ COMPONENT_TYPE_UNSIGNED_LONG = 5135,
+ };
+
private:
GLTFBufferViewIndex buffer_view = -1;
int byte_offset = 0;
- int component_type = 0;
+ GLTFComponentType component_type = COMPONENT_TYPE_NONE;
bool normalized = false;
int count = 0;
GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR;
@@ -62,7 +77,7 @@ private:
int sparse_count = 0;
int sparse_indices_buffer_view = 0;
int sparse_indices_byte_offset = 0;
- int sparse_indices_component_type = 0;
+ GLTFComponentType sparse_indices_component_type = COMPONENT_TYPE_NONE;
int sparse_values_buffer_view = 0;
int sparse_values_byte_offset = 0;
@@ -117,5 +132,6 @@ public:
};
VARIANT_ENUM_CAST(GLTFAccessor::GLTFAccessorType);
+VARIANT_ENUM_CAST(GLTFAccessor::GLTFComponentType);
#endif // GLTF_ACCESSOR_H
diff --git a/modules/gltf/structures/gltf_animation.cpp b/modules/gltf/structures/gltf_animation.cpp
index 94fda8e2f5..adc0354c4b 100644
--- a/modules/gltf/structures/gltf_animation.cpp
+++ b/modules/gltf/structures/gltf_animation.cpp
@@ -42,6 +42,34 @@ void GLTFAnimation::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "get_loop"); // bool
}
+GLTFAnimation::Interpolation GLTFAnimation::godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index) {
+ Animation::InterpolationType interpolation = p_godot_animation->track_get_interpolation_type(p_godot_anim_track_index);
+ switch (interpolation) {
+ case Animation::INTERPOLATION_LINEAR:
+ case Animation::INTERPOLATION_LINEAR_ANGLE:
+ return INTERP_LINEAR;
+ case Animation::INTERPOLATION_NEAREST:
+ return INTERP_STEP;
+ case Animation::INTERPOLATION_CUBIC:
+ case Animation::INTERPOLATION_CUBIC_ANGLE:
+ return INTERP_CUBIC_SPLINE;
+ }
+ return INTERP_LINEAR;
+}
+
+Animation::InterpolationType GLTFAnimation::gltf_to_godot_interpolation(Interpolation p_gltf_interpolation) {
+ switch (p_gltf_interpolation) {
+ case INTERP_LINEAR:
+ return Animation::INTERPOLATION_LINEAR;
+ case INTERP_STEP:
+ return Animation::INTERPOLATION_NEAREST;
+ case INTERP_CATMULLROMSPLINE:
+ case INTERP_CUBIC_SPLINE:
+ return Animation::INTERPOLATION_CUBIC;
+ }
+ return Animation::INTERPOLATION_LINEAR;
+}
+
String GLTFAnimation::get_original_name() {
return original_name;
}
@@ -58,8 +86,16 @@ void GLTFAnimation::set_loop(bool p_val) {
loop = p_val;
}
-HashMap<int, GLTFAnimation::Track> &GLTFAnimation::get_tracks() {
- return tracks;
+HashMap<int, GLTFAnimation::NodeTrack> &GLTFAnimation::get_node_tracks() {
+ return node_tracks;
+}
+
+HashMap<String, GLTFAnimation::Channel<Variant>> &GLTFAnimation::get_pointer_tracks() {
+ return pointer_tracks;
+}
+
+bool GLTFAnimation::is_empty_of_tracks() const {
+ return node_tracks.is_empty() && pointer_tracks.is_empty();
}
GLTFAnimation::GLTFAnimation() {
diff --git a/modules/gltf/structures/gltf_animation.h b/modules/gltf/structures/gltf_animation.h
index afc9784895..6b692d06e6 100644
--- a/modules/gltf/structures/gltf_animation.h
+++ b/modules/gltf/structures/gltf_animation.h
@@ -50,33 +50,41 @@ public:
template <typename T>
struct Channel {
Interpolation interpolation = INTERP_LINEAR;
- Vector<real_t> times;
+ Vector<double> times;
Vector<T> values;
};
- struct Track {
+ struct NodeTrack {
Channel<Vector3> position_track;
Channel<Quaternion> rotation_track;
Channel<Vector3> scale_track;
Vector<Channel<real_t>> weight_tracks;
};
+ String original_name;
+ bool loop = false;
+ HashMap<int, NodeTrack> node_tracks;
+ HashMap<String, Channel<Variant>> pointer_tracks;
+ Dictionary additional_data;
+
public:
+ static Interpolation godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index);
+ static Animation::InterpolationType gltf_to_godot_interpolation(Interpolation p_gltf_interpolation);
+
String get_original_name();
void set_original_name(String p_name);
bool get_loop() const;
void set_loop(bool p_val);
- HashMap<int, GLTFAnimation::Track> &get_tracks();
+
+ HashMap<int, GLTFAnimation::NodeTrack> &get_node_tracks();
+ HashMap<String, GLTFAnimation::Channel<Variant>> &get_pointer_tracks();
+ bool is_empty_of_tracks() const;
+
Variant get_additional_data(const StringName &p_extension_name);
void set_additional_data(const StringName &p_extension_name, Variant p_additional_data);
- GLTFAnimation();
-private:
- String original_name;
- bool loop = false;
- HashMap<int, Track> tracks;
- Dictionary additional_data;
+ GLTFAnimation();
};
#endif // GLTF_ANIMATION_H
diff --git a/modules/gltf/structures/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp
index 863e1df967..2960ec351d 100644
--- a/modules/gltf/structures/gltf_camera.cpp
+++ b/modules/gltf/structures/gltf_camera.cpp
@@ -30,6 +30,7 @@
#include "gltf_camera.h"
+#include "gltf_object_model_property.h"
#include "scene/3d/camera_3d.h"
void GLTFCamera::_bind_methods() {
@@ -57,6 +58,21 @@ void GLTFCamera::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth_near"), "set_depth_near", "get_depth_near");
}
+void GLTFCamera::set_fov_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop) {
+ // Expression to convert glTF yfov in radians to Godot fov in degrees.
+ Ref<Expression> gltf_to_godot_expr;
+ gltf_to_godot_expr.instantiate();
+ PackedStringArray gltf_to_godot_args = { "yfov_rad" };
+ gltf_to_godot_expr->parse("rad_to_deg(yfov_rad)", gltf_to_godot_args);
+ r_obj_model_prop->set_gltf_to_godot_expression(gltf_to_godot_expr);
+ // Expression to convert Godot fov in degrees to glTF yfov in radians.
+ Ref<Expression> godot_to_gltf_expr;
+ godot_to_gltf_expr.instantiate();
+ PackedStringArray godot_to_gltf_args = { "fov_deg" };
+ godot_to_gltf_expr->parse("deg_to_rad(fov_deg)", godot_to_gltf_args);
+ r_obj_model_prop->set_godot_to_gltf_expression(godot_to_gltf_expr);
+}
+
Ref<GLTFCamera> GLTFCamera::from_node(const Camera3D *p_camera) {
Ref<GLTFCamera> c;
c.instantiate();
diff --git a/modules/gltf/structures/gltf_camera.h b/modules/gltf/structures/gltf_camera.h
index 1a583c82cc..497b6cd4f1 100644
--- a/modules/gltf/structures/gltf_camera.h
+++ b/modules/gltf/structures/gltf_camera.h
@@ -34,6 +34,7 @@
#include "core/io/resource.h"
class Camera3D;
+class GLTFObjectModelProperty;
// Reference and test file:
// https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_015_SimpleCameras.md
@@ -54,6 +55,8 @@ protected:
static void _bind_methods();
public:
+ static void set_fov_conversion_expressions(Ref<GLTFObjectModelProperty> &r_obj_model_prop);
+
bool get_perspective() const { return perspective; }
void set_perspective(bool p_val) { perspective = p_val; }
real_t get_fov() const { return fov; }
diff --git a/modules/gltf/structures/gltf_node.cpp b/modules/gltf/structures/gltf_node.cpp
index ccee5e8ca4..1626313551 100644
--- a/modules/gltf/structures/gltf_node.cpp
+++ b/modules/gltf/structures/gltf_node.cpp
@@ -30,6 +30,8 @@
#include "gltf_node.h"
+#include "../gltf_state.h"
+
void GLTFNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_original_name"), &GLTFNode::get_original_name);
ClassDB::bind_method(D_METHOD("set_original_name", "original_name"), &GLTFNode::set_original_name);
@@ -60,6 +62,7 @@ void GLTFNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_light", "light"), &GLTFNode::set_light);
ClassDB::bind_method(D_METHOD("get_additional_data", "extension_name"), &GLTFNode::get_additional_data);
ClassDB::bind_method(D_METHOD("set_additional_data", "extension_name", "additional_data"), &GLTFNode::set_additional_data);
+ ClassDB::bind_method(D_METHOD("get_scene_node_path", "gltf_state", "handle_skeletons"), &GLTFNode::get_scene_node_path, DEFVAL(true));
ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_name"), "set_original_name", "get_original_name"); // String
ADD_PROPERTY(PropertyInfo(Variant::INT, "parent"), "set_parent", "get_parent"); // GLTFNodeIndex
@@ -187,6 +190,48 @@ Variant GLTFNode::get_additional_data(const StringName &p_extension_name) {
return additional_data[p_extension_name];
}
+bool GLTFNode::has_additional_data(const StringName &p_extension_name) {
+ return additional_data.has(p_extension_name);
+}
+
void GLTFNode::set_additional_data(const StringName &p_extension_name, Variant p_additional_data) {
additional_data[p_extension_name] = p_additional_data;
}
+
+NodePath GLTFNode::get_scene_node_path(Ref<GLTFState> p_state, bool p_handle_skeletons) {
+ Vector<StringName> path;
+ Vector<StringName> subpath;
+ Ref<GLTFNode> current_gltf_node = this;
+ const int gltf_node_count = p_state->nodes.size();
+ if (p_handle_skeletons && skeleton != -1) {
+ // Special case for skeleton nodes, skip all bones so that the path is to the Skeleton3D node.
+ // A path that would otherwise be `A/B/C/Bone1/Bone2/Bone3` becomes `A/B/C/Skeleton3D:Bone3`.
+ subpath.append(get_name());
+ // The generated Skeleton3D node will be named Skeleton3D, so add it to the path.
+ path.append("Skeleton3D");
+ do {
+ const int parent_index = current_gltf_node->get_parent();
+ ERR_FAIL_INDEX_V(parent_index, gltf_node_count, NodePath());
+ current_gltf_node = p_state->nodes[parent_index];
+ } while (current_gltf_node->skeleton != -1);
+ }
+ const bool is_godot_single_root = p_state->extensions_used.has("GODOT_single_root");
+ while (true) {
+ const int parent_index = current_gltf_node->get_parent();
+ if (is_godot_single_root && parent_index == -1) {
+ // For GODOT_single_root scenes, the root glTF node becomes the Godot scene root, so it
+ // should not be included in the path. Ex: A/B/C, A is single root, we want B/C only.
+ break;
+ }
+ path.insert(0, current_gltf_node->get_name());
+ if (!is_godot_single_root && parent_index == -1) {
+ break;
+ }
+ ERR_FAIL_INDEX_V(parent_index, gltf_node_count, NodePath());
+ current_gltf_node = p_state->nodes[parent_index];
+ }
+ if (unlikely(path.is_empty())) {
+ path.append(".");
+ }
+ return NodePath(path, subpath, false);
+}
diff --git a/modules/gltf/structures/gltf_node.h b/modules/gltf/structures/gltf_node.h
index f3f6bfa2f1..f72b65a003 100644
--- a/modules/gltf/structures/gltf_node.h
+++ b/modules/gltf/structures/gltf_node.h
@@ -103,7 +103,10 @@ public:
void set_light(GLTFLightIndex p_light);
Variant get_additional_data(const StringName &p_extension_name);
+ bool has_additional_data(const StringName &p_extension_name);
void set_additional_data(const StringName &p_extension_name, Variant p_additional_data);
+
+ NodePath get_scene_node_path(Ref<GLTFState> p_state, bool p_handle_skeletons = true);
};
#endif // GLTF_NODE_H
diff --git a/modules/gltf/structures/gltf_object_model_property.cpp b/modules/gltf/structures/gltf_object_model_property.cpp
new file mode 100644
index 0000000000..d405c362db
--- /dev/null
+++ b/modules/gltf/structures/gltf_object_model_property.cpp
@@ -0,0 +1,173 @@
+/**************************************************************************/
+/* gltf_object_model_property.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "gltf_object_model_property.h"
+
+#include "../gltf_template_convert.h"
+
+void GLTFObjectModelProperty::_bind_methods() {
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_UNKNOWN);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_BOOL);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT_ARRAY);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT2);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT3);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT4);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT2X2);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT3X3);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_FLOAT4X4);
+ BIND_ENUM_CONSTANT(GLTF_OBJECT_MODEL_TYPE_INT);
+
+ ClassDB::bind_method(D_METHOD("append_node_path", "node_path"), &GLTFObjectModelProperty::append_node_path);
+ ClassDB::bind_method(D_METHOD("append_path_to_property", "node_path", "prop_name"), &GLTFObjectModelProperty::append_path_to_property);
+
+ ClassDB::bind_method(D_METHOD("get_accessor_type"), &GLTFObjectModelProperty::get_accessor_type);
+ ClassDB::bind_method(D_METHOD("get_gltf_to_godot_expression"), &GLTFObjectModelProperty::get_gltf_to_godot_expression);
+ ClassDB::bind_method(D_METHOD("set_gltf_to_godot_expression", "gltf_to_godot_expr"), &GLTFObjectModelProperty::set_gltf_to_godot_expression);
+ ClassDB::bind_method(D_METHOD("get_godot_to_gltf_expression"), &GLTFObjectModelProperty::get_godot_to_gltf_expression);
+ ClassDB::bind_method(D_METHOD("set_godot_to_gltf_expression", "godot_to_gltf_expr"), &GLTFObjectModelProperty::set_godot_to_gltf_expression);
+ ClassDB::bind_method(D_METHOD("get_node_paths"), &GLTFObjectModelProperty::get_node_paths);
+ ClassDB::bind_method(D_METHOD("has_node_paths"), &GLTFObjectModelProperty::has_node_paths);
+ ClassDB::bind_method(D_METHOD("set_node_paths", "node_paths"), &GLTFObjectModelProperty::set_node_paths);
+ ClassDB::bind_method(D_METHOD("get_object_model_type"), &GLTFObjectModelProperty::get_object_model_type);
+ ClassDB::bind_method(D_METHOD("set_object_model_type", "type"), &GLTFObjectModelProperty::set_object_model_type);
+ ClassDB::bind_method(D_METHOD("get_json_pointers"), &GLTFObjectModelProperty::get_json_pointers_bind);
+ ClassDB::bind_method(D_METHOD("has_json_pointers"), &GLTFObjectModelProperty::has_json_pointers);
+ ClassDB::bind_method(D_METHOD("set_json_pointers", "json_pointers"), &GLTFObjectModelProperty::set_json_pointers_bind);
+ ClassDB::bind_method(D_METHOD("get_variant_type"), &GLTFObjectModelProperty::get_variant_type);
+ ClassDB::bind_method(D_METHOD("set_variant_type", "variant_type"), &GLTFObjectModelProperty::set_variant_type);
+ ClassDB::bind_method(D_METHOD("set_types", "variant_type", "obj_model_type"), &GLTFObjectModelProperty::set_types);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gltf_to_godot_expression", PROPERTY_HINT_RESOURCE_TYPE, "Expression"), "set_gltf_to_godot_expression", "get_gltf_to_godot_expression"); // Ref<Expression>
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "godot_to_gltf_expression", PROPERTY_HINT_RESOURCE_TYPE, "Expression"), "set_godot_to_gltf_expression", "get_godot_to_gltf_expression"); // Ref<Expression>
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "node_paths", PROPERTY_HINT_TYPE_STRING, "NodePath"), "set_node_paths", "get_node_paths"); // TypedArray<NodePath>
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "object_model_type"), "set_object_model_type", "get_object_model_type"); // GLTFObjectModelType
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "json_pointers"), "set_json_pointers", "get_json_pointers"); // TypedArray<PackedStringArray>
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "variant_type"), "set_variant_type", "get_variant_type"); // Variant::Type
+}
+
+void GLTFObjectModelProperty::append_node_path(const NodePath &p_node_path) {
+ node_paths.push_back(p_node_path);
+}
+
+void GLTFObjectModelProperty::append_path_to_property(const NodePath &p_node_path, const StringName &p_prop_name) {
+ Vector<StringName> node_names = p_node_path.get_names();
+ Vector<StringName> subpath = p_node_path.get_subnames();
+ subpath.append(p_prop_name);
+ node_paths.push_back(NodePath(node_names, subpath, false));
+}
+
+GLTFAccessor::GLTFAccessorType GLTFObjectModelProperty::get_accessor_type() const {
+ switch (object_model_type) {
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT2:
+ return GLTFAccessor::TYPE_VEC2;
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT3:
+ return GLTFAccessor::TYPE_VEC3;
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT4:
+ return GLTFAccessor::TYPE_VEC4;
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT2X2:
+ return GLTFAccessor::TYPE_MAT2;
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT3X3:
+ return GLTFAccessor::TYPE_MAT3;
+ case GLTF_OBJECT_MODEL_TYPE_FLOAT4X4:
+ return GLTFAccessor::TYPE_MAT4;
+ default:
+ return GLTFAccessor::TYPE_SCALAR;
+ }
+}
+
+Ref<Expression> GLTFObjectModelProperty::get_gltf_to_godot_expression() const {
+ return gltf_to_godot_expr;
+}
+
+void GLTFObjectModelProperty::set_gltf_to_godot_expression(Ref<Expression> p_gltf_to_godot_expr) {
+ gltf_to_godot_expr = p_gltf_to_godot_expr;
+}
+
+Ref<Expression> GLTFObjectModelProperty::get_godot_to_gltf_expression() const {
+ return godot_to_gltf_expr;
+}
+
+void GLTFObjectModelProperty::set_godot_to_gltf_expression(Ref<Expression> p_godot_to_gltf_expr) {
+ godot_to_gltf_expr = p_godot_to_gltf_expr;
+}
+
+TypedArray<NodePath> GLTFObjectModelProperty::get_node_paths() const {
+ return node_paths;
+}
+
+bool GLTFObjectModelProperty::has_node_paths() const {
+ return !node_paths.is_empty();
+}
+
+void GLTFObjectModelProperty::set_node_paths(TypedArray<NodePath> p_node_paths) {
+ node_paths = p_node_paths;
+}
+
+GLTFObjectModelProperty::GLTFObjectModelType GLTFObjectModelProperty::get_object_model_type() const {
+ return object_model_type;
+}
+
+void GLTFObjectModelProperty::set_object_model_type(GLTFObjectModelType p_type) {
+ object_model_type = p_type;
+}
+
+Vector<PackedStringArray> GLTFObjectModelProperty::get_json_pointers() const {
+ return json_pointers;
+}
+
+bool GLTFObjectModelProperty::has_json_pointers() const {
+ return !json_pointers.is_empty();
+}
+
+void GLTFObjectModelProperty::set_json_pointers(const Vector<PackedStringArray> &p_json_pointers) {
+ json_pointers = p_json_pointers;
+}
+
+TypedArray<PackedStringArray> GLTFObjectModelProperty::get_json_pointers_bind() const {
+ return GLTFTemplateConvert::to_array(json_pointers);
+}
+
+void GLTFObjectModelProperty::set_json_pointers_bind(const TypedArray<PackedStringArray> &p_json_pointers) {
+ GLTFTemplateConvert::set_from_array(json_pointers, p_json_pointers);
+}
+
+Variant::Type GLTFObjectModelProperty::get_variant_type() const {
+ return variant_type;
+}
+
+void GLTFObjectModelProperty::set_variant_type(Variant::Type p_variant_type) {
+ variant_type = p_variant_type;
+}
+
+void GLTFObjectModelProperty::set_types(Variant::Type p_variant_type, GLTFObjectModelType p_obj_model_type) {
+ variant_type = p_variant_type;
+ object_model_type = p_obj_model_type;
+}
diff --git a/modules/gltf/structures/gltf_object_model_property.h b/modules/gltf/structures/gltf_object_model_property.h
new file mode 100644
index 0000000000..d8a4ed420a
--- /dev/null
+++ b/modules/gltf/structures/gltf_object_model_property.h
@@ -0,0 +1,104 @@
+/**************************************************************************/
+/* gltf_object_model_property.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef GLTF_OBJECT_MODEL_PROPERTY_H
+#define GLTF_OBJECT_MODEL_PROPERTY_H
+
+#include "core/math/expression.h"
+#include "core/variant/typed_array.h"
+#include "gltf_accessor.h"
+
+// Object model: https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/ObjectModel.adoc
+// KHR_animation_pointer: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_animation_pointer
+
+class GLTFObjectModelProperty : public RefCounted {
+ GDCLASS(GLTFObjectModelProperty, RefCounted);
+
+public:
+ enum GLTFObjectModelType {
+ GLTF_OBJECT_MODEL_TYPE_UNKNOWN,
+ GLTF_OBJECT_MODEL_TYPE_BOOL,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT_ARRAY,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT2,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT3,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT4,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT2X2,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT3X3,
+ GLTF_OBJECT_MODEL_TYPE_FLOAT4X4,
+ GLTF_OBJECT_MODEL_TYPE_INT,
+ };
+
+private:
+ Ref<Expression> gltf_to_godot_expr;
+ Ref<Expression> godot_to_gltf_expr;
+ TypedArray<NodePath> node_paths;
+ GLTFObjectModelType object_model_type = GLTF_OBJECT_MODEL_TYPE_UNKNOWN;
+ Vector<PackedStringArray> json_pointers;
+ Variant::Type variant_type = Variant::NIL;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void append_node_path(const NodePath &p_node_path);
+ void append_path_to_property(const NodePath &p_node_path, const StringName &p_prop_name);
+
+ GLTFAccessor::GLTFAccessorType get_accessor_type() const;
+
+ Ref<Expression> get_gltf_to_godot_expression() const;
+ void set_gltf_to_godot_expression(Ref<Expression> p_gltf_to_godot_expr);
+
+ Ref<Expression> get_godot_to_gltf_expression() const;
+ void set_godot_to_gltf_expression(Ref<Expression> p_godot_to_gltf_expr);
+
+ TypedArray<NodePath> get_node_paths() const;
+ bool has_node_paths() const;
+ void set_node_paths(TypedArray<NodePath> p_node_paths);
+
+ GLTFObjectModelType get_object_model_type() const;
+ void set_object_model_type(GLTFObjectModelType p_type);
+
+ Vector<PackedStringArray> get_json_pointers() const;
+ bool has_json_pointers() const;
+ void set_json_pointers(const Vector<PackedStringArray> &p_json_pointers);
+
+ TypedArray<PackedStringArray> get_json_pointers_bind() const;
+ void set_json_pointers_bind(const TypedArray<PackedStringArray> &p_json_pointers);
+
+ Variant::Type get_variant_type() const;
+ void set_variant_type(Variant::Type p_variant_type);
+
+ void set_types(Variant::Type p_variant_type, GLTFObjectModelType p_obj_model_type);
+};
+
+VARIANT_ENUM_CAST(GLTFObjectModelProperty::GLTFObjectModelType);
+
+#endif // GLTF_OBJECT_MODEL_PROPERTY_H