summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Strapp <matt@mattstrapp.net>2021-11-10 13:40:26 -0600
committerMatt Strapp <matt@mattstrapp.net>2021-11-10 13:40:26 -0600
commit4be57d24a1fe1540527c4fc80e978cbace528958 (patch)
tree86e8f20ec08f2b6ca8d25c4a13ad74363914708d
parentMerge branch 'support-code' of https://github.umn.edu/umn-csci-4611-f21/share... (diff)
downloadcsci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar.gz
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar.bz2
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar.lz
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar.xz
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.tar.zst
csci4611-db7eec693336edd7ed8e6d61d0b116d2e408b671.zip
-rw-r--r--dev/a4-dance/animated_character.cc89
-rw-r--r--dev/a4-dance/dance_app.cc31
-rw-r--r--worksheets/a4_dance.md18
3 files changed, 114 insertions, 24 deletions
diff --git a/dev/a4-dance/animated_character.cc b/dev/a4-dance/animated_character.cc
index 110dbbe..84edcde 100644
--- a/dev/a4-dance/animated_character.cc
+++ b/dev/a4-dance/animated_character.cc
@@ -181,7 +181,9 @@ void AnimatedCharacter::DrawBoneRecursive(const std::string &bone_name, const Ma
Third, with the rotations applied relative to the appropriate rotation axes, the vertices must now be transformed back into regular "bone space". At this point, the bone should be properly rotated based upon the current pose, but the vertices are still defined in "bone space" so they are close to the origin.
Finally, the vertices need to be tranformed to the bone's parent space.
-
+ */
+
+ /*
To start, we give you a current transformation matrix (ctm) that only takes this last step into account.
*/
Matrix4 ctm = parent_transform;
@@ -192,41 +194,108 @@ void AnimatedCharacter::DrawBoneRecursive(const std::string &bone_name, const Ma
// character, but once you add the recursive call to draw the children, this
// will draw the axes for each bone.
Matrix4 S = Matrix4::Scale(Vector3(0.15f, 0.15f, 0.15f));
- quick_shapes_.DrawAxes(ctm * S, view_matrix, proj_matrix);
+ // quick_shapes_.DrawAxes(ctm * S, view_matrix, proj_matrix);
// TODO: Eventually, you'll want to draw something different depending on which part
// of the body is being drawn. An if statement like this is an easy way to do that.
if (bone_name == "lhipjoint" || bone_name == "rhipjoint") {
+ Matrix4 hipjoint = Matrix4::Scale(Vector3(0.15f, 0.15f, 0.15f));
+ quick_shapes_.DrawSphere(ctm * hipjoint, view_matrix, proj_matrix, Color(0,0,0));
}
if (bone_name == "lfemur" || bone_name == "rfemur") {
+ Matrix4 femur_sc = Matrix4::Scale(Vector3(0.15f, 0.2f, 0.2f));
+ Matrix4 femur_tr = Matrix4::Translation(Vector3(0, -0.5f, 0));
+ Matrix4 femur_rt = Matrix4::RotationZ(GfxMath::ToRadians(30.0f));
+ quick_shapes_.DrawSphere(ctm * femur_sc * femur_rt * femur_tr, view_matrix, proj_matrix, Color(0, 0, 0));
}
if (bone_name == "ltibia" || bone_name == "rtibia") {
+ if (bone_name == "ltibia") {
+ Matrix4 tibia_sc = Matrix4::Scale(Vector3(0.1f, 0.4f, 0.1f));
+ Matrix4 tibia_tr = Matrix4::Translation(Vector3(0.0f, -0.5f, 0.0f));
+ Matrix4 tibia_rt = Matrix4::RotationZ(GfxMath::ToRadians(30.0f));
+ quick_shapes_.DrawSphere(ctm * tibia_sc * tibia_rt * tibia_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+ else {
+ Matrix4 tibia_sc = Matrix4::Scale(Vector3(0.1f, 0.4f, 0.1f));
+ Matrix4 tibia_tr = Matrix4::Translation(Vector3(0.0f, -0.5f, 0.0f));
+ Matrix4 tibia_rt = Matrix4::RotationZ(GfxMath::ToRadians(-30.0f));
+ quick_shapes_.DrawSphere(ctm * tibia_sc * tibia_rt * tibia_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+
}
- if (bone_name == "lfoot" || bone_name == "rfoot") {
- }
- if (bone_name == "ltoes" || bone_name == "rtoes") {
- }
+ //Feet did not render properly, get rid of them
if (bone_name == "lowerback") {
+ Matrix4 lowerback_sc = Matrix4::Scale(Vector3(0.15f, 0.15f, 0.15f));
+ Matrix4 lowerback_tr = Matrix4::Translation(Vector3(0.0f, -1.0f, 0.0f));
+ quick_shapes_.DrawSphere(ctm * lowerback_sc * lowerback_tr, view_matrix, proj_matrix, Color(0, 0, 0));
}
if (bone_name == "upperback") {
+ quick_shapes_.DrawLineSegment(ctm * S, view_matrix, proj_matrix, Color(0, 0, 0), Point3(0, 0.4, 0), Point3(0, -0.4, 0), 0.8);
}
if (bone_name == "thorax") {
+ quick_shapes_.DrawLineSegment(ctm * S, view_matrix, proj_matrix, Color(0, 0, 0), Point3(0, 0.4, 0), Point3(0, -0.4, 0), 0.6);
}
if (bone_name == "lowerneck" || bone_name == "upperneck") {
+ quick_shapes_.DrawLineSegment(ctm * S, view_matrix, proj_matrix, Color(0, 0, 0), Point3(0, 0.4, 0), Point3(0, -0.4, 0), 0.2);
}
if (bone_name == "head") {
+ Matrix4 head_sc = Matrix4::Scale(Vector3(0.15f, 0.2f, 0.15f));
+ quick_shapes_.DrawSphere(ctm * head_sc, view_matrix, proj_matrix, Color(0, 0, 0));
}
if (bone_name == "lclavicle" || bone_name == "rclavicle") {
+ Matrix4 clavicle_sc = Matrix4::Scale(Vector3(0.2f, 0.1f, 0.1f));
+ quick_shapes_.DrawSphere(ctm * clavicle_sc, view_matrix, proj_matrix, Color(0, 0, 0));
}
if (bone_name == "lhumerus" || bone_name == "rhumerus" || bone_name == "lradius" || bone_name == "rradius") {
+ if (bone_name == "lhumerus" || bone_name == "rhumerus") {
+ Matrix4 humerus_sc = Matrix4::Scale(Vector3(0.08f, 0.04f, 0.04f));
+ quick_shapes_.DrawSphere(ctm * humerus_sc, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+ else {
+ if (bone_name == "rradius") {
+ Matrix4 radius_sc = Matrix4::Scale(Vector3(0.15f, 0.05f, 0.05f));
+ Matrix4 radius_rt = Matrix4::RotationZ(GfxMath::ToRadians(-90.0f));
+ Matrix4 radius_tr = Matrix4::Translation(Vector3(0.0f, 1.0f, 0.0f));
+ quick_shapes_.DrawCylinder(ctm * radius_sc * radius_rt * radius_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+ else {
+ Matrix4 radius_sc = Matrix4::Scale(Vector3(0.15f, 0.05f, 0.05f));
+ Matrix4 radius_rt = Matrix4::RotationZ(GfxMath::ToRadians(90.0f));
+ Matrix4 radius_tr = Matrix4::Translation(Vector3(0.0f, 1.0f, 0.0f));
+ quick_shapes_.DrawCylinder(ctm * radius_sc * radius_rt * radius_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+ }
}
if (bone_name == "lwrist" || bone_name == "rwrist") {
+ if (bone_name == "lwrist") {
+ Matrix4 wrist_sc = Matrix4::Scale(Vector3(0.1f, 0.05f, 0.05f));
+ Matrix4 wrist_tr = Matrix4::Translation(Vector3(-0.5f, 0.0f, 0.0f));
+ quick_shapes_.DrawSphere(ctm * wrist_sc * wrist_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+ else {
+ Matrix4 wrist_sc = Matrix4::Scale(Vector3(0.1f, 0.05f, 0.05f));
+ Matrix4 wrist_tr = Matrix4::Translation(Vector3(0.5f, 0.0f, 0.0f));
+ quick_shapes_.DrawSphere(ctm * wrist_sc * wrist_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
+
}
if (bone_name == "lhand" || bone_name == "rhand" || bone_name == "lthumb" || bone_name == "rthumb" || bone_name == "rfingers" || bone_name == "lfingers") {
+ if (bone_name == "lhand" || bone_name == "rhand") {
+ Matrix4 hand_sc = Matrix4::Scale(Vector3(0.05f, 0.05f, 0.05f));
+ quick_shapes_.DrawSphere(ctm * hand_sc, view_matrix, proj_matrix, Color(0, 0, 0));
+ } else if (bone_name == "lthumb" || bone_name == "rthumb") {
+ Matrix4 thumb_sc = Matrix4::Scale(Vector3(0.03f, 0.03f, 0.03f));
+ Matrix4 thumb_tr = Matrix4::Translation(Vector3(1.0f, 0.0f, 0.0f));
+ quick_shapes_.DrawCylinder(ctm * thumb_sc * thumb_tr, view_matrix, proj_matrix, Color(0, 0, 0));
+ } else if (bone_name == "rfingers" || bone_name == "lfingers") {
+ Matrix4 fingers_sc = Matrix4::Scale(Vector3(0.01f, 0.01f, 0.01f));
+ quick_shapes_.DrawCylinder(ctm * fingers_sc, view_matrix, proj_matrix, Color(0, 0, 0));
+ }
}
+
// Step 2: Draw the bone's children
/**
@@ -239,7 +308,13 @@ void AnimatedCharacter::DrawBoneRecursive(const std::string &bone_name, const Ma
DrawBoneRecursive(skeleton_.child_bone(bone_name, i), child_root_transform, view_matrix, proj_matrix);
}
**/
-}
+ CalcCurrentPose();
+ Matrix4 child_root_transform = ctm * skeleton_.RotAxesSpaceToBoneSpace(bone_name) * pose_.JointRotation(bone_name) * skeleton_.BoneSpaceToRotAxesSpace(bone_name) * skeleton_.BoneSpaceToChildrenSpace(bone_name);
+
+ for (int i=0; i<skeleton_.num_children(bone_name); i++) {
+ DrawBoneRecursive(skeleton_.child_bone(bone_name, i), child_root_transform, view_matrix, proj_matrix);
+ }
+}
diff --git a/dev/a4-dance/dance_app.cc b/dev/a4-dance/dance_app.cc
index 84f394a..3393cec 100644
--- a/dev/a4-dance/dance_app.cc
+++ b/dev/a4-dance/dance_app.cc
@@ -62,10 +62,25 @@ DanceApp::DanceApp() : GraphicsApp(1280,768, "So You Think Ants Can Dance") {
// 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.
-
-
-
-
+ ballet_special2_.LoadFromAMC(Platform::FindFile("05_10.amc", searchPath_), *ballet_ant_.skeleton_ptr());
+ ballet_special2_.TrimFront(280);
+ ballet_special2_.TrimBack(200);
+ ballet_special2_.CalcRelativeTranslations();
+
+ ballet_special3_.LoadFromAMC(Platform::FindFile("05_09.amc", searchPath_), *ballet_ant_.skeleton_ptr());
+ ballet_special3_.TrimFront(280);
+ ballet_special3_.TrimBack(200);
+ ballet_special3_.CalcRelativeTranslations();
+
+ ballet_special4_.LoadFromAMC(Platform::FindFile("05_20.amc", searchPath_), *ballet_ant_.skeleton_ptr());
+ ballet_special4_.TrimFront(280);
+ ballet_special4_.TrimBack(200);
+ ballet_special4_.CalcRelativeTranslations();
+
+ ballet_special5_.LoadFromAMC(Platform::FindFile("05_06.amc", searchPath_), *ballet_ant_.skeleton_ptr());
+ ballet_special5_.TrimFront(280);
+ ballet_special5_.TrimBack(200);
+ ballet_special5_.CalcRelativeTranslations();
// 3. Start the base loop motion
ballet_ant_.Play(ballet_base_loop_);
@@ -121,22 +136,22 @@ void DanceApp::OnMotion1BtnPressed() {
void DanceApp::OnMotion2BtnPressed() {
// TODO: add a call similar to this:
- // ballet_ant_.OverlayClip(ballet_special2_, 100);
+ ballet_ant_.OverlayClip(ballet_special2_, 100);
}
void DanceApp::OnMotion3BtnPressed() {
// TODO: add a call similar to this:
- // ballet_ant_.OverlayClip(ballet_special3_, 100);
+ ballet_ant_.OverlayClip(ballet_special3_, 100);
}
void DanceApp::OnMotion4BtnPressed() {
// TODO: add a call similar to this:
- // ballet_ant_.OverlayClip(ballet_special4_, 100);
+ ballet_ant_.OverlayClip(ballet_special4_, 100);
}
void DanceApp::OnMotion5BtnPressed() {
// TODO: add a call similar to this:
- // ballet_ant_.OverlayClip(ballet_special5_, 100);
+ ballet_ant_.OverlayClip(ballet_special5_, 100);
}
void DanceApp::UpdateSimulation(double dt) {
diff --git a/worksheets/a4_dance.md b/worksheets/a4_dance.md
index fe174fe..6e0cd85 100644
--- a/worksheets/a4_dance.md
+++ b/worksheets/a4_dance.md
@@ -11,7 +11,7 @@ Here's what the house looks like when viewed from some +Z height above and looki
### Q1.1 Basic translation
Here's a simple translation matrix. Draw a picture of the house to show what it would look like if transformed by this matrix.
-```
+```cpp
Matrix4 trans = Matrix4::Translation(Vector3(0.0, 0.5, 0.0));
```
![House transformed by trans](file path to your image)
@@ -19,7 +19,7 @@ Matrix4 trans = Matrix4::Translation(Vector3(0.0, 0.5, 0.0));
### Q1.2 Basic scaling
Here's a simple scaling matrix. Draw a picture to show what the original house would look like if transformed by this matrix.
-```
+```cpp
Matrix4 scale = Matrix4::Scale(Vector3(2.0, 1.0, 1.0));
```
![House transformed by scale](file path to your image)
@@ -27,7 +27,7 @@ Matrix4 scale = Matrix4::Scale(Vector3(2.0, 1.0, 1.0));
### Q1.3 Basic rotation
Here's a simple rotation matrix. Draw a picture to show what the original house would look like if transformed by this matrix.
-```
+```cpp
Matrix4 rot = Matrix4::RotateZ(GfxMath::toRadians(45.0));
```
![House transformed by rot](file path to your image)
@@ -36,7 +36,7 @@ Matrix4 rot = Matrix4::RotateZ(GfxMath::toRadians(45.0));
### Q1.4 Composition 1
Now, let's take a look at different compositions of the basic matrices above. Draw a picture to show what the original house would look like if transformed by the following matrix.
-```
+```cpp
Matrix4 combo1 = trans * scale * rot;
```
![House transformed by combo1](file path to your image)
@@ -45,7 +45,7 @@ Matrix4 combo1 = trans * scale * rot;
### Q1.5 Composition 2
Let's try another. Draw a picture to show what the original house would look like if transformed by the following matrix.
-```
+```cpp
Matrix4 combo2 = rot * scale * trans;
```
![House transformed by combo2](file path to your image)
@@ -66,7 +66,7 @@ The diagram below illustrates this concept with the simple case of a house. It'
It can be useful in these situations to define transformation matrices for moving from one coordinate space to another. For example, given some point defined in the door's coordinate system, such as one of the vertices of the door, we could transform it into the siding's coordinate system like this:
-```
+```cpp
// Transforms points in the door's coordinate system to the siding's coordinate system.
Matrix4 doorToSiding = Matrix4::Translation(Vector3(0.5, -0.2, 0.0));
@@ -76,7 +76,7 @@ Point3 theSamePtExpressedInSidingSpace = doorToSiding * ptInDoorSpace;
```
Similarly, these matrices can convert between the other spaces we've talked about.
-```
+```cpp
// Transforms points in the siding's coordinate system to the house's coordinate system.
Matrix4 sidingToHouse = Matrix4::Translation(Vector3(0.0, 0.5, 0.0));
@@ -92,7 +92,7 @@ show the combined transformation from Door-Space into World-Space as a matrix
multiplication, then show how to transform the point `pInDoorSpace` into
World-Space. Lastly, show the numeric representation of `pInWorldSpace`.
-```
+```cpp
// The magenta point `p` from the diagram, in Door-Space
Point3 pInDoorSpace = Point3(0.2, 0.4, 0.0);
@@ -105,7 +105,7 @@ Point3 pInWorldSpace = /* --- Fill this in --- */
### Q2.2 Let's double-check your work now by calculate the actual "world space" coordinates for p. Show what the following code would output:
-```
+```cpp
std::cout << "p in World-Space: " << pInWorldSpace << std::endl;
/* --- Fill in output for std::cout here --- */
```