/*
* File: transform.js
*
* Encapsulates the matrix transformation functionality, meant to work with
* Renderable
*/
"use strict";
class Transform {
/**
* @classdesc Encapsulates the matrix transformation functionality, meant to work with Renderables
* <p>Found in Chapter 3, page 84 of the textbook</p>
* Example:
* {@link https://mylesacd.github.io/build-your-own-2d-game-engine-2e-doc/BookSourceCode/chapter3/3.3.transform_objects/index.html 3.3 Transform Objects}
* @constructor
* @returns {Transform} a new Transform instance
*/
constructor() {
this.mPosition = vec2.fromValues(0, 0); // this is the translation
this.mScale = vec2.fromValues(1, 1); // this is the width (x) and height (y)
this.mZ = 0.0; // must be a positive number, a larger value is closer to the eye
this.mRotationInRad = 0.0; // in radians!
}
/**
* Clones the attributes of this Transforms to the Transform Arugment
* @method
* @param {Transform} aXform - the Transform object to be cloned into
*/
cloneTo(aXform) {
aXform.mPosition = vec2.clone(this.mPosition);
aXform.mScale = vec2.clone(this.mScale);
aXform.mZ = this.mZ;
aXform.mRotationInRad = this.mRotationInRad;
}
/**
* Sets the x and y position of this Transform in world coordinates
* @method
* @param {float} xPos - the x position of the Transform
* @param {float} yPos - the y position of the Transform
*/
setPosition(xPos, yPos) { this.setXPos(xPos); this.setYPos(yPos); }
/**
* Returns the world coordinate position of this Transform
* @method
* @returns {vec2} mPosition - the x and y position of this Transform
*/
getPosition() { return this.mPosition; }
/**
* Returns the three dimensional world coordinate positionof this Transform
* @method
* @returns {vec3} the x,y,z position of this Transform
*/
get3DPosition() { return vec3.fromValues(this.getXPos(), this.getYPos(), this.getZPos()); }
/**
* Returns the x world coordinate position of this Transform
* @method
* @returns {float} mPosition[0] - the x world coordinate position of this Transform
*/
getXPos() { return this.mPosition[0]; }
/**
* Sets the x world Coordinate of this Tranform
* @method
* @param {float} xPos - the x position to set for this Transform
*/
setXPos(xPos) { this.mPosition[0] = xPos; }
/**
* Add a value to the x world coordinate of this Transform
* @method
* @param {float} delta - the value to be added to the current x value
*/
incXPosBy(delta) { this.mPosition[0] += delta; }
/**
* Returns the y world coordinate position of this Transform
* @method
* @returns {float} mPosition[0] - the y world coordinate position of this Transform
*/
getYPos() { return this.mPosition[1]; }
/**
* Sets the y world Coordinate of this Tranform
* @method
* @param {float} yPos - the y position to set for this Transform
*/
setYPos(yPos) { this.mPosition[1] = yPos; }
/**
* Add a value to the y world coordinate of this Transform
* @method
* @param {float} delta - the value to be added to the current y value
*/
incYPosBy(delta) { this.mPosition[1] += delta; }
/**
* Sets the z world Coordinate of this Tranform
* @method
* @param {float} d - the z position to set for this Transform
*/
setZPos(d) { this.mZ = d; }
/**
* Returns the z world coordinate position of this Transform
* @method
* @returns {float} mZ - the z world coordinate position of this Transform
*/
getZPos() { return this.mZ; }
/**
* Add a value to the z world coordinate of this Transform
* @method
* @param {float} delta - the value to be added to the current z value
*/
incZPosBy(delta) { this.mZ += delta; }
/**
* Sets the size of this Transform
* @param {float} width - the new width of this Transform
* @param {float} height - the new height of this Transform
*/
setSize(width, height) {
this.setWidth(width);
this.setHeight(height);
}
/**
* Returns the width and height of this Transform
* @method
* @returns {vec2} mScale - the width and height of this Transform
*/
getSize() { return this.mScale; }
/**
* Adds a value to the width and height of this Transform
* @method
* @param {float} delta - the value to be added to both the width and height
*/
incSizeBy(delta) {
this.incWidthBy(delta);
this.incHeightBy(delta);
}
/**
* Returns the width of this Transform
* @method
* @returns {float} mScale[0] - the width of this Transform
*/
getWidth() { return this.mScale[0]; }
/**
* Set the width of this Transform
* @param {float} width - new width
*/
setWidth(width) { this.mScale[0] = width; }
/**
* Adds a delta to the width
* @param {float} delta - the value to add
*/
incWidthBy(delta) { this.mScale[0] += delta; }
/**
* Returns the height of this Transform
* @method
* @returns {float} mScale[1] - the height of this Transform
*/
getHeight() { return this.mScale[1]; }
/**
* Sets the new height of this Transform
* @method
* @param {float} height - the new height to set for this Transform
*/
setHeight(height) { this.mScale[1] = height; }
/**
* Add a value to the height of this Transform
* @method
* @param {float} delta - the value to be added to the height
*/
incHeightBy(delta) { this.mScale[1] += delta; }
/**
* Sets the new rotation in radians of this Transform, internally bounded to [0,2*PI]
* @method
* @param {float} rotationInRadians - the new rotation value for this Transform
*/
setRotationInRad(rotationInRadians) {
this.mRotationInRad = rotationInRadians;
while (this.mRotationInRad > (2 * Math.PI)) {
this.mRotationInRad -= (2 * Math.PI);
}
}
/**
* Sets the new rotation in degrees of this Transform, internally bounded to [0,360]
* @method
* @param {float} rotationInDegree - the new rotation value for this Transform
*/
setRotationInDegree(rotationInDegree) {
this.setRotationInRad(rotationInDegree * Math.PI / 180.0);
}
/**
* Adds deltaDegree to the current rotation value of this Transform
* @method
* @param {float} deltaDegree - value to be added to the rotation, in degrees
*/
incRotationByDegree(deltaDegree) {
this.incRotationByRad(deltaDegree * Math.PI / 180.0);
}
/**
* Adds deltaRad to the current rotation value of this Transform
* @method
* @param {float} deltaRad - value to be added to the rotation, in radians
*/
incRotationByRad(deltaRad) {
this.setRotationInRad(this.mRotationInRad + deltaRad);
}
/**
* Returns the rotation of this Transform in radians
* @method
* @returns {float} mRotationInRad - the rotation of this Transform in radians
*/
getRotationInRad() { return this.mRotationInRad; }
/**
* Returns the width of this Transform in degrees
* @method
* @returns {float} the rotation of this Transform in degrees
*/
getRotationInDegree() { return this.mRotationInRad * 180.0 / Math.PI; }
// returns the matrix the concatenates the transformations defined
/**
* Returns the matrix of this Transform used to control Renderables
* @method
* @returns {mat4} matrix - the translated, rotated, and scaled matrix
*/
getTRSMatrix() {
// Creates a blank identity matrix
let matrix = mat4.create();
// The matrices that WebGL uses are transposed, thus the typical matrix
// operations must be in reverse.
// Step A: compute translation, for now z is the height
mat4.translate(matrix, matrix, this.get3DPosition());
// Step B: concatenate with rotation.
mat4.rotateZ(matrix, matrix, this.getRotationInRad());
// Step C: concatenate with scaling
mat4.scale(matrix, matrix, vec3.fromValues(this.getWidth(), this.getHeight(), 1.0));
return matrix;
}
}
export default Transform;