Path: blob/master/scene/resources/2d/skeleton/skeleton_modification_2d_jiggle.cpp
9904 views
/**************************************************************************/1/* skeleton_modification_2d_jiggle.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "skeleton_modification_2d_jiggle.h"3132#include "scene/2d/skeleton_2d.h"33#include "scene/resources/world_2d.h"3435bool SkeletonModification2DJiggle::_set(const StringName &p_path, const Variant &p_value) {36String path = p_path;3738if (path.begins_with("joint_data/")) {39int which = path.get_slicec('/', 1).to_int();40String what = path.get_slicec('/', 2);41ERR_FAIL_INDEX_V(which, jiggle_data_chain.size(), false);4243if (what == "bone2d_node") {44set_jiggle_joint_bone2d_node(which, p_value);45} else if (what == "bone_index") {46set_jiggle_joint_bone_index(which, p_value);47} else if (what == "override_defaults") {48set_jiggle_joint_override(which, p_value);49} else if (what == "stiffness") {50set_jiggle_joint_stiffness(which, p_value);51} else if (what == "mass") {52set_jiggle_joint_mass(which, p_value);53} else if (what == "damping") {54set_jiggle_joint_damping(which, p_value);55} else if (what == "use_gravity") {56set_jiggle_joint_use_gravity(which, p_value);57} else if (what == "gravity") {58set_jiggle_joint_gravity(which, p_value);59} else {60return false;61}62} else if (path == "use_colliders") {63set_use_colliders(p_value);64} else if (path == "collision_mask") {65set_collision_mask(p_value);66} else {67return false;68}69return true;70}7172bool SkeletonModification2DJiggle::_get(const StringName &p_path, Variant &r_ret) const {73String path = p_path;7475if (path.begins_with("joint_data/")) {76int which = path.get_slicec('/', 1).to_int();77String what = path.get_slicec('/', 2);78ERR_FAIL_INDEX_V(which, jiggle_data_chain.size(), false);7980if (what == "bone2d_node") {81r_ret = get_jiggle_joint_bone2d_node(which);82} else if (what == "bone_index") {83r_ret = get_jiggle_joint_bone_index(which);84} else if (what == "override_defaults") {85r_ret = get_jiggle_joint_override(which);86} else if (what == "stiffness") {87r_ret = get_jiggle_joint_stiffness(which);88} else if (what == "mass") {89r_ret = get_jiggle_joint_mass(which);90} else if (what == "damping") {91r_ret = get_jiggle_joint_damping(which);92} else if (what == "use_gravity") {93r_ret = get_jiggle_joint_use_gravity(which);94} else if (what == "gravity") {95r_ret = get_jiggle_joint_gravity(which);96} else {97return false;98}99} else if (path == "use_colliders") {100r_ret = get_use_colliders();101} else if (path == "collision_mask") {102r_ret = get_collision_mask();103} else {104return false;105}106return true;107}108109void SkeletonModification2DJiggle::_get_property_list(List<PropertyInfo> *p_list) const {110p_list->push_back(PropertyInfo(Variant::BOOL, "use_colliders", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT));111if (use_colliders) {112p_list->push_back(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS, "", PROPERTY_USAGE_DEFAULT));113}114115for (int i = 0; i < jiggle_data_chain.size(); i++) {116String base_string = "joint_data/" + itos(i) + "/";117118p_list->push_back(PropertyInfo(Variant::INT, base_string + "bone_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT));119p_list->push_back(PropertyInfo(Variant::NODE_PATH, base_string + "bone2d_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Bone2D", PROPERTY_USAGE_DEFAULT));120p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "override_defaults", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT));121122if (jiggle_data_chain[i].override_defaults) {123p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "stiffness", PROPERTY_HINT_RANGE, "0, 1000, 0.01", PROPERTY_USAGE_DEFAULT));124p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "mass", PROPERTY_HINT_RANGE, "0, 1000, 0.01", PROPERTY_USAGE_DEFAULT));125p_list->push_back(PropertyInfo(Variant::FLOAT, base_string + "damping", PROPERTY_HINT_RANGE, "0, 1, 0.01", PROPERTY_USAGE_DEFAULT));126p_list->push_back(PropertyInfo(Variant::BOOL, base_string + "use_gravity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT));127if (jiggle_data_chain[i].use_gravity) {128p_list->push_back(PropertyInfo(Variant::VECTOR2, base_string + "gravity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT));129}130}131}132}133134void SkeletonModification2DJiggle::_execute(float p_delta) {135ERR_FAIL_COND_MSG(!stack || !is_setup || stack->skeleton == nullptr,136"Modification is not setup and therefore cannot execute!");137if (!enabled) {138return;139}140if (target_node_cache.is_null()) {141WARN_PRINT_ONCE("Target cache is out of date. Attempting to update...");142update_target_cache();143return;144}145Node2D *target = ObjectDB::get_instance<Node2D>(target_node_cache);146if (!target || !target->is_inside_tree()) {147ERR_PRINT_ONCE("Target node is not in the scene tree. Cannot execute modification!");148return;149}150151for (int i = 0; i < jiggle_data_chain.size(); i++) {152_execute_jiggle_joint(i, target, p_delta);153}154}155156void SkeletonModification2DJiggle::_execute_jiggle_joint(int p_joint_idx, Node2D *p_target, float p_delta) {157// Adopted from: https://wiki.unity3d.com/index.php/JiggleBone158// With modifications by TwistedTwigleg.159160if (jiggle_data_chain[p_joint_idx].bone_idx <= -1 || jiggle_data_chain[p_joint_idx].bone_idx > stack->skeleton->get_bone_count()) {161ERR_PRINT_ONCE("Jiggle joint " + itos(p_joint_idx) + " bone index is invalid. Cannot execute modification on joint...");162return;163}164165if (jiggle_data_chain[p_joint_idx].bone2d_node_cache.is_null() && !jiggle_data_chain[p_joint_idx].bone2d_node.is_empty()) {166WARN_PRINT_ONCE("Bone2D cache for joint " + itos(p_joint_idx) + " is out of date. Updating...");167jiggle_joint_update_bone2d_cache(p_joint_idx);168}169170Bone2D *operation_bone = stack->skeleton->get_bone(jiggle_data_chain[p_joint_idx].bone_idx);171if (!operation_bone) {172ERR_PRINT_ONCE("Jiggle joint " + itos(p_joint_idx) + " does not have a Bone2D node or it cannot be found!");173return;174}175176Transform2D operation_bone_trans = operation_bone->get_global_transform();177Vector2 target_position = p_target->get_global_position();178179jiggle_data_chain.write[p_joint_idx].force = (target_position - jiggle_data_chain[p_joint_idx].dynamic_position) * jiggle_data_chain[p_joint_idx].stiffness * p_delta;180181if (jiggle_data_chain[p_joint_idx].use_gravity) {182jiggle_data_chain.write[p_joint_idx].force += jiggle_data_chain[p_joint_idx].gravity * p_delta;183}184185jiggle_data_chain.write[p_joint_idx].acceleration = jiggle_data_chain[p_joint_idx].force / jiggle_data_chain[p_joint_idx].mass;186jiggle_data_chain.write[p_joint_idx].velocity += jiggle_data_chain[p_joint_idx].acceleration * (1 - jiggle_data_chain[p_joint_idx].damping);187188jiggle_data_chain.write[p_joint_idx].dynamic_position += jiggle_data_chain[p_joint_idx].velocity + jiggle_data_chain[p_joint_idx].force;189jiggle_data_chain.write[p_joint_idx].dynamic_position += operation_bone_trans.get_origin() - jiggle_data_chain[p_joint_idx].last_position;190jiggle_data_chain.write[p_joint_idx].last_position = operation_bone_trans.get_origin();191192// Collision detection/response193if (use_colliders) {194if (execution_mode == SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_physics_process) {195Ref<World2D> world_2d = stack->skeleton->get_world_2d();196ERR_FAIL_COND(world_2d.is_null());197PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space());198PhysicsDirectSpaceState2D::RayResult ray_result;199200PhysicsDirectSpaceState2D::RayParameters ray_params;201ray_params.from = operation_bone_trans.get_origin();202ray_params.to = jiggle_data_chain[p_joint_idx].dynamic_position;203ray_params.collision_mask = collision_mask;204205// Add exception support?206bool ray_hit = space_state->intersect_ray(ray_params, ray_result);207208if (ray_hit) {209jiggle_data_chain.write[p_joint_idx].dynamic_position = jiggle_data_chain[p_joint_idx].last_noncollision_position;210jiggle_data_chain.write[p_joint_idx].acceleration = Vector2(0, 0);211jiggle_data_chain.write[p_joint_idx].velocity = Vector2(0, 0);212} else {213jiggle_data_chain.write[p_joint_idx].last_noncollision_position = jiggle_data_chain[p_joint_idx].dynamic_position;214}215} else {216WARN_PRINT_ONCE("Jiggle 2D modifier: You cannot detect colliders without the stack mode being set to _physics_process!");217}218}219220// Rotate the bone using the dynamic position!221operation_bone_trans = operation_bone_trans.looking_at(jiggle_data_chain[p_joint_idx].dynamic_position);222operation_bone_trans.set_rotation(operation_bone_trans.get_rotation() - operation_bone->get_bone_angle());223224// Reset scale225operation_bone_trans.set_scale(operation_bone->get_global_scale());226227operation_bone->set_global_transform(operation_bone_trans);228stack->skeleton->set_bone_local_pose_override(jiggle_data_chain[p_joint_idx].bone_idx, operation_bone->get_transform(), stack->strength, true);229}230231void SkeletonModification2DJiggle::_update_jiggle_joint_data() {232for (int i = 0; i < jiggle_data_chain.size(); i++) {233if (!jiggle_data_chain[i].override_defaults) {234set_jiggle_joint_stiffness(i, stiffness);235set_jiggle_joint_mass(i, mass);236set_jiggle_joint_damping(i, damping);237set_jiggle_joint_use_gravity(i, use_gravity);238set_jiggle_joint_gravity(i, gravity);239}240}241}242243void SkeletonModification2DJiggle::_setup_modification(SkeletonModificationStack2D *p_stack) {244stack = p_stack;245246if (stack) {247is_setup = true;248249if (stack->skeleton) {250for (int i = 0; i < jiggle_data_chain.size(); i++) {251int bone_idx = jiggle_data_chain[i].bone_idx;252if (bone_idx > 0 && bone_idx < stack->skeleton->get_bone_count()) {253Bone2D *bone2d_node = stack->skeleton->get_bone(bone_idx);254jiggle_data_chain.write[i].dynamic_position = bone2d_node->get_global_position();255}256257jiggle_joint_update_bone2d_cache(i);258}259}260261update_target_cache();262}263}264265void SkeletonModification2DJiggle::update_target_cache() {266if (!is_setup || !stack) {267if (is_setup) {268ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!");269}270return;271}272273target_node_cache = ObjectID();274if (stack->skeleton) {275if (stack->skeleton->is_inside_tree()) {276if (stack->skeleton->has_node(target_node)) {277Node *node = stack->skeleton->get_node(target_node);278ERR_FAIL_COND_MSG(!node || stack->skeleton == node,279"Cannot update target cache: node is this modification's skeleton or cannot be found!");280ERR_FAIL_COND_MSG(!node->is_inside_tree(),281"Cannot update target cache: node is not in scene tree!");282target_node_cache = node->get_instance_id();283}284}285}286}287288void SkeletonModification2DJiggle::jiggle_joint_update_bone2d_cache(int p_joint_idx) {289ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Cannot update bone2d cache: joint index out of range!");290if (!is_setup || !stack) {291if (is_setup) {292ERR_PRINT_ONCE("Cannot update Jiggle " + itos(p_joint_idx) + " Bone2D cache: modification is not properly setup!");293}294return;295}296297jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = ObjectID();298if (stack->skeleton) {299if (stack->skeleton->is_inside_tree()) {300if (stack->skeleton->has_node(jiggle_data_chain[p_joint_idx].bone2d_node)) {301Node *node = stack->skeleton->get_node(jiggle_data_chain[p_joint_idx].bone2d_node);302ERR_FAIL_COND_MSG(!node || stack->skeleton == node,303"Cannot update Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: node is this modification's skeleton or cannot be found!");304ERR_FAIL_COND_MSG(!node->is_inside_tree(),305"Cannot update Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: node is not in scene tree!");306jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = node->get_instance_id();307308Bone2D *bone = Object::cast_to<Bone2D>(node);309if (bone) {310jiggle_data_chain.write[p_joint_idx].bone_idx = bone->get_index_in_skeleton();311} else {312ERR_FAIL_MSG("Jiggle joint " + itos(p_joint_idx) + " Bone2D cache: Nodepath to Bone2D is not a Bone2D node!");313}314}315}316}317}318319void SkeletonModification2DJiggle::set_target_node(const NodePath &p_target_node) {320target_node = p_target_node;321update_target_cache();322}323324NodePath SkeletonModification2DJiggle::get_target_node() const {325return target_node;326}327328void SkeletonModification2DJiggle::set_stiffness(float p_stiffness) {329ERR_FAIL_COND_MSG(p_stiffness < 0, "Stiffness cannot be set to a negative value!");330stiffness = p_stiffness;331_update_jiggle_joint_data();332}333334float SkeletonModification2DJiggle::get_stiffness() const {335return stiffness;336}337338void SkeletonModification2DJiggle::set_mass(float p_mass) {339ERR_FAIL_COND_MSG(p_mass < 0, "Mass cannot be set to a negative value!");340mass = p_mass;341_update_jiggle_joint_data();342}343344float SkeletonModification2DJiggle::get_mass() const {345return mass;346}347348void SkeletonModification2DJiggle::set_damping(float p_damping) {349ERR_FAIL_COND_MSG(p_damping < 0, "Damping cannot be set to a negative value!");350ERR_FAIL_COND_MSG(p_damping > 1, "Damping cannot be more than one!");351damping = p_damping;352_update_jiggle_joint_data();353}354355float SkeletonModification2DJiggle::get_damping() const {356return damping;357}358359void SkeletonModification2DJiggle::set_use_gravity(bool p_use_gravity) {360use_gravity = p_use_gravity;361_update_jiggle_joint_data();362}363364bool SkeletonModification2DJiggle::get_use_gravity() const {365return use_gravity;366}367368void SkeletonModification2DJiggle::set_gravity(Vector2 p_gravity) {369gravity = p_gravity;370_update_jiggle_joint_data();371}372373Vector2 SkeletonModification2DJiggle::get_gravity() const {374return gravity;375}376377void SkeletonModification2DJiggle::set_use_colliders(bool p_use_colliders) {378use_colliders = p_use_colliders;379notify_property_list_changed();380}381382bool SkeletonModification2DJiggle::get_use_colliders() const {383return use_colliders;384}385386void SkeletonModification2DJiggle::set_collision_mask(int p_mask) {387collision_mask = p_mask;388}389390int SkeletonModification2DJiggle::get_collision_mask() const {391return collision_mask;392}393394// Jiggle joint data functions395int SkeletonModification2DJiggle::get_jiggle_data_chain_length() {396return jiggle_data_chain.size();397}398399void SkeletonModification2DJiggle::set_jiggle_data_chain_length(int p_length) {400ERR_FAIL_COND(p_length < 0);401jiggle_data_chain.resize(p_length);402notify_property_list_changed();403}404405void SkeletonModification2DJiggle::set_jiggle_joint_bone2d_node(int p_joint_idx, const NodePath &p_target_node) {406ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Jiggle joint out of range!");407jiggle_data_chain.write[p_joint_idx].bone2d_node = p_target_node;408jiggle_joint_update_bone2d_cache(p_joint_idx);409410notify_property_list_changed();411}412413NodePath SkeletonModification2DJiggle::get_jiggle_joint_bone2d_node(int p_joint_idx) const {414ERR_FAIL_INDEX_V_MSG(p_joint_idx, jiggle_data_chain.size(), NodePath(), "Jiggle joint out of range!");415return jiggle_data_chain[p_joint_idx].bone2d_node;416}417418void SkeletonModification2DJiggle::set_jiggle_joint_bone_index(int p_joint_idx, int p_bone_idx) {419ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Jiggle joint out of range!");420ERR_FAIL_COND_MSG(p_bone_idx < 0, "Bone index is out of range: The index is too low!");421422if (is_setup) {423if (stack->skeleton) {424ERR_FAIL_INDEX_MSG(p_bone_idx, stack->skeleton->get_bone_count(), "Passed-in Bone index is out of range!");425jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx;426jiggle_data_chain.write[p_joint_idx].bone2d_node_cache = stack->skeleton->get_bone(p_bone_idx)->get_instance_id();427jiggle_data_chain.write[p_joint_idx].bone2d_node = stack->skeleton->get_path_to(stack->skeleton->get_bone(p_bone_idx));428} else {429WARN_PRINT("Cannot verify the Jiggle joint " + itos(p_joint_idx) + " bone index for this modification...");430jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx;431}432} else {433jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx;434}435436notify_property_list_changed();437}438439int SkeletonModification2DJiggle::get_jiggle_joint_bone_index(int p_joint_idx) const {440ERR_FAIL_INDEX_V_MSG(p_joint_idx, jiggle_data_chain.size(), -1, "Jiggle joint out of range!");441return jiggle_data_chain[p_joint_idx].bone_idx;442}443444void SkeletonModification2DJiggle::set_jiggle_joint_override(int p_joint_idx, bool p_override) {445ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());446jiggle_data_chain.write[p_joint_idx].override_defaults = p_override;447_update_jiggle_joint_data();448notify_property_list_changed();449}450451bool SkeletonModification2DJiggle::get_jiggle_joint_override(int p_joint_idx) const {452ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), false);453return jiggle_data_chain[p_joint_idx].override_defaults;454}455456void SkeletonModification2DJiggle::set_jiggle_joint_stiffness(int p_joint_idx, float p_stiffness) {457ERR_FAIL_COND_MSG(p_stiffness < 0, "Stiffness cannot be set to a negative value!");458ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());459jiggle_data_chain.write[p_joint_idx].stiffness = p_stiffness;460}461462float SkeletonModification2DJiggle::get_jiggle_joint_stiffness(int p_joint_idx) const {463ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1);464return jiggle_data_chain[p_joint_idx].stiffness;465}466467void SkeletonModification2DJiggle::set_jiggle_joint_mass(int p_joint_idx, float p_mass) {468ERR_FAIL_COND_MSG(p_mass < 0, "Mass cannot be set to a negative value!");469ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());470jiggle_data_chain.write[p_joint_idx].mass = p_mass;471}472473float SkeletonModification2DJiggle::get_jiggle_joint_mass(int p_joint_idx) const {474ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1);475return jiggle_data_chain[p_joint_idx].mass;476}477478void SkeletonModification2DJiggle::set_jiggle_joint_damping(int p_joint_idx, float p_damping) {479ERR_FAIL_COND_MSG(p_damping < 0, "Damping cannot be set to a negative value!");480ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());481jiggle_data_chain.write[p_joint_idx].damping = p_damping;482}483484float SkeletonModification2DJiggle::get_jiggle_joint_damping(int p_joint_idx) const {485ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), -1);486return jiggle_data_chain[p_joint_idx].damping;487}488489void SkeletonModification2DJiggle::set_jiggle_joint_use_gravity(int p_joint_idx, bool p_use_gravity) {490ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());491jiggle_data_chain.write[p_joint_idx].use_gravity = p_use_gravity;492notify_property_list_changed();493}494495bool SkeletonModification2DJiggle::get_jiggle_joint_use_gravity(int p_joint_idx) const {496ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), false);497return jiggle_data_chain[p_joint_idx].use_gravity;498}499500void SkeletonModification2DJiggle::set_jiggle_joint_gravity(int p_joint_idx, Vector2 p_gravity) {501ERR_FAIL_INDEX(p_joint_idx, jiggle_data_chain.size());502jiggle_data_chain.write[p_joint_idx].gravity = p_gravity;503}504505Vector2 SkeletonModification2DJiggle::get_jiggle_joint_gravity(int p_joint_idx) const {506ERR_FAIL_INDEX_V(p_joint_idx, jiggle_data_chain.size(), Vector2(0, 0));507return jiggle_data_chain[p_joint_idx].gravity;508}509510void SkeletonModification2DJiggle::_bind_methods() {511ClassDB::bind_method(D_METHOD("set_target_node", "target_nodepath"), &SkeletonModification2DJiggle::set_target_node);512ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonModification2DJiggle::get_target_node);513514ClassDB::bind_method(D_METHOD("set_jiggle_data_chain_length", "length"), &SkeletonModification2DJiggle::set_jiggle_data_chain_length);515ClassDB::bind_method(D_METHOD("get_jiggle_data_chain_length"), &SkeletonModification2DJiggle::get_jiggle_data_chain_length);516517ClassDB::bind_method(D_METHOD("set_stiffness", "stiffness"), &SkeletonModification2DJiggle::set_stiffness);518ClassDB::bind_method(D_METHOD("get_stiffness"), &SkeletonModification2DJiggle::get_stiffness);519ClassDB::bind_method(D_METHOD("set_mass", "mass"), &SkeletonModification2DJiggle::set_mass);520ClassDB::bind_method(D_METHOD("get_mass"), &SkeletonModification2DJiggle::get_mass);521ClassDB::bind_method(D_METHOD("set_damping", "damping"), &SkeletonModification2DJiggle::set_damping);522ClassDB::bind_method(D_METHOD("get_damping"), &SkeletonModification2DJiggle::get_damping);523ClassDB::bind_method(D_METHOD("set_use_gravity", "use_gravity"), &SkeletonModification2DJiggle::set_use_gravity);524ClassDB::bind_method(D_METHOD("get_use_gravity"), &SkeletonModification2DJiggle::get_use_gravity);525ClassDB::bind_method(D_METHOD("set_gravity", "gravity"), &SkeletonModification2DJiggle::set_gravity);526ClassDB::bind_method(D_METHOD("get_gravity"), &SkeletonModification2DJiggle::get_gravity);527528ClassDB::bind_method(D_METHOD("set_use_colliders", "use_colliders"), &SkeletonModification2DJiggle::set_use_colliders);529ClassDB::bind_method(D_METHOD("get_use_colliders"), &SkeletonModification2DJiggle::get_use_colliders);530ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SkeletonModification2DJiggle::set_collision_mask);531ClassDB::bind_method(D_METHOD("get_collision_mask"), &SkeletonModification2DJiggle::get_collision_mask);532533// Jiggle joint data functions534ClassDB::bind_method(D_METHOD("set_jiggle_joint_bone2d_node", "joint_idx", "bone2d_node"), &SkeletonModification2DJiggle::set_jiggle_joint_bone2d_node);535ClassDB::bind_method(D_METHOD("get_jiggle_joint_bone2d_node", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_bone2d_node);536ClassDB::bind_method(D_METHOD("set_jiggle_joint_bone_index", "joint_idx", "bone_idx"), &SkeletonModification2DJiggle::set_jiggle_joint_bone_index);537ClassDB::bind_method(D_METHOD("get_jiggle_joint_bone_index", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_bone_index);538ClassDB::bind_method(D_METHOD("set_jiggle_joint_override", "joint_idx", "override"), &SkeletonModification2DJiggle::set_jiggle_joint_override);539ClassDB::bind_method(D_METHOD("get_jiggle_joint_override", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_override);540ClassDB::bind_method(D_METHOD("set_jiggle_joint_stiffness", "joint_idx", "stiffness"), &SkeletonModification2DJiggle::set_jiggle_joint_stiffness);541ClassDB::bind_method(D_METHOD("get_jiggle_joint_stiffness", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_stiffness);542ClassDB::bind_method(D_METHOD("set_jiggle_joint_mass", "joint_idx", "mass"), &SkeletonModification2DJiggle::set_jiggle_joint_mass);543ClassDB::bind_method(D_METHOD("get_jiggle_joint_mass", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_mass);544ClassDB::bind_method(D_METHOD("set_jiggle_joint_damping", "joint_idx", "damping"), &SkeletonModification2DJiggle::set_jiggle_joint_damping);545ClassDB::bind_method(D_METHOD("get_jiggle_joint_damping", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_damping);546ClassDB::bind_method(D_METHOD("set_jiggle_joint_use_gravity", "joint_idx", "use_gravity"), &SkeletonModification2DJiggle::set_jiggle_joint_use_gravity);547ClassDB::bind_method(D_METHOD("get_jiggle_joint_use_gravity", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_use_gravity);548ClassDB::bind_method(D_METHOD("set_jiggle_joint_gravity", "joint_idx", "gravity"), &SkeletonModification2DJiggle::set_jiggle_joint_gravity);549ClassDB::bind_method(D_METHOD("get_jiggle_joint_gravity", "joint_idx"), &SkeletonModification2DJiggle::get_jiggle_joint_gravity);550551ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_nodepath", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_target_node", "get_target_node");552ADD_PROPERTY(PropertyInfo(Variant::INT, "jiggle_data_chain_length", PROPERTY_HINT_RANGE, "0,100,1"), "set_jiggle_data_chain_length", "get_jiggle_data_chain_length");553ADD_GROUP("Default Joint Settings", "");554ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stiffness"), "set_stiffness", "get_stiffness");555ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass"), "set_mass", "get_mass");556ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0, 1, 0.01"), "set_damping", "get_damping");557ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_gravity"), "set_use_gravity", "get_use_gravity");558ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity");559ADD_GROUP("", "");560}561562SkeletonModification2DJiggle::SkeletonModification2DJiggle() {563stack = nullptr;564is_setup = false;565jiggle_data_chain = Vector<Jiggle_Joint_Data2D>();566stiffness = 3;567mass = 0.75;568damping = 0.75;569use_gravity = false;570gravity = Vector2(0, 6.0);571enabled = true;572editor_draw_gizmo = false; // Nothing to really show in a gizmo right now.573}574575SkeletonModification2DJiggle::~SkeletonModification2DJiggle() {576}577578579