mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-16 00:51:49 -05:00
171 lines
6.7 KiB
C++
171 lines
6.7 KiB
C++
//
|
|
// 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 <iostream>
|
|
#include "cubic_types.h"
|
|
#include <cmath>
|
|
|
|
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__) */
|