Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
9a34f39d
Commit
9a34f39d
authored
Feb 21, 2020
by
Juan Linietsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for named binds in Skin.
Helps better reutilization of skeletons from Maya exported files.
parent
851cb429
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
110 additions
and
8 deletions
+110
-8
editor_scene_importer_gltf.cpp
editor/import/editor_scene_importer_gltf.cpp
+12
-3
editor_scene_importer_gltf.h
editor/import/editor_scene_importer_gltf.h
+3
-0
resource_importer_scene.cpp
editor/import/resource_importer_scene.cpp
+4
-0
resource_importer_scene.h
editor/import/resource_importer_scene.h
+2
-1
skeleton.cpp
scene/3d/skeleton.cpp
+44
-2
skeleton.h
scene/3d/skeleton.h
+5
-0
skin.cpp
scene/resources/skin.cpp
+29
-1
skin.h
scene/resources/skin.h
+11
-1
No files found.
editor/import/editor_scene_importer_gltf.cpp
View file @
9a34f39d
...
...
@@ -2183,6 +2183,8 @@ Error EditorSceneImporterGLTF::_map_skin_joints_indices_to_skeleton_bone_indices
const
GLTFNodeIndex
node_i
=
skin
.
joints_original
[
joint_index
];
const
GLTFNode
*
node
=
state
.
nodes
[
node_i
];
skin
.
joint_i_to_name
.
insert
(
joint_index
,
node
->
name
);
const
int
bone_index
=
skeleton
.
godot_skeleton
->
find_bone
(
node
->
name
);
ERR_FAIL_COND_V
(
bone_index
<
0
,
FAILED
);
...
...
@@ -2204,12 +2206,18 @@ Error EditorSceneImporterGLTF::_create_skins(GLTFState &state) {
const
bool
has_ibms
=
!
gltf_skin
.
inverse_binds
.
empty
();
for
(
int
joint_i
=
0
;
joint_i
<
gltf_skin
.
joints_original
.
size
();
++
joint_i
)
{
int
bone_i
=
gltf_skin
.
joint_i_to_bone_i
[
joint_i
];
Transform
xform
;
if
(
has_ibms
)
{
skin
->
add_bind
(
bone_i
,
gltf_skin
.
inverse_binds
[
joint_i
]);
xform
=
gltf_skin
.
inverse_binds
[
joint_i
];
}
if
(
state
.
use_named_skin_binds
)
{
StringName
name
=
gltf_skin
.
joint_i_to_name
[
joint_i
];
skin
->
add_named_bind
(
name
,
xform
);
}
else
{
skin
->
add_bind
(
bone_i
,
Transform
());
int
bone_i
=
gltf_skin
.
joint_i_to_bone_i
[
joint_i
];
skin
->
add_bind
(
bone_i
,
xform
);
}
}
...
...
@@ -2995,6 +3003,7 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
state
.
major_version
=
version
.
get_slice
(
"."
,
0
).
to_int
();
state
.
minor_version
=
version
.
get_slice
(
"."
,
1
).
to_int
();
state
.
use_named_skin_binds
=
p_flags
&
IMPORT_USE_NAMED_SKIN_BINDS
;
/* STEP 0 PARSE SCENE */
Error
err
=
_parse_scenes
(
state
);
...
...
editor/import/editor_scene_importer_gltf.h
View file @
9a34f39d
...
...
@@ -231,6 +231,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
// A mapping from the joint indices (in the order of joints_original) to the
// Godot Skeleton's bone_indices
Map
<
int
,
int
>
joint_i_to_bone_i
;
Map
<
int
,
StringName
>
joint_i_to_name
;
// The Actual Skin that will be created as a mapping between the IBM's of this skin
// to the generated skeleton for the mesh instances.
...
...
@@ -298,6 +299,8 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
int
minor_version
;
Vector
<
uint8_t
>
glb_data
;
bool
use_named_skin_binds
;
Vector
<
GLTFNode
*>
nodes
;
Vector
<
Vector
<
uint8_t
>
>
buffers
;
Vector
<
GLTFBufferView
>
buffer_views
;
...
...
editor/import/resource_importer_scene.cpp
View file @
9a34f39d
...
...
@@ -1171,6 +1171,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
INT
,
"meshes/storage"
,
PROPERTY_HINT_ENUM
,
"Built-In,Files (.mesh),Files (.tres)"
),
meshes_out
?
1
:
0
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
INT
,
"meshes/light_baking"
,
PROPERTY_HINT_ENUM
,
"Disabled,Enable,Gen Lightmaps"
,
PROPERTY_USAGE_DEFAULT
|
PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED
),
0
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
REAL
,
"meshes/lightmap_texel_size"
,
PROPERTY_HINT_RANGE
,
"0.001,100,0.001"
),
0.1
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
BOOL
,
"skins/use_named_skins"
),
true
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
BOOL
,
"external_files/store_in_subdir"
),
false
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
BOOL
,
"animation/import"
,
PROPERTY_HINT_NONE
,
""
,
PROPERTY_USAGE_DEFAULT
|
PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED
),
true
));
r_options
->
push_back
(
ImportOption
(
PropertyInfo
(
Variant
::
REAL
,
"animation/fps"
,
PROPERTY_HINT_RANGE
,
"1,120,1"
),
15
));
...
...
@@ -1313,6 +1314,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
if
(
int
(
p_options
[
"materials/location"
])
==
0
)
import_flags
|=
EditorSceneImporter
::
IMPORT_MATERIALS_IN_INSTANCES
;
if
(
bool
(
p_options
[
"skins/use_named_skins"
]))
import_flags
|=
EditorSceneImporter
::
IMPORT_USE_NAMED_SKIN_BINDS
;
Error
err
=
OK
;
List
<
String
>
missing_deps
;
// for now, not much will be done with this
Node
*
scene
=
importer
->
import_scene
(
src_path
,
import_flags
,
fps
,
&
missing_deps
,
&
err
);
...
...
editor/import/resource_importer_scene.h
View file @
9a34f39d
...
...
@@ -59,7 +59,8 @@ public:
IMPORT_GENERATE_TANGENT_ARRAYS
=
256
,
IMPORT_FAIL_ON_MISSING_DEPENDENCIES
=
512
,
IMPORT_MATERIALS_IN_INSTANCES
=
1024
,
IMPORT_USE_COMPRESSION
=
2048
IMPORT_USE_COMPRESSION
=
2048
,
IMPORT_USE_NAMED_SKIN_BINDS
=
4096
,
};
...
...
scene/3d/skeleton.cpp
View file @
9a34f39d
...
...
@@ -41,6 +41,7 @@ void SkinReference::_skin_changed() {
if
(
skeleton_node
)
{
skeleton_node
->
_make_dirty
();
}
skeleton_version
=
0
;
}
void
SkinReference
::
_bind_methods
()
{
...
...
@@ -322,10 +323,49 @@ void Skeleton::_notification(int p_what) {
if
(
E
->
get
()
->
bind_count
!=
bind_count
)
{
VS
::
get_singleton
()
->
skeleton_allocate
(
skeleton
,
bind_count
);
E
->
get
()
->
bind_count
=
bind_count
;
E
->
get
()
->
skin_bone_indices
.
resize
(
bind_count
);
E
->
get
()
->
skin_bone_indices_ptrs
=
E
->
get
()
->
skin_bone_indices
.
ptrw
();
}
if
(
E
->
get
()
->
skeleton_version
!=
version
)
{
for
(
uint32_t
i
=
0
;
i
<
bind_count
;
i
++
)
{
StringName
bind_name
=
skin
->
get_bind_name
(
i
);
if
(
bind_name
!=
StringName
())
{
//bind name used, use this
bool
found
=
false
;
for
(
int
j
=
0
;
j
<
len
;
j
++
)
{
if
(
bonesptr
[
j
].
name
==
bind_name
)
{
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
=
j
;
found
=
true
;
break
;
}
}
if
(
!
found
)
{
ERR_PRINT
(
"Skin bind #"
+
itos
(
i
)
+
" contains named bind '"
+
String
(
bind_name
)
+
"' but Skeleton has no bone by that name."
);
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
=
0
;
}
}
else
if
(
skin
->
get_bind_bone
(
i
)
>=
0
)
{
int
bind_index
=
skin
->
get_bind_bone
(
i
);
if
(
bind_index
>=
len
)
{
ERR_PRINT
(
"Skin bind #"
+
itos
(
i
)
+
" contains bone index bind: "
+
itos
(
bind_index
)
+
" , which is greater than the skeleton bone count: "
+
itos
(
len
)
+
"."
);
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
=
0
;
}
else
{
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
=
bind_index
;
}
}
else
{
ERR_PRINT
(
"Skin bind #"
+
itos
(
i
)
+
" does not contain a name nor a bone index."
);
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
=
0
;
}
}
E
->
get
()
->
skeleton_version
=
version
;
}
for
(
uint32_t
i
=
0
;
i
<
bind_count
;
i
++
)
{
uint32_t
bone_index
=
skin
->
get_bind_bone
(
i
)
;
uint32_t
bone_index
=
E
->
get
()
->
skin_bone_indices_ptrs
[
i
]
;
ERR_CONTINUE
(
bone_index
>=
(
uint32_t
)
len
);
vs
->
skeleton_bone_set_transform
(
skeleton
,
i
,
bonesptr
[
bone_index
].
pose_global
*
skin
->
get_bind_pose
(
i
));
}
...
...
@@ -388,6 +428,7 @@ void Skeleton::add_bone(const String &p_name) {
b
.
name
=
p_name
;
bones
.
push_back
(
b
);
process_order_dirty
=
true
;
version
++
;
_make_dirty
();
update_gizmo
();
}
...
...
@@ -539,7 +580,7 @@ void Skeleton::clear_bones() {
bones
.
clear
();
process_order_dirty
=
true
;
version
++
;
_make_dirty
();
}
...
...
@@ -894,6 +935,7 @@ Skeleton::Skeleton() {
animate_physical_bones
=
true
;
dirty
=
false
;
version
=
1
;
process_order_dirty
=
true
;
}
...
...
scene/3d/skeleton.h
View file @
9a34f39d
...
...
@@ -51,6 +51,9 @@ class SkinReference : public Reference {
RID
skeleton
;
Ref
<
Skin
>
skin
;
uint32_t
bind_count
=
0
;
uint64_t
skeleton_version
=
0
;
Vector
<
uint32_t
>
skin_bone_indices
;
uint32_t
*
skin_bone_indices_ptrs
;
void
_skin_changed
();
protected
:
...
...
@@ -123,6 +126,8 @@ private:
void
_make_dirty
();
bool
dirty
;
uint64_t
version
;
// bind helpers
Array
_get_bound_child_nodes_to_bone
(
int
p_bone
)
const
{
...
...
scene/resources/skin.cpp
View file @
9a34f39d
...
...
@@ -45,6 +45,24 @@ void Skin::add_bind(int p_bone, const Transform &p_pose) {
set_bind_pose
(
index
,
p_pose
);
}
void
Skin
::
add_named_bind
(
const
String
&
p_name
,
const
Transform
&
p_pose
)
{
uint32_t
index
=
bind_count
;
set_bind_count
(
bind_count
+
1
);
set_bind_name
(
index
,
p_name
);
set_bind_pose
(
index
,
p_pose
);
}
void
Skin
::
set_bind_name
(
int
p_index
,
const
StringName
&
p_name
)
{
ERR_FAIL_INDEX
(
p_index
,
bind_count
);
bool
notify_change
=
(
binds_ptr
[
p_index
].
name
!=
StringName
())
!=
(
p_name
!=
StringName
());
binds_ptr
[
p_index
].
name
=
p_name
;
emit_changed
();
if
(
notify_change
)
{
_change_notify
();
}
}
void
Skin
::
set_bind_bone
(
int
p_index
,
int
p_bone
)
{
ERR_FAIL_INDEX
(
p_index
,
bind_count
);
binds_ptr
[
p_index
].
bone
=
p_bone
;
...
...
@@ -75,6 +93,9 @@ bool Skin::_set(const StringName &p_name, const Variant &p_value) {
if
(
what
==
"bone"
)
{
set_bind_bone
(
index
,
p_value
);
return
true
;
}
else
if
(
what
==
"name"
)
{
set_bind_name
(
index
,
p_value
);
return
true
;
}
else
if
(
what
==
"pose"
)
{
set_bind_pose
(
index
,
p_value
);
return
true
;
...
...
@@ -95,6 +116,9 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
if
(
what
==
"bone"
)
{
r_ret
=
get_bind_bone
(
index
);
return
true
;
}
else
if
(
what
==
"name"
)
{
r_ret
=
get_bind_name
(
index
);
return
true
;
}
else
if
(
what
==
"pose"
)
{
r_ret
=
get_bind_pose
(
index
);
return
true
;
...
...
@@ -105,7 +129,8 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
void
Skin
::
_get_property_list
(
List
<
PropertyInfo
>
*
p_list
)
const
{
p_list
->
push_back
(
PropertyInfo
(
Variant
::
INT
,
"bind_count"
,
PROPERTY_HINT_RANGE
,
"0,16384,1,or_greater"
));
for
(
int
i
=
0
;
i
<
get_bind_count
();
i
++
)
{
p_list
->
push_back
(
PropertyInfo
(
Variant
::
INT
,
"bind/"
+
itos
(
i
)
+
"/bone"
,
PROPERTY_HINT_RANGE
,
"0,16384,1,or_greater"
));
p_list
->
push_back
(
PropertyInfo
(
Variant
::
STRING
,
"bind/"
+
itos
(
i
)
+
"/name"
,
PROPERTY_HINT_RANGE
,
"0,16384,1,or_greater"
));
p_list
->
push_back
(
PropertyInfo
(
Variant
::
INT
,
"bind/"
+
itos
(
i
)
+
"/bone"
,
PROPERTY_HINT_RANGE
,
"0,16384,1,or_greater"
,
get_bind_name
(
i
)
!=
StringName
()
?
PROPERTY_USAGE_NOEDITOR
:
PROPERTY_USAGE_DEFAULT
));
p_list
->
push_back
(
PropertyInfo
(
Variant
::
TRANSFORM
,
"bind/"
+
itos
(
i
)
+
"/pose"
));
}
}
...
...
@@ -120,6 +145,9 @@ void Skin::_bind_methods() {
ClassDB
::
bind_method
(
D_METHOD
(
"set_bind_pose"
,
"bind_index"
,
"pose"
),
&
Skin
::
set_bind_pose
);
ClassDB
::
bind_method
(
D_METHOD
(
"get_bind_pose"
,
"bind_index"
),
&
Skin
::
get_bind_pose
);
ClassDB
::
bind_method
(
D_METHOD
(
"set_bind_name"
,
"bind_index"
,
"name"
),
&
Skin
::
set_bind_name
);
ClassDB
::
bind_method
(
D_METHOD
(
"get_bind_name"
,
"bind_index"
),
&
Skin
::
get_bind_name
);
ClassDB
::
bind_method
(
D_METHOD
(
"set_bind_bone"
,
"bind_index"
,
"bone"
),
&
Skin
::
set_bind_bone
);
ClassDB
::
bind_method
(
D_METHOD
(
"get_bind_bone"
,
"bind_index"
),
&
Skin
::
get_bind_bone
);
...
...
scene/resources/skin.h
View file @
9a34f39d
...
...
@@ -37,7 +37,8 @@ class Skin : public Resource {
GDCLASS
(
Skin
,
Resource
)
struct
Bind
{
int
bone
;
int
bone
=
-
1
;
StringName
name
;
Transform
pose
;
};
...
...
@@ -58,9 +59,11 @@ public:
inline
int
get_bind_count
()
const
{
return
bind_count
;
}
void
add_bind
(
int
p_bone
,
const
Transform
&
p_pose
);
void
add_named_bind
(
const
String
&
p_name
,
const
Transform
&
p_pose
);
void
set_bind_bone
(
int
p_index
,
int
p_bone
);
void
set_bind_pose
(
int
p_index
,
const
Transform
&
p_pose
);
void
set_bind_name
(
int
p_index
,
const
StringName
&
p_name
);
inline
int
get_bind_bone
(
int
p_index
)
const
{
#ifdef DEBUG_ENABLED
...
...
@@ -69,6 +72,13 @@ public:
return
binds_ptr
[
p_index
].
bone
;
}
inline
StringName
get_bind_name
(
int
p_index
)
const
{
#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V
(
p_index
,
bind_count
,
StringName
());
#endif
return
binds_ptr
[
p_index
].
name
;
}
inline
Transform
get_bind_pose
(
int
p_index
)
const
{
#ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V
(
p_index
,
bind_count
,
Transform
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment