feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -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() {

View file

@ -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

View file

@ -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() {

View file

@ -31,7 +31,7 @@
#ifndef GLTF_ANIMATION_H
#define GLTF_ANIMATION_H
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
class GLTFAnimation : public Resource {
GDCLASS(GLTFAnimation, Resource);
@ -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

View file

@ -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,14 +58,29 @@ 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();
ERR_FAIL_NULL_V_MSG(p_camera, c, "Tried to create a GLTFCamera from a Camera3D node, but the given node was null.");
c->set_perspective(p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE);
// GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
// glTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
c->set_fov(Math::deg_to_rad(p_camera->get_fov()));
// GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
// 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());
@ -74,9 +90,9 @@ Ref<GLTFCamera> GLTFCamera::from_node(const Camera3D *p_camera) {
Camera3D *GLTFCamera::to_node() const {
Camera3D *camera = memnew(Camera3D);
camera->set_projection(perspective ? Camera3D::PROJECTION_PERSPECTIVE : Camera3D::PROJECTION_ORTHOGONAL);
// GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
// glTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
camera->set_fov(Math::rad_to_deg(fov));
// GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
// glTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
camera->set_size(size_mag * 2.0f);
camera->set_near(depth_near);
camera->set_far(depth_far);
@ -84,7 +100,7 @@ Camera3D *GLTFCamera::to_node() const {
}
Ref<GLTFCamera> GLTFCamera::from_dictionary(const Dictionary p_dictionary) {
ERR_FAIL_COND_V_MSG(!p_dictionary.has("type"), Ref<GLTFCamera>(), "Failed to parse GLTF camera, missing required field 'type'.");
ERR_FAIL_COND_V_MSG(!p_dictionary.has("type"), Ref<GLTFCamera>(), "Failed to parse glTF camera, missing required field 'type'.");
Ref<GLTFCamera> camera;
camera.instantiate();
const String &type = p_dictionary["type"];
@ -107,7 +123,7 @@ Ref<GLTFCamera> GLTFCamera::from_dictionary(const Dictionary p_dictionary) {
camera->set_depth_near(ortho["znear"]);
}
} else {
ERR_PRINT("Error parsing GLTF camera: Camera type '" + type + "' is unknown, should be perspective or orthographic.");
ERR_PRINT("Error parsing glTF camera: Camera type '" + type + "' is unknown, should be perspective or orthographic.");
}
return camera;
}

View file

@ -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
@ -42,8 +43,8 @@ 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.
// 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;
real_t fov = Math::deg_to_rad(75.0);
real_t size_mag = 0.5;
@ -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; }

View file

@ -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);
@ -55,10 +57,12 @@ void GLTFNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &GLTFNode::set_scale);
ClassDB::bind_method(D_METHOD("get_children"), &GLTFNode::get_children);
ClassDB::bind_method(D_METHOD("set_children", "children"), &GLTFNode::set_children);
ClassDB::bind_method(D_METHOD("append_child_index", "child_index"), &GLTFNode::append_child_index);
ClassDB::bind_method(D_METHOD("get_light"), &GLTFNode::get_light);
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
@ -170,6 +174,10 @@ void GLTFNode::set_children(Vector<int> p_children) {
children = p_children;
}
void GLTFNode::append_child_index(int p_child_index) {
children.append(p_child_index);
}
GLTFLightIndex GLTFNode::get_light() {
return light;
}
@ -182,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);
}

View file

@ -97,12 +97,16 @@ public:
Vector<int> get_children();
void set_children(Vector<int> p_children);
void append_child_index(int p_child_index);
GLTFLightIndex get_light();
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

View file

@ -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;
}

View file

@ -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