Skip to content

Commit

Permalink
Add animation node extension
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilhermeGSousa committed Nov 14, 2024
1 parent cb411fa commit 61f3ab5
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 0 deletions.
115 changes: 115 additions & 0 deletions scene/animation/animation_node_extension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**************************************************************************/
/* animation_node_extension.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 "animation_node_extension.h"

void NodeTimeInfoRC::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_length"), &NodeTimeInfoRC::get_length);
ClassDB::bind_method(D_METHOD("set_length", "length"), &NodeTimeInfoRC::set_length);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length");

ClassDB::bind_method(D_METHOD("get_position"), &NodeTimeInfoRC::get_position);
ClassDB::bind_method(D_METHOD("set_position", "position"), &NodeTimeInfoRC::set_position);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "position"), "set_position", "get_position");

ClassDB::bind_method(D_METHOD("get_delta"), &NodeTimeInfoRC::get_delta);
ClassDB::bind_method(D_METHOD("set_delta", "delta"), &NodeTimeInfoRC::set_delta);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "delta"), "set_delta", "get_delta");

ClassDB::bind_method(D_METHOD("get_loop_mode"), &NodeTimeInfoRC::get_loop_mode);
ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &NodeTimeInfoRC::set_loop_mode);
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "None,Linear,PingPong"), "set_loop_mode", "get_loop_mode");

ClassDB::bind_method(D_METHOD("get_will_end"), &NodeTimeInfoRC::get_will_end);
ClassDB::bind_method(D_METHOD("set_will_end", "will_end"), &NodeTimeInfoRC::set_will_end);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "will_end"), "set_will_end", "get_will_end");

ClassDB::bind_method(D_METHOD("get_is_infinity"), &NodeTimeInfoRC::get_is_infinity);
ClassDB::bind_method(D_METHOD("set_is_infinity", "is_infinity"), &NodeTimeInfoRC::set_is_infinity);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_infinity"), "set_is_infinity", "get_is_infinity");
}

void PlaybackInfoRC::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_time"), &PlaybackInfoRC::get_time);
ClassDB::bind_method(D_METHOD("set_time", "time"), &PlaybackInfoRC::set_time);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time"), "set_time", "get_time");

ClassDB::bind_method(D_METHOD("get_delta"), &PlaybackInfoRC::get_delta);
ClassDB::bind_method(D_METHOD("set_delta", "delta"), &PlaybackInfoRC::set_delta);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "delta"), "set_delta", "get_delta");

ClassDB::bind_method(D_METHOD("get_start"), &PlaybackInfoRC::get_start);
ClassDB::bind_method(D_METHOD("set_start", "start"), &PlaybackInfoRC::set_start);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "start"), "set_start", "get_start");

ClassDB::bind_method(D_METHOD("get_end"), &PlaybackInfoRC::get_end);
ClassDB::bind_method(D_METHOD("set_end", "end"), &PlaybackInfoRC::set_end);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "end"), "set_end", "get_end");

ClassDB::bind_method(D_METHOD("get_seeked"), &PlaybackInfoRC::get_seeked);
ClassDB::bind_method(D_METHOD("set_seeked", "seeked"), &PlaybackInfoRC::set_seeked);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seeked"), "set_seeked", "get_seeked");

ClassDB::bind_method(D_METHOD("get_is_external_seeking"), &PlaybackInfoRC::get_is_external_seeking);
ClassDB::bind_method(D_METHOD("set_is_external_seeking", "is_external_seeking"), &PlaybackInfoRC::set_is_external_seeking);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_external_seeking"), "set_is_external_seeking", "get_is_external_seeking");

ClassDB::bind_method(D_METHOD("get_looped_flag"), &PlaybackInfoRC::get_looped_flag);
ClassDB::bind_method(D_METHOD("set_looped_flag", "looped_flag"), &PlaybackInfoRC::set_looped_flag);
ADD_PROPERTY(PropertyInfo(Variant::INT, "looped_flag", PROPERTY_HINT_ENUM, "None,End,Start"), "set_looped_flag", "get_looped_flag");

ClassDB::bind_method(D_METHOD("get_weight"), &PlaybackInfoRC::get_weight);
ClassDB::bind_method(D_METHOD("set_weight", "weight"), &PlaybackInfoRC::set_weight);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "weight"), "set_weight", "get_weight");
}

AnimationNodeExtension::AnimationNodeExtension() {
_node_time_info.instantiate();
_playback_info.instantiate();
}

AnimationNode::NodeTimeInfo AnimationNodeExtension::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) {
_node_time_info->_reset();
_playback_info->_reset(p_playback_info);

GDVIRTUAL_CALL(_process, _playback_info, _node_time_info, p_test_only);

return _node_time_info->_get_node_time_info();
}

AnimationTree *AnimationNodeExtension::get_process_tree() const {
ERR_FAIL_NULL_V(process_state, nullptr);
return process_state->tree;
}

void AnimationNodeExtension::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_process_tree"), &get_process_tree);

Check failure on line 113 in scene/animation/animation_node_extension.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor w/ Mono (target=editor)

ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&AnimationNodeExtension::get_process_tree' [-fpermissive]

Check failure on line 113 in scene/animation/animation_node_extension.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

must explicitly qualify name of member function when taking its address

Check failure on line 113 in scene/animation/animation_node_extension.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Template w/ Mono (target=template_release, tests=yes)

ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&AnimationNodeExtension::get_process_tree' [-fpermissive]

Check failure on line 113 in scene/animation/animation_node_extension.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Minimal template (target=template_release, tests=yes, everything disabled)

ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&AnimationNodeExtension::get_process_tree' [-fpermissive]
GDVIRTUAL_BIND(_process, "playback_info", "node_time_info", "test_only");
}
189 changes: 189 additions & 0 deletions scene/animation/animation_node_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/**************************************************************************/
/* animation_node_extension.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 ANIMATION_NODE_EXTENSION_H
#define ANIMATION_NODE_EXTENSION_H

#include "scene/animation/animation_tree.h"

class NodeTimeInfoRC : public RefCounted {
GDCLASS(NodeTimeInfoRC, RefCounted);

public:
double get_length() const {
return node_time_info.length;
}
void set_length(double p_length) {
node_time_info.length = p_length;
}

double get_position() const {
return node_time_info.position;
}
void set_position(double p_position) {
node_time_info.position = p_position;
}

double get_delta() const {
return node_time_info.delta;
}
void set_delta(double p_delta) {
node_time_info.delta = p_delta;
}

Animation::LoopMode get_loop_mode() const {
return node_time_info.loop_mode;
}
void set_loop_mode(Animation::LoopMode p_loop_mode) {
node_time_info.loop_mode = p_loop_mode;
}

bool get_will_end() const {
return node_time_info.will_end;
}
void set_will_end(bool p_will_end) {
node_time_info.will_end = p_will_end;
}

bool get_is_infinity() const {
return node_time_info.is_infinity;
}
void set_is_infinity(bool p_is_infinity) {
node_time_info.is_infinity = p_is_infinity;
}

void _reset() {
node_time_info = AnimationNode::NodeTimeInfo();
}

const AnimationNode::NodeTimeInfo &_get_node_time_info() const {
return node_time_info;
}

protected:
static void _bind_methods();

private:
AnimationNode::NodeTimeInfo node_time_info;
};

class PlaybackInfoRC : public RefCounted {
GDCLASS(PlaybackInfoRC, RefCounted);

public:
double get_time() const {
return playback_info.time;
}
void set_time(double p_time) {
playback_info.time = p_time;
}

double get_delta() const {
return playback_info.delta;
}
void set_delta(double p_delta) {
playback_info.delta = p_delta;
}

double get_start() const {
return playback_info.start;
}
void set_start(double p_start) {
playback_info.start = p_start;
}

double get_end() const {
return playback_info.end;
}
void set_end(double p_end) {
playback_info.end = p_end;
}

bool get_seeked() const {
return playback_info.seeked;
}
void set_seeked(bool p_seeked) {
playback_info.seeked = p_seeked;
}

bool get_is_external_seeking() const {
return playback_info.is_external_seeking;
}
void set_is_external_seeking(bool p_is_external_seeking) {
playback_info.is_external_seeking = p_is_external_seeking;
}

Animation::LoopedFlag get_looped_flag() const {
return playback_info.looped_flag;
}
void set_looped_flag(Animation::LoopedFlag p_looped_flag) {
playback_info.looped_flag = p_looped_flag;
}

real_t get_weight() const {
return playback_info.weight;
}
void set_weight(real_t p_weight) {
playback_info.weight = p_weight;
}

void _reset(const AnimationMixer::PlaybackInfo &p_playback_info) {
playback_info = p_playback_info;
}

protected:
static void _bind_methods();

private:
AnimationMixer::PlaybackInfo playback_info;
};

class AnimationNodeExtension : public AnimationRootNode {
GDCLASS(AnimationNodeExtension, AnimationRootNode);

public:
AnimationNodeExtension();
virtual ~AnimationNodeExtension() = default;

virtual NodeTimeInfo _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false) override;

AnimationTree *get_process_tree() const;

protected:
static void _bind_methods();

GDVIRTUAL3(_process, Ref<PlaybackInfoRC>, Ref<NodeTimeInfoRC>, bool);

private:
Ref<NodeTimeInfoRC> _node_time_info;
Ref<PlaybackInfoRC> _playback_info;
};

#endif // ANIMATION_NODE_EXTENSION_H
4 changes: 4 additions & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "scene/animation/animation_blend_space_2d.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_mixer.h"
#include "scene/animation/animation_node_extension.h"
#include "scene/animation/animation_node_state_machine.h"
#include "scene/animation/animation_player.h"
#include "scene/animation/animation_tree.h"
Expand Down Expand Up @@ -512,6 +513,9 @@ void register_scene_types() {
GDREGISTER_CLASS(AnimationNodeBlendSpace2D);
GDREGISTER_CLASS(AnimationNodeStateMachine);
GDREGISTER_CLASS(AnimationNodeStateMachinePlayback);
GDREGISTER_CLASS(AnimationNodeExtension);
GDREGISTER_CLASS(NodeTimeInfoRC);
GDREGISTER_CLASS(PlaybackInfoRC);

GDREGISTER_INTERNAL_CLASS(AnimationNodeStartState);
GDREGISTER_INTERNAL_CLASS(AnimationNodeEndState);
Expand Down

0 comments on commit 61f3ab5

Please sign in to comment.