diff --git a/CMakeLists.txt b/CMakeLists.txt index c6518a7..9a66d2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,6 +264,7 @@ SET (cubicsdr_sources external/tinyxml/tinystr.cpp external/tinyxml/tinyxmlparser.cpp external/tinyxml/tinyxmlerror.cpp + external/cubicvr2/math/cubic_math.cpp ) SET (cubicsdr_headers @@ -312,6 +313,20 @@ SET (cubicsdr_headers external/lodepng/lodepng.h external/tinyxml/tinyxml.h external/tinyxml/tinystr.h + external/cubicvr2/math/aabb.h + external/cubicvr2/math/cubic_math.h + external/cubicvr2/math/cubic_types.h + external/cubicvr2/math/frustum.h + external/cubicvr2/math/mat3.h + external/cubicvr2/math/mat4.h + external/cubicvr2/math/plane.h + external/cubicvr2/math/quaternion.h + external/cubicvr2/math/sphere.h + external/cubicvr2/math/transform.h + external/cubicvr2/math/triangle.h + external/cubicvr2/math/vec2.h + external/cubicvr2/math/vec3.h + external/cubicvr2/math/vec4.h ) include_directories ( @@ -325,6 +340,7 @@ include_directories ( ${PROJECT_SOURCE_DIR}/external/rtaudio ${PROJECT_SOURCE_DIR}/external/lodepng ${PROJECT_SOURCE_DIR}/external/tinyxml + ${PROJECT_SOURCE_DIR}/external/cubicvr2/math ) IF (MSVC) diff --git a/external/cubicvr2/math/aabb.h b/external/cubicvr2/math/aabb.h new file mode 100644 index 0000000..bcf34ba --- /dev/null +++ b/external/cubicvr2/math/aabb.h @@ -0,0 +1,110 @@ +// +// aabb.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__aabb__ +#define __CubicVR2__aabb__ + +#include +#include "vec3.h" + +namespace CubicVR { + + enum aabb_enum { AABB_DISJOINT, AABB_A_INSIDE_B, AABB_B_INSIDE_A, AABB_INTERSECT }; + + struct aabb { + vec3 min, max; + + aabb(vec3 min_in, vec3 max_in) { + min=min_in; + max=max_in; + } + + aabb() { + min=max=vec3(0,0,0); + } + + aabb engulf(aabb aabb, vec3 point) { + if (aabb.min[0] > point[0]) { + aabb.min[0] = point[0]; + } + if (aabb.min[1] > point[1]) { + aabb.min[1] = point[1]; + } + if (aabb.min[2] > point[2]) { + aabb.min[2] = point[2]; + } + if (aabb.max[0] < point[0]) { + aabb.max[0] = point[0]; + } + if (aabb.max[1] < point[1]) { + aabb.max[1] = point[1]; + } + if (aabb.max[2] < point[2]) { + aabb.max[2] = point[2]; + } + return aabb; + }; + + static aabb reset(aabb aabb, vec3 point=vec3(0.0f,0.0f,0.0f)) { + + aabb.min[0] = point[0]; + aabb.min[1] = point[1]; + aabb.min[2] = point[2]; + aabb.max[0] = point[0]; + aabb.max[1] = point[1]; + aabb.max[2] = point[2]; + + return aabb; + }; + + static vec3 size(aabb aabb) { + __float x = aabb.min[0] < aabb.max[0] ? aabb.max[0] - aabb.min[0] : aabb.min[0] - aabb.max[0]; + __float y = aabb.min[1] < aabb.max[1] ? aabb.max[1] - aabb.min[1] : aabb.min[1] - aabb.max[1]; + __float z = aabb.min[2] < aabb.max[2] ? aabb.max[2] - aabb.min[2] : aabb.min[2] - aabb.max[2]; + return vec3(x,y,z); + }; + /** + Returns positive integer if intersect between A and B, 0 otherwise. + For more detailed intersect result check value: + CubicVR.enums.aabb.INTERSECT if AABBs intersect + CubicVR.enums.aabb.A_INSIDE_B if boxA is inside boxB + CubicVR.enums.aabb.B_INSIDE_A if boxB is inside boxA + CubicVR.enums.aabb.DISJOINT if AABBs are disjoint (do not intersect) + */ + aabb_enum intersects(aabb boxA, aabb boxB) { + // Disjoint + if( boxA.min[0] > boxB.max[0] || boxA.max[0] < boxB.min[0] ){ + return AABB_DISJOINT; + } + if( boxA.min[1] > boxB.max[1] || boxA.max[1] < boxB.min[1] ){ + return AABB_DISJOINT; + } + if( boxA.min[2] > boxB.max[2] || boxA.max[2] < boxB.min[2] ){ + return AABB_DISJOINT; + } + + // boxA is inside boxB. + if( boxA.min[0] >= boxB.min[0] && boxA.max[0] <= boxB.max[0] && + boxA.min[1] >= boxB.min[1] && boxA.max[1] <= boxB.max[1] && + boxA.min[2] >= boxB.min[2] && boxA.max[2] <= boxB.max[2]) { + return AABB_A_INSIDE_B; + } + // boxB is inside boxA. + if( boxB.min[0] >= boxA.min[0] && boxB.max[0] <= boxA.max[0] && + boxB.min[1] >= boxA.min[1] && boxB.max[1] <= boxA.max[1] && + boxB.min[2] >= boxA.min[2] && boxB.max[2] <= boxA.max[2]) { + return AABB_B_INSIDE_A; + } + + // Otherwise AABB's intersect. + return AABB_INTERSECT; + } + }; +}; + +#endif /* defined(__CubicVR2__aabb__) */ diff --git a/external/cubicvr2/math/cubic_math.cpp b/external/cubicvr2/math/cubic_math.cpp new file mode 100644 index 0000000..45470ff --- /dev/null +++ b/external/cubicvr2/math/cubic_math.cpp @@ -0,0 +1,27 @@ +// +// math.cpp +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#include "cubic_math.h" + +namespace CubicVR { + std::ostream& operator<<(std::ostream &strm, const vec4 &v) { + return strm << "{" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "}"; + } + std::ostream& operator<<(std::ostream &strm, const vec3 &v) { + return strm << "{" << v.x << ", " << v.y << ", " << v.z << "}"; + } + std::ostream& operator<<(std::ostream &strm, const vec2 &v) { + return strm << "{" << v.x << ", " << v.y << "}"; + } + std::ostream& operator<<(std::ostream &strm, const mat4 &m) { + return strm << "{ " << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << endl + << " " << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << endl + << " " << m[8] << ", " << m[9] << ", " << m[10] << ", " << m[11] << endl + << " " << m[12] << ", " << m[13] << ", " << m[14] << ", " << m[15] << " }" << endl; + } +} diff --git a/external/cubicvr2/math/cubic_math.h b/external/cubicvr2/math/cubic_math.h new file mode 100644 index 0000000..7f74264 --- /dev/null +++ b/external/cubicvr2/math/cubic_math.h @@ -0,0 +1,35 @@ +// +// math.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__math__ +#define __CubicVR2__math__ + +#include + +#include "aabb.h" +#include "mat3.h" +#include "mat4.h" +#include "quaternion.h" +#include "transform.h" +#include "triangle.h" +#include "vec2.h" +#include "vec3.h" +#include "vec4.h" +#include "plane.h" +#include "sphere.h" +#include "frustum.h" + +namespace CubicVR { + std::ostream& operator<<(std::ostream &strm, const vec4 &v); + std::ostream& operator<<(std::ostream &strm, const vec3 &v); + std::ostream& operator<<(std::ostream &strm, const vec2 &v); + std::ostream& operator<<(std::ostream &strm, const mat4 &m); +} + + +#endif /* defined(__CubicVR2__math__) */ diff --git a/external/cubicvr2/math/cubic_types.h b/external/cubicvr2/math/cubic_types.h new file mode 100644 index 0000000..bc4ddc7 --- /dev/null +++ b/external/cubicvr2/math/cubic_types.h @@ -0,0 +1,41 @@ +// +// types.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-21. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef CubicVR2_types_h +#define CubicVR2_types_h + +namespace CubicVR { + + typedef double __float64; + typedef float __float32; + + typedef __float32 __float; + + #define COMBINE(x,y) x ## y + #define floatSG(c, x,y) \ + __float COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(__float value) { y = value; return *this; } + #define intSG(c, x,y) \ + int COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(int value) { y = value; return *this; } + #define uintSG(c, x,y) \ + unsigned int COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(unsigned int value) { y = value; return *this; } + #define boolSG(c,x,y) \ + bool COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(bool value) { y = value; return *this; } + #define stringSG(c,x,y) \ + string COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(string value) { y = value; return *this; } + #define isBoolSG(c,x,y) \ + bool COMBINE(is,x)() { return y; } \ + c & COMBINE(set,x)(bool value) { y = value; return *this; } + +} + +#endif diff --git a/external/cubicvr2/math/frustum.h b/external/cubicvr2/math/frustum.h new file mode 100644 index 0000000..5da030f --- /dev/null +++ b/external/cubicvr2/math/frustum.h @@ -0,0 +1,166 @@ +// +// frustum.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef CubicVR2_frustum_h +#define CubicVR2_frustum_h + +#include +#include "mat4.h" +#include "vec3.h" +#include "vec4.h" +#include "plane.h" + +namespace CubicVR { + + enum frustum_plane { PLANE_LEFT, PLANE_RIGHT, PLANE_TOP, PLANE_BOTTOM, PLANE_NEAR, PLANE_FAR }; + + struct frustum { + std::vector planes; + vec4 sphere; + + frustum() { + planes.resize(6); + for (int i = 0; i < 6; ++i) { + planes[i] = vec4(0, 0, 0, 0); + } //for + } //Frustum::Constructor + + void extract(vec3 position, mat4 mvMatrix, mat4 pMatrix) { + mat4 comboMatrix = mat4::multiply(pMatrix, mvMatrix, true); + + // Left clipping plane + planes[PLANE_LEFT][0] = comboMatrix[3] + comboMatrix[0]; + planes[PLANE_LEFT][1] = comboMatrix[7] + comboMatrix[4]; + planes[PLANE_LEFT][2] = comboMatrix[11] + comboMatrix[8]; + planes[PLANE_LEFT][3] = comboMatrix[15] + comboMatrix[12]; + + // Right clipping plane + planes[PLANE_RIGHT][0] = comboMatrix[3] - comboMatrix[0]; + planes[PLANE_RIGHT][1] = comboMatrix[7] - comboMatrix[4]; + planes[PLANE_RIGHT][2] = comboMatrix[11] - comboMatrix[8]; + planes[PLANE_RIGHT][3] = comboMatrix[15] - comboMatrix[12]; + + // Top clipping plane + planes[PLANE_TOP][0] = comboMatrix[3] - comboMatrix[1]; + planes[PLANE_TOP][1] = comboMatrix[7] - comboMatrix[5]; + planes[PLANE_TOP][2] = comboMatrix[11] - comboMatrix[9]; + planes[PLANE_TOP][3] = comboMatrix[15] - comboMatrix[13]; + + // Bottom clipping plane + planes[PLANE_BOTTOM][0] = comboMatrix[3] + comboMatrix[1]; + planes[PLANE_BOTTOM][1] = comboMatrix[7] + comboMatrix[5]; + planes[PLANE_BOTTOM][2] = comboMatrix[11] + comboMatrix[9]; + planes[PLANE_BOTTOM][3] = comboMatrix[15] + comboMatrix[13]; + + // Near clipping plane + planes[PLANE_NEAR][0] = comboMatrix[3] + comboMatrix[2]; + planes[PLANE_NEAR][1] = comboMatrix[7] + comboMatrix[6]; + planes[PLANE_NEAR][2] = comboMatrix[11] + comboMatrix[10]; + planes[PLANE_NEAR][3] = comboMatrix[15] + comboMatrix[14]; + + // Far clipping plane + planes[PLANE_FAR][0] = comboMatrix[3] - comboMatrix[2]; + planes[PLANE_FAR][1] = comboMatrix[7] - comboMatrix[6]; + planes[PLANE_FAR][2] = comboMatrix[11] - comboMatrix[10]; + planes[PLANE_FAR][3] = comboMatrix[15] - comboMatrix[14]; + + for (unsigned int i = 0; i < 6; ++i) { + planes[i] = vec4::normalize(planes[i]); + } + + //Sphere + __float fov = 1 / pMatrix[5]; + __float near = -planes[PLANE_NEAR][3]; + __float far = planes[PLANE_FAR][3]; + __float view_length = far - near; + __float height = view_length * fov; + __float width = height; + + vec3 P(0, 0, near + view_length * 0.5f); + vec3 Q(width, height, near + view_length); + vec3 diff = vec3::subtract(P, Q); + __float diff_mag = vec3::length(diff); + + vec3 look_v = vec3(comboMatrix[3], comboMatrix[9], comboMatrix[10]); + __float look_mag = vec3::length(look_v); + look_v = vec3::multiply(look_v, 1 / look_mag); + + vec3 pos = vec3(position[0], position[1], position[2]); + pos = vec3::add(pos, vec3::multiply(look_v, view_length * 0.5f)); + pos = vec3::add(pos, vec3::multiply(look_v, 1)); + + sphere = vec4(pos[0], pos[1], pos[2], diff_mag); + + }; //Frustum::extract + + int contains_sphere(vec4 sphere) { + + for (unsigned int i = 0; i < 6; ++i) { + vec4 &p = planes[i]; + vec3 normal = vec3(p[0], p[1], p[2]); + __float distance = vec3::dot(normal, vec3(sphere[0],sphere[1],sphere[2])) + p[3]; + + //OUT + if (distance < -sphere[3]) { + return -1; + } + + //INTERSECT + if (fabs(distance) < sphere[3]) { + return 0; + } + + } //for + //IN + return 1; + }; //Frustum::contains_sphere + + int contains_box(aabb bbox) { + int total_in = 0; + + vec3 points[8]; + + points[0] = bbox.min; + points[1] = vec3(bbox.min[0], bbox.min[1], bbox.max[2]); + points[2] = vec3(bbox.min[0], bbox.max[1], bbox.min[2]); + points[3] = vec3(bbox.min[0], bbox.max[1], bbox.max[2]); + points[4] = vec3(bbox.max[0], bbox.min[1], bbox.min[2]); + points[5] = vec3(bbox.max[0], bbox.min[1], bbox.max[2]); + points[6] = vec3(bbox.max[0], bbox.max[1], bbox.min[2]); + points[7] = bbox.max; + + for (unsigned int i = 0; i < 6; ++i) { + unsigned int in_count = 8; + unsigned int point_in = 1; + + for (unsigned int j = 0; j < 8; ++j) { + if (plane::classifyPoint(planes[i], points[j]) == -1) { + point_in = 0; + --in_count; + } //if + } //for j + + //OUT + if (in_count == 0) { + return -1; + } + + total_in += point_in; + } //for i + //IN + if (total_in == 6) { + return 1; + } + + return 0; + }; //Frustum::contains_box + + }; +} + +#endif diff --git a/external/cubicvr2/math/mat3.h b/external/cubicvr2/math/mat3.h new file mode 100644 index 0000000..90553c4 --- /dev/null +++ b/external/cubicvr2/math/mat3.h @@ -0,0 +1,83 @@ +// +// mat3.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__mat3__ +#define __CubicVR2__mat3__ + +#include +#include "vec3.h" + +namespace CubicVR { + + #define mat3SG(c,x,y) \ + mat3 COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(mat3 value) { y = value; return *this; } + + struct mat3 { + __float a,b,c,d,e,f,g,h,i; + + // __float operator [] (unsigned i) const { return ((__float *)this)[i]; } + __float& operator [] (unsigned i) { return ((__float *)this)[i]; } + operator __float*() const { return (__float *)this; } + + mat3(__float ai,__float bi,__float ci,__float di,__float ei,__float fi,__float gi,__float hi,__float ii) { + a = ai; b = bi; c = ci; d = di; e = ei; f = fi; g = gi; h = hi; i = ii; + }; + + mat3() { memset((__float *)this, 0, sizeof(mat3)); } + // mat3 operator* (mat4 m) { return mat3::multiply(*this,m); }; + // void operator*= (mat4 m) { *this = mat3::multiply(*this,m); }; + + + static mat3 identity() { + return mat3(1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f); + } + + static void transpose_inline(mat3 &mat) { + __float a01 = mat[1], a02 = mat[2], a12 = mat[5]; + + mat[1] = mat[3]; + mat[2] = mat[6]; + mat[3] = a01; + mat[5] = mat[7]; + mat[6] = a02; + mat[7] = a12; + }; + + static mat3 transpose(mat3 mat_in) { + __float a01 = mat_in[1], a02 = mat_in[2], a12 = mat_in[5]; + + mat3 mat; + + mat[1] = mat_in[3]; + mat[2] = mat_in[6]; + mat[3] = a01; + mat[5] = mat_in[7]; + mat[6] = a02; + mat[7] = a12; + + return mat; + }; + + static vec3 multiply(mat3 m1, vec3 m2) { + vec3 mOut; + + mOut[0] = m2[0] * m1[0] + m2[3] * m1[1] + m2[6] * m1[2] ; + mOut[1] = m2[1] * m1[0] + m2[4] * m1[1] + m2[7] * m1[2] ; + mOut[2] = m2[2] * m1[0] + m2[5] * m1[1] + m2[8] * m1[2]; + + return mOut; + }; + }; + + +} + +#endif /* defined(__CubicVR2__mat3__) */ diff --git a/external/cubicvr2/math/mat4.h b/external/cubicvr2/math/mat4.h new file mode 100644 index 0000000..b54029b --- /dev/null +++ b/external/cubicvr2/math/mat4.h @@ -0,0 +1,304 @@ +// +// mat4.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-21. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__mat4__ +#define __CubicVR2__mat4__ + +#include +#include "cubic_types.h" +#include "vec3.h" +#include "vec4.h" +#include "mat3.h" +#include + +namespace CubicVR { + using namespace std; + #define mat4SG(c,x,y) \ + mat4 COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(mat4 value) { y = value; return *this; } + struct mat4 { + __float a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p; + + // __float operator [] (unsigned i) const { return ((__float *)this)[i]; } + __float& operator [] (unsigned i) { return ((__float *)this)[i]; } + operator __float*() const { return (__float *)this; } + mat4(__float ai,__float bi,__float ci,__float di,__float ei,__float fi,__float gi,__float hi,__float ii,__float ji,__float ki,__float li,__float mi,__float ni,__float oi,__float pi) { + a = ai; b = bi; c = ci; d = di; e = ei; f = fi; g = gi; h = hi; i = ii; j = ji; k = ki; l = li; m = mi; n = ni; o = oi; p = pi; + } + mat4() { memset(this,0,sizeof(mat4)); } + mat4 operator* (mat4 m) { return mat4::multiply(*this, m, true); }; + void operator*= (mat4 m) { *this = mat4::multiply(*this, m, true); }; +// mat4 &operator= (const mat4 &m) { memcpy(this,(__float *)m,sizeof(__float)*16); return *this; }; + + static mat4 identity() { + return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } + + static mat4 multiply(mat4 mLeft, mat4 mRight, bool updated) { + mat4 mOut; + + mOut[0] = mLeft[0] * mRight[0] + mLeft[4] * mRight[1] + mLeft[8] * mRight[2] + mLeft[12] * mRight[3]; + mOut[1] = mLeft[1] * mRight[0] + mLeft[5] * mRight[1] + mLeft[9] * mRight[2] + mLeft[13] * mRight[3]; + mOut[2] = mLeft[2] * mRight[0] + mLeft[6] * mRight[1] + mLeft[10] * mRight[2] + mLeft[14] * mRight[3]; + mOut[3] = mLeft[3] * mRight[0] + mLeft[7] * mRight[1] + mLeft[11] * mRight[2] + mLeft[15] * mRight[3]; + mOut[4] = mLeft[0] * mRight[4] + mLeft[4] * mRight[5] + mLeft[8] * mRight[6] + mLeft[12] * mRight[7]; + mOut[5] = mLeft[1] * mRight[4] + mLeft[5] * mRight[5] + mLeft[9] * mRight[6] + mLeft[13] * mRight[7]; + mOut[6] = mLeft[2] * mRight[4] + mLeft[6] * mRight[5] + mLeft[10] * mRight[6] + mLeft[14] * mRight[7]; + mOut[7] = mLeft[3] * mRight[4] + mLeft[7] * mRight[5] + mLeft[11] * mRight[6] + mLeft[15] * mRight[7]; + mOut[8] = mLeft[0] * mRight[8] + mLeft[4] * mRight[9] + mLeft[8] * mRight[10] + mLeft[12] * mRight[11]; + mOut[9] = mLeft[1] * mRight[8] + mLeft[5] * mRight[9] + mLeft[9] * mRight[10] + mLeft[13] * mRight[11]; + mOut[10] = mLeft[2] * mRight[8] + mLeft[6] * mRight[9] + mLeft[10] * mRight[10] + mLeft[14] * mRight[11]; + mOut[11] = mLeft[3] * mRight[8] + mLeft[7] * mRight[9] + mLeft[11] * mRight[10] + mLeft[15] * mRight[11]; + mOut[12] = mLeft[0] * mRight[12] + mLeft[4] * mRight[13] + mLeft[8] * mRight[14] + mLeft[12] * mRight[15]; + mOut[13] = mLeft[1] * mRight[12] + mLeft[5] * mRight[13] + mLeft[9] * mRight[14] + mLeft[13] * mRight[15]; + mOut[14] = mLeft[2] * mRight[12] + mLeft[6] * mRight[13] + mLeft[10] * mRight[14] + mLeft[14] * mRight[15]; + mOut[15] = mLeft[3] * mRight[12] + mLeft[7] * mRight[13] + mLeft[11] * mRight[14] + mLeft[15] * mRight[15]; + + return mOut; + }; + + static vec3 multiply(mat4 m1, vec3 m2, bool updated) { + vec3 mOut; + + mOut[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12]; + mOut[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13]; + mOut[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14]; + + return mOut; + } + + static mat4 perspective(__float fovy, __float aspect, __float near, __float far) { + __float yFac = tan(fovy * (float)M_PI / 360.0f); + __float xFac = yFac * aspect; + + return mat4( + 1.0f / xFac, 0, 0, 0, 0, 1.0f / yFac, 0, 0, 0, 0, -(far + near) / (far - near), -1, 0, 0, -(2.0f * far * near) / (far - near), 0); + }; + static mat4 ortho(__float left,__float right,__float bottom,__float top,__float near,__float far) { + return mat4(2.0f / (right - left), 0, 0, 0, 0, 2.0f / (top - bottom), 0, 0, 0, 0, -2.0f / (far - near), 0, -(left + right) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1); + }; + static __float determinant(mat4 m) { + + __float a0 = m[0] * m[5] - m[1] * m[4]; + __float a1 = m[0] * m[6] - m[2] * m[4]; + __float a2 = m[0] * m[7] - m[3] * m[4]; + __float a3 = m[1] * m[6] - m[2] * m[5]; + __float a4 = m[1] * m[7] - m[3] * m[5]; + __float a5 = m[2] * m[7] - m[3] * m[6]; + __float b0 = m[8] * m[13] - m[9] * m[12]; + __float b1 = m[8] * m[14] - m[10] * m[12]; + __float b2 = m[8] * m[15] - m[11] * m[12]; + __float b3 = m[9] * m[14] - m[10] * m[13]; + __float b4 = m[9] * m[15] - m[11] * m[13]; + __float b5 = m[10] * m[15] - m[11] * m[14]; + + __float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0; + + return det; + }; + // coFactor: function (m, n, out) { + // // .. todo.. + // }, + + static mat4 transpose(mat4 m) { + return mat4(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]); + }; + + static mat3 inverse_mat3(mat4 mat) { + mat3 dest; + + __float a00 = mat[0], a01 = mat[1], a02 = mat[2], + a10 = mat[4], a11 = mat[5], a12 = mat[6], + a20 = mat[8], a21 = mat[9], a22 = mat[10]; + + __float b01 = a22*a11-a12*a21, + b11 = -a22*a10+a12*a20, + b21 = a21*a10-a11*a20; + + __float d = a00*b01 + a01*b11 + a02*b21; + if (!d) { return dest; } + __float id = 1/d; + + dest[0] = b01*id; + dest[1] = (-a22*a01 + a02*a21)*id; + dest[2] = (a12*a01 - a02*a11)*id; + dest[3] = b11*id; + dest[4] = (a22*a00 - a02*a20)*id; + dest[5] = (-a12*a00 + a02*a10)*id; + dest[6] = b21*id; + dest[7] = (-a21*a00 + a01*a20)*id; + dest[8] = (a11*a00 - a01*a10)*id; + + return dest; + }; + + static mat4 inverse(mat4 m) { + mat4 m_inv; + + __float a0 = m[0] * m[5] - m[1] * m[4]; + __float a1 = m[0] * m[6] - m[2] * m[4]; + __float a2 = m[0] * m[7] - m[3] * m[4]; + __float a3 = m[1] * m[6] - m[2] * m[5]; + __float a4 = m[1] * m[7] - m[3] * m[5]; + __float a5 = m[2] * m[7] - m[3] * m[6]; + __float b0 = m[8] * m[13] - m[9] * m[12]; + __float b1 = m[8] * m[14] - m[10] * m[12]; + __float b2 = m[8] * m[15] - m[11] * m[12]; + __float b3 = m[9] * m[14] - m[10] * m[13]; + __float b4 = m[9] * m[15] - m[11] * m[13]; + __float b5 = m[10] * m[15] - m[11] * m[14]; + + __float determinant = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0; + + if (determinant != 0) { + m_inv[0] = 0 + m[5] * b5 - m[6] * b4 + m[7] * b3; + m_inv[4] = 0 - m[4] * b5 + m[6] * b2 - m[7] * b1; + m_inv[8] = 0 + m[4] * b4 - m[5] * b2 + m[7] * b0; + m_inv[12] = 0 - m[4] * b3 + m[5] * b1 - m[6] * b0; + m_inv[1] = 0 - m[1] * b5 + m[2] * b4 - m[3] * b3; + m_inv[5] = 0 + m[0] * b5 - m[2] * b2 + m[3] * b1; + m_inv[9] = 0 - m[0] * b4 + m[1] * b2 - m[3] * b0; + m_inv[13] = 0 + m[0] * b3 - m[1] * b1 + m[2] * b0; + m_inv[2] = 0 + m[13] * a5 - m[14] * a4 + m[15] * a3; + m_inv[6] = 0 - m[12] * a5 + m[14] * a2 - m[15] * a1; + m_inv[10] = 0 + m[12] * a4 - m[13] * a2 + m[15] * a0; + m_inv[14] = 0 - m[12] * a3 + m[13] * a1 - m[14] * a0; + m_inv[3] = 0 - m[9] * a5 + m[10] * a4 - m[11] * a3; + m_inv[7] = 0 + m[8] * a5 - m[10] * a2 + m[11] * a1; + m_inv[11] = 0 - m[8] * a4 + m[9] * a2 - m[11] * a0; + m_inv[15] = 0 + m[8] * a3 - m[9] * a1 + m[10] * a0; + + __float inverse_det = 1.0f / determinant; + + m_inv[0] *= inverse_det; + m_inv[1] *= inverse_det; + m_inv[2] *= inverse_det; + m_inv[3] *= inverse_det; + m_inv[4] *= inverse_det; + m_inv[5] *= inverse_det; + m_inv[6] *= inverse_det; + m_inv[7] *= inverse_det; + m_inv[8] *= inverse_det; + m_inv[9] *= inverse_det; + m_inv[10] *= inverse_det; + m_inv[11] *= inverse_det; + m_inv[12] *= inverse_det; + m_inv[13] *= inverse_det; + m_inv[14] *= inverse_det; + m_inv[15] *= inverse_det; + + return m_inv; + } + + return mat4::identity(); + }; + + static mat4 translate(__float x, __float y, __float z) { + mat4 m = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, x, y, z, 1.0f); + + return m; + }; + + static mat4 rotateAxis(__float r, __float x, __float y, __float z) { // rotate r about axis x,y,z + __float sAng = sinf(r*((float)M_PI/180.0f)); + __float cAng = cosf(r*((float)M_PI/180.0f)); + + return mat4( cAng+(x*x)*(1.0f-cAng), x*y*(1.0f-cAng) - z*sAng, x*z*(1.0f-cAng) + y*sAng, 0, + y*x*(1.0f-cAng)+z*sAng, cAng + y*y*(1.0f-cAng), y*z*(1.0f-cAng)-x*sAng, 0, + z*x*(1.0f-cAng)-y*sAng, z*y*(1.0f-cAng)+x*sAng, cAng+(z*z)*(1.0f-cAng), 0, + 0, 0, 0, 1 ); + }; + + static mat4 rotate(__float x, __float y, __float z) { // rotate each axis, angles x, y, z in turn + __float sAng,cAng; + mat4 mOut = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + + if (z!=0) { + sAng = sinf(z*((float)M_PI/180.0f)); + cAng = cosf(z*((float)M_PI/180.0f)); + + mOut *= mat4(cAng, sAng, 0.0f, 0.0f, -sAng, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } + + if (y!=0) { + sAng = sinf(y*((float)M_PI/180.0f)); + cAng = cosf(y*((float)M_PI/180.0f)); + + mOut *= mat4(cAng, 0.0f, -sAng, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, sAng, 0.0f, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } + + if (x!=0) { + sAng = sinf(x*((float)M_PI/180.0f)); + cAng = cosf(x*((float)M_PI/180.0f)); + + mOut *= mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, cAng, sAng, 0.0f, 0.0f, -sAng, cAng, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } + + return mOut; + }; + + static mat4 scale(__float x, __float y, __float z) { + return mat4(x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + }; + + static mat4 transform(vec3 position, vec3 rotation, vec3 scale) { + mat4 m = mat4::identity(); + + if (position!=NULL) { + m *= mat4::translate(position[0],position[1],position[2]); + } + if (rotation!=NULL) { + if (!(rotation[0] == 0 && rotation[1] == 0 && rotation[2] == 0)) { + m *= mat4::rotate(rotation[0],rotation[1],rotation[2]); + } + } + if (scale!=NULL) { + if (!(scale[0] == 1 && scale[1] == 1 && scale[2] == 1)) { + m *= mat4::scale(scale[0],scale[1],scale[2]); + } + } + + return m; + }; + static vec4 vec4_multiply(vec4 m1, mat4 m2) { + vec4 mOut; + + mOut[0] = m2[0] * m1[0] + m2[4] * m1[1] + m2[8] * m1[2] + m2[12] * m1[3]; + mOut[1] = m2[1] * m1[0] + m2[5] * m1[1] + m2[9] * m1[2] + m2[13] * m1[3]; + mOut[2] = m2[2] * m1[0] + m2[6] * m1[1] + m2[10] * m1[2] + m2[14] * m1[3]; + mOut[3] = m2[3] * m1[0] + m2[7] * m1[1] + m2[11] * m1[2] + m2[15] * m1[3]; + + return mOut; + }; + static mat4 lookat(__float eyex, __float eyey, __float eyez, __float centerx, __float centery, __float centerz, __float upx, __float upy, __float upz) { + vec3 forward, side, up; + + forward[0] = centerx - eyex; + forward[1] = centery - eyey; + forward[2] = centerz - eyez; + + up[0] = upx; + up[1] = upy; + up[2] = upz; + + forward = vec3::normalize(forward); + + /* Side = forward x up */ + side = vec3::cross(forward, up); + side = vec3::normalize(side); + + /* Recompute up as: up = side x forward */ + up = vec3::cross(side, forward); + + return mat4::translate(-eyex,-eyey,-eyez) * mat4( side[0], up[0], -forward[0], 0, side[1], up[1], -forward[1], 0, side[2], up[2], -forward[2], 0, 0, 0, 0, 1); + }; + }; + +} + +#endif /* defined(__CubicVR2__mat4__) */ diff --git a/external/cubicvr2/math/plane.h b/external/cubicvr2/math/plane.h new file mode 100644 index 0000000..4db2c2c --- /dev/null +++ b/external/cubicvr2/math/plane.h @@ -0,0 +1,32 @@ +// +// plane.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef CubicVR2_plane_h +#define CubicVR2_plane_h + +#include "vec4.h" +#include "vec3.h" + +namespace CubicVR { + + struct plane : vec4 { + static int classifyPoint(vec4 plane, vec3 pt) { + __float dist = (plane[0] * pt[0]) + (plane[1] * pt[1]) + (plane[2] * pt[2]) + (plane[3]); + if (dist < 0) { + return -1; + } + else if (dist > 0) { + return 1; + } + return 0; + }; + }; + +} + +#endif diff --git a/external/cubicvr2/math/quaternion.h b/external/cubicvr2/math/quaternion.h new file mode 100644 index 0000000..41d33db --- /dev/null +++ b/external/cubicvr2/math/quaternion.h @@ -0,0 +1,100 @@ +// +// quaternion.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__quaternion__ +#define __CubicVR2__quaternion__ + +#include +#include "vec4.h" +#include "mat4.h" + +namespace CubicVR { + + struct quaternion : vec4 { + + static vec4 fromMatrix(mat4 mat) { + __float t = 1 + mat[0] + mat[5] + mat[10]; + __float S,X,Y,Z,W; + + if ( t > 0.00000001 ) { + S = sqrtf(t) * 2; + X = ( mat[9] - mat[6] ) / S; + Y = ( mat[2] - mat[8] ) / S; + Z = ( mat[4] - mat[1] ) / S; + W = 0.25f * S; + } else { + if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0: + S = sqrtf( 1.0f + mat[0] - mat[5] - mat[10] ) * 2.0f; + X = 0.25f * S; + Y = (mat[4] + mat[1] ) / S; + Z = (mat[2] + mat[8] ) / S; + W = (mat[9] - mat[6] ) / S; + } else if ( mat[5] > mat[10] ) { // Column 1: + S = sqrtf( 1.0f + mat[5] - mat[0] - mat[10] ) * 2.0f; + X = (mat[4] + mat[1] ) / S; + Y = 0.25f * S; + Z = (mat[9] + mat[6] ) / S; + W = (mat[2] - mat[8] ) / S; + } else { // Column 2: + S = sqrtf( 1.0f + mat[10] - mat[0] - mat[5] ) * 2.0f; + X = (mat[2] + mat[8] ) / S; + Y = (mat[9] + mat[6] ) / S; + Z = 0.25f * S; + W = (mat[4] - mat[1] ) / S; + } + } + + return vec4(X,Y,Z,W); + }; + + static vec4 fromEuler(__float bank, __float heading, __float pitch) { // x,y,z + __float c1 = cosf(((float)M_PI / 180.0f) * heading / 2.0f); + __float s1 = sinf(((float)M_PI / 180.0f) * heading / 2.0f); + __float c2 = cosf(((float)M_PI / 180.0f) * pitch / 2.0f); + __float s2 = sinf(((float)M_PI / 180.0f) * pitch / 2.0f); + __float c3 = cosf(((float)M_PI / 180.0f) * bank / 2.0f); + __float s3 = sinf(((float)M_PI / 180.0f) * bank / 2.0f); + __float c1c2 = c1 * c2; + __float s1s2 = s1 * s2; + + vec4 mOut; + + mOut[0] = c1c2 * c3 - s1s2 * s3; + mOut[1] = c1c2 * s3 + s1s2 * c3; + mOut[2] = s1 * c2 * c3 + c1 * s2 * s3; + mOut[3] = c1 * s2 * c3 - s1 * c2 * s3; + + return mOut; + }; + + static vec3 toEuler(vec4 q) { + __float sqx = q[0] * q[0]; + __float sqy = q[1] * q[1]; + __float sqz = q[2] * q[2]; + __float sqw = q[3] * q[3]; + + __float x = (180.0f / (float)M_PI) * ((atan2f(2.0f * (q[1] * q[2] + q[0] * q[3]), (-sqx - sqy + sqz + sqw)))); + __float y = (180.0f / (float)M_PI) * ((asinf(-2.0f * (q[0] * q[2] - q[1] * q[3])))); + __float z = (180.0f / (float)M_PI) * ((atan2f(2.0f * (q[0] * q[1] + q[2] * q[3]), (sqx - sqy - sqz + sqw)))); + + return vec3(x, y, z); + }; + + static vec4 multiply(vec4 q1, vec4 q2) { + __float x = q1[0] * q2[3] + q1[3] * q2[0] + q1[1] * q2[2] - q1[2] * q2[1]; + __float y = q1[1] * q2[3] + q1[3] * q2[1] + q1[2] * q2[0] - q1[0] * q2[2]; + __float z = q1[2] * q2[3] + q1[3] * q2[2] + q1[0] * q2[1] - q1[1] * q2[0]; + __float w = q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2]; + + return vec4(x,y,z,w); + }; + + }; +} + +#endif /* defined(__CubicVR2__quaternion__) */ diff --git a/external/cubicvr2/math/sphere.h b/external/cubicvr2/math/sphere.h new file mode 100644 index 0000000..8e33530 --- /dev/null +++ b/external/cubicvr2/math/sphere.h @@ -0,0 +1,34 @@ +// +// sphere.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef CubicVR2_sphere_h +#define CubicVR2_sphere_h + +#include "vec3.h" +#include "vec4.h" + +namespace CubicVR { + + struct sphere { + bool intersects(vec4 sphere, vec4 other) { + vec3 spherePos(sphere[0], sphere[1], sphere[2]); + vec3 otherPos(other[0], other[1], other[2]); + vec3 diff = vec3::subtract(spherePos, otherPos); + + __float mag = sqrtf(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]); + __float sum_radii = sphere[3] + other[3]; + + if (mag * mag < sum_radii * sum_radii) { + return true; + } + return false; + } + }; +} + +#endif diff --git a/external/cubicvr2/math/transform.h b/external/cubicvr2/math/transform.h new file mode 100644 index 0000000..bd6ddde --- /dev/null +++ b/external/cubicvr2/math/transform.h @@ -0,0 +1,175 @@ +// +// Transform.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__Transform__ +#define __CubicVR2__Transform__ + +#include +#include "cubic_types.h" +#include "mat4.h" +#include "vec3.h" +#include + +namespace CubicVR { + + class transform { + std::vector m_stack; + std::vector m_cache; + int c_stack; + int valid; + mat4 result; + + transform() { + c_stack = 0; + valid = false; + result = mat4::identity(); + }; + + transform(mat4 init_mat) { + clearStack(init_mat); + }; + + void setIdentity() { + m_stack[c_stack] = mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + if (valid == c_stack && c_stack) { + valid--; + } + } + + mat4 getIdentity() { + return mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); + } + + void invalidate() { + valid = 0; + result = mat4::identity(); + } + + mat4 getResult() { + if (!c_stack) { + return m_stack[0]; + } + + mat4 m = getIdentity(); + + if (valid > c_stack-1) valid = c_stack-1; + + for (int i = valid; i < c_stack+1; i++) { + m = mat4::multiply(m, m_stack[i], true); + m_cache[i] = m; + } + + valid = c_stack-1; + + result = m_cache[c_stack]; + + return result; + } + + void pushMatrix(mat4 m) { + c_stack++; + m_stack[c_stack] = (m ? m : getIdentity()); + } + + void popMatrix() { + if (c_stack == 0) { + return; + } + c_stack--; + } + + void clearStack(mat4 init_mat) { + m_stack.clear(); + m_cache.clear(); + c_stack = 0; + valid = 0; + delete result; + result = mat4::identity(); + + if (init_mat != NULL) { + m_stack[0] = init_mat; + } else { + setIdentity(); + } + } + + void translate(__float x, __float y, __float z) { + mat4 m = getIdentity(); + + m[12] = x; + m[13] = y; + m[14] = z; + + m_stack[c_stack] = mat4::multiply(m, m_stack[c_stack], true); + if (valid == c_stack && c_stack) { + valid--; + } + } + + void scale(__float x, __float y, __float z) { + mat4 m = getIdentity(); + + m[0] = x; + m[5] = y; + m[10] = z; + + m_stack[c_stack] = mat4::multiply(m, m_stack[c_stack], true); + if (valid == c_stack && c_stack) { + valid--; + } + } + + void rotate(__float ang, __float x, __float y, __float z) { + __float sAng, cAng; + + if (x || y || z) { + sAng = sin(-ang * ((float)M_PI / 180.0f)); + cAng = cos(-ang * ((float)M_PI / 180.0f)); + } + + if (x) { + mat4 X_ROT = getIdentity(); + + X_ROT[5] = cAng * x; + X_ROT[9] = sAng * x; + X_ROT[6] = -sAng * x; + X_ROT[10] = cAng * x; + + m_stack[c_stack] = mat4::multiply(m_stack[c_stack], X_ROT, true); + } + + if (y) { + mat4 Y_ROT = getIdentity(); + + Y_ROT[0] = cAng * y; + Y_ROT[8] = -sAng * y; + Y_ROT[2] = sAng * y; + Y_ROT[10] = cAng * y; + + m_stack[c_stack] = mat4::multiply(m_stack[c_stack], Y_ROT, true); + } + + if (z) { + mat4 Z_ROT = getIdentity(); + + Z_ROT[0] = cAng * z; + Z_ROT[4] = sAng * z; + Z_ROT[1] = -sAng * z; + Z_ROT[5] = cAng * z; + + m_stack[c_stack] = mat4::multiply(m_stack[c_stack], Z_ROT, true); + } + + if (valid == c_stack && c_stack) { + valid--; + } + }; + }; +} + +#endif /* defined(__CubicVR2__Transform__) */ diff --git a/external/cubicvr2/math/triangle.h b/external/cubicvr2/math/triangle.h new file mode 100644 index 0000000..147380d --- /dev/null +++ b/external/cubicvr2/math/triangle.h @@ -0,0 +1,40 @@ +// +// triangle.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__triangle__ +#define __CubicVR2__triangle__ + +#include +#include "vec3.h" + +namespace CubicVR { + + struct triangle { + static vec3 normal(vec3 pt1, vec3 pt2, vec3 pt3) { + + __float v10 = pt1[0] - pt2[0]; + __float v11 = pt1[1] - pt2[1]; + __float v12 = pt1[2] - pt2[2]; + __float v20 = pt2[0] - pt3[0]; + __float v21 = pt2[1] - pt3[1]; + __float v22 = pt2[2] - pt3[2]; + + vec3 mOut; + + mOut[0] = v11 * v22 - v12 * v21; + mOut[1] = v12 * v20 - v10 * v22; + mOut[2] = v10 * v21 - v11 * v20; + + return mOut; + }; + }; + +} + + +#endif /* defined(__CubicVR2__triangle__) */ diff --git a/external/cubicvr2/math/vec2.h b/external/cubicvr2/math/vec2.h new file mode 100644 index 0000000..d7a7aad --- /dev/null +++ b/external/cubicvr2/math/vec2.h @@ -0,0 +1,92 @@ +// +// vec2.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__vec2__ +#define __CubicVR2__vec2__ + +#include +#include +#include "cubic_types.h" + +namespace CubicVR { + #define vec2SG(c,x,y) \ + vec2 COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(vec2 value) { y = value; return *this; } + + struct vec2 { + __float x, y; + public: + __float& u() { return x; } + __float& v() { return y; } + +// __float operator [] (unsigned i) const { return ((__float *)this)[i]; } + __float& operator [] (unsigned i) { return ((__float *)this)[i]; } + + vec2 (__float xi,__float yi) { x = xi; y = yi; } + vec2 () { x = y = 0.0f; } + + operator __float*() const { return (__float *)this; } + + vec2 operator*(__float v) { return vec2( x*v, y*v ); } + // vec2 operator*(vec2 v) { return vec2::cross(*this,v); } + vec2 operator+(vec2 v) { return vec2::add(*this,v); } + vec2 operator-(vec2 v) { return vec2::subtract(*this,v); } + + + static bool equal(vec2 a, vec2 b, __float epsilon = 0.00000001) { + return (fabs(a[0] - b[0]) < epsilon && fabs(a[1] - b[1]) < epsilon); + }; + + static bool onLine(vec2 a, vec2 b,vec2 c) { + __float minx = (a[0]b[0])?a[0]:b[0]; + __float maxy = (a[1]>b[1])?a[1]:b[1]; + + if ((minx <= c[0] && c[0] <= maxx) && (miny <= c[1] && c[1] <= maxy)) { + return true; + } else { + return false; + } + }; + + static vec2 lineIntersect(vec2 a1, vec2 a2, vec2 b1, vec2 b2) { + __float x1 = a1[0], y1 = a1[1], x2 = a2[0], y2 = a2[1]; + __float x3 = b1[0], y3 = b1[1], x4 = b2[0], y4 = b2[1]; + + __float d = ((x1-x2) * (y3-y4)) - ((y1-y2) * (x3-x4)); + if (d == 0) return vec2(INFINITY,INFINITY); + + __float xi = (((x3-x4) * ((x1*y2)-(y1*x2))) - ((x1-x2) *((x3*y4)-(y3*x4))))/d; + __float yi = (((y3-y4) * ((x1*y2)-(y1*x2))) - ((y1-y2) *((x3*y4)-(y3*x4))))/d; + + return vec2( xi,yi ); + }; + + static vec2 add(vec2 a,vec2 b) { + return vec2(a[0]+b[0],a[1]+b[1]); + }; + + static vec2 subtract(vec2 a, vec2 b) { + return vec2(a[0]-b[0],a[1]-b[1]); + }; + + static __float length(vec2 a,vec2 b) { + vec2 s(a[0]-b[0],a[1]-b[1]); + + return sqrtf(s[0]*s[0]+s[1]*s[1]); + }; + + static __float length(vec2 a) { + return sqrtf(a[0]*a[0]+a[1]*a[1]); + }; + + }; + +} +#endif /* defined(__CubicVR2__vec2__) */ diff --git a/external/cubicvr2/math/vec3.h b/external/cubicvr2/math/vec3.h new file mode 100644 index 0000000..9dcdca6 --- /dev/null +++ b/external/cubicvr2/math/vec3.h @@ -0,0 +1,170 @@ +// +// vec3.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-21. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__vec3__ +#define __CubicVR2__vec3__ + +#include +#include "cubic_types.h" +#include + +namespace CubicVR { + +#define vec3SG(c,x,y) \ + vec3 COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(vec3 value) { y = value; return *this; } + + + struct vec3 { + __float x,y,z; + + operator __float*() const { return (__float *)this; } + + __float& r() { return x; } + __float& g() { return y; } + __float& b() { return z; } + + __float& operator [] (unsigned i) { return ((__float *)this)[i]; } + vec3 (__float xi,__float yi,__float zi) { x = xi; y = yi; z = zi; } + vec3 () { x = y = z = 0.0f; } + + + vec3 operator*(__float v) { return vec3(x*v, y*v, z*v); } + vec3 operator*(vec3 v) { return vec3::cross(*this,v); } + vec3 operator+(vec3 v) { return vec3::add(*this,v); } + vec3 operator-(vec3 v) { return vec3::subtract(*this,v); } + + + static __float length(vec3 pta, vec3 ptb) { + __float a,b,c; + a = ptb[0]-pta[0]; + b = ptb[1]-pta[1]; + c = ptb[2]-pta[2]; + return sqrtf((a*a) + (b*b) + (c*c)); + }; + static __float length(vec3 pta) { + __float a,b,c; + a = pta[0]; + b = pta[1]; + c = pta[2]; + return sqrtf((a*a) + (b*b) + (c*c)); + }; + static vec3 normalize(vec3 pt) { + __float a = pt[0], b = pt[1], c = pt[2], + d = sqrtf((a*a) + (b*b) + (c*c)); + if (d) { + pt[0] = pt[0]/d; + pt[1] = pt[1]/d; + pt[2] = pt[2]/d; + + return pt; + } + + pt = vec3(0.0f,0.0f,0.0f); + + return pt; + }; + static __float dot(vec3 v1, vec3 v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; + }; + static __float angle(vec3 v1, vec3 v2) { + __float a = acosf((v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) / (sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]) * sqrtf(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2]))); + + return a; + }; + static vec3 cross(vec3 vectA, vec3 vectB) { + return vec3( + vectA[1] * vectB[2] - vectB[1] * vectA[2], vectA[2] * vectB[0] - vectB[2] * vectA[0], vectA[0] * vectB[1] - vectB[0] * vectA[1] + ); + }; + static vec3 multiply(vec3 vectA, __float constB) { + return vec3(vectA[0] * constB, vectA[1] * constB, vectA[2] * constB); + }; + static vec3 add(vec3 vectA, vec3 vectB) { + return vec3(vectA[0] + vectB[0], vectA[1] + vectB[1], vectA[2] + vectB[2]); + }; + + static vec3 subtract(vec3 vectA, vec3 vectB) { + return vec3(vectA[0] - vectB[0], vectA[1] - vectB[1], vectA[2] - vectB[2]); + }; + + static bool equal(vec3 a, vec3 b, __float epsilon = 0.0000001f) { + return ((fabs(a[0] - b[0]) < epsilon) && (fabs(a[1] - b[1]) < epsilon) && (fabs(a[2] - b[2]) < epsilon)); + }; + + static vec3 moveViewRelative(vec3 position, vec3 target, __float xdelta, __float zdelta) { + __float ang = atan2f(zdelta, xdelta); + __float cam_ang = atan2f(target[2] - position[2], target[0] - position[0]); + __float mag = sqrtf(xdelta * xdelta + zdelta * zdelta); + + __float move_ang = cam_ang + ang + (float)M_PI/2.0f; + + // if (typeof(alt_source) === 'object') { + // return [alt_source[0] + mag * Math.cos(move_ang), alt_source[1], alt_source[2] + mag * Math.sin(move_ang)]; + // } + + return vec3(position[0] + mag * cosf(move_ang), position[1], position[2] + mag * sinf(move_ang)); + }; + + static vec3 trackTarget(vec3 position, vec3 target, __float trackingSpeed, __float safeDistance) { + vec3 camv = vec3::subtract(target, position); + vec3 dist = camv; + __float fdist = vec3::length(dist); + vec3 motionv = camv; + + motionv = vec3::normalize(motionv); + motionv = vec3::multiply(motionv, trackingSpeed * (1.0f / (1.0f / (fdist - safeDistance)))); + + vec3 ret_pos; + + if (fdist > safeDistance) { + ret_pos = vec3::add(position, motionv); + } else if (fdist < safeDistance) { + motionv = camv; + motionv = vec3::normalize(motionv); + motionv = vec3::multiply(motionv, trackingSpeed * (1.0f / (1.0f / (fabsf(fdist - safeDistance))))); + ret_pos = vec3::subtract(position, motionv); + } else { + ret_pos = vec3(position[0], position[1] + motionv[2], position[2]); + } + + return ret_pos; + }; + + static vec3 getClosestTo(vec3 ptA, vec3 ptB, vec3 ptTest) { + vec3 S, T, U; + + S = vec3::subtract(ptB, ptA); + T = vec3::subtract(ptTest, ptA); + U = vec3::add(vec3::multiply(S, vec3::dot(S, T) / vec3::dot(S, S)), ptA); + + return U; + }; + + // linePlaneIntersect: function(normal, point_on_plane, segment_start, segment_end) + // { + // // form a plane from normal and point_on_plane and test segment start->end to find intersect point + // var denom,mu; + // + // var d = - normal[0] * point_on_plane[0] - normal[1] * point_on_plane[1] - normal[2] * point_on_plane[2]; + // + // // calculate position where the plane intersects the segment + // denom = normal[0] * (segment_end[0] - segment_start[0]) + normal[1] * (segment_end[1] - segment_start[1]) + normal[2] * (segment_end[2] - segment_start[2]); + // if (Math.fabs(denom) < 0.001) return false; + // + // mu = - (d + normal[0] * segment_start[0] + normal[1] * segment_start[1] + normal[2] * segment_start[2]) / denom; + // return [ + // (segment_start[0] + mu * (segment_end[0] - segment_start[0])), + // (segment_start[1] + mu * (segment_end[1] - segment_start[1])), + // (segment_start[2] + mu * (segment_end[2] - segment_start[2])) + // ]; + // } + }; + +} +#endif /* defined(__CubicVR2__vec3__) */ diff --git a/external/cubicvr2/math/vec4.h b/external/cubicvr2/math/vec4.h new file mode 100644 index 0000000..5975079 --- /dev/null +++ b/external/cubicvr2/math/vec4.h @@ -0,0 +1,71 @@ +// +// vec4.h +// CubicVR2 +// +// Created by Charles J. Cliffe on 2013-02-22. +// Copyright (c) 2013 Charles J. Cliffe. All rights reserved. +// + +#ifndef __CubicVR2__vec4__ +#define __CubicVR2__vec4__ + +#include +#include "cubic_types.h" +#include + +namespace CubicVR { + +#define vec4SG(c,x,y) \ + vec3 COMBINE(get,x)() { return y; } \ + c & COMBINE(set,x)(vec3 value) { y = value; return *this; } + + struct vec4 { + __float x,y,z,w; + public: + __float& r() { return x; } + __float& g() { return y; } + __float& b() { return z; } + __float& a() { return w; } + +// __float operator [] (unsigned i) const { return ((__float *)this)[i]; } + __float& operator [] (unsigned i) { return ((__float *)this)[i]; } + + vec4 (__float xi,__float yi,__float zi,__float wi) { x = xi; y = yi; z = zi; w = wi; } + vec4 () { x = y = z = w = 0.0f; } + + operator __float*() const { return (__float *)this; } + + vec4 operator*(__float v) { return vec4(x*v, y*v, z*v, w*v); } +// vec4 operator*(vec4 v) { return vec4::cross(*this,v); } +// vec4 operator+(vec4 v) { return vec4::add(*this,v); } +// vec4 operator-(vec4 v) { return vec4::subtract(*this,v); } + + static __float length(vec4 a, vec4 b) { + __float v[4] = {a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]}; + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + }; + + static __float length(vec4 v) { + return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + }; + + static vec4 normalize(vec4 v) { + __float n = sqrtf(vec4::length(v)); + + v[0] /= n; + v[1] /= n; + v[2] /= n; + v[3] /= n; + + return v; + }; + + static __float dot(vec4 v1, vec4 v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3]; + }; + + }; + +} + +#endif /* defined(__CubicVR2__vec4__) */ diff --git a/src/ui/GLPanel.cpp b/src/ui/GLPanel.cpp index e09217a..5b0c6aa 100644 --- a/src/ui/GLPanel.cpp +++ b/src/ui/GLPanel.cpp @@ -1,8 +1,8 @@ #include "GLPanel.h" +#include "cubic_math.h" - -GLPanel::GLPanel() : fillType(GLPANEL_FILL_SOLID), coord(GLPANEL_Y_DOWN_ZERO_ONE), contentsVisible(true) { +GLPanel::GLPanel() : fillType(GLPANEL_FILL_SOLID), contentsVisible(true), transform(CubicVR::mat4::identity()) { pos[0] = 0.0f; pos[1] = 0.0f; size[0] = 1.0f; @@ -10,7 +10,7 @@ GLPanel::GLPanel() : fillType(GLPANEL_FILL_SOLID), coord(GLPANEL_Y_DOWN_ZERO_ONE fill[0] = RGB(0.5,0.5,0.5); fill[1] = RGB(0.1,0.1,0.1); borderColor = RGB(0.8, 0.8, 0.8); - genArrays(); + setCoordinateSystem(GLPANEL_Y_DOWN_ZERO_ONE); } void GLPanel::genArrays() { @@ -125,6 +125,7 @@ void GLPanel::genArrays() { } } + void GLPanel::setViewport() { GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); @@ -151,6 +152,23 @@ float GLPanel::getHeightPx() { return size[1]*view[0]; } + +void GLPanel::setCoordinateSystem(GLPanelCoordinateSystem coord_in) { + coord = coord_in; + + if (coord == GLPANEL_Y_DOWN || coord == GLPANEL_Y_UP) { + min = -1; + mid = 0; + max = 1; + } else { + min = 0; + mid = 0.5; + max = 1; + } + + genArrays(); +} + void GLPanel::setFill(GLPanelFillType fill_mode) { fillType = fill_mode; genArrays(); @@ -202,7 +220,7 @@ void GLPanel::drawChildren() { std::vector::iterator panel_i; for (panel_i = children.begin(); panel_i != children.end(); panel_i++) { - (*panel_i)->draw(this); + (*panel_i)->draw(transform, this); } } } @@ -211,41 +229,53 @@ void GLPanel::drawPanelContents() { drawChildren(); } -void GLPanel::draw(GLPanel *parent) { - float min, mid, max; +void GLPanel::draw(CubicVR::mat4 transform_in, GLPanel *parent) { + using namespace CubicVR; - if (coord == GLPANEL_Y_DOWN || coord == GLPANEL_Y_UP) { - min = -1; - mid = 0; - max = 1; - } else { - min = 0; - mid = 0.5; - max = 1; - } + mat4 mCoord = mat4::identity(); if (!parent) { if (coord == GLPANEL_Y_DOWN_ZERO_ONE) { - glPushMatrix(); - glTranslatef(-1.0f, 1.0f, 0.0f); - glScalef(2.0f, -2.0f, 2.0f); + mCoord *= mat4::translate(-1.0f, 1.0f, 0.0f) * mat4::scale(2.0f, -2.0f, 2.0f); } if (coord == GLPANEL_Y_UP_ZERO_ONE) { - glPushMatrix(); - glTranslatef(-1.0f, -1.0f, 0.0f); - glScalef(2.0f, 2.0f, 2.0f); + mCoord = mat4::translate(-1.0f, -1.0f, 0.0f) * mat4::scale(2.0f, 2.0f, 2.0f); } if (coord == GLPANEL_Y_DOWN) { - glPushMatrix(); - glScalef(1.0f, -1.0f, 1.0f); - } - if (coord == GLPANEL_Y_UP) { - glPushMatrix(); + mCoord = mat4::scale(2.0f, 2.0f, 2.0f); } +// if (coord == GLPANEL_Y_UP) { +// } } - glPushMatrix(); - glTranslatef(pos[0]+margin.left, pos[1]+margin.top, 0); - glScalef(size[0]-(margin.left+margin.right), size[1]-(margin.top+margin.bottom), 0); + + // compute local transform + localTransform = mCoord * mat4::translate(pos[0]+margin.left, pos[1]+margin.top, 0) * + mat4::scale(size[0]-(margin.left+margin.right), size[1]-(margin.top+margin.bottom), 0); + + // compute global transform + transform = transform_in * localTransform; + + glLoadMatrixf(transform); + + // init view[] + setViewport(); + + // get min/max transform + vec4 vmin_t = mat4::vec4_multiply(vec4(min, min, 0, 1), transform); + vec4 vmax_t = mat4::vec4_multiply(vec4(max, max, 0, 1), transform); + + // screen dimensions + vec2 vmin((vmin_t.x>vmax_t.x)?vmax_t.x:vmin_t.x, vmin.y = (vmin_t.y>vmax_t.y)?vmax_t.y:vmin_t.y); + vec2 vmax((vmin_t.y>vmax_t.y)?vmin_t.y:vmax_t.y, vmax.y = (vmin_t.y>vmax_t.y)?vmin_t.y:vmax_t.y); + + // unit dimensions + vec2 umin = (vmin * 0.5) + vec2(1,1); + vec2 umax = (vmax * 0.5) + vec2(1,1); + + // pixel dimensions + vec2 pdim((umax.x - umin.x) * view[0], (umax.y - umin.y) * view[1]); + + std::cout << umin << " :: " << umax << " :: " << pdim << std::endl; if (fillType != GLPANEL_FILL_NONE) { glEnableClientState(GL_VERTEX_ARRAY); @@ -303,11 +333,6 @@ void GLPanel::draw(GLPanel *parent) { drawPanelContents(); glPopMatrix(); } - - glPopMatrix(); - if (!parent) { - glPopMatrix(); - } } diff --git a/src/ui/GLPanel.h b/src/ui/GLPanel.h index 4ec248d..5de11d1 100644 --- a/src/ui/GLPanel.h +++ b/src/ui/GLPanel.h @@ -3,6 +3,7 @@ #include #include "GLExt.h" #include "ColorTheme.h" +#include "cubic_math.h" class GLPanelEdges { public: @@ -26,8 +27,9 @@ class GLPanel { private: std::vector glPoints; std::vector glColors; - + void genArrays(); + void setViewport(); public: typedef enum GLPanelFillType { GLPANEL_FILL_NONE, GLPANEL_FILL_SOLID, GLPANEL_FILL_GRAD_X, GLPANEL_FILL_GRAD_Y, GLPANEL_FILL_GRAD_BAR_X, GLPANEL_FILL_GRAD_BAR_Y } GLPanelFillType; @@ -42,16 +44,19 @@ public: RGB fill[2]; RGB borderColor; bool contentsVisible; - + CubicVR::mat4 transform; + CubicVR::mat4 localTransform; + float min, mid, max; + std::vector children; GLPanel(); - void setViewport(); void setPosition(float x, float y); void setSize(float w, float h); float getWidthPx(); float getHeightPx(); + void setCoordinateSystem(GLPanelCoordinateSystem coord); void setFill(GLPanelFillType fill_mode); void setFillColor(RGB color1); @@ -67,7 +72,7 @@ public: void drawChildren(); virtual void drawPanelContents(); - void draw(GLPanel *parent=NULL); + void draw(CubicVR::mat4 transform, GLPanel *parent=NULL); }; diff --git a/src/ui/UITestContext.cpp b/src/ui/UITestContext.cpp index b1b48fb..3169469 100644 --- a/src/ui/UITestContext.cpp +++ b/src/ui/UITestContext.cpp @@ -44,7 +44,7 @@ void UITestContext::DrawBegin() { } void UITestContext::Draw() { - testPanel.draw(); + testPanel.draw(CubicVR::mat4::identity()); } void UITestContext::DrawEnd() {