Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Courses
Scotty3D
Commits
1555a334
Commit
1555a334
authored
Nov 19, 2020
by
TheNumbat
Browse files
upstream changes
parent
0ec99641
Changes
14
Hide whitespace changes
Inline
Side-by-side
src/gui/animate.cpp
View file @
1555a334
...
...
@@ -26,17 +26,6 @@ void Animate::update_dim(Vec2 dim) { ui_camera.dim(dim); }
bool
Animate
::
keydown
(
Widgets
&
widgets
,
Undo
&
undo
,
Scene_ID
sel
,
SDL_Keysym
key
)
{
#ifdef __APPLE__
if
(
key
.
sym
==
SDLK_BACKSPACE
&&
key
.
mod
&
KMOD_GUI
)
{
#else
if
(
key
.
sym
==
SDLK_DELETE
)
{
#endif
if
(
joint_select
)
undo
.
del_bone
(
sel
,
joint_select
);
else
if
(
sel
)
undo
.
del_obj
(
sel
);
}
if
(
key
.
sym
==
SDLK_SPACE
)
{
playing
=
!
playing
;
last_frame
=
SDL_GetPerformanceCounter
();
...
...
@@ -76,16 +65,17 @@ void Animate::render(Scene &scene, Scene_Maybe obj_opt, Widgets &widgets, Camera
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
joint_id_offset
=
scene
.
used_ids
();
obj
.
armature
.
render
(
view
*
obj
.
pose
.
transform
(),
joint_select
,
false
,
true
,
obj
.
armature
.
render
(
view
*
obj
.
pose
.
transform
(),
joint_select
,
handle_select
,
false
,
true
,
joint_id_offset
);
if
(
!
joint_select
)
{
if
(
!
joint_select
&&
!
handle_select
)
{
R
.
begin_outline
();
BBox
box
=
obj
.
bbox
();
obj
.
render
(
view
,
false
,
true
);
obj
.
armature
.
outline
(
view
*
obj
.
pose
.
transform
(),
joint_select
,
false
,
true
,
box
,
joint_id_offset
);
obj
.
armature
.
outline
(
view
*
obj
.
pose
.
transform
(),
false
,
true
,
box
,
joint_id_offset
);
R
.
end_outline
(
view
,
box
);
}
else
if
(
handle_select
)
{
widgets
.
active
=
Widget_Type
::
move
;
}
else
{
widgets
.
active
=
Widget_Type
::
rotate
;
}
...
...
@@ -94,7 +84,12 @@ void Animate::render(Scene &scene, Scene_Maybe obj_opt, Widgets &widgets, Camera
R
.
outline
(
view
,
item
);
}
if
(
joint_select
)
{
if
(
handle_select
)
{
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
widgets
.
render
(
view
,
pose
.
transform
()
*
(
handle_select
->
target
+
obj
.
armature
.
base
()),
scale
);
}
else
if
(
joint_select
)
{
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
widgets
.
render
(
view
,
pose
.
transform
()
*
obj
.
armature
.
posed_base_of
(
joint_select
),
scale
);
...
...
@@ -150,19 +145,49 @@ void Animate::camera_spline() {
void
Animate
::
UIsidebar
(
Manager
&
manager
,
Undo
&
undo
,
Scene_Maybe
obj_opt
,
Camera
&
user_cam
)
{
if
(
joint_select
)
{
if
(
handle_select
)
{
Scene_ID
id
=
obj_opt
.
value
().
get
().
id
();
ImGui
::
Text
(
"Edit IK Handle"
);
ImGui
::
DragFloat3
(
"Pos"
,
handle_select
->
target
.
data
,
0.1
f
,
0.0
f
,
0.0
f
,
"%.2f"
);
if
(
ImGui
::
IsItemActivated
())
old_euler
=
handle_select
->
target
;
if
(
ImGui
::
IsItemDeactivatedAfterEdit
()
&&
old_euler
!=
handle_select
->
target
)
{
undo
.
move_handle
(
id
,
handle_select
,
old_euler
);
}
ImGui
::
Checkbox
(
"Enable"
,
&
handle_select
->
enabled
);
ImGui
::
Separator
();
}
else
if
(
joint_select
)
{
Scene_Item
&
item
=
obj_opt
.
value
().
get
();
Scene_ID
id
=
item
.
id
();
ImGui
::
Text
(
"Edit Joint"
);
if
(
ImGui
::
DragFloat3
(
"Pose"
,
joint_select
->
pose
.
data
,
1.0
f
,
0.0
f
,
0.0
f
,
"%.2f"
))
obj_opt
.
value
().
get
().
get
<
Scene_Object
>
().
set_pose_dirty
();
if
(
ImGui
::
IsItemActivated
())
old_euler
=
joint_select
->
pose
;
if
(
ImGui
::
IsItemDeactivatedAfterEdit
()
&&
old_euler
!=
joint_select
->
pose
)
{
joint_select
->
pose
=
joint_select
->
pose
.
range
(
0.0
f
,
360.0
f
);
undo
.
pose_bone
(
obj_opt
.
value
().
get
().
id
()
,
joint_select
,
old_euler
);
undo
.
pose_bone
(
id
,
joint_select
,
old_euler
);
}
ImGui
::
Separator
();
}
if
(
obj_opt
.
has_value
())
{
Scene_Item
&
item
=
obj_opt
.
value
().
get
();
if
(
item
.
is
<
Scene_Object
>
())
{
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
if
(
obj
.
armature
.
has_bones
())
{
if
(
obj
.
armature
.
do_ik
())
obj
.
set_pose_dirty
();
}
}
}
if
(
ui_camera
.
UI
(
undo
,
user_cam
))
{
camera_selected
=
true
;
if
(
obj_opt
.
has_value
())
...
...
@@ -171,17 +196,22 @@ void Animate::UIsidebar(Manager &manager, Undo &undo, Scene_Maybe obj_opt, Camer
}
void
Animate
::
end_transform
(
Undo
&
undo
,
Scene_Item
&
obj
)
{
if
(
joint_select
)
{
if
(
handle_select
)
{
undo
.
move_handle
(
obj
.
id
(),
handle_select
,
old_pose
.
pos
-
obj
.
get
<
Scene_Object
>
().
armature
.
base
());
}
else
if
(
joint_select
)
{
undo
.
pose_bone
(
obj
.
id
(),
joint_select
,
old_euler
);
}
else
{
undo
.
update_pose
(
obj
.
id
(),
old_pose
);
}
old_pose
=
{};
old_euler
=
{};
old_p_to_j
=
Mat4
::
I
;
}
Vec3
Animate
::
selected_pos
(
Scene_Item
&
item
)
{
if
(
joint_select
)
{
if
(
handle_select
)
{
return
item
.
pose
().
transform
()
*
(
handle_select
->
target
+
item
.
get
<
Scene_Object
>
().
armature
.
base
());
}
else
if
(
joint_select
)
{
return
item
.
pose
().
transform
()
*
item
.
get
<
Scene_Object
>
().
armature
.
posed_base_of
(
joint_select
);
}
...
...
@@ -189,7 +219,9 @@ Vec3 Animate::selected_pos(Scene_Item &item) {
}
void
Animate
::
apply_transform
(
Widgets
&
widgets
,
Scene_Item
&
item
)
{
if
(
joint_select
)
{
if
(
handle_select
)
{
handle_select
->
target
=
widgets
.
apply_action
(
old_pose
).
pos
-
item
.
get
<
Scene_Object
>
().
armature
.
base
();
}
else
if
(
joint_select
)
{
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
Vec3
euler
=
widgets
.
apply_action
(
old_pose
).
euler
;
joint_select
->
pose
=
(
old_p_to_j
*
Mat4
::
euler
(
euler
)).
to_euler
();
...
...
@@ -204,7 +236,14 @@ bool Animate::select(Scene &scene, Widgets &widgets, Scene_ID selected, Scene_ID
if
(
widgets
.
want_drag
())
{
if
(
joint_select
)
{
if
(
handle_select
)
{
Scene_Object
&
obj
=
scene
.
get_obj
(
selected
);
widgets
.
start_drag
(
handle_select
->
target
+
obj
.
armature
.
base
(),
cam
,
spos
,
dir
);
old_pose
=
{};
old_pose
.
pos
=
handle_select
->
target
+
obj
.
armature
.
base
();
}
else
if
(
joint_select
)
{
Scene_Object
&
obj
=
scene
.
get_obj
(
selected
);
Vec3
base
=
obj
.
pose
.
transform
()
*
obj
.
armature
.
posed_base_of
(
joint_select
);
...
...
@@ -238,8 +277,11 @@ bool Animate::select(Scene &scene, Widgets &widgets, Scene_ID selected, Scene_ID
Scene_ID
j_id
=
id
-
joint_id_offset
;
joint_select
=
obj
.
armature
.
get_joint
(
j_id
);
handle_select
=
obj
.
armature
.
get_handle
(
j_id
);
if
(
joint_select
)
{
widgets
.
active
=
Widget_Type
::
rotate
;
}
else
if
(
handle_select
)
{
widgets
.
active
=
Widget_Type
::
move
;
}
return
false
;
}
...
...
@@ -249,11 +291,13 @@ bool Animate::select(Scene &scene, Widgets &widgets, Scene_ID selected, Scene_ID
if
(
id
>=
n_Widget_IDs
)
{
if
(
id
==
selected
)
{
joint_select
=
nullptr
;
handle_select
=
nullptr
;
}
return
true
;
}
joint_select
=
nullptr
;
handle_select
=
nullptr
;
return
false
;
}
...
...
@@ -564,6 +608,15 @@ void Animate::refresh(Scene &scene) { set_time(scene, (float)current_frame); }
void
Animate
::
clear
()
{
anim_camera
.
splines
.
clear
();
joint_select
=
nullptr
;
handle_select
=
nullptr
;
}
void
Animate
::
invalidate
(
Skeleton
::
IK_Handle
*
handle
)
{
if
(
handle_select
==
handle
)
handle_select
=
nullptr
;
}
void
Animate
::
invalidate
(
Joint
*
j
)
{
if
(
joint_select
==
j
)
joint_select
=
nullptr
;
}
void
Animate
::
update
(
Scene
&
scene
)
{
...
...
src/gui/animate.h
View file @
1555a334
...
...
@@ -52,6 +52,8 @@ public:
const
Anim_Camera
&
camera
()
const
;
Anim_Camera
&
camera
();
void
set
(
int
n_frames
,
int
fps
);
void
invalidate
(
Skeleton
::
IK_Handle
*
handle
);
void
invalidate
(
Joint
*
handle
);
private:
Uint64
last_frame
=
0
;
...
...
@@ -66,6 +68,7 @@ private:
Anim_Camera
anim_camera
;
Joint
*
joint_select
=
nullptr
;
Skeleton
::
IK_Handle
*
handle_select
=
nullptr
;
unsigned
int
joint_id_offset
=
0
;
Pose
old_pose
;
...
...
src/gui/manager.cpp
View file @
1555a334
...
...
@@ -38,6 +38,8 @@ void Manager::invalidate_obj(Scene_ID id) {
if
(
id
==
layout
.
selected
())
{
layout
.
clear_select
();
model
.
unset_mesh
();
rig
.
clear
();
animate
.
clear
();
}
}
...
...
@@ -129,12 +131,22 @@ void Manager::save_scene(Scene &scene) {
set_error
(
error
);
}
static
bool
postfix
(
const
std
::
string
&
path
,
const
std
::
string
&
type
)
{
if
(
path
.
length
()
>=
type
.
length
())
return
path
.
compare
(
path
.
length
()
-
type
.
length
(),
type
.
length
(),
type
)
==
0
;
return
false
;
}
void
Manager
::
write_scene
(
Scene
&
scene
)
{
char
*
path
=
nullptr
;
NFD_SaveDialog
(
"dae"
,
nullptr
,
&
path
);
if
(
path
)
{
std
::
string
error
=
scene
.
write
(
std
::
string
(
path
),
render
.
get_cam
(),
animate
);
std
::
string
spath
(
path
);
if
(
!
postfix
(
path
,
".dae"
))
{
spath
+=
".dae"
;
}
std
::
string
error
=
scene
.
write
(
spath
,
render
.
get_cam
(),
animate
);
set_error
(
error
);
free
(
path
);
}
...
...
src/gui/manager.h
View file @
1555a334
...
...
@@ -39,6 +39,7 @@ struct Color {
RGBv
(
red
,
163
,
66
,
81
);
RGBv
(
green
,
124
,
172
,
40
);
RGBv
(
blue
,
64
,
127
,
193
);
RGBv
(
hoverg
,
102
,
204
,
102
);
static
Vec3
axis
(
Axis
a
);
};
#undef RGBv
...
...
src/gui/rig.cpp
View file @
1555a334
...
...
@@ -13,11 +13,17 @@ bool Rig::keydown(Widgets &widgets, Undo &undo, SDL_Keysym key) {
#ifdef __APPLE__
if
(
key
.
sym
==
SDLK_BACKSPACE
&&
key
.
mod
&
KMOD_GUI
)
{
#else
if
(
key
.
sym
==
SDLK_DELETE
&&
selected
)
{
if
(
key
.
sym
==
SDLK_DELETE
&&
(
selected
||
handle
)
)
{
#endif
undo
.
del_bone
(
my_obj
->
id
(),
selected
);
selected
=
nullptr
;
return
true
;
if
(
selected
)
{
undo
.
del_bone
(
my_obj
->
id
(),
selected
);
selected
=
nullptr
;
return
true
;
}
else
if
(
handle
)
{
undo
.
del_handle
(
my_obj
->
id
(),
handle
);
handle
=
nullptr
;
return
true
;
}
}
return
false
;
}
...
...
@@ -38,6 +44,7 @@ void Rig::render(Scene_Maybe obj_opt, Widgets &widgets, Camera &cam) {
if
(
my_obj
!=
&
obj
)
{
my_obj
=
&
obj
;
selected
=
nullptr
;
handle
=
nullptr
;
}
if
(
my_obj
->
rig_dirty
)
{
mesh_bvh
.
build
(
obj
.
mesh
());
...
...
@@ -46,15 +53,17 @@ void Rig::render(Scene_Maybe obj_opt, Widgets &widgets, Camera &cam) {
Mat4
view
=
cam
.
get_view
();
obj
.
render
(
view
,
false
,
false
,
false
,
false
);
obj
.
armature
.
render
(
view
,
selected
,
root_selected
,
false
);
obj
.
armature
.
render
(
view
,
selected
,
handle
,
root_selected
,
false
);
if
(
selected
||
root_selected
)
{
if
(
selected
||
handle
||
root_selected
)
{
widgets
.
active
=
Widget_Type
::
move
;
Vec3
pos
;
if
(
selected
)
pos
=
obj
.
armature
.
end_of
(
selected
);
else
if
(
handle
)
pos
=
handle
->
target
+
obj
.
armature
.
base
();
else
pos
=
obj
.
armature
.
base
();
...
...
@@ -70,11 +79,18 @@ void Rig::invalidate(Joint *j) {
new_joint
=
nullptr
;
}
void
Rig
::
invalidate
(
Skeleton
::
IK_Handle
*
j
)
{
if
(
handle
==
j
)
handle
=
nullptr
;
}
void
Rig
::
end_transform
(
Widgets
&
widgets
,
Undo
&
undo
,
Scene_Object
&
obj
)
{
if
(
root_selected
)
undo
.
move_root
(
obj
.
id
(),
old_
ext
);
else
undo
.
move_root
(
obj
.
id
(),
old_
pos
);
else
if
(
selected
)
undo
.
move_bone
(
obj
.
id
(),
selected
,
old_ext
);
else
if
(
handle
)
undo
.
move_handle
(
obj
.
id
(),
handle
,
old_pos
-
my_obj
->
armature
.
base
());
obj
.
set_skel_dirty
();
}
...
...
@@ -86,16 +102,23 @@ void Rig::apply_transform(Widgets &widgets) {
Vec3
new_pos
=
widgets
.
apply_action
(
Pose
::
moved
(
old_pos
)).
pos
;
selected
->
extent
=
new_pos
-
old_base
;
my_obj
->
set_skel_dirty
();
}
else
if
(
handle
)
{
Vec3
new_pos
=
widgets
.
apply_action
(
Pose
::
moved
(
old_pos
)).
pos
;
handle
->
target
=
new_pos
-
my_obj
->
armature
.
base
();
my_obj
->
set_skel_dirty
();
}
}
Vec3
Rig
::
selected_pos
()
{
if
(
root_selected
)
{
return
my_obj
->
armature
.
base
();
}
else
{
assert
(
selected
);
}
else
if
(
selected
)
{
return
my_obj
->
armature
.
end_of
(
selected
);
}
else
if
(
handle
)
{
return
handle
->
target
+
my_obj
->
armature
.
base
();
}
assert
(
false
);
return
Vec3
();
}
void
Rig
::
select
(
Scene
&
scene
,
Widgets
&
widgets
,
Undo
&
undo
,
Scene_ID
id
,
Vec3
cam
,
Vec2
spos
,
...
...
@@ -110,6 +133,7 @@ void Rig::select(Scene &scene, Widgets &widgets, Undo &undo, Scene_ID id, Vec3 c
selected
=
new_joint
;
new_joint
=
nullptr
;
handle
=
nullptr
;
creating_bone
=
false
;
root_selected
=
false
;
...
...
@@ -118,17 +142,19 @@ void Rig::select(Scene &scene, Widgets &widgets, Undo &undo, Scene_ID id, Vec3 c
if
(
root_selected
)
{
old_pos
=
my_obj
->
armature
.
base
();
}
else
{
assert
(
selected
);
}
else
if
(
selected
)
{
old_pos
=
my_obj
->
armature
.
end_of
(
selected
);
old_base
=
my_obj
->
armature
.
base_of
(
selected
);
old_ext
=
selected
->
extent
;
}
else
if
(
handle
)
{
old_pos
=
handle
->
target
+
my_obj
->
armature
.
base
();
}
widgets
.
start_drag
(
old_pos
,
cam
,
spos
,
dir
);
}
else
if
(
!
id
||
id
>=
n_Widget_IDs
)
{
selected
=
my_obj
->
armature
.
get_joint
(
id
);
handle
=
my_obj
->
armature
.
get_handle
(
id
);
root_selected
=
my_obj
->
armature
.
is_root_id
(
id
);
}
}
...
...
@@ -136,9 +162,13 @@ void Rig::select(Scene &scene, Widgets &widgets, Undo &undo, Scene_ID id, Vec3 c
void
Rig
::
clear
()
{
my_obj
=
nullptr
;
selected
=
nullptr
;
handle
=
nullptr
;
}
void
Rig
::
clear_select
()
{
selected
=
nullptr
;
}
void
Rig
::
clear_select
()
{
selected
=
nullptr
;
handle
=
nullptr
;
}
void
Rig
::
hover
(
Vec3
cam
,
Vec2
spos
,
Vec3
dir
)
{
...
...
@@ -183,6 +213,7 @@ Mode Rig::UIsidebar(Manager &manager, Undo &undo, Widgets &widgets, Scene_Maybe
if
(
my_obj
!=
&
obj
)
{
my_obj
=
&
obj
;
selected
=
nullptr
;
handle
=
nullptr
;
}
if
(
my_obj
->
rig_dirty
)
{
mesh_bvh
.
build
(
obj
.
mesh
());
...
...
@@ -196,11 +227,13 @@ Mode Rig::UIsidebar(Manager &manager, Undo &undo, Widgets &widgets, Scene_Maybe
creating_bone
=
false
;
my_obj
->
armature
.
erase
(
new_joint
);
new_joint
=
nullptr
;
handle
=
nullptr
;
my_obj
->
set_skel_dirty
();
}
}
else
if
(
ImGui
::
Button
(
"New Bone"
))
{
creating_bone
=
true
;
handle
=
nullptr
;
if
(
!
selected
||
root_selected
)
{
new_joint
=
my_obj
->
armature
.
add_root
(
Vec3
{
0.0
f
});
...
...
@@ -223,10 +256,28 @@ Mode Rig::UIsidebar(Manager &manager, Undo &undo, Widgets &widgets, Scene_Maybe
ImGui
::
DragFloat3
(
"Pose"
,
selected
->
pose
.
data
,
0.1
f
);
if
(
ImGui
::
Button
(
"Add IK"
))
{
handle
=
my_obj
->
armature
.
add_handle
(
my_obj
->
armature
.
end_of
(
selected
),
selected
);
undo
.
add_handle
(
my_obj
->
id
(),
handle
);
selected
=
nullptr
;
}
ImGui
::
SameLine
();
if
(
ImGui
::
Button
(
"Delete [del]"
))
{
undo
.
del_bone
(
my_obj
->
id
(),
selected
);
selected
=
nullptr
;
}
}
else
if
(
handle
)
{
ImGui
::
Separator
();
ImGui
::
Text
(
"Edit Handle"
);
ImGui
::
DragFloat3
(
"Target"
,
handle
->
target
.
data
,
0.1
f
);
ImGui
::
Checkbox
(
"Enable"
,
&
handle
->
enabled
);
if
(
ImGui
::
Button
(
"Delete [del]"
))
{
undo
.
del_handle
(
my_obj
->
id
(),
handle
);
handle
=
nullptr
;
}
}
return
Mode
::
rig
;
...
...
src/gui/rig.h
View file @
1555a334
...
...
@@ -25,6 +25,7 @@ public:
void
clear_select
();
void
clear
();
void
invalidate
(
Joint
*
j
);
void
invalidate
(
Skeleton
::
IK_Handle
*
j
);
void
render
(
Scene_Maybe
obj_opt
,
Widgets
&
widgets
,
Camera
&
cam
);
Mode
UIsidebar
(
Manager
&
manager
,
Undo
&
undo
,
Widgets
&
widgets
,
Scene_Maybe
obj
);
...
...
@@ -36,6 +37,7 @@ private:
Scene_Object
*
my_obj
=
nullptr
;
Joint
*
selected
=
nullptr
;
Skeleton
::
IK_Handle
*
handle
=
nullptr
;
Joint
*
new_joint
=
nullptr
;
PT
::
Tri_Mesh
mesh_bvh
;
};
...
...
src/gui/widgets.cpp
View file @
1555a334
...
...
@@ -709,6 +709,12 @@ void Widget_Render::animate(Scene &scene, Widget_Camera &cam, Camera &user_cam,
ImGui
::
End
();
}
static
bool
postfix
(
const
std
::
string
&
path
,
const
std
::
string
&
type
)
{
if
(
path
.
length
()
>=
type
.
length
())
return
path
.
compare
(
path
.
length
()
-
type
.
length
(),
type
.
length
(),
type
)
==
0
;
return
false
;
}
bool
Widget_Render
::
UI
(
Scene
&
scene
,
Widget_Camera
&
cam
,
Camera
&
user_cam
,
std
::
string
&
err
)
{
bool
ret
=
false
;
...
...
@@ -752,6 +758,11 @@ bool Widget_Render::UI(Scene &scene, Widget_Camera &cam, Camera &user_cam, std::
NFD_SaveDialog
(
"png"
,
nullptr
,
&
path
);
if
(
path
)
{
std
::
string
spath
(
path
);
if
(
!
postfix
(
spath
,
".png"
))
{
spath
+=
".png"
;
}
std
::
vector
<
unsigned
char
>
data
;
if
(
method
==
1
)
{
...
...
@@ -762,7 +773,7 @@ bool Widget_Render::UI(Scene &scene, Widget_Camera &cam, Camera &user_cam, std::
stbi_flip_vertically_on_write
(
true
);
}
if
(
!
stbi_write_png
(
path
,
(
int
)
out_w
,
(
int
)
out_h
,
4
,
data
.
data
(),
(
int
)
out_w
*
4
))
{
if
(
!
stbi_write_png
(
s
path
.
c_str
()
,
(
int
)
out_w
,
(
int
)
out_h
,
4
,
data
.
data
(),
(
int
)
out_w
*
4
))
{
err
=
"Failed to write png!"
;
}
free
(
path
);
...
...
src/scene/scene.cpp
View file @
1555a334
...
...
@@ -459,12 +459,19 @@ static void load_node(Scene &scobj, std::vector<std::string> &errors,
aiBone
*
bone
=
node_to_aibone
[
node
];
aiVector3D
t
,
r
,
s
;
bone
->
mOffsetMatrix
.
Decompose
(
s
,
r
,
t
);
Joint
*
c
=
skeleton
.
add_child
(
p
,
aiVec
(
t
));
node_to_bone
[
node
]
=
c
;
c
->
pose
=
aiVec
(
r
);
c
->
radius
=
bone
->
mWeights
[
0
].
mWeight
;
for
(
unsigned
int
j
=
0
;
j
<
node
->
mNumChildren
;
j
++
)
build_tree
(
c
,
node
->
mChildren
[
j
]);
std
::
string
name
(
bone
->
mName
.
C_Str
());
if
(
name
.
find
(
"S3D-joint-IK"
)
!=
std
::
string
::
npos
)
{
Skeleton
::
IK_Handle
*
h
=
skeleton
.
add_handle
(
aiVec
(
t
),
p
);
h
->
enabled
=
bone
->
mWeights
[
0
].
mWeight
>
1.0
f
;
}
else
{
Joint
*
c
=
skeleton
.
add_child
(
p
,
aiVec
(
t
));
node_to_bone
[
node
]
=
c
;
c
->
pose
=
aiVec
(
r
);
c
->
radius
=
bone
->
mWeights
[
0
].
mWeight
;
for
(
unsigned
int
j
=
0
;
j
<
node
->
mNumChildren
;
j
++
)
build_tree
(
c
,
node
->
mChildren
[
j
]);
}
};
for
(
unsigned
int
j
=
0
;
j
<
arm_node
->
mNumChildren
;
j
++
)
{
aiNode
*
root_node
=
arm_node
->
mChildren
[
j
];
...
...
@@ -1011,35 +1018,53 @@ std::string Scene::write(std::string file, const Camera &render_cam,
ai_mat
->
AddProperty
(
new
float
(
opt
.
intensity
),
1
,
AI_MATKEY_SHININESS
);
if
(
obj
.
armature
.
has_bones
())
{
ai_mesh
->
mNumBones
=
obj
.
armature
.
n_bones
();
ai_mesh
->
mNumBones
=
obj
.
armature
.
n_bones
()
+
obj
.
armature
.
n_handles
()
;
ai_mesh
->
mBones
=
new
aiBone
*
[
ai_mesh
->
mNumBones
];
size_t
bone_idx
=
0
;
std
::
string
prefix
=
"S3D-joint-"
+
std
::
to_string
(
obj
.
id
())
+
"-"
;
std
::
string
jprefix
=
"S3D-joint-"
+
std
::
to_string
(
obj
.
id
())
+
"-"
;
std
::
string
ikprefix
=
"S3D-joint-IK-"
+
std
::
to_string
(
obj
.
id
())
+
"-"
;
aiNode
*
arm_node
=
new
aiNode
();
scene
.
mRootNode
->
mChildren
[
node_idx
++
]
=
arm_node
;
arm_node
->
mName
=
aiString
(
prefix
+
"armature"
);
arm_node
->
mName
=
aiString
(
j
prefix
+
"armature"
);
arm_node
->
mTransformation
=
matMat
(
Mat4
::
translate
(
obj
.
armature
.
base_pos
));
arm_node
->
mNumChildren
=
(
unsigned
int
)
obj
.
armature
.
roots
.
size
();
arm_node
->
mChildren
=
new
aiNode
*
[
obj
.
armature
.
roots
.
size
()];
std
::
unordered_map
<
Joint
*
,
aiNode
*>
j_to_node
;
std
::
unordered_map
<
Skeleton
::
IK_Handle
*
,
aiNode
*>
ik_to_node
;
std
::
function
<
void
(
std
::
string
,
aiNode
*
,
Joint
*
)
>
joint_tree
;
joint_tree
=
[
&
joint_tree
,
&
j_to_node
](
std
::
string
n
,
aiNode
*
node
,
Joint
*
j
)
{
std
::
string
name
=
n
+
std
::
to_string
(
j
->
_id
);
node
->
mName
=
aiString
(
name
);
std
::
function
<
void
(
aiNode
*
,
Joint
*
)
>
joint_tree
;
joint_tree
=
[
&
](
aiNode
*
node
,
Joint
*
j
)
{
std
::
string
j
name
=
jprefix
+
std
::
to_string
(
j
->
_id
);
node
->
mName
=
aiString
(
j
name
);
j_to_node
[
j
]
=
node
;
if
(
j
->
children
.
size
())
{
node
->
mNumChildren
=
(
unsigned
int
)
j
->
children
.
size
();
node
->
mChildren
=
new
aiNode
*
[
j
->
children
.
size
()];
size_t
children
=
j
->
children
.
size
();
for
(
Skeleton
::
IK_Handle
*
h
:
obj
.
armature
.
handles
)
{
if
(
h
->
joint
==
j
)
{
children
++
;
}
}
if
(
children
>
0
)
{
node
->
mNumChildren
=
(
unsigned
int
)
children
;
node
->
mChildren
=
new
aiNode
*
[
children
];
size_t
i
=
0
;
for
(
Joint
*
c
:
j
->
children
)
{
node
->
mChildren
[
i
]
=
new
aiNode
();
joint_tree
(
n
,
node
->
mChildren
[
i
],
c
);
joint_tree
(
node
->
mChildren
[
i
],
c
);
i
++
;
}
for
(
Skeleton
::
IK_Handle
*
h
:
obj
.
armature
.
handles
)
{
if
(
h
->
joint
==
j
)
{
aiNode
*
iknode
=
new
aiNode
();
std
::
string
ikname
=
ikprefix
+
std
::
to_string
(
h
->
_id
);
iknode
->
mName
=
aiString
(
ikname
);
node
->
mChildren
[
i
]
=
iknode
;
ik_to_node
[
h
]
=
iknode
;
i
++
;
}
}
}
};
...
...
@@ -1048,7 +1073,7 @@ std::string Scene::write(std::string file, const Camera &render_cam,
aiNode
*
root_node
=
new
aiNode
();
arm_node
->
mChildren
[
i
]
=
root_node
;
j_to_node
[
j
]
=
root_node
;
joint_tree
(
prefix
,
root_node
,
j
);
joint_tree
(
root_node
,
j
);
i
++
;
}
...
...
@@ -1061,12 +1086,23 @@ std::string Scene::write(std::string file, const Camera &render_cam,
ai_mesh
->
mBones
[
bone_idx
++
]
=
bone
;
bone
->
mOffsetMatrix
=
matMat
(
Mat4
::
translate
(
j
->
extent
)
*
Mat4
::
euler
(
j
->
pose
));
bone
->
mNode
=
j_to_node
[
j
];
std
::
string
name
=
prefix
+
std
::
to_string
(
j
->
_id
);
std
::
string
name
=
j
prefix
+
std
::
to_string
(
j
->
_id
);
bone
->
mName
=
aiString
(
name
);
bone
->
mNumWeights
=
1
;
bone
->
mWeights
=
new
aiVertexWeight
[
1
];
bone
->
mWeights
[
0
].
mWeight
=
j
->
radius
;
});
for
(
Skeleton
::
IK_Handle
*
h
:
obj
.
armature
.
handles
)
{
aiBone
*
bone
=
new
aiBone
();
ai_mesh
->
mBones
[
bone_idx
++
]
=
bone
;
bone
->
mOffsetMatrix
=
matMat
(
Mat4
::
translate
(
h
->
target
));
bone
->
mNode
=
ik_to_node
[
h
];
std
::
string
ikname
=
ikprefix
+
std
::
to_string
(
h
->
_id
);
bone
->
mName
=
aiString
(
ikname
);
bone
->
mNumWeights
=
1
;
bone
->
mWeights
=
new
aiVertexWeight
[
1
];
bone
->
mWeights
[
0
].
mWeight
=
h
->
enabled
?
2.0
f
:
1.0
f
;
}
}
}
else
if
(
entry
.
second
.
is
<
Scene_Light
>
())
{
...
...
src/scene/skeleton.cpp
View file @
1555a334
...
...
@@ -24,8 +24,12 @@ Skeleton::Skeleton(unsigned int obj_id) {
Skeleton
::~
Skeleton
()
{
for
(
Joint
*
j
:
roots
)
delete
j
;
for
(
Joint
*
j
:
erased
)
delete
j
;
for
(
auto
&
e
:
erased
)
delete
e
.
first
;
for
(
IK_Handle
*
h
:
handles
)
delete
h
;
for
(
IK_Handle
*
h
:
erased_handles
)
delete
h
;
}
bool
Skeleton
::
set_time
(
float
time
)
{
...
...
@@ -57,6 +61,15 @@ void Skeleton::crop(float t) {
for_joints
([
t
](
Joint
*
j
)
{
j
->
anim
.
crop
(
t
);
});
}
Skeleton
::
IK_Handle
*
Skeleton
::
get_handle
(
unsigned
int
id
)
{
IK_Handle
*
j
=
nullptr
;
for
(
IK_Handle
*
h
:
handles
)
{
if
(
h
->
_id
==
id
)
j
=
h
;
}
return
j
;
}
Joint
*
Skeleton
::
get_joint
(
unsigned
int
id
)
{
Joint
*
j
=
nullptr
;
for_joints
([
&
](
Joint
*
jt
)
{
...
...
@@ -66,7 +79,7 @@ Joint *Skeleton::get_joint(unsigned int id) {
return
j
;
}
void
Skeleton
::
render
(
const
Mat4
&
view
,
Joint
*
select
,
bool
root
,
bool
posed
,
unsigned
int
offset
)
{
void
Skeleton
::
render
(
const
Mat4
&
view
,
Joint
*
jselect
,
IK_Handle
*
h
select
,
bool
root
,
bool
posed
,
unsigned
int
offset
)
{
Renderer
&
R
=
Renderer
::
get
();
...
...
@@ -81,41 +94,55 @@ void Skeleton::render(const Mat4 &view, Joint *select, bool root, bool posed, un
R
.
capsule
(
opt
,
j
->
extent
.
norm
(),
j
->
radius
);
});
if
(
select
)
{
if
(
j
select
)
{
R
.
begin_outline
();
Mat4
model
=
Mat4
::
translate
(
base_pos
)
*
(
posed
?
select
->
joint_to_posed
()
:
select
->
joint_to_bind
())
*
Mat4
::
rotate_to
(
select
->
extent
);
(
posed
?
j
select
->
joint_to_posed
()
:
j
select
->
joint_to_bind
())
*
Mat4
::
rotate_to
(
j
select
->
extent
);
Renderer
::
MeshOpt
opt
;
opt
.
modelview
=
view
;
opt
.
id
=
select
->
_id
+
offset
;
opt
.
id
=
j
select
->
_id
+
offset
;
opt
.
depth_only
=
true
;
BBox
box
;
R
.
capsule
(
opt
,
model
,
select
->
extent
.
norm
(),
select
->
radius
,
box
);
R
.
capsule
(
opt
,
model
,
j
select
->
extent
.
norm
(),
j
select
->
radius
,
box
);
R
.
end_outline
(
view
,
box
);
}
R
.
reset_depth
();
Renderer
::
MeshOpt
opt
;
opt
.
id
=
root_id
+
offset
;
opt
.
modelview
=
V
*
Mat4
::
scale
(
Vec3
{
0.1
f
});
opt
.
color
=
root
?
Gui
::
Color
::
outline
:
Gui
::
Color
::
hover
;
R
.
sphere
(
opt
);
{
Renderer
::
MeshOpt
opt
;
opt
.
id
=
root_id
+
offset
;
opt
.
modelview
=
V
*
Mat4
::
scale
(
Vec3
{
0.1
f
});
opt
.
color
=
root
?
Gui
::
Color
::
outline
:
Gui
::
Color
::
hover
;
R
.
sphere
(
opt
);
}
for_joints
([
&
](
Joint
*
j
)
{
Renderer
::
MeshOpt
opt
;
opt
.
modelview
=
V
*
(
posed
?
j
->
joint_to_posed
()
:
j
->
joint_to_bind
())
*
Mat4
::
translate
(
j
->
extent
)
*
Mat4
::
scale
(
Vec3
{
j
->
radius
*
0.25
f
});
opt
.
id
=
j
->
_id
+
offset
;
opt
.
color
=
select
==
j
?
Gui
::
Color
::
outline
:
Gui
::
Color
::
hover
;
opt
.
color
=
j
select
==
j
?
Gui
::
Color
::
outline
:
Gui
::
Color
::
hover
;
R
.
sphere
(
opt
);
});
GL
::
Lines
ik_lines
;
for
(
IK_Handle
*
h
:
handles
)
{
Renderer
::
MeshOpt
opt
;
opt
.
modelview
=
V
*
Mat4
::
translate
(
h
->
target
)
*
Mat4
::
scale
(
Vec3
{
h
->
joint
->
radius
*
0.3
f
});
opt
.
id
=
h
->
_id
+
offset
;
opt
.
color
=
hselect
==
h
?
Gui
::
Color
::
outline
:
Gui
::
Color
::
hoverg
;
Vec3
j_world
=
posed
?
posed_end_of
(
h
->
joint
)
:
end_of
(
h
->
joint
);
ik_lines
.
add
(
h
->
target
,
j_world
-
base_pos
,
h
->
enabled
?
Vec3
(
1.0
f
,
0.0
f
,
0.0
f
)
:
Vec3
(
0.0
f
));
R
.
sphere
(
opt
);
}
R
.
lines
(
ik_lines
,
V
);
}
void
Skeleton
::
outline
(
const
Mat4
&
view
,
Joint
*
select
,
bool
root
,
bool
posed
,
BBox
&
box
,
void
Skeleton
::
outline
(
const
Mat4
&
view
,
bool
root
,
bool
posed
,
BBox
&
box
,
unsigned
int
offset
)
{
Renderer
&
R
=
Renderer
::
get
();
...
...
@@ -145,6 +172,10 @@ unsigned int Skeleton::n_bones() {
return
n
;
}
unsigned
int
Skeleton
::
n_handles
()
{
return
(
unsigned
int
)
handles
.
size
();
}
Vec3
&
Skeleton
::
base
()
{
return
base_pos
;
}
Joint
*
Skeleton
::
add_child
(
Joint
*
j
,
Vec3
e
)
{
...
...
@@ -162,6 +193,13 @@ void Skeleton::restore(Joint *j) {
}
else
{
roots
.
insert
(
j
);
}
auto
entry
=
erased
.
find
(
j
);
assert
(
entry
!=
erased
.
end
());
for
(
IK_Handle
*
handle
:
entry
->
second
)
{
restore
(
handle
);
}
erased
.
erase
(
j
);
}
...
...
@@ -171,7 +209,16 @@ void Skeleton::erase(Joint *j) {
}
else
{
roots
.
erase
(
j
);
}
erased
.
insert
(
j
);
std
::
vector
<
IK_Handle
*>
herase
;
for
(
IK_Handle
*
h
:
handles
)
{
if
(
h
->
joint
==
j
)
{
herase
.
push_back
(
h
);
}
}
for
(
IK_Handle
*
h
:
herase
)
{
erase
(
h
);
}
erased
.
insert
({
j
,
std
::
move
(
herase
)});
}
Vec3
Skeleton
::
posed_base_of
(
Joint
*
j
)
{
return
j
->
is_root
()
?
base
()
:
posed_end_of
(
parent
(
j
));
}
...
...
@@ -216,3 +263,32 @@ std::unordered_map<unsigned int, Vec3> Skeleton::at(float t) {
void
Skeleton
::
set
(
float
t
,
const
std
::
unordered_map
<
unsigned
int
,
Vec3
>
&
data
)
{
for_joints
([
&
data
,
t
](
Joint
*
j
)
{
j
->
anim
.
set
(
t
,
Quat
::
euler
(
data
.
at
(
j
->
_id
)));
});
}
void
Skeleton
::
restore
(
IK_Handle
*
h
)
{
handles
.
insert
(
h
);
erased_handles
.
erase
(
h
);
}
void
Skeleton
::
erase
(
IK_Handle
*
h
)
{
handles
.
erase
(
h
);
erased_handles
.
insert
(
h
);
}
Skeleton
::
IK_Handle
*
Skeleton
::
add_handle
(
Vec3
pos
,
Joint
*
j
)
{
IK_Handle
*
handle
=
new
IK_Handle
{
pos
-
base_pos
,
j
,
false
,
next_id
++
};
handles
.
insert
(
handle
);
return
handle
;
}
bool
Skeleton
::
do_ik
()
{
std
::
vector
<
IK_Handle
*>
enabled
;
for
(
IK_Handle
*
h
:
handles
)
{
if
(
h
->
enabled
)
{
enabled
.
push_back
(
h
);
}
}
if
(
enabled
.
empty
())
return
false
;
step_ik
(
std
::
move
(
enabled
));
return
true
;
}
src/scene/skeleton.h
View file @
1555a334
...
...
@@ -59,6 +59,13 @@ private:
// Set of child joints - owned by this joint (could be shared_ptr and everything else weak_ptr)
std
::
unordered_set
<
Joint
*>
children
;
// Current angle gradient for IK
Vec3
angle_gradient
;
// Computes the gradient of IK energy for this joint and, recursively,
// upward in the heirarchy, storing the result in angle_gradient.
void
compute_gradient
(
Vec3
target
,
Vec3
current
);
void
for_joints
(
std
::
function
<
void
(
Joint
*
)
>
func
);
unsigned
int
_id
=
0
;
...
...
@@ -70,6 +77,13 @@ private:
class
Skeleton
{
public:
struct
IK_Handle
{
Vec3
target
;
Joint
*
joint
=
nullptr
;
bool
enabled
=
false
;
unsigned
int
_id
=
0
;
};
Skeleton
();
Skeleton
(
unsigned
int
obj_id
);
~
Skeleton
();
...
...
@@ -80,36 +94,51 @@ public:
void
operator
=
(
const
Skeleton
&
src
)
=
delete
;
Skeleton
&
operator
=
(
Skeleton
&&
src
)
=
default
;
////////////////////////////////////////////
// You will implement these functions
Vec3
end_of
(
Joint
*
j
);
Vec3
posed_end_of
(
Joint
*
j
);
void
step_ik
(
std
::
vector
<
IK_Handle
*>
active_handles
);
Mat4
joint_to_bind
(
const
Joint
*
j
)
const
;
Mat4
joint_to_posed
(
const
Joint
*
j
)
const
;
void
find_joints
(
const
GL
::
Mesh
&
src
,
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
);
void
skin
(
const
GL
::
Mesh
&
input
,
GL
::
Mesh
&
output
,
const
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
);
////////////////////////////////////////////
Vec3
&
base
();
bool
has_bones
()
const
;
unsigned
int
n_bones
();
unsigned
int
n_handles
();
Joint
*
parent
(
Joint
*
j
);
Joint
*
get_joint
(
unsigned
int
id
);
void
erase
(
Joint
*
j
);
void
restore
(
Joint
*
j
);
Vec3
end_of
(
Joint
*
j
);
Vec3
base_of
(
Joint
*
j
);
Vec3
posed_end_of
(
Joint
*
j
);
Vec3
posed_base_of
(
Joint
*
j
);
void
for_joints
(
std
::
function
<
void
(
Joint
*
)
>
func
);
Mat4
joint_to_bind
(
const
Joint
*
j
)
const
;
Mat4
joint_to_posed
(
const
Joint
*
j
)
const
;
void
erase
(
IK_Handle
*
handle
);
void
restore
(
IK_Handle
*
handle
);
IK_Handle
*
get_handle
(
unsigned
int
id
);
IK_Handle
*
add_handle
(
Vec3
pos
,
Joint
*
j
);
bool
do_ik
();
Joint
*
add_root
(
Vec3
extent
);
Joint
*
add_child
(
Joint
*
j
,
Vec3
extent
);
bool
is_root_id
(
unsigned
int
id
);
bool
set_time
(
float
time
);
void
render
(
const
Mat4
&
view
,
Joint
*
select
,
bool
root
,
bool
posed
,
unsigned
int
offset
=
0
);
void
outline
(
const
Mat4
&
view
,
Joint
*
select
,
bool
root
,
bool
posed
,
BBox
&
box
,
unsigned
int
offset
=
0
);
void
find_joints
(
const
GL
::
Mesh
&
src
,
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
);
void
skin
(
const
GL
::
Mesh
&
input
,
GL
::
Mesh
&
output
,
const
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
);
void
render
(
const
Mat4
&
view
,
Joint
*
jselect
,
IK_Handle
*
hselect
,
bool
root
,
bool
posed
,
unsigned
int
offset
=
0
);
void
outline
(
const
Mat4
&
view
,
bool
root
,
bool
posed
,
BBox
&
box
,
unsigned
int
offset
=
0
);
void
set
(
float
t
);
void
crop
(
float
t
);
...
...
@@ -123,6 +152,8 @@ public:
private:
Vec3
base_pos
;
unsigned
int
root_id
,
next_id
;
std
::
unordered_set
<
Joint
*>
roots
,
erased
;
std
::
unordered_set
<
Joint
*>
roots
;
std
::
unordered_map
<
Joint
*
,
std
::
vector
<
IK_Handle
*>>
erased
;
std
::
unordered_set
<
IK_Handle
*>
handles
,
erased_handles
;
friend
class
Scene
;
};
src/scene/undo.cpp
View file @
1555a334
...
...
@@ -74,6 +74,28 @@ void Undo::del_bone(Scene_ID id, Joint *j) {
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
erase
(
j
);
gui
.
get_rig
().
invalidate
(
j
);
gui
.
get_animate
().
invalidate
(
j
);
obj
.
set_skel_dirty
();
},
[
this
,
id
,
j
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
restore
(
j
);
obj
.
set_skel_dirty
();
});
}
void
Undo
::
del_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
)
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
erase
(
j
);
obj
.
set_skel_dirty
();
action
(
[
this
,
id
,
j
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
erase
(
j
);
gui
.
get_animate
().
invalidate
(
j
);
gui
.
get_rig
().
invalidate
(
j
);
obj
.
set_skel_dirty
();
},
[
this
,
id
,
j
]()
{
...
...
@@ -97,6 +119,20 @@ void Undo::move_bone(Scene_ID id, Joint *j, Vec3 old) {
});
}
void
Undo
::
move_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
,
Vec3
old
)
{
action
(
[
this
,
id
,
j
,
ne
=
j
->
target
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
j
->
target
=
ne
;
obj
.
set_skel_dirty
();
},
[
this
,
id
,
j
,
oe
=
old
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
j
->
target
=
oe
;
obj
.
set_skel_dirty
();
});
}
void
Undo
::
pose_bone
(
Scene_ID
id
,
Joint
*
j
,
Vec3
old
)
{
action
(
[
this
,
id
,
j
,
ne
=
j
->
pose
]()
{
...
...
@@ -111,6 +147,22 @@ void Undo::pose_bone(Scene_ID id, Joint *j, Vec3 old) {
});
}
void
Undo
::
add_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
)
{
action
(
[
this
,
id
,
j
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
restore
(
j
);
obj
.
set_skel_dirty
();
},
[
this
,
id
,
j
]()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
erase
(
j
);
gui
.
get_rig
().
invalidate
(
j
);
gui
.
get_animate
().
invalidate
(
j
);
obj
.
set_skel_dirty
();
});
}
void
Undo
::
add_bone
(
Scene_ID
id
,
Joint
*
j
)
{
action
(
...
...
@@ -123,6 +175,7 @@ void Undo::add_bone(Scene_ID id, Joint *j) {
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
armature
.
erase
(
j
);
gui
.
get_rig
().
invalidate
(
j
);
gui
.
get_animate
().
invalidate
(
j
);
obj
.
set_skel_dirty
();
});
}
...
...
src/scene/undo.h
View file @
1555a334
...
...
@@ -59,9 +59,12 @@ public:
void
update_pose
(
Scene_ID
id
,
Pose
old
);
void
del_bone
(
Scene_ID
id
,
Joint
*
j
);
void
del_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
);
void
add_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
);
void
add_bone
(
Scene_ID
id
,
Joint
*
j
);
void
move_bone
(
Scene_ID
id
,
Joint
*
j
,
Vec3
old
);
void
pose_bone
(
Scene_ID
id
,
Joint
*
j
,
Vec3
old
);
void
move_handle
(
Scene_ID
id
,
Skeleton
::
IK_Handle
*
j
,
Vec3
old
);
void
move_root
(
Scene_ID
id
,
Vec3
old
);
void
update_light
(
Scene_ID
id
,
Scene_Light
::
Options
old
);
...
...
src/student/skeleton.cpp
View file @
1555a334
...
...
@@ -111,3 +111,19 @@ void Skeleton::skin(const GL::Mesh &input, GL::Mesh &output,
std
::
vector
<
GL
::
Mesh
::
Index
>
idxs
=
input
.
indices
();
output
.
recreate
(
std
::
move
(
verts
),
std
::
move
(
idxs
));
}
void
Joint
::
compute_gradient
(
Vec3
target
,
Vec3
current
)
{
// TODO(Animation): Task 2
// Computes the gradient of IK energy for this joint and, should be called
// recursively upward in the heirarchy. Each call should storing the result
// in the angle_gradient for this joint.
}
void
Skeleton
::
step_ik
(
std
::
vector
<
IK_Handle
*>
active_handles
)
{
// TODO(Animation): Task 2
// Do several iterations of Jacobian Transpose gradient descent for IK
}
src/util/hdr_image.cpp
View file @
1555a334
...
...
@@ -90,6 +90,8 @@ std::string HDR_Image::load_from(std::string file) {
size_t
didx
=
4
*
(
j
*
w
+
i
);
size_t
pidx
=
(
h
-
j
-
1
)
*
w
+
i
;
pixels
[
pidx
]
=
Spectrum
(
data
[
didx
],
data
[
didx
+
1
],
data
[
didx
+
2
]);
if
(
!
pixels
[
pidx
].
valid
())
pixels
[
pidx
]
=
{};
}
}
...
...
@@ -118,12 +120,12 @@ std::string HDR_Image::load_from(std::string file) {
}
stbi_image_free
(
data
);
}
for
(
size_t
i
=
0
;
i
<
pixels
.
size
();
i
++
)
{
pixels
[
i
].
make_linear
();
if
(
!
pixels
[
i
].
valid
())
pixels
[
i
]
=
{};
for
(
size_t
i
=
0
;
i
<
pixels
.
size
();
i
++
)
{
pixels
[
i
].
make_linear
();
if
(
!
pixels
[
i
].
valid
())
pixels
[
i
]
=
{};
}
}
last_path
=
file
;
...
...
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