1 /*************************************************************************/
2 /* bone_attachment.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30 #include "bone_attachment.h"
31
_get(const StringName & p_name,Variant & r_ret) const32 bool BoneAttachment::_get(const StringName &p_name, Variant &r_ret) const {
33
34 if (String(p_name) == "bone_name") {
35
36 r_ret = get_bone_name();
37 return true;
38 }
39
40 return false;
41 }
_set(const StringName & p_name,const Variant & p_value)42 bool BoneAttachment::_set(const StringName &p_name, const Variant &p_value) {
43
44 if (String(p_name) == "bone_name") {
45
46 set_bone_name(p_value);
47 return true;
48 }
49
50 return false;
51 }
_get_property_list(List<PropertyInfo> * p_list) const52 void BoneAttachment::_get_property_list(List<PropertyInfo> *p_list) const {
53
54 Skeleton *parent = NULL;
55 if (get_parent())
56 parent = get_parent()->cast_to<Skeleton>();
57
58 if (parent) {
59
60 String names;
61 for (int i = 0; i < parent->get_bone_count(); i++) {
62 if (i > 0)
63 names += ",";
64 names += parent->get_bone_name(i);
65 }
66
67 p_list->push_back(PropertyInfo(Variant::STRING, "bone_name", PROPERTY_HINT_ENUM, names));
68 } else {
69
70 p_list->push_back(PropertyInfo(Variant::STRING, "bone_name"));
71 }
72 }
73
_check_bind()74 void BoneAttachment::_check_bind() {
75
76 if (get_parent() && get_parent()->cast_to<Skeleton>()) {
77 Skeleton *sk = get_parent()->cast_to<Skeleton>();
78 int idx = sk->find_bone(bone_name);
79 if (idx != -1) {
80 sk->bind_child_node_to_bone(idx, this);
81 set_transform(sk->get_bone_global_pose(idx));
82 bound = true;
83 }
84 }
85 }
86
_check_unbind()87 void BoneAttachment::_check_unbind() {
88
89 if (bound) {
90
91 if (get_parent() && get_parent()->cast_to<Skeleton>()) {
92 Skeleton *sk = get_parent()->cast_to<Skeleton>();
93 int idx = sk->find_bone(bone_name);
94 if (idx != -1) {
95 sk->unbind_child_node_from_bone(idx, this);
96 }
97 }
98 bound = false;
99 }
100 }
101
set_bone_name(const String & p_name)102 void BoneAttachment::set_bone_name(const String &p_name) {
103
104 if (is_inside_tree())
105 _check_unbind();
106
107 bone_name = p_name;
108
109 if (is_inside_tree())
110 _check_bind();
111 }
112
get_bone_name() const113 String BoneAttachment::get_bone_name() const {
114
115 return bone_name;
116 }
117
_notification(int p_what)118 void BoneAttachment::_notification(int p_what) {
119
120 switch (p_what) {
121
122 case NOTIFICATION_ENTER_TREE: {
123
124 _check_bind();
125 } break;
126 case NOTIFICATION_EXIT_TREE: {
127
128 _check_unbind();
129 } break;
130 }
131 }
132
BoneAttachment()133 BoneAttachment::BoneAttachment() {
134 bound = false;
135 }
136
_bind_methods()137 void BoneAttachment::_bind_methods() {
138 ObjectTypeDB::bind_method(_MD("set_bone_name", "bone_name"), &BoneAttachment::set_bone_name);
139 ObjectTypeDB::bind_method(_MD("get_bone_name"), &BoneAttachment::get_bone_name);
140 }
141