Look at behavior + Z.Vec3 and Z.Mat documentation


#1

Hey,

Any possibility of providing some docs (or hints) for functions in Z.Vec3 and Z.Mat? I’m especially interested in Z.Mat.createRotationMatrix() and Z.Mat.anglesFromRotationMatrix().

I’m trying to build up a ‘look at’ function for rotating objects towards a specified point. I’ve made a heading vector from the objects current Euler angles and another one pointing towards my target point. If I’m not entirely mistaken, I can use atan2 to get the required rotation angle and define the axis to rotate around with a cross product. My problem lies in applying this angle and rotation-axis to the Euler angles of my zappar object.

I was wondering if the Z.Mat functions could help me with this issue. Math certainly isn’t my strong suit but I still feel like I might be fairly close with this. Any help would be appreciated!


#2

Hey Ero,

Good catch, look like we missed them when documenting.

While we work on doing so the platform team provided some descriptions below which will hopefully help:

// reference: http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm
matrixFromAxisAngle(axis, angle) {
	var c = Math.cos(angle);
    var s = Math.sin(angle);
    var t = 1.0 - c;

    var m00 = c + axis[0]*axis[0]*t;
    var m11 = c + axis[1]*axis[1]*t;
    var m22 = c + axis[2]*axis[2]*t;


    var tmp1 = axis[0]*axis[1]*t;
    var tmp2 = axis[2]*s;
    var m10 = tmp1 + tmp2;
    var m01 = tmp1 - tmp2;
    tmp1 = axis[0]*axis[2]*t;
    tmp2 = axis[1]*s;
    var m20 = tmp1 - tmp2;
    var m02 = tmp1 + tmp2;    
    tmp1 = axis[1]*axis[2]*t;
    tmp2 = axis[0]*s;
    var m21 = tmp1 + tmp2;
    var m12 = tmp1 - tmp2;

    return [m00, m01, m02,
            m10, m11, m12,
            m20, m21, m22];
}

normalize(vec) {
	return Z.Vec3.scalarMultiply(forwardVec, 1.0 / Z.Vec3.magnitude(forwardVec));
}

cross(vecA, vecB) {
	var x = vecA[1] * vecB[2] - vecB[1] * vecA[2];
	var y = vecA[2] * vecB[0] - vecB[2] * vecA[0];
	var z = vecA[0] * vecB[1] - vecB[0] * vecA[1];

	return [x, y, z]
}

lookAt(forwardVec, targetVec) {
	// normalize
	var forward = normalize(forwardVec);
	var target = normalize(targetVec);

	// compute the rotation axis
	var axis = cross(forward, target);

	// compute the angle
	var cosTheta = Z.Vec3.dot(forward, target);
	var angle = Math.acos(cosTheta);

	// compute the rotation matrix
	var rotM = matrixFromAxisAngle(axis, angle);

	// get the Euler angels
	return Z.Mat.anglesFromRotationMatrix(rotM);
}

// let's say, the object's position is objPos with the defined forward vector as objForward, and the look at target's postion is targetPos, then call
var angles = lookAt(objForward, Z.Vec3.subtract(targetPos, objPos));

Cheers,
Mark


#3

Hey Mark,

Thank you! That helps a lot.

I managed to implement this behavior with simpler math, but with separate transform groups for pitch and yaw. I think what you posted makes things cleaner though so I’ll probably switch over to that.

I used this behavior to implement hacky line drawing between points and it’s working quite well. Probably not the best performance-wise, but it works for now. Now this made me think of more feature requests. :wink:

Thanks again!