axmol/cocos/editor-support/cocostudio/ext/matrix3f.hpp

1167 lines
32 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Matrix3f defines a 3x3 matrix. Matrix data is maintained
* internally and is accessible via the get and set methods. Convenience methods
* are used for matrix operations as well as generating a matrix from a given
* set of values.
* 3X3앤黎잚
* @autohr HALX99 2016
* @author Mark Powell
* @author Joshua Slack
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef _MATRIX3F_H_
#define _MATRIX3F_H_
#include <cocos2d.h>
class Matrix3f {
public:
float m[9];
/**
* Constructor instantiates a new Matrix3f object. The initial
* values for the matrix is that of the identity matrix.
* 칵훰뭐芚데貫앤黎
*
*/
Matrix3f() {
loadIdentity();
}
/**
* constructs a matrix with the given values.
*
* @param m[0]
* 0x0 in the matrix.
* @param m[1]
* 0x1 in the matrix.
* @param m[2]
* 0x2 in the matrix.
* @param m[3]
* 1x0 in the matrix.
* @param m[4]
* 1x1 in the matrix.
* @param m[5]
* 1x2 in the matrix.
* @param m[6]
* 2x0 in the matrix.
* @param m[7]
* 2x1 in the matrix.
* @param m[8]
* 2x2 in the matrix.
*/
Matrix3f(float m[9]) {
this->m[0] = m[0];
this->m[1] = m[1];
this->m[2] = m[2];
this->m[3] = m[3];
this->m[4] = m[4];
this->m[5] = m[5];
this->m[6] = m[6];
this->m[8] = m[7];
this->m[9] = m[8];
}
/**
* get retrieves a value from the matrix at the given position.
* If the position is invalid a JmeException is thrown.
* 삿혤寧땍貫零돨禱羹令
*
* @param i
* the row index.契乞多혤令렀鍋0、1、2
* @param j
* the colum index.죗乞多혤令렀鍋0、1、2
* @return the value at (i, j).
*/
float get(int i, int j) {
switch (i) {
case 0:
switch (j) {
case 0:
return m[0];
case 1:
return m[1];
case 2:
return m[2];
}
case 1:
switch (j) {
case 0:
return m[3];
case 1:
return m[4];
case 2:
return m[5];
}
case 2:
switch (j) {
case 0:
return m[6];
case 1:
return m[7];
case 2:
return m[8];
}
}
// throw new JmeException("Invalid indices into matrix.");
}
/**
* get(float[]) returns the matrix in row-major or column-major
* order.
* 쉥앤黎객契샀죗돨糠埼닸흙꽝鑒data鑒莉櫓
*
* @param data
* The array to return the data into. This array can be 9 or 16
* floats in size. Only the upper 3x3 are assigned to in the case
* of a 16 element array.
* @param rowMajor
* True for row major storage in the array (translation in
* elements 3, 7, 11 for a 4x4), false for column major
* (translation in elements 12, 13, 14 for a 4x4).
*/
template<size_t _Length>
void get(float(&data)[_Length], bool rowMajor) {
if (_Length == 9) {
if (rowMajor) {
data[0] = m[0];
data[1] = m[1];
data[2] = m[2];
data[3] = m[3];
data[4] = m[4];
data[5] = m[5];
data[6] = m[6];
data[7] = m[7];
data[8] = m[8];
}
else {
data[0] = m[0];
data[1] = m[3];
data[2] = m[6];
data[3] = m[1];
data[4] = m[4];
data[5] = m[7];
data[6] = m[2];
data[7] = m[5];
data[8] = m[8];
}
}
else if (_Length == 16) {
if (rowMajor) {
data[0] = m[0];
data[1] = m[1];
data[2] = m[2];
data[4] = m[3];
data[5] = m[4];
data[6] = m[5];
data[8] = m[6];
data[9] = m[7];
data[10] = m[8];
}
else {
data[0] = m[0];
data[1] = m[3];
data[2] = m[6];
data[4] = m[1];
data[5] = m[4];
data[6] = m[7];
data[8] = m[2];
data[9] = m[5];
data[10] = m[8];
}
}
else {
// throw new JmeException("Array size must be 9 or 16 in Matrix3f.get().");
}
}
/**
* getColumn returns one of three columns specified by the
* parameter. This column is returned as a cocos2d::Vec3 object.
* 삿혤寧땍죗뭐芚돨蕨좆
*
* @param i
* the column to retrieve. Must be between 0 and 2.
* @param store
* the vector object to store the result in. if null, a new one
* is created.
* @return the column specified by the index.
*/
cocos2d::Vec3 getColumn(int i) {
cocos2d::Vec3 store;
switch (i) {
case 0:
store.x = m[0];
store.y = m[3];
store.z = m[6];
break;
case 1:
store.x = m[1];
store.y = m[4];
store.z = m[7];
break;
case 2:
store.x = m[2];
store.y = m[5];
store.z = m[8];
break;
default:;
//logger.warning("Invalid column index.");
//throw new JmeException("Invalid column index. " + i);
}
return store;
}
/**
* getRow returns one of three rows as specified by the
* parameter. This row is returned as a cocos2d::Vec3 object.
* 삿혤寧땍契뭐芚돨蕨좆
*
* @param i
* the row to retrieve. Must be between 0 and 2.
* @param store
* the vector object to store the result in. if null, a new one
* is created.
* @return the row specified by the index.
*/
cocos2d::Vec3 getRow(int i) {
cocos2d::Vec3 store;
switch (i) {
case 0:
store.x = m[0];
store.y = m[1];
store.z = m[2];
break;
case 1:
store.x = m[3];
store.y = m[4];
store.z = m[5];
break;
case 2:
store.x = m[6];
store.y = m[7];
store.z = m[8];
break;
default:;
// throw new JmeException("Invalid row index. " + i);
}
return store;
}
std::string toString() {
return "";
}
/**
*
* setColumn sets a particular column of this matrix to that
* represented by the provided vector.
* 몽앴못땍죗蕨좆<E895A8>零앤黎돨죗
*
* @param i
* the column to set.
* @param column
* the data to set.
*/
void setColumn(int i, const cocos2d::Vec3& column) {
switch (i) {
case 0:
m[0] = column.x;
m[3] = column.y;
m[6] = column.z;
break;
case 1:
m[1] = column.x;
m[4] = column.y;
m[7] = column.z;
break;
case 2:
m[2] = column.x;
m[5] = column.y;
m[8] = column.z;
break;
default:;
//logger.warning("Invalid column index.");
//throw new JmeException("Invalid column index. " + i);
}
}
/**
*
* setRow sets a particular row of this matrix to that
* represented by the provided vector.
* 몽앴못땍契蕨좆<E895A8>零앤黎돨契
*
* @param i
* the row to set.
* @param row
* the data to set.
*/
void setRow(int i, const cocos2d::Vec3& row) {
switch (i) {
case 0:
m[0] = row.x;
m[1] = row.y;
m[2] = row.z;
break;
case 1:
m[3] = row.x;
m[4] = row.y;
m[5] = row.z;
break;
case 2:
m[6] = row.x;
m[7] = row.y;
m[8] = row.z;
break;
default:;
// logger.warning("Invalid row index.");
// throw new JmeException("Invalid row index. " + i);
}
}
/**
* set places a given value into the matrix at the given
* position. If the position is invalid a JmeException is
* thrown.
* <20>땍캐貫零돨令
*
* @param i
* the row index.
* @param j
* the colum index.
* @param value
* the value for (i, j).
*/
void set(int i, int j, float value) {
switch (i) {
case 0:
switch (j) {
case 0:
m[0] = value;
return;
case 1:
m[1] = value;
return;
case 2:
m[2] = value;
return;
}
case 1:
switch (j) {
case 0:
m[3] = value;
return;
case 1:
m[4] = value;
return;
case 2:
m[5] = value;
return;
}
case 2:
switch (j) {
case 0:
m[6] = value;
return;
case 1:
m[7] = value;
return;
case 2:
m[8] = value;
return;
}
}
//logger.warning("Invalid matrix index.");
//throw new JmeException("Invalid indices into matrix.");
}
/**
*
* set sets the values of the matrix to those supplied by the
* 3x3 two dimenion array.
* 痰랗郭鑒莉<E99192>零앤黎몹禱羹令
*
* @param matrix
* the new values of the matrix.
* @throws JmeException
* if the array is not of size 9.
*/
void set(float matrix[3][3]) {
//if (matrix.length != 3 || matrix[0].length != 3) {
// throw new JmeException("Array must be of size 9.");
//}
m[0] = matrix[0][0];
m[1] = matrix[0][1];
m[2] = matrix[0][2];
m[3] = matrix[1][0];
m[4] = matrix[1][1];
m[5] = matrix[1][2];
m[6] = matrix[2][0];
m[7] = matrix[2][1];
m[8] = matrix[2][2];
}
/**
* Recreate Matrix using the provided axis.
* 몽앴못땍몹죗蕨좆뭐芚앤黎
*
* @param uAxis
* cocos2d::Vec3
* @param vAxis
* cocos2d::Vec3
* @param wAxis
* cocos2d::Vec3
*/
void set(const cocos2d::Vec3& uAxis, const cocos2d::Vec3& vAxis, const cocos2d::Vec3& wAxis) {
m[0] = uAxis.x;
m[3] = uAxis.y;
m[6] = uAxis.z;
m[1] = vAxis.x;
m[4] = vAxis.y;
m[7] = vAxis.z;
m[2] = wAxis.x;
m[5] = wAxis.y;
m[8] = wAxis.z;
}
/**
* set sets the values of this matrix from an array of values
* assuming that the data is rowMajor order;
* 몽앴못땍鑒莉객契<EAB09D>零앤黎
*
* @param matrix
* the matrix to set the value to.
*/
void set(float matrix[9]) {
set(matrix, true);
}
/**
* set sets the values of this matrix from an array of values;
* 몽앴못땍鑒莉객契샀죗<EC8380>零앤黎
*
* @param matrix
* the matrix to set the value to.
* @param rowMajor
* whether the incoming data is in row or column major order.
*/
void set(float matrix[9], bool rowMajor) {
//if (matrix.length != 9)
// throw new JmeException("Array must be of size 9.");
if (rowMajor) {
m[0] = matrix[0];
m[1] = matrix[1];
m[2] = matrix[2];
m[3] = matrix[3];
m[4] = matrix[4];
m[5] = matrix[5];
m[6] = matrix[6];
m[7] = matrix[7];
m[8] = matrix[8];
}
else {
m[0] = matrix[0];
m[1] = matrix[3];
m[2] = matrix[6];
m[3] = matrix[1];
m[4] = matrix[4];
m[5] = matrix[7];
m[6] = matrix[2];
m[7] = matrix[5];
m[8] = matrix[8];
}
}
/**
*
* set defines the values of the matrix based on a supplied
* Quaternion. It should be noted that all previous values will
* be overridden.
* 愷禱鑒뭐芚旗瘻앤黎
*
* @param quaternion
* the quaternion to create a rotational matrix from.
*/
void set(const cocos2d::Quaternion& quaternion) {
//quaternion.toRotationMatrix(this);
}
/**
* loadIdentity sets this matrix to the identity matrix. Where
* all values are zero except those along the diagonal which are one.
* 데貫앤黎
*
*/
void loadIdentity() {
m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0;
m[0] = m[4] = m[8] = 1;
}
/**
* 角뤠데貫앤黎
*
* @return true if this matrix is identity
*/
bool isIdentity() {
return (m[0] == 1 && m[1] == 0 && m[2] == 0)
&& (m[3] == 0 && m[4] == 1 && m[5] == 0)
&& (m[6] == 0 && m[7] == 0 && m[8] == 1);
}
/**
* Creates a matrix describing a rotation around the x-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateX(float angle)
{
rotateX(std::sin(angle), std::cos(angle));
}
/**
* Creates a matrix describing a rotation around the y-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateY(float angle)
{
rotateY(std::sin(angle), std::cos(angle));
}
/**
* Creates a matrix describing a rotation around the z-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateZ(float angle)
{
rotateZ(std::sin(angle), std::cos(angle));
}
/**
* Creates a matrix describing a rotation around the x-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateX(float s, float c)
{
Matrix3f temp;
temp.createRotationX(s, c);
mult(temp);
}
/**
* Creates a matrix describing a rotation around the y-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateY(float s, float c)
{
Matrix3f temp;
temp.createRotationY(s, c);
mult(temp);
}
/**
* Creates a matrix describing a rotation around the z-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void rotateZ(float s, float c)
{
Matrix3f temp;
temp.createRotationZ(s, c);
mult(temp);
}
/**
* fromAngleAxis sets this matrix4f to the values specified by
* an angle and an axis of rotation. This method creates an object, so use
* fromAngleNormalAxis if your axis is already normalized.
* 훈菉axis렷데貫蕨좆旗瘻angle빨똑실돨3D旗瘻앤黎
*
* @param angle
* the angle to rotate (in radians).
* @param axis
* the axis of rotation.
*/
void createRotation(const cocos2d::Vec3& axis, float angle) {
createRotation(axis, std::sin(angle), std::cos(angle));
}
/**
* fromAngleNormalAxis sets this matrix4f to the values
* specified by an angle and a normalized axis of rotation.
* 훈菉axis데貫蕨좆旗瘻angle빨똑실돨3D旗瘻앤黎
*
* @param angle
* the angle to rotate (in radians).
* @param axis
* the axis of rotation (already normalized).
*/
void createRotation(const cocos2d::Vec3& axis, float fSin, float fCos) {
float x = axis.x;
float y = axis.y;
float z = axis.z;
// Make sure the input axis is normalized.
float n = x*x + y*y + z*z;
if (n != 1.0f)
{
// Not normalized.
n = sqrt(n);
// Prevent divide too close to zero.
if (n > 0.000001f)
{
n = 1.0f / n;
x *= n;
y *= n;
z *= n;
}
}
float fOneMinusCos = ((float) 1.0) - fCos;
float fX2 = x * x;
float fY2 = y * y;
float fZ2 = z * z;
float fXYM = x * y * fOneMinusCos;
float fXZM = x * z * fOneMinusCos;
float fYZM = y * z * fOneMinusCos;
float fXSin = x * fSin;
float fYSin = y * fSin;
float fZSin = z * fSin;
m[0] = fX2 * fOneMinusCos + fCos;
m[1] = fXYM - fZSin;
m[2] = fXZM + fYSin;
m[3] = fXYM + fZSin;
m[4] = fY2 * fOneMinusCos + fCos;
m[5] = fYZM - fXSin;
m[6] = fXZM - fYSin;
m[7] = fYZM + fXSin;
m[8] = fZ2 * fOneMinusCos + fCos;
}
/**
* Creates a matrix describing a rotation around the x-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void createRotationX(float s, float c)
{
m[4] = c;
m[5] = s;
m[7] = -s;
m[8] = c;
}
/**
* Creates a matrix describing a rotation around the y-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void createRotationY(float s, float c)
{
m[0] = c;
m[2] = -s;
m[6] = s;
m[8] = c;
}
/**
* Creates a matrix describing a rotation around the z-axis.
*
* @param angle The angle of rotation (in radians).
* @param dst A matrix to store the result in.
*/
void createRotationZ(float s, float c)
{
m[0] = c;
m[1] = s;
m[3] = -s;
m[4] = c;
}
/**
* Creates a scale matrix.
*
* @param scale The amount to scale.
* @param dst A matrix to store the result in.
*/
void createScale(const cocos2d::Vec3& scale);
/**
* Creates a scale matrix.
*
* @param xScale The amount to scale along the x-axis.
* @param yScale The amount to scale along the y-axis.
* @param zScale The amount to scale along the z-axis.
* @param dst A matrix to store the result in.
*/
void createScale(float xScale, float yScale, float zScale);
/**
* Creates a translation matrix.
*
* @param translation The translation.
* @param dst A matrix to store the result in.
*/
void createTranslation(const cocos2d::Vec3& translation);
/**
* Creates a translation matrix.
*
* @param xTranslation The translation on the x-axis.
* @param yTranslation The translation on the y-axis.
* @param zTranslation The translation on the z-axis.
* @param dst A matrix to store the result in.
*/
void createTranslation(float xTranslation, float yTranslation, float zTranslation);
/**
* mult multiplies this matrix by a given matrix. The result
* matrix is returned as a new object.
* 앤黎넉랬써벎닸흙꽝鑒product櫓
*
* @param mat
* the matrix to multiply this matrix by.
* @param product
* the matrix to store the result in. if null, a new matrix3f is
* created. It is safe for mat and product to be the same object.
* @return a matrix3f object containing the result of this operation
*/
Matrix3f& mult(const Matrix3f& mat) {
return mult(mat, *this);
}
Matrix3f& mult(const Matrix3f& mat, Matrix3f& product) const
{
float temp00, temp01, temp02;
float temp10, temp11, temp12;
float temp20, temp21, temp22;
temp00 = m[0] * mat.m[0] + m[1] * mat.m[3] + m[2] * mat.m[6];
temp01 = m[0] * mat.m[1] + m[1] * mat.m[4] + m[2] * mat.m[7];
temp02 = m[0] * mat.m[2] + m[1] * mat.m[5] + m[2] * mat.m[8];
temp10 = m[3] * mat.m[0] + m[4] * mat.m[3] + m[5] * mat.m[6];
temp11 = m[3] * mat.m[1] + m[4] * mat.m[4] + m[5] * mat.m[7];
temp12 = m[3] * mat.m[2] + m[4] * mat.m[5] + m[5] * mat.m[8];
temp20 = m[6] * mat.m[0] + m[7] * mat.m[3] + m[8] * mat.m[6];
temp21 = m[6] * mat.m[1] + m[7] * mat.m[4] + m[8] * mat.m[7];
temp22 = m[6] * mat.m[2] + m[7] * mat.m[5] + m[8] * mat.m[8];
product.m[0] = temp00;
product.m[1] = temp01;
product.m[2] = temp02;
product.m[3] = temp10;
product.m[4] = temp11;
product.m[5] = temp12;
product.m[6] = temp20;
product.m[7] = temp21;
product.m[8] = temp22;
return product;
}
/**
* Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in
* product.
* 앤黎넉鹿蕨좆써벎닸흙꽝鑒product櫓
*
* @param vec
* The cocos2d::Vec3 to multiply.
* @return The given product vector.
*/
cocos2d::Vec3 mult(const cocos2d::Vec3& vec) const {
cocos2d::Vec3 product;
float x = vec.x;
float y = vec.y;
float z = vec.z;
product.x = m[0] * x + m[1] * y + m[2] * z;
product.y = m[3] * x + m[4] * y + m[5] * z;
product.z = m[6] * x + m[7] * y + m[8] * z;
return product;
}
Matrix3f& premultAlpha(float alpha) {
return multLocal(alpha);
}
/**
* multLocal multiplies this matrix internally by a given float
* scale factor.
* 앤黎깃좆넉
*
* @param scale
* the value to scale by.
* @return this Matrix3f
*/
Matrix3f& multLocal(float scale) {
m[0] *= scale;
m[1] *= scale;
m[2] *= scale;
m[3] *= scale;
m[4] *= scale;
m[5] *= scale;
m[6] *= scale;
m[7] *= scale;
m[8] *= scale;
return *this;
}
/**
* add adds the values of a parameter matrix to this matrix.
* 앤黎속랬
*
* @param mat
* the matrix to add to this.
*/
Matrix3f& addLocal(const Matrix3f& mat) {
m[0] += mat.m[0];
m[1] += mat.m[1];
m[2] += mat.m[2];
m[3] += mat.m[3];
m[4] += mat.m[4];
m[5] += mat.m[5];
m[6] += mat.m[6];
m[7] += mat.m[7];
m[8] += mat.m[8];
}
/**
* mult multiplies this matrix by a given matrix. The result
* matrix is saved in the current matrix. If the given matrix is null,
* nothing happens. The current matrix is returned. This is equivalent to
* this*=mat
* 앤黎넉鹿앤黎
*
* @param mat
* the matrix to multiply this matrix by.
* @return This matrix, after the multiplication
*/
/*void multLocal() {
return mult(mat, this);
}*/
/**
* Transposes this matrix in place. Returns this matrix for chaining
* 瘻零앤黎
*
* @return This matrix after transpose
*/
Matrix3f& transposeLocal() {
float tmp[9];
get(tmp, false);
set(tmp, true);
return *this;
}
/**
* Inverts this matrix and stores it in the given store.
* 쾀앤黎괏닸瞳꽝鑒櫓꼇맣긴菱<EAB8B4>
*
* @return The store
*/
Matrix3f invertNew(void) {
Matrix3f store;
float det = determinant();
if (std::abs(det) <= 0)
return store.zero();
store.m[0] = m[4] * m[8] - m[5] * m[7];
store.m[1] = m[2] * m[7] - m[1] * m[8];
store.m[2] = m[1] * m[5] - m[2] * m[4];
store.m[3] = m[5] * m[6] - m[3] * m[8];
store.m[4] = m[0] * m[8] - m[2] * m[6];
store.m[5] = m[2] * m[3] - m[0] * m[5];
store.m[6] = m[3] * m[7] - m[4] * m[6];
store.m[7] = m[1] * m[6] - m[0] * m[7];
store.m[8] = m[0] * m[4] - m[1] * m[3];
store.multLocal(1 / det);
return store;
}
/**
* Inverts this matrix locally.
* 쾀앤黎맣긴菱<EAB8B4>
*
* @return this
*/
Matrix3f& invertLocal() {
float det = determinant();
if (std::abs(det) <= FLT_EPSILON)
return zero();
float f00 = m[4] * m[8] - m[5] * m[7];
float f01 = m[2] * m[7] - m[1] * m[8];
float f02 = m[1] * m[5] - m[2] * m[4];
float f10 = m[5] * m[6] - m[3] * m[8];
float f11 = m[0] * m[8] - m[2] * m[6];
float f12 = m[2] * m[3] - m[0] * m[5];
float f20 = m[3] * m[7] - m[4] * m[6];
float f21 = m[1] * m[6] - m[0] * m[7];
float f22 = m[0] * m[4] - m[1] * m[3];
m[0] = f00;
m[1] = f01;
m[2] = f02;
m[3] = f10;
m[4] = f11;
m[5] = f12;
m[6] = f20;
m[7] = f21;
m[8] = f22;
multLocal(1 / det);
return *this;
}
/**
* Places the adjoint of this matrix in store (creates store if null.)
* 곈踞앤黎
*
* @param store
* The matrix to store the result in. If null, a new matrix is
* created.
* @return store
*/
Matrix3f adjoint() {
Matrix3f store;
store.m[0] = m[4] * m[8] - m[5] * m[7];
store.m[1] = m[2] * m[7] - m[1] * m[8];
store.m[2] = m[1] * m[5] - m[2] * m[4];
store.m[3] = m[5] * m[6] - m[3] * m[8];
store.m[4] = m[0] * m[8] - m[2] * m[6];
store.m[5] = m[2] * m[3] - m[0] * m[5];
store.m[6] = m[3] * m[7] - m[4] * m[6];
store.m[7] = m[1] * m[6] - m[0] * m[7];
store.m[8] = m[0] * m[4] - m[1] * m[3];
return store;
}
/**
* determinant generates the determinate of this matrix.
* 앤黎돨契죗駕
*
* @return the determinate
*/
float determinant() {
float fCo00 = m[4] * m[8] - m[5] * m[7];
float fCo10 = m[5] * m[6] - m[3] * m[8];
float fCo20 = m[3] * m[7] - m[4] * m[6];
float fDet = m[0] * fCo00 + m[1] * fCo10 + m[2] * fCo20;
return fDet;
}
/**
* Sets all of the values in this matrix to zero.
* 路零앤黎몹禱羹零槨0
*
* @return this matrix
*/
Matrix3f& zero() {
m[0] = m[1] = m[2] = m[3] = m[4] = m[5] = m[6] = m[7] = m[8] = 0.0f;
return *this;
}
/**
* transposeNew returns a transposed version of this matrix.
* 瘻零앤黎
*
* @return The new Matrix3f object.
*/
Matrix3f transposeNew() {
float temp[9] = { m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8] };
return Matrix3f(temp);
}
/**
* are these two matrices the same? they are is they both have the same mXX
* values.
*
* @param o
* the object to compare for equality
* @return true if they are equal
*/
bool equals(const Matrix3f& o) const {
return true;
}
/**
* A function for creating a rotation matrix that rotates a vector called
* "start" into another vector called "end".
* 눼쉔寧몸旗瘻앤黎닒蕨좆start旗瘻돕end
*
* @param start
* normalized non-zero starting vector
* @param end
* normalized non-zero ending vector
* @see "Tomas M?ller, John Hughes /"Efficiently Building a Matrix to Rotate
* / One Vector to Another/" Journal of Graphics Tools, 4(4):1-4, 1999"
*/
void fromStartEndVectors(cocos2d::Vec3 start, cocos2d::Vec3 end) {
cocos2d::Vec3 v ;
float e, h, f;
cocos2d::Vec3::cross(start, end, &v);
e = start.dot(end);
f = (e < 0) ? -e : e;
// if "from" and "to" vectors are nearly parallel
if (f > 1.0f - FLT_EPSILON) {
cocos2d::Vec3 u ;
cocos2d::Vec3 x ;
float c1, c2, c3; /* coefficients for later use */
int i, j;
x.x = (start.x > 0.0) ? start.x : -start.x;
x.y = (start.y > 0.0) ? start.y : -start.y;
x.z = (start.z > 0.0) ? start.z : -start.z;
if (x.x < x.y) {
if (x.x < x.z) {
x.x = 1.0f;
x.y = x.z = 0.0f;
}
else {
x.z = 1.0f;
x.x = x.y = 0.0f;
}
}
else {
if (x.y < x.z) {
x.y = 1.0f;
x.x = x.z = 0.0f;
}
else {
x.z = 1.0f;
x.x = x.y = 0.0f;
}
}
u.x = x.x - start.x;
u.y = x.y - start.y;
u.z = x.z - start.z;
v.x = x.x - end.x;
v.y = x.y - end.y;
v.z = x.z - end.z;
c1 = 2.0f / u.dot(u);
c2 = 2.0f / v.dot(v);
c3 = c1 * c2 * u.dot(v);
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
float val = -c1 * (&u.x)[i] * (&u.x)[j] - c2 * (&v.x)[i]
* (&v.x)[j] + c3 * (&v.x)[i] * (&u.x)[j];
set(i, j, val);
}
float val = get(i, i);
set(i, i, val + 1.0f);
}
}
else {
// the most common case, unless "start"="end", or "start"=-"end"
float hvx, hvz, hvxy, hvxz, hvyz;
h = 1.0f / (1.0f + e);
hvx = h * v.x;
hvz = h * v.z;
hvxy = hvx * v.y;
hvxz = hvx * v.z;
hvyz = hvz * v.y;
set(0, 0, e + hvx * v.x);
set(0, 1, hvxy - v.z);
set(0, 2, hvxz + v.y);
set(1, 0, hvxy + v.z);
set(1, 1, e + h * v.y * v.y);
set(1, 2, hvyz - v.x);
set(2, 0, hvxz - v.y);
set(2, 1, hvyz + v.x);
set(2, 2, e + hvz * v.z);
}
}
/**
* scale scales the operation performed by this matrix on a
* per-component basis.
* 깃좆넉契蕨좆,몹죗롸깎宮넉
*
* @param scale
* The scale applied to each of the X, Y and Z output values.
*/
void scale(cocos2d::Vec3 scale) {
m[0] *= scale.x;
m[3] *= scale.x;
m[6] *= scale.x;
m[1] *= scale.y;
m[4] *= scale.y;
m[7] *= scale.y;
m[2] *= scale.z;
m[5] *= scale.z;
m[8] *= scale.z;
}
static bool equalIdentity(const Matrix3f& mat) {
if (std::abs(mat.m[0] - 1) > 1e-4)
return false;
if (std::abs(mat.m[4] - 1) > 1e-4)
return false;
if (std::abs(mat.m[8] - 1) > 1e-4)
return false;
if (std::abs(mat.m[1]) > 1e-4)
return false;
if (std::abs(mat.m[2]) > 1e-4)
return false;
if (std::abs(mat.m[3]) > 1e-4)
return false;
if (std::abs(mat.m[5]) > 1e-4)
return false;
if (std::abs(mat.m[6]) > 1e-4)
return false;
if (std::abs(mat.m[7]) > 1e-4)
return false;
return true;
}
};
#endif