1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
#include "dance_app.h"
#include "config.h"
#include <iostream>
#include <sstream>
DanceApp::DanceApp() : GraphicsApp(1280,768, "So You Think Ants Can Dance") {
// Define a search path for finding data files (images and shaders)
searchPath_.push_back(".");
searchPath_.push_back("./data");
searchPath_.push_back(DATA_DIR_INSTALL);
searchPath_.push_back(DATA_DIR_BUILD);
// INIT SALSA DANCING PAIR
// 1. Load skeletons
salsa_ant_male_.LoadSkeleton(Platform::FindFile("60.asf", searchPath_));
salsa_ant_male_.set_fps(60);
salsa_ant_female_.LoadSkeleton(Platform::FindFile("61.asf", searchPath_));
salsa_ant_female_.set_fps(60);
// 2. Prep the motion clips (trim, loop) the exact same way since the pair
// must be coordinated.
MotionClip male_salsa_motion;
male_salsa_motion.LoadFromAMC(Platform::FindFile("60_12.amc", searchPath_), *salsa_ant_male_.skeleton_ptr());
male_salsa_motion.TrimFront(100);
male_salsa_motion.TrimBack(150);
male_salsa_motion.MakeLoop(100);
MotionClip female_salsa_motion;
female_salsa_motion.LoadFromAMC(Platform::FindFile("61_12.amc", searchPath_), *salsa_ant_female_.skeleton_ptr());
female_salsa_motion.TrimFront(100);
female_salsa_motion.TrimBack(150);
female_salsa_motion.MakeLoop(100);
// 3. Make the animated characters play the motion clips, the clips will automatically repeat
salsa_ant_male_.Play(male_salsa_motion);
salsa_ant_female_.Play(female_salsa_motion);
// INIT BALLET DANCER
// 1. Load skeleton
ballet_ant_.LoadSkeleton(Platform::FindFile("61.asf", searchPath_));
// 2. Load the raw motion clips
ballet_base_loop_.LoadFromAMC(Platform::FindFile("05_20.amc", searchPath_), *ballet_ant_.skeleton_ptr());
ballet_base_loop_.TrimBack(600);
ballet_base_loop_.MakeLoop(50);
ballet_base_loop_.CalcRelativeTranslations();
ballet_special1_.LoadFromAMC(Platform::FindFile("05_02.amc", searchPath_), *ballet_ant_.skeleton_ptr());
ballet_special1_.TrimFront(280);
ballet_special1_.TrimBack(200);
ballet_special1_.CalcRelativeTranslations();
// TODO: Add special motions 2-5 on your own.
// You can pick your own motions from the CMU mocap database (http://mocap.cs.cmu.edu) or
// you can use the same dance moves that we did. We used:
// 05_10.amc, 05_09.amc, 05_20.amc, and 05_06.amc -- you need to trim them
// isolate the interesting portions of the motion.
// 3. Start the base loop motion
ballet_ant_.Play(ballet_base_loop_);
salsa_ants_transform_ = Matrix4::Translation(Vector3(1, 0, 0.5));
ballet_ant_transform_ = Matrix4::Translation(Vector3(-1, ballet_base_loop_.pose(0).root_position()[1], 0));
}
DanceApp::~DanceApp() {
}
void DanceApp::InitNanoGUI() {
// Setup the GUI window
nanogui::Window *window = new nanogui::Window(screen(), "Ballet Controls");
window->setPosition(Eigen::Vector2i(10, 10));
window->setSize(Eigen::Vector2i(200,100));
window->setLayout(new nanogui::GroupLayout());
nanogui::Button* btn1 = new nanogui::Button(window, "Motion 1");
btn1->setCallback(std::bind(&DanceApp::OnMotion1BtnPressed, this));
nanogui::Button* btn2 = new nanogui::Button(window, "Motion 2");
btn2->setCallback(std::bind(&DanceApp::OnMotion2BtnPressed, this));
nanogui::Button* btn3 = new nanogui::Button(window, "Motion 3");
btn3->setCallback(std::bind(&DanceApp::OnMotion3BtnPressed, this));
nanogui::Button* btn4 = new nanogui::Button(window, "Motion 4");
btn4->setCallback(std::bind(&DanceApp::OnMotion4BtnPressed, this));
nanogui::Button* btn5 = new nanogui::Button(window, "Motion 5");
btn5->setCallback(std::bind(&DanceApp::OnMotion5BtnPressed, this));
screen()->performLayout();
}
void DanceApp::InitOpenGL() {
// Set up the camera in a good position to see the scene
projMatrix_ = Matrix4::Perspective(60.0, aspect_ratio(), 0.01f, 100.0f);
viewMatrix_ = Matrix4::LookAt(Point3(0,1.5,3.5), Point3(0,1,0), Vector3(0,1,0));
glClearColor(0.5, 0.5, 0.5, 1);
bg_tex_.InitFromFile(Platform::FindFile("ants-dance.png", searchPath_));
floor_tex_.InitFromFile(Platform::FindFile("woodfloor.png", searchPath_));
}
void DanceApp::OnMotion1BtnPressed() {
ballet_ant_.OverlayClip(ballet_special1_, 100);
}
void DanceApp::OnMotion2BtnPressed() {
// TODO: add a call similar to this:
// ballet_ant_.OverlayClip(ballet_special2_, 100);
}
void DanceApp::OnMotion3BtnPressed() {
// TODO: add a call similar to this:
// ballet_ant_.OverlayClip(ballet_special3_, 100);
}
void DanceApp::OnMotion4BtnPressed() {
// TODO: add a call similar to this:
// ballet_ant_.OverlayClip(ballet_special4_, 100);
}
void DanceApp::OnMotion5BtnPressed() {
// TODO: add a call similar to this:
// ballet_ant_.OverlayClip(ballet_special5_, 100);
}
void DanceApp::UpdateSimulation(double dt) {
salsa_ant_male_.AdvanceAnimation(dt);
salsa_ant_female_.AdvanceAnimation(dt);
ballet_ant_.AdvanceAnimation(dt);
}
void DanceApp::DrawUsingOpenGL() {
quick_shapes_.DrawFullscreenTexture(Color(1,1,1), bg_tex_);
// Draw the dancing characters.
// The salsa ants are drawn using absolute positioning
salsa_ant_male_.Draw(salsa_ants_transform_, viewMatrix_, projMatrix_, true);
salsa_ant_female_.Draw(salsa_ants_transform_, viewMatrix_, projMatrix_, true);
// The ballet ant is drawn with relative positioning
ballet_ant_.Draw(ballet_ant_transform_, viewMatrix_, projMatrix_, false);
// Draw the dance floor
Matrix4 M_floor = Matrix4::Scale(Vector3(8, 1, 3));
quick_shapes_.DrawSquare(M_floor, viewMatrix_, projMatrix_, Color(1,1,1), floor_tex_);
}
|