Hi!
I'm going through the source code to the old Excess demo - Cortex Sous-vide for learning purposes (even though it is DirectX 9 the algorithms are still useful). I'm stuck on a method that is used in a few places to control the position of the camera and some other objects. I'm sure someone in here knows the theory behind this and can point me in the right direction. I'm not even sure what background reading to do.
Code is at the bottom of this post. The code should be understandable in isolation, but the full source is here
https://github.com/kusma/vlee/tree/cortex-sous-videgetCubePos is the method used to get the position for the camera in 3D. I have plotted out the points that would be returned from getCubeKeyframe in the attached image.
With this image, the getCubeKeyframe method makes a bit more sense to me.
The more confusing part to me is why 4 samples are taken, and what the tangents and those particular polynomials are for. I guess the polynomials are to make the path curved?
After a bit of research I think they are Hermite basis functions?
Thanks!
madeyes
Vector3 getCubeKeyframe(int key)
{
const Vector3 keyframes[] = {
Vector3(0, 0, 0),
Vector3(60, 0, 0),
Vector3(120, 0, 0),
Vector3(120, 60, 0),
Vector3(120, 120, 0),
Vector3(60, 120, 0),
Vector3(0, 120, 0),
Vector3(0, 120, 60),
Vector3(0, 120, 120),
Vector3(0, 60, 120),
Vector3(0, 0, 120),
Vector3(0, 0, 60),
Vector3(0, 0, 0),
Vector3(0, 0, -60),
Vector3(0, 0, -120),
Vector3(60, 0, -120),
Vector3(120, 0, -120),
Vector3(120,-60, -120),
Vector3(120,-120,-120),
Vector3(60, -120,-120),
Vector3(0, -120,-120),
Vector3(0, -120,-60),
Vector3(0, -120, 0),
Vector3(0, -60, 0)
};
return keyframes[key % ARRAY_SIZE(keyframes)] * 0.5
+ keyframes[(key - 1) % ARRAY_SIZE(keyframes)] * 0.25
+ keyframes[(key + 1) % ARRAY_SIZE(keyframes)] * 0.25;
}
Vector3 getCubePos(float cam_time)
{
int k0 = int(floor(cam_time) - 1);
int k1 = k0 + 1;
int k2 = k1 + 1;
int k3 = k2 + 1;
Vector3 samples[4] = {
getCubeKeyframe(k0), getCubeKeyframe(k1), getCubeKeyframe(k2), getCubeKeyframe(k3)
};
Vector3 tangents[2] = {
(samples[2] - samples[0]) / 2.0,
(samples[3] - samples[1]) / 2.0
};
float t = cam_time - floor(cam_time);
float t2 = t * t;
float t3 = t2 * t;
float w[4] = {
// 2t^3 - 3t^2 + 1
2.0f * t3 - 3.0f * t2 + 1.0f,
// t^3 - 2t^2 + t
1.0f * t3 - 2.0f * t2 + t,
// -2t^3 + 3t^2
w[2] = -2.0f * t3 + 3.0f * t2,
// t^3 - t^2
w[3] = 1.0f * t3 - 1.0f * t2
};
return samples[1] * w[0] +
tangents[0] * w[1] +
samples[2] * w[2] +
tangents[1] * w[3];
}