Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Hands-On C++ Game Animation Programming

You're reading from   Hands-On C++ Game Animation Programming Learn modern animation techniques from theory to implementation with C++ and OpenGL

Arrow left icon
Product type Paperback
Published in Jun 2020
Publisher Packt
ISBN-13 9781800208087
Length 368 pages
Edition 1st Edition
Languages
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Gabor Szauer Gabor Szauer
Author Profile Icon Gabor Szauer
Gabor Szauer
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface 1. Chapter 1: Creating a Game Window 2. Chapter 2: Implementing Vectors FREE CHAPTER 3. Chapter 3: Implementing Matrices 4. Chapter 4: Implementing Quaternions 5. Chapter 5: Implementing Transforms 6. Chapter 6: Building an Abstract Renderer 7. Chapter 7: Exploring the glTF File Format 8. Chapter 8: Creating Curves, Frames, and Tracks 9. Chapter 9: Implementing Animation Clips 10. Chapter 10: Mesh Skinning 11. Chapter 11: Optimizing the Animation Pipeline 12. Chapter 12: Blending between Animations 13. Chapter 13: Implementing Inverse Kinematics 14. Chapter 14: Using Dual Quaternions for Skinning 15. Chapter 15: Rendering Instanced Crowds 16. Other Books You May Enjoy

Understanding component-wise operations

Several vector operations are just component-wise operations. A component-wise operation is one that you perform on each component of a vector or on like components of two vectors. Like components are components that have the same subscript. The component-wise operations that you will implement are as follows:

  • Vector addition
  • Vector subtraction
  • Vector scaling
  • Multiplying vectors
  • Dot product

Let's look at each of these in more detail.

Vector addition

Adding two vectors together yields a third vector, which has the combined displacement of both input vectors. Vector addition is a component-wise operation; to perform it, you need to add like components.

To visualize the addition of two vectors, draw the base of the second vector at the tip of the first vector. Next, draw an arrow from the base of the first vector to the tip of the second vector. This arrow represents the vector that is the result of the addition:

Figure 2.2: Vector addition

To implement vector addition in code, add like components of the input vectors. Create a new file, vec3.cpp. This is where you will define functions related to the vec3 struct. Don't forget to include vec3.h. Overload the + operator to perform vector addition. Don't forget to add the function signature to vec3.h:

vec3 operator+(const vec3 &l, const vec3 &r) {
    return vec3(l.x + r.x, l.y + r.y, l.z + r.z);
}

When thinking about vector addition, remember that a vector represents a displacement. When adding two vectors, the result is the combined displacement of both input vectors.

Vector subtraction

As with adding vectors, subtracting vectors is also a component-wise operation. You can think of subtracting vectors as adding the negative of the second vector to the first vector. When visualized as an arrow, subtraction points from the tip of the second vector to the tip of the first one.

To visually subtract vectors, place both vectors so they share the same origin. Draw a vector from the tip of the second arrow to the tip of the first one. The resulting arrow is the subtraction result vector:

Figure 2.3: Vector subtraction

Figure 2.3: Vector subtraction

To implement vector subtraction, subtract like components. Implement the subtraction function by overloading the - operator in vec3.cpp. Don't forget to add the function declaration to vec3.h:

vec3 operator-(const vec3 &l, const vec3 &r) {
    return vec3(l.x - r.x, l.y - r.y, l.z - r.z);
}

The steps and logic are very similar to vector addition. It might help to think of vector subtraction as adding a negative vector.

Scaling vectors

When a vector is scaled, it only changes in magnitude, not direction. As with addition and subtraction, scaling is a component-wise operation. Unlike addition and subtraction, a vector is scaled by a scalar, not another vector.

Visually, a scaled vector points in the same direction as the original vector, but it has a different length. The following figure shows two vectors: (2, 1) and (2, 4). Both vectors share the same direction, but the magnitude of the second vector is longer:

Figure 2.4: Vector scaling

Figure 2.4: Vector scaling

To implement vector scaling, multiply every component of the vector by the given scalar value.

Implement the scale function by overloading the * operator in vec3.cpp. Don't forget to add the function declaration to vec3.h:

vec3 operator*(const vec3 &v, float f) {
    return vec3(v.x * f, v.y * f, v.z * f);
}

Negating a vector can be done by scaling the vector by -1. When negating a vector, the vector maintains its magnitude but changes its direction.

Multiplying vectors

Vector multiplication can be considered a non-uniform scale. Instead of scaling every component of a vector by a scalar, to multiply two vectors, you scale every component of a vector by the like component of another vector.

You can implement vector multiplication by overloading the * operator in vec3.cpp. Don't forget to add the function declaration to vec3.h:

vec3 operator*(const vec3 &l, const vec3 &r) {
    return vec3(l.x * r.x, l.y * r.y, l.z * r.z);
}

The result generated by multiplying two vectors will have a different direction and magnitude.

Dot product

The dot product is used to measure how similar two vectors are. Given two vectors, the dot product returns a scalar value. The result of the dot product has the following properties:

  • It is positive if the vectors point in the same direction.
  • It is negative if the vectors point in opposite directions.
  • It is 0 if the vectors are perpendicular.

If both input vectors have a unit length (you will learn about unit length vectors in the Normal vectors section of this chapter), the dot product will have a range of -1 to 1.

The dot product between two vectors, A and B, is equal to the length of A multiplied by the length of B multiplied by the cosine of the angle between the two vectors:

The easiest way to calculate the dot product is to sum the products of like components in the input vectors:

Implement the dot function in vec3.cpp. Don't forget to add the function definition to vec3.h:

float dot(const vec3 &l, const vec3 &r) {
    return l.x * r.x + l.y * r.y + l.z * r.z;
}

The dot product is one of the most used operations for video games. It's often used to check angles and in lighting calculations.

With the dot product, you have implemented the common component-wise operations of vectors. Next, you will learn about some of the non-component-wise operations that can be performed on vectors.

You have been reading a chapter from
Hands-On C++ Game Animation Programming
Published in: Jun 2020
Publisher: Packt
ISBN-13: 9781800208087
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime