1052 lines
22 KiB
C++
1052 lines
22 KiB
C++
/*
|
|
* Copyright 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef VECMATH_H_
|
|
#define VECMATH_H_
|
|
|
|
#include <math.h>
|
|
#include "JNIHelper.h"
|
|
|
|
/******************************************************************
|
|
* Helper class for vector math operations
|
|
* Currently all implementations are in pure C++.
|
|
* Each class is an opaque class so caller does not have a direct access
|
|
* to each element. This is for an ease of future optimization to use vector operations.
|
|
*
|
|
*/
|
|
|
|
class vec2;
|
|
class vec3;
|
|
class vec4;
|
|
class mat4;
|
|
|
|
/******************************************************************
|
|
* 2 elements vector class
|
|
*
|
|
*/
|
|
class vec2
|
|
{
|
|
private:
|
|
float x,y;
|
|
|
|
public:
|
|
friend class vec3;
|
|
friend class vec4;
|
|
friend class mat4;
|
|
friend class quaternion;
|
|
|
|
vec2()
|
|
{
|
|
x = y = 0.f;
|
|
}
|
|
|
|
vec2(const float fX, const float fY)
|
|
{
|
|
x = fX; y = fY;
|
|
}
|
|
|
|
vec2(const vec2& vec)
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
}
|
|
|
|
vec2(const float* pVec)
|
|
{
|
|
x = (*pVec++); y = (*pVec++);
|
|
}
|
|
|
|
//Operators
|
|
vec2 operator*(const vec2& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x*rhs.x;
|
|
ret.y = y*rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
vec2 operator/(const vec2& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x/rhs.x;
|
|
ret.y = y/rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
vec2 operator+(const vec2& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x + rhs.x;
|
|
ret.y = y + rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
vec2 operator-(const vec2& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x - rhs.x;
|
|
ret.y = y - rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
vec2& operator+=(const vec2& rhs)
|
|
{
|
|
x += rhs.x;
|
|
y += rhs.y;
|
|
return *this;
|
|
}
|
|
|
|
vec2& operator-=(const vec2& rhs)
|
|
{
|
|
x -= rhs.x;
|
|
y -= rhs.y;
|
|
return *this;
|
|
}
|
|
|
|
vec2& operator*=(const vec2& rhs)
|
|
{
|
|
x *= rhs.x;
|
|
y *= rhs.y;
|
|
return *this;
|
|
}
|
|
|
|
vec2& operator/=(const vec2& rhs)
|
|
{
|
|
x /= rhs.x;
|
|
y /= rhs.y;
|
|
return *this;
|
|
}
|
|
|
|
//External operators
|
|
friend vec2 operator-(const vec2& rhs) { return vec2(rhs) *= -1; }
|
|
|
|
friend vec2 operator*(const float lhs, const vec2& rhs)
|
|
{
|
|
vec2 ret;
|
|
ret.x = lhs * rhs.x;
|
|
ret.y = lhs * rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
friend vec2 operator/(const float lhs, const vec2& rhs)
|
|
{
|
|
vec2 ret;
|
|
ret.x = lhs / rhs.x;
|
|
ret.y = lhs / rhs.y;
|
|
return ret;
|
|
}
|
|
|
|
//Operators with float
|
|
vec2 operator*(const float& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x * rhs;
|
|
ret.y = y * rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec2& operator*=(const float& rhs)
|
|
{
|
|
x = x * rhs;
|
|
y = y * rhs;
|
|
return *this;
|
|
}
|
|
|
|
vec2 operator/(const float& rhs) const
|
|
{
|
|
vec2 ret;
|
|
ret.x = x / rhs;
|
|
ret.y = y / rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec2& operator/=(const float& rhs)
|
|
{
|
|
x = x / rhs;
|
|
y = y / rhs;
|
|
return *this;
|
|
}
|
|
|
|
//Compare
|
|
bool operator==(const vec2& rhs) const
|
|
{
|
|
if(x != rhs.x || y != rhs.y ) return false;
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const vec2& rhs) const
|
|
{
|
|
if(x == rhs.x)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
float length() const
|
|
{
|
|
return sqrtf(x*x + y*y);
|
|
}
|
|
|
|
vec2 normalize()
|
|
{
|
|
float len = length();
|
|
x = x / len;
|
|
y = y / len;
|
|
return *this;
|
|
}
|
|
|
|
float dot(const vec2& rhs)
|
|
{
|
|
return x * rhs.x + y*rhs.y;
|
|
}
|
|
|
|
bool validate()
|
|
{
|
|
if( isnan( x ) || isnan( y ) )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void value(float& fX, float& fY)
|
|
{
|
|
fX = x;
|
|
fY = y;
|
|
}
|
|
|
|
void dump()
|
|
{
|
|
LOGI("vec2 %f %f", x, y);
|
|
}
|
|
};
|
|
|
|
/******************************************************************
|
|
* 3 elements vector class
|
|
*
|
|
*/
|
|
class vec3
|
|
{
|
|
private:
|
|
float x,y,z;
|
|
|
|
public:
|
|
friend class vec4;
|
|
friend class mat4;
|
|
friend class quaternion;
|
|
|
|
vec3()
|
|
{
|
|
x = y = z = 0.f;
|
|
}
|
|
|
|
vec3(const float fX, const float fY, const float fZ)
|
|
{
|
|
x = fX; y = fY; z = fZ;
|
|
}
|
|
|
|
vec3(const vec3& vec)
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
z = vec.z;
|
|
}
|
|
|
|
vec3(const float* pVec)
|
|
{
|
|
x = (*pVec++); y = (*pVec++); z = *pVec;
|
|
}
|
|
|
|
vec3(const vec2& vec, float f )
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
z = f;
|
|
}
|
|
|
|
vec3(const vec4& vec );
|
|
|
|
//Operators
|
|
vec3 operator*(const vec3& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x*rhs.x;
|
|
ret.y = y*rhs.y;
|
|
ret.z = z*rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
vec3 operator/(const vec3& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x/rhs.x;
|
|
ret.y = y/rhs.y;
|
|
ret.z = z/rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
vec3 operator+(const vec3& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x + rhs.x;
|
|
ret.y = y + rhs.y;
|
|
ret.z = z + rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
vec3 operator-(const vec3& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x - rhs.x;
|
|
ret.y = y - rhs.y;
|
|
ret.z = z - rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
vec3& operator+=(const vec3& rhs)
|
|
{
|
|
x += rhs.x;
|
|
y += rhs.y;
|
|
z += rhs.z;
|
|
return *this;
|
|
}
|
|
|
|
vec3& operator-=(const vec3& rhs)
|
|
{
|
|
x -= rhs.x;
|
|
y -= rhs.y;
|
|
z -= rhs.z;
|
|
return *this;
|
|
}
|
|
|
|
vec3& operator*=(const vec3& rhs)
|
|
{
|
|
x *= rhs.x;
|
|
y *= rhs.y;
|
|
z *= rhs.z;
|
|
return *this;
|
|
}
|
|
|
|
vec3& operator/=(const vec3& rhs)
|
|
{
|
|
x /= rhs.x;
|
|
y /= rhs.y;
|
|
z /= rhs.z;
|
|
return *this;
|
|
}
|
|
|
|
//External operators
|
|
friend vec3 operator-(const vec3& rhs) { return vec3(rhs) *= -1; }
|
|
|
|
friend vec3 operator*(const float lhs, const vec3& rhs)
|
|
{
|
|
vec3 ret;
|
|
ret.x = lhs * rhs.x;
|
|
ret.y = lhs * rhs.y;
|
|
ret.z = lhs * rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
friend vec3 operator/(const float lhs, const vec3& rhs)
|
|
{
|
|
vec3 ret;
|
|
ret.x = lhs / rhs.x;
|
|
ret.y = lhs / rhs.y;
|
|
ret.z = lhs / rhs.z;
|
|
return ret;
|
|
}
|
|
|
|
//Operators with float
|
|
vec3 operator*(const float& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x * rhs;
|
|
ret.y = y * rhs;
|
|
ret.z = z * rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec3& operator*=(const float& rhs)
|
|
{
|
|
x = x * rhs;
|
|
y = y * rhs;
|
|
z = z * rhs;
|
|
return *this;
|
|
}
|
|
|
|
vec3 operator/(const float& rhs) const
|
|
{
|
|
vec3 ret;
|
|
ret.x = x / rhs;
|
|
ret.y = y / rhs;
|
|
ret.z = z / rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec3& operator/=(const float& rhs)
|
|
{
|
|
x = x / rhs;
|
|
y = y / rhs;
|
|
z = z / rhs;
|
|
return *this;
|
|
}
|
|
|
|
//Compare
|
|
bool operator==(const vec3& rhs) const
|
|
{
|
|
if(x != rhs.x || y != rhs.y || z != rhs.z) return false;
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const vec3& rhs) const
|
|
{
|
|
if(x == rhs.x)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
float length() const
|
|
{
|
|
return sqrtf(x*x + y*y + z*z);
|
|
}
|
|
|
|
vec3 normalize()
|
|
{
|
|
float len = length();
|
|
x = x / len;
|
|
y = y / len;
|
|
z = z / len;
|
|
return *this;
|
|
}
|
|
|
|
float dot(const vec3& rhs)
|
|
{
|
|
return x * rhs.x + y*rhs.y + z*rhs.z;
|
|
}
|
|
|
|
vec3 cross(const vec3& rhs)
|
|
{
|
|
vec3 ret;
|
|
ret.x = y*rhs.z - z*rhs.y;
|
|
ret.y = z*rhs.x - x*rhs.z;
|
|
ret.z = x*rhs.y - y*rhs.x;
|
|
return ret;
|
|
}
|
|
|
|
bool validate()
|
|
{
|
|
if( isnan( x ) || isnan( y ) || isnan( z ) )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void value(float& fX, float& fY, float& fZ)
|
|
{
|
|
fX = x;
|
|
fY = y;
|
|
fZ = z;
|
|
}
|
|
|
|
void dump()
|
|
{
|
|
LOGI("vec3 %f %f %f", x, y, z);
|
|
}
|
|
};
|
|
|
|
/******************************************************************
|
|
* 4 elements vector class
|
|
*
|
|
*/
|
|
class vec4
|
|
{
|
|
private:
|
|
float x,y,z,w;
|
|
|
|
public:
|
|
friend class vec3;
|
|
friend class mat4;
|
|
friend class quaternion;
|
|
|
|
vec4()
|
|
{
|
|
x = y = z = w = 0.f;
|
|
}
|
|
|
|
vec4(const float fX, const float fY, const float fZ, const float fW )
|
|
{
|
|
x = fX; y = fY; z = fZ; w = fW;
|
|
}
|
|
|
|
vec4(const vec4& vec)
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
z = vec.z;
|
|
w = vec.w;
|
|
}
|
|
|
|
vec4(const vec3& vec, const float fW )
|
|
{
|
|
x = vec.x; y = vec.y; z = vec.z; w = fW;
|
|
}
|
|
|
|
vec4(const float* pVec)
|
|
{
|
|
x = (*pVec++); y = (*pVec++); z = *pVec; w = *pVec;
|
|
}
|
|
|
|
//Operators
|
|
vec4 operator*(const vec4& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x*rhs.x;
|
|
ret.y = y*rhs.y;
|
|
ret.z = z*rhs.z;
|
|
ret.w = z*rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
vec4 operator/(const vec4& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x/rhs.x;
|
|
ret.y = y/rhs.y;
|
|
ret.z = z/rhs.z;
|
|
ret.w = z/rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
vec4 operator+(const vec4& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x+rhs.x;
|
|
ret.y = y+rhs.y;
|
|
ret.z = z+rhs.z;
|
|
ret.w = z+rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
vec4 operator-(const vec4& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x-rhs.x;
|
|
ret.y = y-rhs.y;
|
|
ret.z = z-rhs.z;
|
|
ret.w = z-rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
vec4& operator+=(const vec4& rhs)
|
|
{
|
|
x += rhs.x;
|
|
y += rhs.y;
|
|
z += rhs.z;
|
|
w += rhs.w;
|
|
return *this;
|
|
}
|
|
|
|
vec4& operator-=(const vec4& rhs)
|
|
{
|
|
x -= rhs.x;
|
|
y -= rhs.y;
|
|
z -= rhs.z;
|
|
w -= rhs.w;
|
|
return *this;
|
|
}
|
|
|
|
vec4& operator*=(const vec4& rhs)
|
|
{
|
|
x *= rhs.x;
|
|
y *= rhs.y;
|
|
z *= rhs.z;
|
|
w *= rhs.w;
|
|
return *this;
|
|
}
|
|
|
|
vec4& operator/=(const vec4& rhs)
|
|
{
|
|
x /= rhs.x;
|
|
y /= rhs.y;
|
|
z /= rhs.z;
|
|
w /= rhs.w;
|
|
return *this;
|
|
}
|
|
|
|
//External operators
|
|
friend vec4 operator-(const vec4& rhs) { return vec4(rhs) *= -1; }
|
|
|
|
friend vec4 operator*(const float lhs, const vec4& rhs)
|
|
{
|
|
vec4 ret;
|
|
ret.x = lhs * rhs.x;
|
|
ret.y = lhs * rhs.y;
|
|
ret.z = lhs * rhs.z;
|
|
ret.w = lhs * rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
friend vec4 operator/(const float lhs, const vec4& rhs)
|
|
{
|
|
vec4 ret;
|
|
ret.x = lhs / rhs.x;
|
|
ret.y = lhs / rhs.y;
|
|
ret.z = lhs / rhs.z;
|
|
ret.w = lhs / rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
//Operators with float
|
|
vec4 operator*(const float& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x * rhs;
|
|
ret.y = y * rhs;
|
|
ret.z = z * rhs;
|
|
ret.w = w * rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec4& operator*=(const float& rhs)
|
|
{
|
|
x = x * rhs;
|
|
y = y * rhs;
|
|
z = z * rhs;
|
|
w = w * rhs;
|
|
return *this;
|
|
}
|
|
|
|
vec4 operator/(const float& rhs) const
|
|
{
|
|
vec4 ret;
|
|
ret.x = x / rhs;
|
|
ret.y = y / rhs;
|
|
ret.z = z /rhs;
|
|
ret.w = w /rhs;
|
|
return ret;
|
|
}
|
|
|
|
vec4& operator/=(const float& rhs)
|
|
{
|
|
x = x / rhs;
|
|
y = y / rhs;
|
|
z = z / rhs;
|
|
w = w / rhs;
|
|
return *this;
|
|
}
|
|
|
|
//Compare
|
|
bool operator==(const vec4& rhs) const
|
|
{
|
|
if(x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w) return false;
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const vec4& rhs) const
|
|
{
|
|
if(x == rhs.x)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
vec4 operator*(const mat4& rhs) const;
|
|
|
|
float length() const
|
|
{
|
|
return sqrtf(x*x + y*y + z*z + w*w);
|
|
}
|
|
|
|
vec4 normalize()
|
|
{
|
|
float len = length();
|
|
x = x / len;
|
|
y = y / len;
|
|
z = z / len;
|
|
w = w / len;
|
|
return *this;
|
|
}
|
|
|
|
float dot(const vec3& rhs)
|
|
{
|
|
return x * rhs.x + y*rhs.y + z*rhs.z;
|
|
}
|
|
|
|
vec3 cross(const vec3& rhs)
|
|
{
|
|
vec3 ret;
|
|
ret.x = y*rhs.z - z*rhs.y;
|
|
ret.y = z*rhs.x - x*rhs.z;
|
|
ret.z = x*rhs.y - y*rhs.x;
|
|
return ret;
|
|
}
|
|
|
|
bool validate()
|
|
{
|
|
if( isnan( x ) || isnan( y ) || isnan( z ) || isnan( w ))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void value(float& fX, float& fY, float& fZ, float& fW)
|
|
{
|
|
fX = x;
|
|
fY = y;
|
|
fZ = z;
|
|
fW = w;
|
|
}
|
|
};
|
|
|
|
/******************************************************************
|
|
* 4x4 matrix
|
|
*
|
|
*/
|
|
class mat4
|
|
{
|
|
private:
|
|
float f[16];
|
|
|
|
public:
|
|
friend class vec3;
|
|
friend class vec4;
|
|
friend class quaternion;
|
|
|
|
mat4();
|
|
mat4(const float*);
|
|
|
|
mat4 operator*(const mat4& rhs) const;
|
|
vec4 operator*(const vec4& rhs) const;
|
|
|
|
mat4 operator+(const mat4& rhs) const
|
|
{
|
|
mat4 ret;
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
ret.f[i] = f[i] + rhs.f[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
mat4 operator-(const mat4& rhs) const
|
|
{
|
|
mat4 ret;
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
ret.f[i] = f[i] - rhs.f[i];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
mat4& operator+=(const mat4& rhs)
|
|
{
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
f[i] += rhs.f[i];
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
mat4& operator-=(const mat4& rhs)
|
|
{
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
f[i] -= rhs.f[i];
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
mat4& operator*=(const mat4& rhs)
|
|
{
|
|
mat4 ret;
|
|
ret.f[0] = f[0] * rhs.f[0] + f[4] * rhs.f[1] + f[8] * rhs.f[2] + f[12] * rhs.f[3];
|
|
ret.f[1] = f[1] * rhs.f[0] + f[5] * rhs.f[1] + f[9] * rhs.f[2] + f[13] * rhs.f[3];
|
|
ret.f[2] = f[2] * rhs.f[0] + f[6] * rhs.f[1] + f[10] * rhs.f[2] + f[14] * rhs.f[3];
|
|
ret.f[3] = f[3] * rhs.f[0] + f[7] * rhs.f[1] + f[11] * rhs.f[2] + f[15] * rhs.f[3];
|
|
|
|
ret.f[4] = f[0] * rhs.f[4] + f[4] * rhs.f[5] + f[8] * rhs.f[6] + f[12] * rhs.f[7];
|
|
ret.f[5] = f[1] * rhs.f[4] + f[5] * rhs.f[5] + f[9] * rhs.f[6] + f[13] * rhs.f[7];
|
|
ret.f[6] = f[2] * rhs.f[4] + f[6] * rhs.f[5] + f[10] * rhs.f[6] + f[14] * rhs.f[7];
|
|
ret.f[7] = f[3] * rhs.f[4] + f[7] * rhs.f[5] + f[11] * rhs.f[6] + f[15] * rhs.f[7];
|
|
|
|
ret.f[8] = f[0] * rhs.f[8] + f[4] * rhs.f[9] + f[8] * rhs.f[10] + f[12] * rhs.f[11];
|
|
ret.f[9] = f[1] * rhs.f[8] + f[5] * rhs.f[9] + f[9] * rhs.f[10] + f[13] * rhs.f[11];
|
|
ret.f[10] = f[2] * rhs.f[8] + f[6] * rhs.f[9] + f[10] * rhs.f[10] + f[14] * rhs.f[11];
|
|
ret.f[11] = f[3] * rhs.f[8] + f[7] * rhs.f[9] + f[11] * rhs.f[10] + f[15] * rhs.f[11];
|
|
|
|
ret.f[12] = f[0] * rhs.f[12] + f[4] * rhs.f[13] + f[8] * rhs.f[14] + f[12] * rhs.f[15];
|
|
ret.f[13] = f[1] * rhs.f[12] + f[5] * rhs.f[13] + f[9] * rhs.f[14] + f[13] * rhs.f[15];
|
|
ret.f[14] = f[2] * rhs.f[12] + f[6] * rhs.f[13] + f[10] * rhs.f[14] + f[14] * rhs.f[15];
|
|
ret.f[15] = f[3] * rhs.f[12] + f[7] * rhs.f[13] + f[11] * rhs.f[14] + f[15] * rhs.f[15];
|
|
|
|
*this = ret;
|
|
return *this;
|
|
}
|
|
|
|
mat4 operator*(const float rhs)
|
|
{
|
|
mat4 ret;
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
ret.f[i] = f[i] * rhs;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
mat4& operator*=(const float rhs)
|
|
{
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
f[i] *= rhs;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
mat4& operator=(const mat4& rhs)
|
|
{
|
|
for(int32_t i=0; i < 16; ++i)
|
|
{
|
|
f[i] = rhs.f[i];
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
mat4 inverse();
|
|
|
|
mat4 transpose()
|
|
{
|
|
mat4 ret;
|
|
ret.f[0] = f[0]; ret.f[1] = f[4]; ret.f[2] = f[8]; ret.f[3] = f[12];
|
|
ret.f[4] = f[1]; ret.f[5] = f[5]; ret.f[6] = f[9]; ret.f[7] = f[13];
|
|
ret.f[8] = f[2]; ret.f[9] = f[6]; ret.f[10] = f[10]; ret.f[11] = f[14];
|
|
ret.f[12] = f[3]; ret.f[13] = f[7]; ret.f[14] = f[11]; ret.f[15] = f[15];
|
|
*this = ret;
|
|
return *this;
|
|
}
|
|
|
|
mat4& postTranslate(float tx, float ty, float tz)
|
|
{
|
|
f[12] += (tx*f[0])+(ty*f[4])+(tz*f[8]);
|
|
f[13] += (tx*f[1])+(ty*f[5])+(tz*f[9]);
|
|
f[14] += (tx*f[2])+(ty*f[6])+(tz*f[10]);
|
|
f[15] += (tx*f[3])+(ty*f[7])+(tz*f[11]);
|
|
return *this;
|
|
}
|
|
|
|
float* ptr() {
|
|
return f;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// Misc
|
|
//--------------------------------------------------------------------------------
|
|
static mat4 perspective(
|
|
float width,
|
|
float height,
|
|
float nearPlane, float farPlane);
|
|
|
|
static mat4 lookAt(const vec3& vEye, const vec3& vAt, const vec3& vUp);
|
|
|
|
static mat4 translation(
|
|
const float fX,
|
|
const float fY,
|
|
const float fZ);
|
|
static mat4 translation(
|
|
const vec3 vec);
|
|
|
|
static mat4 rotationX(
|
|
const float fAngle);
|
|
|
|
static mat4 rotationY(const float fAngle);
|
|
|
|
static mat4 rotationZ(const float fAngle);
|
|
|
|
static mat4 identity()
|
|
{
|
|
mat4 ret;
|
|
ret.f[0] = 1.f; ret.f[1] = 0; ret.f[2] = 0; ret.f[3] = 0;
|
|
ret.f[4] = 0; ret.f[5] = 1.f; ret.f[6] = 0; ret.f[7] = 0;
|
|
ret.f[8] = 0; ret.f[9] = 0; ret.f[10] = 1.f;ret.f[11] = 0;
|
|
ret.f[12] = 0; ret.f[13] = 0; ret.f[14] = 0; ret.f[15] = 1.f;
|
|
return ret;
|
|
}
|
|
|
|
void dump()
|
|
{
|
|
LOGI("%f %f %f %f", f[0], f[1], f[2], f[3]);
|
|
LOGI("%f %f %f %f", f[4], f[5], f[6], f[7]);
|
|
LOGI("%f %f %f %f", f[8], f[9], f[10], f[11]);
|
|
LOGI("%f %f %f %f", f[12], f[13], f[14], f[15]);
|
|
}
|
|
};
|
|
|
|
/******************************************************************
|
|
* quaternion class
|
|
*
|
|
*/
|
|
class quaternion
|
|
{
|
|
private:
|
|
float x,y,z,w;
|
|
|
|
public:
|
|
friend class vec3;
|
|
friend class vec4;
|
|
friend class mat4;
|
|
|
|
quaternion()
|
|
{
|
|
x = 0.f;
|
|
y = 0.f;
|
|
z = 0.f;
|
|
w = 1.f;
|
|
}
|
|
|
|
quaternion(const float fX, const float fY, const float fZ, const float fW)
|
|
{
|
|
x = fX;
|
|
y = fY;
|
|
z = fZ;
|
|
w = fW;
|
|
}
|
|
|
|
quaternion(const vec3 vec, const float fW)
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
z = vec.z;
|
|
w = fW;
|
|
}
|
|
|
|
quaternion(const float* p)
|
|
{
|
|
x = *p++;
|
|
y = *p++;
|
|
z = *p++;
|
|
w = *p++;
|
|
}
|
|
|
|
quaternion operator*(const quaternion rhs)
|
|
{
|
|
quaternion ret;
|
|
ret.x = x * rhs.w + y * rhs.z - z * rhs.y + w * rhs.x;
|
|
ret.y = -x * rhs.z + y * rhs.w + z * rhs.x + w * rhs.y;
|
|
ret.z = x * rhs.y - y * rhs.x + z * rhs.w + w * rhs.z;
|
|
ret.w = -x * rhs.x - y * rhs.y - z * rhs.z + w * rhs.w;
|
|
return ret;
|
|
}
|
|
|
|
quaternion& operator*=(const quaternion rhs)
|
|
{
|
|
quaternion ret;
|
|
ret.x = x * rhs.w + y * rhs.z - z * rhs.y + w * rhs.x;
|
|
ret.y = -x * rhs.z + y * rhs.w + z * rhs.x + w * rhs.y;
|
|
ret.z = x * rhs.y - y * rhs.x + z * rhs.w + w * rhs.z;
|
|
ret.w = -x * rhs.x - y * rhs.y - z * rhs.z + w * rhs.w;
|
|
*this = ret;
|
|
return *this;
|
|
}
|
|
|
|
quaternion conjugate()
|
|
{
|
|
x = -x;
|
|
y = -y;
|
|
z = -z;
|
|
return *this;
|
|
}
|
|
|
|
//Non destuctive version
|
|
quaternion conjugated()
|
|
{
|
|
quaternion ret;
|
|
ret.x = -x;
|
|
ret.y = -y;
|
|
ret.z = -z;
|
|
ret.w = w;
|
|
return ret;
|
|
}
|
|
|
|
void toMatrix(mat4& mat)
|
|
{
|
|
float x2 = x * x * 2.0f;
|
|
float y2 = y * y * 2.0f;
|
|
float z2 = z * z * 2.0f;
|
|
float xy = x * y * 2.0f;
|
|
float yz = y * z * 2.0f;
|
|
float zx = z * x * 2.0f;
|
|
float xw = x * w * 2.0f;
|
|
float yw = y * w * 2.0f;
|
|
float zw = z * w * 2.0f;
|
|
|
|
mat.f[0] = 1.0f - y2 - z2;
|
|
mat.f[1] = xy + zw;
|
|
mat.f[2] = zx - yw;
|
|
mat.f[4] = xy - zw;
|
|
mat.f[5] = 1.0f - z2 - x2;
|
|
mat.f[6] = yz + xw;
|
|
mat.f[8] = zx + yw;
|
|
mat.f[9] = yz - xw;
|
|
mat.f[10] = 1.0f - x2 - y2;
|
|
|
|
mat.f[3] = mat.f[7] = mat.f[11] = mat.f[12] = mat.f[13] = mat.f[14] = 0.0f;
|
|
mat.f[15] = 1.0f;
|
|
}
|
|
|
|
void toMatrixPreserveTranslate(mat4& mat)
|
|
{
|
|
float x2 = x * x * 2.0f;
|
|
float y2 = y * y * 2.0f;
|
|
float z2 = z * z * 2.0f;
|
|
float xy = x * y * 2.0f;
|
|
float yz = y * z * 2.0f;
|
|
float zx = z * x * 2.0f;
|
|
float xw = x * w * 2.0f;
|
|
float yw = y * w * 2.0f;
|
|
float zw = z * w * 2.0f;
|
|
|
|
mat.f[0] = 1.0f - y2 - z2;
|
|
mat.f[1] = xy + zw;
|
|
mat.f[2] = zx - yw;
|
|
mat.f[4] = xy - zw;
|
|
mat.f[5] = 1.0f - z2 - x2;
|
|
mat.f[6] = yz + xw;
|
|
mat.f[8] = zx + yw;
|
|
mat.f[9] = yz - xw;
|
|
mat.f[10] = 1.0f - x2 - y2;
|
|
|
|
mat.f[3] = mat.f[7] = mat.f[11] = 0.0f;
|
|
mat.f[15] = 1.0f;
|
|
}
|
|
|
|
static quaternion rotationAxis(const vec3 axis, const float angle )
|
|
{
|
|
quaternion ret;
|
|
float s = sinf(angle / 2);
|
|
ret.x = s * axis.x;
|
|
ret.y = s * axis.y;
|
|
ret.z = s * axis.z;
|
|
ret.w = cosf( angle / 2 );
|
|
return ret;
|
|
}
|
|
|
|
void value(float& fX, float& fY, float& fZ, float& fW)
|
|
{
|
|
fX = x;
|
|
fY = y;
|
|
fZ = z;
|
|
fW = w;
|
|
}
|
|
};
|
|
|
|
#endif /* VECMATH_H_ */
|