glm::eulerAngleZXY vs glm::yawPitchRoll


template
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXY
(
T const & t1,
T const & t2,
T const & t3
)
{
T c1 = glm::cos(t1);
T s1 = glm::sin(t1);
T c2 = glm::cos(t2);
T s2 = glm::sin(t2);
T c3 = glm::cos(t3);
T s3 = glm::sin(t3);

mat<4, 4, T, defaultp> Result;
Result[0][0] = c1 * c3 – s1 * s2 * s3;
Result[0][1] = c3 * s1 + c1 * s2 * s3;
Result[0][2] =-c2 * s3;
Result[0][3] = static_cast(0);
Result[1][0] =-c2 * s1;
Result[1][1] = c1 * c2;
Result[1][2] = s2;
Result[1][3] = static_cast(0);
Result[2][0] = c1 * s3 + c3 * s1 * s2;
Result[2][1] = s1 * s3 – c1 * c3 * s2;
Result[2][2] = c2 * c3;
Result[2][3] = static_cast(0);
Result[3][0] = static_cast(0);
Result[3][1] = static_cast(0);
Result[3][2] = static_cast(0);
Result[3][3] = static_cast(1);
return Result;
}

template
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> yawPitchRoll
(
T const& yaw,
T const& pitch,
T const& roll
)
{
T tmp_ch = glm::cos(yaw);
T tmp_sh = glm::sin(yaw);
T tmp_cp = glm::cos(pitch);
T tmp_sp = glm::sin(pitch);
T tmp_cb = glm::cos(roll);
T tmp_sb = glm::sin(roll);

mat<4, 4, T, defaultp> Result;
Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
Result[0][1] = tmp_sb * tmp_cp;
Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
Result[0][3] = static_cast(0);
Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
Result[1][1] = tmp_cb * tmp_cp;
Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
Result[1][3] = static_cast(0);
Result[2][0] = tmp_sh * tmp_cp;
Result[2][1] = -tmp_sp;
Result[2][2] = tmp_ch * tmp_cp;
Result[2][3] = static_cast(0);
Result[3][0] = static_cast(0);
Result[3][1] = static_cast(0);
Result[3][2] = static_cast(0);
Result[3][3] = static_cast(1);
return Result;
}

Catmull Rom Spline

https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline


// Loop around the total time if necessary
if (elapsedTime >= endTime) {
    if (loop) {
        while (elapsedTime > endTime)
            elapsedTime -= endTime;
    }
    else {
        position = frames[frames.size() - 1].position;
        return;
    }
}

int i = 0;
// Find the index of the current frame
while (frames[i+1].time < elapsedTime) i++;
	
// Find the time since the beginning of this frame
elapsedTime -= frames[i].time;

// Find how far we are between the current and next frame (0 to 1)
float fraction = (float)(elapsedTime / (frames[i + 1].time - frames[i].time));

// Interpolate position and rotation values between frames
position = glm::catmullRom (
                   frames[wrap(i - 1, frames.size() - 1)].position,
                   frames[wrap(i, frames.size() - 1)].position,
                   frames[wrap(i + 1, frames.size() - 1)].position,
                   frames[wrap(i + 2, frames.size() - 1)].position,
                   fraction);
template<typename genType> 
GLM_FUNC_QUALIFIER genType catmullRom(
		genType const& v1,
		genType const& v2,
		genType const& v3,
		genType const& v4,
		typename genType::value_type const& s
	) {
    typename genType::value_type s2 = pow2(s);
    typename genType::value_type s3 = pow3(s);

    typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s;
    typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2);
    typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s;
    typename genType::value_type f4 = s3 - s2;

    return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2);
}

http://www.lighthouse3d.com/tutorials/maths/catmull-rom-spline/

f(x) = [1, x, x^2, x^3] * M * [v1, v2, v3, v4]

/* Coefficients for Matrix M */
#define M11	 0.0
#define M12	 1.0
#define M13	 0.0
#define M14	 0.0
#define M21	-0.5
#define M22	 0.0
#define M23	 0.5
#define M24	 0.0
#define M31	 1.0
#define M32	-2.5
#define M33	 2.0
#define M34	-0.5
#define M41	-0.5
#define M42	 1.5
#define M43	-1.5
#define M44	 0.5

double catmullRomSpline(float x, float v1,float v2, float v3,float v4) {
	double c1,c2,c3,c4;

	c1 =  	      M12*v2;
	c2 = M21*v1          + M23*v3;
	c3 = M31*v1 + M32*v2 + M33*v3 + M34*v4;
	c4 = M41*v1 + M42*v2 + M43*v3 + M44*v4;

	return(((c4*x + c3)*x +c2)*x + c1);
}

lab6

lab6-GeometryPositionColorSimpleCar-src

SimpleCar::SimpleCar()
{
angle = 0.0f; // 0~360
direction = 1.0f; // +/-1
position = glm::vec3(-3.0f, 0.0f, 0.0f);

init();
}

void SimpleCar::init()
{
body = Parallelepiped(glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 1.0f, 0.0f));
body.setColor(glm::vec3(0.0f, 1.0f, 0.0f));
wheel[0] = Torus(glm::vec3(0.0f, 0.0f, .0f), 0.3f, 0.1f, 32, 16);
wheel[0].setColor(glm::vec3(1.0f, 0.0f, 0.0f));
wheel[1] = Torus(glm::vec3(0.0f, 0.0f, .0f), 0.3f, 0.1f, 32, 16);
wheel[1].setColor(glm::vec3(0.0f, 0.0f, 1.0f));

bodyTransform = glm::translate(glm::mat4(1.0f), position); // RHS x+ right
wheelTransform[0] = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.0f, -0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[1] = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.0f, 0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[2] = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.0f, -0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[3] = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.0f, 0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
}

void SimpleCar::draw(Program* p, glm::mat4& projection, glm::mat4& view, glm::mat4& model)
{
p->useProgram();
p->setUniform(“gProjection”, projection);
p->setUniform(“gView”, view);

glm::mat4 carMatrix = model * bodyTransform;
p->setUniform(“gModel”, carMatrix);
body.draw();

glm::mat4 wheelMatrix = model * bodyTransform * wheelTransform[0];
p->setUniform(“gModel”, wheelMatrix);
wheel[0].draw();

wheelMatrix = model * bodyTransform * wheelTransform[1];
p->setUniform(“gModel”, wheelMatrix);
wheel[0].draw();

wheelMatrix = model * bodyTransform * wheelTransform[2];
p->setUniform(“gModel”, wheelMatrix);
wheel[1].draw();

wheelMatrix = model * bodyTransform * wheelTransform[3];
p->setUniform(“gModel”, wheelMatrix);
wheel[1].draw();
}

bool SimpleCar::update(float deltaTime)
{
angle = angle – 180.0f * (float) (deltaTime) * 0.001f * direction;
position[0] = position[0] + (float) (deltaTime) * 0.001f * direction;

//std::cout << “position[0]=” << position[0] << std::endl;
if (position[0] * direction > 3)
direction = -direction;

bodyTransform = glm::translate(glm::mat4(1.0f), position); // RHS x+ right
wheelTransform[0] = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.0f, -0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[1] = glm::translate(glm::mat4(1.0f), glm::vec3(-0.5f, 0.0f, 0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[2] = glm::translate(glm::mat4(1.0f), glm::vec3( 0.5f, 0.0f, -0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
wheelTransform[3] = glm::translate(glm::mat4(1.0f), glm::vec3( 0.5f, 0.0f, 0.5f)) * glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));

return true;
}

 

lab5

lab5-GeometryPositionColorComposeTransformation-src

// MVP matrix
Projection = glm::perspective(g_fovy, g_aspect, g_zNear, g_zFar);
View = glm::lookAt(g_eye, g_at, g_up);
spMain.useProgram();
spMain.setUniform(“gProjection”, Projection);
spMain.setUniform(“gView”, View);

// p’ = M3 * M2 * M1 * p (OpenGL uses Column-Major Order)
glm::mat4 Tx = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)); // RHS x+ right
glm::mat4 Rz = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 0.0f, 1.0f)); // RHS z+ (X->Y rotation)
glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(2.0f, 2.0f, 2.0f)); // RHS

World = glm::mat4(1.0f);
spMain.setUniform(“gModel”, World);
cube1->draw();

// p’= R T p (red) => translate, and then rotate
glm::mat4 RT = Rz * Tx;
World = RT;
spMain.setUniform(“gModel”, World);
cube2->draw();

// p’= T R p (green) => rotate, and then translate
glm::mat4 TR = Tx * Rz;
World = TR;
spMain.setUniform(“gModel”, World);
cube3->draw();

// p’= T R S p (blue) => scale, and then rotate, and then translate
glm::mat4 TRS = Tx * Rz * S;
World = TRS;
spMain.setUniform(“gModel”, World);
cube4->draw();

// p’= S R T p (cyan) => translate, and then rotate, and then scale
glm::mat4 SRT = S * Rz * Tx;
World = SRT;
spMain.setUniform(“gModel”, World);
cube5->draw();

// p’= Ra p (yellow green) => rotate by arbitrary axis
glm::mat4 Ra = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(1.0f, 1.0f, 1.0f)));
World = Ra;
spMain.setUniform(“gModel”, World);
cube6->draw();