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 69c6e4a
Show file tree
Hide file tree
Showing 6 changed files with 382 additions and 0 deletions.
24 changes: 24 additions & 0 deletions doc/classes/AnimationNodeExtension.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AnimationNodeExtension" inherits="AnimationRootNode" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="_process" qualifiers="virtual">
<return type="void" />
<param index="0" name="playback_info" type="PlaybackInfoRC" />
<param index="1" name="node_time_info" type="NodeTimeInfoRC" />
<param index="2" name="test_only" type="bool" />
<description>
</description>
</method>
<method name="get_process_tree" qualifiers="const">
<return type="AnimationTree" />
<description>
</description>
</method>
</methods>
</class>
23 changes: 23 additions & 0 deletions doc/classes/NodeTimeInfoRC.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NodeTimeInfoRC" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="delta" type="float" setter="set_delta" getter="get_delta" default="0.0">
</member>
<member name="is_infinity" type="bool" setter="set_is_infinity" getter="get_is_infinity" default="false">
</member>
<member name="length" type="float" setter="set_length" getter="get_length" default="0.0">
</member>
<member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="Animation.LoopMode" default="0">
</member>
<member name="position" type="float" setter="set_position" getter="get_position" default="0.0">
</member>
<member name="will_end" type="bool" setter="set_will_end" getter="get_will_end" default="false">
</member>
</members>
</class>
27 changes: 27 additions & 0 deletions doc/classes/PlaybackInfoRC.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PlaybackInfoRC" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="delta" type="float" setter="set_delta" getter="get_delta" default="0.0">
</member>
<member name="end" type="float" setter="set_end" getter="get_end" default="0.0">
</member>
<member name="is_external_seeking" type="bool" setter="set_is_external_seeking" getter="get_is_external_seeking" default="false">
</member>
<member name="looped_flag" type="int" setter="set_looped_flag" getter="get_looped_flag" enum="Animation.LoopedFlag" default="0">
</member>
<member name="seeked" type="bool" setter="set_seeked" getter="get_seeked" default="false">
</member>
<member name="start" type="float" setter="set_start" getter="get_start" default="0.0">
</member>
<member name="time" type="float" setter="set_time" getter="get_time" default="0.0">
</member>
<member name="weight" type="float" setter="set_weight" getter="get_weight" default="0.0">
</member>
</members>
</class>
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"), &AnimationNodeExtension::get_process_tree);
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
Loading

0 comments on commit 69c6e4a

Please sign in to comment.