Added own camera object and its vectorial dependency.
This commit is contained in:
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_CONFIG_H
|
||||
#define VECTORIAL_CONFIG_H
|
||||
|
||||
|
||||
#ifndef VECTORIAL_FORCED
|
||||
#if defined(__SSE__) || (_M_IX86_FP > 0) || (_M_X64 > 0)
|
||||
|
||||
#define VECTORIAL_SSE
|
||||
|
||||
// __ARM_NEON is used instead of __ARM_NEON__ on armv8.
|
||||
#elif defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||||
|
||||
#define VECTORIAL_NEON
|
||||
|
||||
// Don't use gnu extension for arm, buggy with some gccs with armv6 and -Os,
|
||||
// Also doesn't seem perform as well
|
||||
#elif defined(__GNUC__) && !defined(__arm__)
|
||||
|
||||
#define VECTORIAL_GNU
|
||||
|
||||
#else
|
||||
|
||||
#define VECTORIAL_SCALAR
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef VECTORIAL_SCALAR
|
||||
#define VECTORIAL_SIMD_TYPE "scalar"
|
||||
#endif
|
||||
|
||||
#ifdef VECTORIAL_SSE
|
||||
#define VECTORIAL_SIMD_TYPE "sse"
|
||||
#endif
|
||||
|
||||
#ifdef VECTORIAL_NEON
|
||||
#define VECTORIAL_SIMD_TYPE "neon"
|
||||
#define VECTORIAL_HAVE_SIMD2F
|
||||
#endif
|
||||
|
||||
#ifdef VECTORIAL_GNU
|
||||
#define VECTORIAL_SIMD_TYPE "gnu"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(VECTORIAL_FORCED) && !defined(VECTORIAL_SIMD_TYPE)
|
||||
#error VECTORIAL_FORCED set but no simd-type found, try f.ex. VECTORIAL_SCALAR
|
||||
#endif
|
||||
|
||||
|
||||
#define vectorial_inline static inline
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__cplusplus)
|
||||
#define vectorial_restrict __restrict
|
||||
#endif
|
||||
#define simd4f_aligned16 __attribute__ ((aligned (16)))
|
||||
#elif defined(_WIN32)
|
||||
#define vectorial_restrict
|
||||
#define simd4f_aligned16 __declspec(align(16))
|
||||
#else
|
||||
#define vectorial_restrict restrict
|
||||
#define simd4f_aligned16
|
||||
#endif
|
||||
// #define vectorial_restrict
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define vectorial_pure __attribute__((pure))
|
||||
#else
|
||||
#define vectorial_pure
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(min) || defined(max)
|
||||
#pragma message ( "set NOMINMAX as preprocessor macro, undefining min/max " )
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
// Hack around msvc badness
|
||||
#define SIMD_PARAM(t, p) const t& p
|
||||
#else
|
||||
#define SIMD_PARAM(t, p) t p
|
||||
#endif
|
||||
|
||||
#define VECTORIAL_PI 3.14159265f
|
||||
#define VECTORIAL_HALFPI 1.57079633f
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_MAT4F_H
|
||||
#define VECTORIAL_MAT4F_H
|
||||
|
||||
#ifndef VECTORIAL_SIMD4X4F_H
|
||||
#include "vectorial/simd4x4f.h"
|
||||
#endif
|
||||
|
||||
#ifndef VECTORIAL_VEC4F_H
|
||||
#include "vectorial/vec4f.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace vectorial {
|
||||
|
||||
|
||||
class mat4f {
|
||||
public:
|
||||
|
||||
simd4x4f value;
|
||||
|
||||
inline mat4f() {}
|
||||
inline mat4f(const mat4f& m) : value(m.value) {}
|
||||
inline mat4f(const simd4x4f& v) : value(v) {}
|
||||
inline mat4f(const vec4f& v0, const vec4f& v1, const vec4f& v2, const vec4f& v3) : value(simd4x4f_create(v0.value, v1.value, v2.value, v3.value)) {}
|
||||
explicit inline mat4f(const float *ary) { simd4x4f_uload(&value, ary); }
|
||||
|
||||
inline void load(const float *ary) {
|
||||
value.x = simd4f_uload4(ary);
|
||||
value.y = simd4f_uload4(ary+4);
|
||||
value.z = simd4f_uload4(ary+8);
|
||||
value.w = simd4f_uload4(ary+12);
|
||||
}
|
||||
|
||||
inline void store(float *ary) const {
|
||||
simd4f_ustore4(value.x, ary);
|
||||
simd4f_ustore4(value.y, ary+4);
|
||||
simd4f_ustore4(value.z, ary+8);
|
||||
simd4f_ustore4(value.w, ary+12);
|
||||
}
|
||||
|
||||
static mat4f identity() { mat4f m; simd4x4f_identity(&m.value); return m; }
|
||||
|
||||
static mat4f perspective(float fovy, float aspect, float znear, float zfar) {
|
||||
simd4x4f m;
|
||||
simd4x4f_perspective(&m, fovy, aspect, znear, zfar);
|
||||
return m;
|
||||
}
|
||||
|
||||
static mat4f ortho(float left, float right, float bottom, float top, float znear, float zfar) {
|
||||
simd4x4f m;
|
||||
simd4x4f_ortho(&m, left, right, bottom, top, znear, zfar);
|
||||
return m;
|
||||
}
|
||||
|
||||
static mat4f lookAt(const vec3f& eye, const vec3f& center, const vec3f& up) {
|
||||
simd4x4f m;
|
||||
simd4x4f_lookat(&m, eye.value, center.value, up.value);
|
||||
return m;
|
||||
}
|
||||
|
||||
static mat4f translation(const vec3f& pos) {
|
||||
simd4x4f m;
|
||||
simd4x4f_translation(&m, pos.x(), pos.y(), pos.z());
|
||||
return m;
|
||||
}
|
||||
|
||||
static mat4f axisRotation(float angle, const vec3f& axis) {
|
||||
simd4x4f m;
|
||||
simd4x4f_axis_rotation(&m, angle, axis.value);
|
||||
return m;
|
||||
}
|
||||
|
||||
static mat4f scale(float scale) {
|
||||
return simd4x4f_create( simd4f_create(scale,0,0,0),
|
||||
simd4f_create(0,scale,0,0),
|
||||
simd4f_create(0,0,scale,0),
|
||||
simd4f_create(0,0,0,1) );
|
||||
}
|
||||
|
||||
static mat4f scale(const vec3f& scale) {
|
||||
return simd4x4f_create( simd4f_create(scale.x(),0,0,0),
|
||||
simd4f_create(0,scale.y(),0,0),
|
||||
simd4f_create(0,0,scale.z(),0),
|
||||
simd4f_create(0,0,0,1) );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
vectorial_inline mat4f operator*(const mat4f& lhs, const mat4f& rhs) {
|
||||
mat4f ret;
|
||||
simd4x4f_matrix_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline mat4f operator*=(mat4f& lhs, const mat4f& rhs) {
|
||||
const simd4x4f tmp = lhs.value;
|
||||
simd4x4f_matrix_mul(&tmp, &rhs.value, &lhs.value);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec4f operator*(const mat4f& lhs, const vec4f& rhs) {
|
||||
vec4f ret;
|
||||
simd4x4f_matrix_vector_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline vec3f transformVector(const mat4f& lhs, const vec3f& rhs) {
|
||||
vec3f ret;
|
||||
simd4x4f_matrix_vector3_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline vec4f transformVector(const mat4f& lhs, const vec4f& rhs) {
|
||||
vec4f ret;
|
||||
simd4x4f_matrix_vector_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline vec3f transformPoint(const mat4f& lhs, const vec3f& rhs) {
|
||||
vec3f ret;
|
||||
simd4x4f_matrix_point3_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline vec3f orthoInverseTransformPoint(const mat4f& lhs, const vec3f& rhs) {
|
||||
vec3f ret;
|
||||
simd4x4f_inv_ortho_matrix_point3_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline vec3f orthoInverseTransformVector(const mat4f& lhs, const vec3f& rhs) {
|
||||
vec3f ret;
|
||||
simd4x4f_inv_ortho_matrix_vector3_mul(&lhs.value, &rhs.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline mat4f transpose(const mat4f& m) {
|
||||
mat4f ret;
|
||||
simd4x4f_transpose(&m.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline mat4f inverse(const mat4f& m) {
|
||||
mat4f ret;
|
||||
simd4x4f_inverse(&m.value, &ret.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
//#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const vectorial::mat4f& v) {
|
||||
|
||||
os << "[ ";
|
||||
os << simd4f_get_x(v.value.x) << ", ";
|
||||
os << simd4f_get_x(v.value.y) << ", ";
|
||||
os << simd4f_get_x(v.value.z) << ", ";
|
||||
os << simd4f_get_x(v.value.w) << " ; ";
|
||||
|
||||
os << simd4f_get_y(v.value.x) << ", ";
|
||||
os << simd4f_get_y(v.value.y) << ", ";
|
||||
os << simd4f_get_y(v.value.z) << ", ";
|
||||
os << simd4f_get_y(v.value.w) << " ; ";
|
||||
|
||||
os << simd4f_get_z(v.value.x) << ", ";
|
||||
os << simd4f_get_z(v.value.y) << ", ";
|
||||
os << simd4f_get_z(v.value.z) << ", ";
|
||||
os << simd4f_get_z(v.value.w) << " ; ";
|
||||
|
||||
os << simd4f_get_w(v.value.x) << ", ";
|
||||
os << simd4f_get_w(v.value.y) << ", ";
|
||||
os << simd4f_get_w(v.value.z) << ", ";
|
||||
os << simd4f_get_w(v.value.w) << " ]";
|
||||
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
|
||||
#ifndef VECTORIAL_SIMD2F_H
|
||||
#define VECTORIAL_SIMD2F_H
|
||||
|
||||
#include "vectorial/config.h"
|
||||
|
||||
#if defined(VECTORIAL_NEON)
|
||||
#include "simd2f_neon.h"
|
||||
#else
|
||||
#error No implementation defined
|
||||
#endif
|
||||
|
||||
#include "simd2f_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const simd2f& v) {
|
||||
os << "simd2f(" << simd2f_get_x(v) << ", "
|
||||
<< simd2f_get_y(v) << ")";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2014 Google
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD2F_COMMON_H
|
||||
#define VECTORIAL_SIMD2F_COMMON_H
|
||||
|
||||
vectorial_inline simd2f simd2f_length2(simd2f v) {
|
||||
return simd2f_sqrt( simd2f_dot2(v,v) );
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_length2_squared(simd2f v) {
|
||||
return simd2f_dot2(v,v);
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_normalize2(simd2f a) {
|
||||
simd2f invlen = simd2f_rsqrt( simd2f_dot2(a,a) );
|
||||
return simd2f_mul(a, invlen);
|
||||
}
|
||||
|
||||
#endif
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD2F_NEON_H
|
||||
#define VECTORIAL_SIMD2F_NEON_H
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef float32x2_t simd2f;
|
||||
|
||||
typedef union {
|
||||
simd2f s ;
|
||||
float f[2];
|
||||
} _simd2f_union;
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd2f simd2f_create(float x, float y) {
|
||||
const float32_t d[2] = { x,y };
|
||||
simd2f s = vld1_f32(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_zero() { return vdup_n_f32(0.0f); }
|
||||
|
||||
vectorial_inline simd2f simd2f_uload2(const float *ary) {
|
||||
const float32_t* ary32 = (const float32_t*)ary;
|
||||
simd2f s = vld1_f32(ary32);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline void simd2f_ustore2(const simd2f val, float *ary) {
|
||||
vst1_f32( (float32_t*)ary, val);
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_splat(float v) {
|
||||
simd2f s = vdup_n_f32(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_splat_x(simd2f v) {
|
||||
simd2f ret = vdup_lane_f32(v, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_splat_y(simd2f v) {
|
||||
simd2f ret = vdup_lane_f32(v, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_reciprocal(simd2f v) {
|
||||
simd2f estimate = vrecpe_f32(v);
|
||||
estimate = vmul_f32(vrecps_f32(estimate, v), estimate);
|
||||
estimate = vmul_f32(vrecps_f32(estimate, v), estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline void simd2f_rsqrt_1iteration(const simd2f& v, simd2f& estimate) {
|
||||
simd2f estimate2 = vmul_f32(estimate, v);
|
||||
estimate = vmul_f32(estimate, vrsqrts_f32(estimate2, estimate));
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_rsqrt1(simd2f v) {
|
||||
simd2f estimate = vrsqrte_f32(v);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_rsqrt2(simd2f v) {
|
||||
simd2f estimate = vrsqrte_f32(v);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_rsqrt3(simd2f v) {
|
||||
simd2f estimate = vrsqrte_f32(v);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
simd2f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Fast_inverse_square_root makes the argument for
|
||||
// one iteration but two gives a signficant accuracy improvment.
|
||||
vectorial_inline simd2f simd2f_rsqrt(simd2f v) {
|
||||
return simd2f_rsqrt2(v);
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_sqrt(simd2f v) {
|
||||
|
||||
return vreinterpret_f32_u32(vand_u32( vtst_u32(vreinterpret_u32_f32(v),
|
||||
vreinterpret_u32_f32(v)),
|
||||
vreinterpret_u32_f32(
|
||||
simd2f_reciprocal(simd2f_rsqrt(v)))
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// arithmetics
|
||||
|
||||
vectorial_inline simd2f simd2f_add(simd2f lhs, simd2f rhs) {
|
||||
simd2f ret = vadd_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_sub(simd2f lhs, simd2f rhs) {
|
||||
simd2f ret = vsub_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_mul(simd2f lhs, simd2f rhs) {
|
||||
simd2f ret = vmul_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_div(simd2f lhs, simd2f rhs) {
|
||||
simd2f recip = simd2f_reciprocal( rhs );
|
||||
simd2f ret = vmul_f32(lhs, recip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_madd(simd2f m1, simd2f m2, simd2f a) {
|
||||
return vmla_f32( a, m1, m2 );
|
||||
}
|
||||
|
||||
vectorial_inline float simd2f_get_x(simd2f s) { return vget_lane_f32(s, 0); }
|
||||
vectorial_inline float simd2f_get_y(simd2f s) { return vget_lane_f32(s, 1); }
|
||||
|
||||
vectorial_inline simd2f simd2f_dot2(simd2f lhs, simd2f rhs) {
|
||||
const simd2f m = simd2f_mul(lhs, rhs);
|
||||
return vpadd_f32(m, m);
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_min(simd2f a, simd2f b) {
|
||||
return vmin_f32( a, b );
|
||||
}
|
||||
|
||||
vectorial_inline simd2f simd2f_max(simd2f a, simd2f b) {
|
||||
return vmax_f32( a, b );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
|
||||
#ifndef VECTORIAL_SIMD4F_H
|
||||
#define VECTORIAL_SIMD4F_H
|
||||
|
||||
#ifndef VECTORIAL_CONFIG_H
|
||||
#include "vectorial/config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef VECTORIAL_SCALAR
|
||||
#include "simd4f_scalar.h"
|
||||
#elif defined(VECTORIAL_SSE)
|
||||
#include "simd4f_sse.h"
|
||||
#elif defined(VECTORIAL_GNU)
|
||||
#include "simd4f_gnu.h"
|
||||
#elif defined(VECTORIAL_NEON)
|
||||
#include "simd4f_neon.h"
|
||||
#else
|
||||
#error No implementation defined
|
||||
#endif
|
||||
|
||||
#include "simd4f_common.h"
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const simd4f& v) {
|
||||
os << "simd4f(" << simd4f_get_x(v) << ", "
|
||||
<< simd4f_get_y(v) << ", "
|
||||
<< simd4f_get_z(v) << ", "
|
||||
<< simd4f_get_w(v) << ")";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4F_COMMON_H
|
||||
#define VECTORIAL_SIMD4F_COMMON_H
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_sum(simd4f v) {
|
||||
const simd4f s1 = simd4f_add(simd4f_splat_x(v), simd4f_splat_y(v));
|
||||
const simd4f s2 = simd4f_add(s1, simd4f_splat_z(v));
|
||||
const simd4f s3 = simd4f_add(s2, simd4f_splat_w(v));
|
||||
return s3;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_dot4(simd4f lhs, simd4f rhs) {
|
||||
return simd4f_sum( simd4f_mul(lhs, rhs) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_dot2(simd4f lhs, simd4f rhs) {
|
||||
const simd4f m = simd4f_mul(lhs, rhs);
|
||||
const simd4f s1 = simd4f_add(simd4f_splat_x(m), simd4f_splat_y(m));
|
||||
return s1;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_length4(simd4f v) {
|
||||
return simd4f_sqrt( simd4f_dot4(v,v) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_length3(simd4f v) {
|
||||
return simd4f_sqrt( simd4f_dot3(v,v) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_length2(simd4f v) {
|
||||
return simd4f_sqrt( simd4f_dot2(v,v) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_length4_squared(simd4f v) {
|
||||
return simd4f_dot4(v,v);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_length3_squared(simd4f v) {
|
||||
return simd4f_dot3(v,v);
|
||||
}
|
||||
|
||||
vectorial_inline float simd4f_length3_squared_scalar(simd4f v) {
|
||||
return simd4f_dot3_scalar(v,v);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_length2_squared(simd4f v) {
|
||||
return simd4f_dot2(v,v);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_normalize4(simd4f a) {
|
||||
simd4f invlen = simd4f_rsqrt( simd4f_dot4(a,a) );
|
||||
return simd4f_mul(a, invlen);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_normalize3(simd4f a) {
|
||||
simd4f invlen = simd4f_rsqrt( simd4f_dot3(a,a) );
|
||||
return simd4f_mul(a, invlen);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_normalize2(simd4f a) {
|
||||
simd4f invlen = simd4f_rsqrt( simd4f_dot2(a,a) );
|
||||
return simd4f_mul(a, invlen);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4F_GNU_H
|
||||
#define VECTORIAL_SIMD4F_GNU_H
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h> // memcpy
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef float simd4f __attribute__ ((vector_size (16)));
|
||||
|
||||
typedef union {
|
||||
simd4f s ;
|
||||
float f[4];
|
||||
} _simd4f_union;
|
||||
|
||||
vectorial_inline float simd4f_get_x(simd4f s) { _simd4f_union u={s}; return u.f[0]; }
|
||||
vectorial_inline float simd4f_get_y(simd4f s) { _simd4f_union u={s}; return u.f[1]; }
|
||||
vectorial_inline float simd4f_get_z(simd4f s) { _simd4f_union u={s}; return u.f[2]; }
|
||||
vectorial_inline float simd4f_get_w(simd4f s) { _simd4f_union u={s}; return u.f[3]; }
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_create(float x, float y, float z, float w) {
|
||||
simd4f s = { x, y, z, w };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero() { return simd4f_create(0.0f, 0.0f, 0.0f, 0.0f); }
|
||||
|
||||
vectorial_inline simd4f simd4f_uload4(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], ary[2], ary[3] };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload3(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], ary[2], 0 };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload2(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], 0, 0 };
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4f_ustore4(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore3(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore2(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 2);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_splat(float v) {
|
||||
simd4f s = { v, v, v, v };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_x(simd4f v) {
|
||||
float s = simd4f_get_x(v);
|
||||
simd4f ret = { s, s, s, s };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_y(simd4f v) {
|
||||
float s = simd4f_get_y(v);
|
||||
simd4f ret = { s, s, s, s };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_z(simd4f v) {
|
||||
float s = simd4f_get_z(v);
|
||||
simd4f ret = { s, s, s, s };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_w(simd4f v) {
|
||||
float s = simd4f_get_w(v);
|
||||
simd4f ret = { s, s, s, s };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_reciprocal(simd4f v) {
|
||||
return simd4f_splat(1.0f) / v;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sqrt(simd4f v) {
|
||||
simd4f ret = { sqrtf(simd4f_get_x(v)), sqrtf(simd4f_get_y(v)), sqrtf(simd4f_get_z(v)), sqrtf(simd4f_get_w(v)) };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt(simd4f v) {
|
||||
return simd4f_splat(1.0f) / simd4f_sqrt(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_add(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = lhs + rhs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sub(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = lhs - rhs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_mul(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = lhs * rhs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_div(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = lhs / rhs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_madd(simd4f m1, simd4f m2, simd4f a) {
|
||||
return simd4f_add( simd4f_mul(m1, m2), a );
|
||||
}
|
||||
|
||||
vectorial_inline float simd4f_dot3_scalar(simd4f lhs, simd4f rhs) {
|
||||
_simd4f_union l = {lhs};
|
||||
_simd4f_union r = {rhs};
|
||||
return l.f[0] * r.f[0] + l.f[1] * r.f[1] + l.f[2] * r.f[2];
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_dot3(simd4f lhs, simd4f rhs) {
|
||||
return simd4f_splat( simd4f_dot3_scalar(lhs, rhs) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_cross3(simd4f l, simd4f r) {
|
||||
_simd4f_union lhs = {l};
|
||||
_simd4f_union rhs = {r};
|
||||
|
||||
return simd4f_create( lhs.f[1] * rhs.f[2] - lhs.f[2] * rhs.f[1],
|
||||
lhs.f[2] * rhs.f[0] - lhs.f[0] * rhs.f[2],
|
||||
lhs.f[0] * rhs.f[1] - lhs.f[1] * rhs.f[0], 0);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_wxyz(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[3], u.f[0], u.f[1], u.f[2]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_zwxy(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[2], u.f[3], u.f[0], u.f[1]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_yzwx(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[1], u.f[2], u.f[3], u.f[0]);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_w(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[0], u.f[1], u.f[2], 0.0f);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_zw(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[0], u.f[1], 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_merge_high(simd4f abcd, simd4f xyzw) {
|
||||
_simd4f_union u1 = {abcd};
|
||||
_simd4f_union u2 = {xyzw};
|
||||
return simd4f_create(u1.f[2], u1.f[3], u2.f[2], u2.f[3]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_0101(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[0], -u.f[1], u.f[2], -u.f[3]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_1010(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(-u.f[0], u.f[1], -u.f[2], u.f[3]);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_min(simd4f a, simd4f b) {
|
||||
_simd4f_union ua = {a};
|
||||
_simd4f_union ub = {b};
|
||||
return simd4f_create( ua.f[0] < ub.f[0] ? ua.f[0] : ub.f[0],
|
||||
ua.f[1] < ub.f[1] ? ua.f[1] : ub.f[1],
|
||||
ua.f[2] < ub.f[2] ? ua.f[2] : ub.f[2],
|
||||
ua.f[3] < ub.f[3] ? ua.f[3] : ub.f[3] );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_max(simd4f a, simd4f b) {
|
||||
_simd4f_union ua = {a};
|
||||
_simd4f_union ub = {b};
|
||||
return simd4f_create( ua.f[0] > ub.f[0] ? ua.f[0] : ub.f[0],
|
||||
ua.f[1] > ub.f[1] ? ua.f[1] : ub.f[1],
|
||||
ua.f[2] > ub.f[2] ? ua.f[2] : ub.f[2],
|
||||
ua.f[3] > ub.f[3] ? ua.f[3] : ub.f[3] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+280
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4F_NEON_H
|
||||
#define VECTORIAL_SIMD4F_NEON_H
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef float32x4_t simd4f;
|
||||
typedef float32x2_t simd2f;
|
||||
|
||||
typedef union {
|
||||
simd4f s ;
|
||||
float f[4];
|
||||
} _simd4f_union;
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_create(float x, float y, float z, float w) {
|
||||
const float32_t d[4] = { x,y,z,w };
|
||||
simd4f s = vld1q_f32(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero() { return vdupq_n_f32(0.0f); }
|
||||
|
||||
vectorial_inline simd4f simd4f_uload4(const float *ary) {
|
||||
const float32_t* ary32 = (const float32_t*)ary;
|
||||
simd4f s = vld1q_f32(ary32);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload3(const float *ary) {
|
||||
simd4f s = simd4f_create(ary[0], ary[1], ary[2], 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload2(const float *ary) {
|
||||
const float32_t* ary32 = (const float32_t*)ary;
|
||||
float32x2_t low = vld1_f32(ary32);
|
||||
const float32_t zero = 0;
|
||||
float32x2_t high = vld1_dup_f32(&zero); // { 0,0 } but stupid warnings from llvm-gcc
|
||||
return vcombine_f32(low, high);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4f_ustore4(const simd4f val, float *ary) {
|
||||
vst1q_f32( (float32_t*)ary, val);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore3(const simd4f val, float *ary) {
|
||||
float* local_data = ary;
|
||||
vst1q_lane_f32(local_data++, val, 0);
|
||||
vst1q_lane_f32(local_data++, val, 1);
|
||||
vst1q_lane_f32(local_data, val, 2);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore2(const simd4f val, float *ary) {
|
||||
const float32x2_t low = vget_low_f32(val);
|
||||
vst1_f32( (float32_t*)ary, low);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_splat(float v) {
|
||||
simd4f s = vdupq_n_f32(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
// todo: or is simd4f_splat(simd4f_get_x(v)) better?
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_x(simd4f v) {
|
||||
float32x2_t o = vget_low_f32(v);
|
||||
simd4f ret = vdupq_lane_f32(o, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_y(simd4f v) {
|
||||
float32x2_t o = vget_low_f32(v);
|
||||
simd4f ret = vdupq_lane_f32(o, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_z(simd4f v) {
|
||||
float32x2_t o = vget_high_f32(v);
|
||||
simd4f ret = vdupq_lane_f32(o, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_w(simd4f v) {
|
||||
float32x2_t o = vget_high_f32(v);
|
||||
simd4f ret = vdupq_lane_f32(o, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_reciprocal(simd4f v) {
|
||||
simd4f estimate = vrecpeq_f32(v);
|
||||
estimate = vmulq_f32(vrecpsq_f32(estimate, v), estimate);
|
||||
estimate = vmulq_f32(vrecpsq_f32(estimate, v), estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_rsqrt_1iteration(const simd4f& v, simd4f& estimate) {
|
||||
simd4f estimate2 = vmulq_f32(estimate, v);
|
||||
estimate = vmulq_f32(estimate, vrsqrtsq_f32(estimate2, estimate));
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt1(simd4f v) {
|
||||
simd4f estimate = vrsqrteq_f32(v);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt2(simd4f v) {
|
||||
simd4f estimate = vrsqrteq_f32(v);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt3(simd4f v) {
|
||||
simd4f estimate = vrsqrteq_f32(v);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
simd4f_rsqrt_1iteration(v, estimate);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Fast_inverse_square_root makes the argument for
|
||||
// one iteration but two gives a signficant accuracy improvment.
|
||||
vectorial_inline simd4f simd4f_rsqrt(simd4f v) {
|
||||
return simd4f_rsqrt2(v);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sqrt(simd4f v) {
|
||||
|
||||
return vreinterpretq_f32_u32(vandq_u32( vtstq_u32(vreinterpretq_u32_f32(v),
|
||||
vreinterpretq_u32_f32(v)),
|
||||
vreinterpretq_u32_f32(
|
||||
simd4f_reciprocal(simd4f_rsqrt(v)))
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// arithmetics
|
||||
|
||||
vectorial_inline simd4f simd4f_add(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = vaddq_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sub(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = vsubq_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_mul(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = vmulq_f32(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_div(simd4f lhs, simd4f rhs) {
|
||||
simd4f recip = simd4f_reciprocal( rhs );
|
||||
simd4f ret = vmulq_f32(lhs, recip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_madd(simd4f m1, simd4f m2, simd4f a) {
|
||||
return vmlaq_f32( a, m1, m2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline float simd4f_get_x(simd4f s) { return vgetq_lane_f32(s, 0); }
|
||||
vectorial_inline float simd4f_get_y(simd4f s) { return vgetq_lane_f32(s, 1); }
|
||||
vectorial_inline float simd4f_get_z(simd4f s) { return vgetq_lane_f32(s, 2); }
|
||||
vectorial_inline float simd4f_get_w(simd4f s) { return vgetq_lane_f32(s, 3); }
|
||||
|
||||
// This function returns x*x+y*y+z*z and ignores the w component.
|
||||
vectorial_inline float simd4f_dot3_scalar(simd4f lhs, simd4f rhs) {
|
||||
const simd4f m = simd4f_mul(lhs, rhs);
|
||||
simd2f s1 = vpadd_f32(vget_low_f32(m), vget_low_f32(m));
|
||||
s1 = vadd_f32(s1, vget_high_f32(m));
|
||||
return vget_lane_f32(s1, 0);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_dot3(simd4f lhs, simd4f rhs) {
|
||||
return simd4f_splat(simd4f_dot3_scalar(lhs, rhs));
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_cross3(simd4f lhs, simd4f rhs) {
|
||||
// Compute lhs and rhs in order yzx
|
||||
simd2f lhs_low = vget_low_f32(lhs);
|
||||
simd2f rhs_low = vget_low_f32(rhs);
|
||||
simd4f lhs_yzx = vcombine_f32(vext_f32(lhs_low, vget_high_f32(lhs),1), lhs_low);
|
||||
simd4f rhs_yzx = vcombine_f32(vext_f32(rhs_low, vget_high_f32(rhs),1), rhs_low);
|
||||
// Compute cross in order zxy
|
||||
simd4f s3 = simd4f_sub(simd4f_mul(rhs_yzx, lhs), simd4f_mul(lhs_yzx, rhs));
|
||||
// Permute cross to order xyz and zero out the fourth value
|
||||
simd2f low = vget_low_f32(s3);
|
||||
static const uint32_t mask_array[] = {
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0};
|
||||
static const int32x4_t mask = vld1q_s32((const int32_t*)mask_array);
|
||||
s3 = vcombine_f32(vext_f32(low, vget_high_f32(s3), 1), low);
|
||||
return (simd4f)vandq_s32((int32x4_t)s3,mask);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_wxyz(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create( u.f[3], u.f[0], u.f[1], u.f[2]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_zwxy(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[2], u.f[3], u.f[0], u.f[1]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_yzwx(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[1], u.f[2], u.f[3], u.f[0]);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_w(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[0], u.f[1], u.f[2], 0.0f);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_zw(simd4f s) {
|
||||
_simd4f_union u = {s};
|
||||
return simd4f_create(u.f[0], u.f[1], 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_merge_high(simd4f xyzw, simd4f abcd) {
|
||||
_simd4f_union u1 = {xyzw};
|
||||
_simd4f_union u2 = {abcd};
|
||||
return simd4f_create(u1.f[2], u1.f[3], u2.f[2], u2.f[3]);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_0101(simd4f s) {
|
||||
const unsigned int upnpn[4] = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
|
||||
const uint32x4_t pnpn = vld1q_u32( upnpn );
|
||||
return vreinterpretq_f32_u32( veorq_u32( vreinterpretq_u32_f32(s), pnpn ) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_1010(simd4f s) {
|
||||
const unsigned int unpnp[4] = { 0x80000000, 0x00000000, 0x80000000, 0x00000000 };
|
||||
const uint32x4_t npnp = vld1q_u32( unpnp );
|
||||
return vreinterpretq_f32_u32( veorq_u32( vreinterpretq_u32_f32(s), npnp ) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_min(simd4f a, simd4f b) {
|
||||
return vminq_f32( a, b );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_max(simd4f a, simd4f b) {
|
||||
return vmaxq_f32( a, b );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4F_SCALAR_H
|
||||
#define VECTORIAL_SIMD4F_SCALAR_H
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
} simd4f;
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_create(float x, float y, float z, float w) {
|
||||
simd4f s = { x, y, z, w };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero() { return simd4f_create(0.0f, 0.0f, 0.0f, 0.0f); }
|
||||
|
||||
vectorial_inline simd4f simd4f_uload4(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], ary[2], ary[3] };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload3(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], ary[2], 0 };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload2(const float *ary) {
|
||||
simd4f s = { ary[0], ary[1], 0, 0 };
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4f_ustore4(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore3(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore2(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// utilities
|
||||
vectorial_inline simd4f simd4f_splat(float v) {
|
||||
simd4f s = { v, v, v, v };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_x(simd4f v) {
|
||||
simd4f s = { v.x, v.x, v.x, v.x };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_y(simd4f v) {
|
||||
simd4f s = { v.y, v.y, v.y, v.y };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_z(simd4f v) {
|
||||
simd4f s = { v.z, v.z, v.z, v.z };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_w(simd4f v) {
|
||||
simd4f s = { v.w, v.w, v.w, v.w };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_reciprocal(simd4f v) {
|
||||
simd4f s = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z, 1.0f/v.w };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sqrt(simd4f v) {
|
||||
simd4f s = { sqrtf(v.x), sqrtf(v.y), sqrtf(v.z), sqrtf(v.w) };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt(simd4f v) {
|
||||
simd4f s = { 1.0f/sqrtf(v.x), 1.0f/sqrtf(v.y), 1.0f/sqrtf(v.z), 1.0f/sqrtf(v.w) };
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// arithmetic
|
||||
|
||||
vectorial_inline simd4f simd4f_add(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sub(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_mul(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = { lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_div(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = { lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w };
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_madd(simd4f m1, simd4f m2, simd4f a) {
|
||||
return simd4f_add( simd4f_mul(m1, m2), a );
|
||||
}
|
||||
|
||||
vectorial_inline float simd4f_dot3_scalar(simd4f lhs, simd4f rhs) {
|
||||
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_dot3(simd4f lhs, simd4f rhs) {
|
||||
return simd4f_splat( simd4f_dot3_scalar(lhs, rhs) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_cross3(simd4f lhs, simd4f rhs) {
|
||||
return simd4f_create( lhs.y * rhs.z - lhs.z * rhs.y,
|
||||
lhs.z * rhs.x - lhs.x * rhs.z,
|
||||
lhs.x * rhs.y - lhs.y * rhs.x, 0);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float simd4f_get_x(simd4f s) { return s.x; }
|
||||
vectorial_inline float simd4f_get_y(simd4f s) { return s.y; }
|
||||
vectorial_inline float simd4f_get_z(simd4f s) { return s.z; }
|
||||
vectorial_inline float simd4f_get_w(simd4f s) { return s.w; }
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_wxyz(simd4f s) { return simd4f_create(s.w, s.x, s.y, s.z); }
|
||||
vectorial_inline simd4f simd4f_shuffle_zwxy(simd4f s) { return simd4f_create(s.z, s.w, s.x, s.y); }
|
||||
vectorial_inline simd4f simd4f_shuffle_yzwx(simd4f s) { return simd4f_create(s.y, s.z, s.w, s.x); }
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_w(simd4f s) {
|
||||
return simd4f_create(s.x, s.y, s.z, 0.0f);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_zw(simd4f s) {
|
||||
return simd4f_create(s.x, s.y, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_merge_high(simd4f abcd, simd4f xyzw) {
|
||||
return simd4f_create(abcd.z, abcd.w, xyzw.z, xyzw.w);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_0101(simd4f s) {
|
||||
return simd4f_create(s.x, -s.y, s.z, -s.w);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_1010(simd4f s) {
|
||||
return simd4f_create(-s.x, s.y, -s.z, s.w);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_min(simd4f a, simd4f b) {
|
||||
return simd4f_create( a.x < b.x ? a.x : b.x,
|
||||
a.y < b.y ? a.y : b.y,
|
||||
a.z < b.z ? a.z : b.z,
|
||||
a.w < b.w ? a.w : b.w );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_max(simd4f a, simd4f b) {
|
||||
return simd4f_create( a.x > b.x ? a.x : b.x,
|
||||
a.y > b.y ? a.y : b.y,
|
||||
a.z > b.z ? a.z : b.z,
|
||||
a.w > b.w ? a.w : b.w );
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4F_SSE_H
|
||||
#define VECTORIAL_SIMD4F_SSE_H
|
||||
|
||||
// Conditionally enable SSE4.1 otherwise fallback to SSE.
|
||||
#if defined(_M_IX86_FP)
|
||||
#if _M_IX86_FP >=2
|
||||
#define VECTORIAL_USE_SSE4_1
|
||||
#endif
|
||||
#elif defined(__SSE4_1__)
|
||||
#define VECTORIAL_USE_SSE4_1
|
||||
#endif
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#if defined(VECTORIAL_USE_SSE4_1)
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef __m128 simd4f;
|
||||
|
||||
typedef union {
|
||||
simd4f s ;
|
||||
float f[4];
|
||||
unsigned int ui[4];
|
||||
} _simd4f_union;
|
||||
|
||||
// creating
|
||||
|
||||
vectorial_inline simd4f simd4f_create(float x, float y, float z, float w) {
|
||||
simd4f s = { x, y, z, w };
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero() { return _mm_setzero_ps(); }
|
||||
|
||||
vectorial_inline simd4f simd4f_uload4(const float *ary) {
|
||||
simd4f s = _mm_loadu_ps(ary);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload3(const float *ary) {
|
||||
simd4f s = simd4f_create(ary[0], ary[1], ary[2], 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_uload2(const float *ary) {
|
||||
simd4f s = simd4f_create(ary[0], ary[1], 0, 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4f_ustore4(const simd4f val, float *ary) {
|
||||
_mm_storeu_ps(ary, val);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore3(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4f_ustore2(const simd4f val, float *ary) {
|
||||
memcpy(ary, &val, sizeof(float) * 2);
|
||||
}
|
||||
|
||||
|
||||
// utilites
|
||||
|
||||
vectorial_inline simd4f simd4f_splat(float v) {
|
||||
simd4f s = _mm_set1_ps(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_x(simd4f v) {
|
||||
simd4f s = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0,0,0,0));
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_y(simd4f v) {
|
||||
simd4f s = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1,1,1,1));
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_z(simd4f v) {
|
||||
simd4f s = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2,2,2,2));
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_splat_w(simd4f v) {
|
||||
simd4f s = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3,3,3,3));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// arithmetic
|
||||
|
||||
vectorial_inline simd4f simd4f_add(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = _mm_add_ps(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sub(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = _mm_sub_ps(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_mul(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = _mm_mul_ps(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_div(simd4f lhs, simd4f rhs) {
|
||||
simd4f ret = _mm_div_ps(lhs, rhs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_madd(simd4f m1, simd4f m2, simd4f a) {
|
||||
return simd4f_add( simd4f_mul(m1, m2), a );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4f simd4f_reciprocal(simd4f v) {
|
||||
simd4f s = _mm_rcp_ps(v);
|
||||
const simd4f two = simd4f_create(2.0f, 2.0f, 2.0f, 2.0f);
|
||||
s = simd4f_mul(s, simd4f_sub(two, simd4f_mul(v, s)));
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_sqrt(simd4f v) {
|
||||
simd4f s = _mm_sqrt_ps(v);
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_rsqrt(simd4f v) {
|
||||
simd4f s = _mm_rsqrt_ps(v);
|
||||
const simd4f half = simd4f_create(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
const simd4f three = simd4f_create(3.0f, 3.0f, 3.0f, 3.0f);
|
||||
s = simd4f_mul(simd4f_mul(s, half), simd4f_sub(three, simd4f_mul(s, simd4f_mul(v,s))));
|
||||
return s;
|
||||
}
|
||||
|
||||
vectorial_inline float simd4f_get_x(simd4f s) { _simd4f_union u={s}; return u.f[0]; }
|
||||
vectorial_inline float simd4f_get_y(simd4f s) { _simd4f_union u={s}; return u.f[1]; }
|
||||
vectorial_inline float simd4f_get_z(simd4f s) { _simd4f_union u={s}; return u.f[2]; }
|
||||
vectorial_inline float simd4f_get_w(simd4f s) { _simd4f_union u={s}; return u.f[3]; }
|
||||
|
||||
vectorial_inline simd4f simd4f_dot3(simd4f lhs,simd4f rhs) {
|
||||
#if defined(VECTORIAL_USE_SSE4_1)
|
||||
return _mm_dp_ps(lhs, rhs, 0x7f);
|
||||
#else
|
||||
simd4f_aligned16 const unsigned int mask_array[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0 };
|
||||
const simd4f mask = _mm_load_ps((const float*)mask_array);
|
||||
const simd4f m = _mm_mul_ps(lhs, rhs);
|
||||
const simd4f s0 = _mm_and_ps(m, mask);
|
||||
const simd4f s1 = _mm_add_ps(s0, _mm_movehl_ps(s0, s0));
|
||||
const simd4f s2 = _mm_add_ss(s1, _mm_shuffle_ps(s1, s1, 1));
|
||||
return _mm_shuffle_ps(s2,s2, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
vectorial_inline float simd4f_dot3_scalar(simd4f lhs,simd4f rhs) {
|
||||
return simd4f_get_x(simd4f_dot3(lhs, rhs));
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_cross3(simd4f lhs, simd4f rhs) {
|
||||
|
||||
const simd4f lyzx = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(3,0,2,1));
|
||||
const simd4f lzxy = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(3,1,0,2));
|
||||
|
||||
const simd4f ryzx = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(3,0,2,1));
|
||||
const simd4f rzxy = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(3,1,0,2));
|
||||
|
||||
return _mm_sub_ps(_mm_mul_ps(lyzx, rzxy), _mm_mul_ps(lzxy, ryzx));
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_shuffle_wxyz(simd4f s) { return _mm_shuffle_ps(s,s, _MM_SHUFFLE(2,1,0,3) ); }
|
||||
vectorial_inline simd4f simd4f_shuffle_zwxy(simd4f s) { return _mm_shuffle_ps(s,s, _MM_SHUFFLE(1,0,3,2) ); }
|
||||
vectorial_inline simd4f simd4f_shuffle_yzwx(simd4f s) { return _mm_shuffle_ps(s,s, _MM_SHUFFLE(0,3,2,1) ); }
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_w(simd4f s) {
|
||||
simd4f r = _mm_unpackhi_ps(s, _mm_setzero_ps());
|
||||
return _mm_movelh_ps(s, r);
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_zero_zw(simd4f s) {
|
||||
return _mm_movelh_ps(s, _mm_setzero_ps());
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_merge_high(simd4f xyzw, simd4f abcd) {
|
||||
return _mm_movehl_ps(abcd, xyzw);
|
||||
}
|
||||
|
||||
|
||||
typedef simd4f_aligned16 union {
|
||||
unsigned int ui[4];
|
||||
float f[4];
|
||||
} _simd4f_uif;
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_0101(simd4f s) {
|
||||
const _simd4f_uif upnpn = { { 0x00000000, 0x80000000, 0x00000000, 0x80000000 } };
|
||||
return _mm_xor_ps( s, _mm_load_ps(upnpn.f) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_flip_sign_1010(simd4f s) {
|
||||
const _simd4f_uif unpnp = { { 0x80000000, 0x00000000, 0x80000000, 0x00000000 } };
|
||||
return _mm_xor_ps( s, _mm_load_ps(unpnp.f) );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_min(simd4f a, simd4f b) {
|
||||
return _mm_min_ps( a, b );
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4f_max(simd4f a, simd4f b) {
|
||||
return _mm_max_ps( a, b );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4X4F_H
|
||||
#define VECTORIAL_SIMD4X4F_H
|
||||
|
||||
|
||||
#include "simd4f.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
Note, x,y,z,w are conceptually columns with matrix math.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
simd4f x,y,z,w;
|
||||
} simd4x4f;
|
||||
|
||||
|
||||
|
||||
vectorial_inline simd4x4f simd4x4f_create(simd4f x, simd4f y, simd4f z, SIMD_PARAM(simd4f, w)) {
|
||||
simd4x4f s = { x, y, z, w };
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_identity(simd4x4f* m) {
|
||||
*m = simd4x4f_create( simd4f_create(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
simd4f_create(0.0f, 1.0f, 0.0f, 0.0f),
|
||||
simd4f_create(0.0f, 0.0f, 1.0f, 0.0f),
|
||||
simd4f_create(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_uload(simd4x4f* m, const float *f) {
|
||||
|
||||
m->x = simd4f_uload4(f + 0);
|
||||
m->y = simd4f_uload4(f + 4);
|
||||
m->z = simd4f_uload4(f + 8);
|
||||
m->w = simd4f_uload4(f + 12);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef VECTORIAL_SCALAR
|
||||
#include "simd4x4f_scalar.h"
|
||||
#elif defined(VECTORIAL_SSE)
|
||||
#include "simd4x4f_sse.h"
|
||||
#elif defined(VECTORIAL_GNU)
|
||||
#include "simd4x4f_gnu.h"
|
||||
#elif defined(VECTORIAL_NEON)
|
||||
#include "simd4x4f_neon.h"
|
||||
#else
|
||||
#error No implementation defined
|
||||
#endif
|
||||
|
||||
vectorial_inline void simd4x4f_sum(const simd4x4f* a, simd4f* out) {
|
||||
simd4f t;
|
||||
t = simd4f_add(a->x, a->y);
|
||||
t = simd4f_add(t, a->z);
|
||||
t = simd4f_add(t, a->w);
|
||||
*out = t;
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_matrix_vector_mul(const simd4x4f* a, const simd4f * b, simd4f* out) {
|
||||
|
||||
const simd4f x = a->x;
|
||||
const simd4f y = a->y;
|
||||
const simd4f z = a->z;
|
||||
const simd4f w = a->w;
|
||||
const simd4f v = *b;
|
||||
const simd4f vx = simd4f_splat_x(v);
|
||||
const simd4f vy = simd4f_splat_y(v);
|
||||
const simd4f vz = simd4f_splat_z(v);
|
||||
const simd4f vw = simd4f_splat_w(v);
|
||||
|
||||
#if 0
|
||||
// In a hasty benchmark, this actually performed worse on neon
|
||||
// TODO: revisit and conditionalize accordingly
|
||||
|
||||
*out = simd4f_madd(x, vx,
|
||||
simd4f_madd(y, vy,
|
||||
simd4f_madd(z, vz,
|
||||
simd4f_mul(w, vw) ) ) );
|
||||
|
||||
#else
|
||||
|
||||
*out = simd4f_add(simd4f_mul(x, vx),
|
||||
simd4f_add(simd4f_mul(y, vy),
|
||||
simd4f_add(simd4f_mul(z, vz),
|
||||
simd4f_mul(w, vw) ) ) );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_matrix_vector3_mul(const simd4x4f* a, const simd4f * b, simd4f* out) {
|
||||
|
||||
#if 0
|
||||
*out = simd4f_madd( a->x, simd4f_splat_x(*b),
|
||||
simd4f_madd( a->y, simd4f_splat_y(*b),
|
||||
simd4f_mul(a->z, simd4f_splat_z(*b)) ) );
|
||||
#else
|
||||
*out = simd4f_add( simd4f_mul(a->x, simd4f_splat_x(*b)),
|
||||
simd4f_add( simd4f_mul(a->y, simd4f_splat_y(*b)),
|
||||
simd4f_mul(a->z, simd4f_splat_z(*b)) ) );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_matrix_point3_mul(const simd4x4f* a, const simd4f * b, simd4f* out) {
|
||||
|
||||
#if 0
|
||||
*out = simd4f_madd( a->x, simd4f_splat_x(*b),
|
||||
simd4f_madd( a->y, simd4f_splat_y(*b),
|
||||
simd4f_madd( a->z, simd4f_splat_z(*b),
|
||||
a->w ) ) );
|
||||
#else
|
||||
*out = simd4f_add( simd4f_mul(a->x, simd4f_splat_x(*b)),
|
||||
simd4f_add( simd4f_mul(a->y, simd4f_splat_y(*b)),
|
||||
simd4f_add( simd4f_mul(a->z, simd4f_splat_z(*b)),
|
||||
a->w ) ) );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_inv_ortho_matrix_point3_mul(const simd4x4f* a, const simd4f * b, simd4f* out) {
|
||||
simd4f translation = simd4f_sub(*b, a->w);
|
||||
|
||||
simd4x4f transpose = *a;
|
||||
|
||||
transpose.w = simd4f_create(0,0,0,0);
|
||||
simd4x4f_transpose_inplace(&transpose);
|
||||
|
||||
simd4x4f_matrix_point3_mul(&transpose, &translation, out);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_inv_ortho_matrix_vector3_mul(const simd4x4f* a, const simd4f * b, simd4f* out) {
|
||||
simd4f translation = *b;
|
||||
|
||||
simd4x4f transpose = *a;
|
||||
|
||||
transpose.w = simd4f_create(0,0,0,0);
|
||||
simd4x4f_transpose_inplace(&transpose);
|
||||
|
||||
simd4x4f_matrix_vector3_mul(&transpose, &translation, out);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_matrix_mul(const simd4x4f* a, const simd4x4f* b, simd4x4f* out) {
|
||||
|
||||
simd4x4f_matrix_vector_mul(a, &b->x, &out->x);
|
||||
simd4x4f_matrix_vector_mul(a, &b->y, &out->y);
|
||||
simd4x4f_matrix_vector_mul(a, &b->z, &out->z);
|
||||
simd4x4f_matrix_vector_mul(a, &b->w, &out->w);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_perspective(simd4x4f *m, float fovy_radians, float aspect, float znear, float zfar) {
|
||||
|
||||
float deltaz = zfar - znear;
|
||||
float cotangent = tanf( VECTORIAL_HALFPI - fovy_radians * 0.5f );
|
||||
|
||||
float a = cotangent / aspect;
|
||||
float b = cotangent;
|
||||
float c = -(zfar + znear) / deltaz;
|
||||
float d = -2 * znear * zfar / deltaz;
|
||||
|
||||
m->x = simd4f_create( a, 0, 0, 0);
|
||||
m->y = simd4f_create( 0, b, 0, 0);
|
||||
m->z = simd4f_create( 0, 0, c, -1);
|
||||
m->w = simd4f_create( 0, 0, d, 0);
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_ortho(simd4x4f *m, float left, float right, float bottom, float top, float znear, float zfar) {
|
||||
|
||||
float deltax = right - left;
|
||||
float deltay = top - bottom;
|
||||
float deltaz = zfar - znear;
|
||||
|
||||
float a = 2.0f / deltax;
|
||||
float b = -(right + left) / deltax;
|
||||
float c = 2.0f / deltay;
|
||||
float d = -(top + bottom) / deltay;
|
||||
float e = -2.0f / deltaz;
|
||||
float f = -(zfar + znear) / deltaz;
|
||||
|
||||
m->x = simd4f_create( a, 0, 0, 0);
|
||||
m->y = simd4f_create( 0, c, 0, 0);
|
||||
m->z = simd4f_create( 0, 0, e, 0);
|
||||
m->w = simd4f_create( b, d, f, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_lookat(simd4x4f *m, simd4f eye, simd4f center, simd4f up) {
|
||||
|
||||
simd4f zaxis = simd4f_normalize3( simd4f_sub(center, eye) );
|
||||
simd4f xaxis = simd4f_normalize3( simd4f_cross3( zaxis, up ) );
|
||||
simd4f yaxis = simd4f_cross3(xaxis, zaxis);
|
||||
|
||||
zaxis = simd4f_sub( simd4f_zero(), zaxis);
|
||||
|
||||
float x = -simd4f_dot3_scalar(xaxis, eye);
|
||||
float y = -simd4f_dot3_scalar(yaxis, eye);
|
||||
float z = -simd4f_dot3_scalar(zaxis, eye);
|
||||
|
||||
m->x = xaxis;
|
||||
m->y = yaxis;
|
||||
m->z = zaxis;
|
||||
|
||||
m->w = simd4f_create( 0,0,0, 1);
|
||||
simd4x4f_transpose_inplace(m);
|
||||
m->w = simd4f_create( x,y,z,1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_translation(simd4x4f* m, float x, float y, float z) {
|
||||
*m = simd4x4f_create( simd4f_create(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
simd4f_create(0.0f, 1.0f, 0.0f, 0.0f),
|
||||
simd4f_create(0.0f, 0.0f, 1.0f, 0.0f),
|
||||
simd4f_create( x, y, z, 1.0f));
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_axis_rotation(simd4x4f* m, float radians, simd4f axis) {
|
||||
|
||||
radians = -radians;
|
||||
|
||||
axis = simd4f_normalize3(axis);
|
||||
|
||||
const float sine = sinf(radians);
|
||||
const float cosine = cosf(radians);
|
||||
|
||||
const float x = simd4f_get_x(axis);
|
||||
const float y = simd4f_get_y(axis);
|
||||
const float z = simd4f_get_z(axis);
|
||||
|
||||
const float ab = x * y * (1 - cosine);
|
||||
const float bc = y * z * (1 - cosine);
|
||||
const float ca = z * x * (1 - cosine);
|
||||
|
||||
const float tx = x * x;
|
||||
const float ty = y * y;
|
||||
const float tz = z * z;
|
||||
|
||||
const simd4f i = simd4f_create( tx + cosine * (1 - tx), ab - z * sine, ca + y * sine, 0);
|
||||
const simd4f j = simd4f_create( ab + z * sine, ty + cosine * (1 - ty), bc - x * sine, 0);
|
||||
const simd4f k = simd4f_create( ca - y * sine, bc + x * sine, tz + cosine * (1 - tz), 0);
|
||||
|
||||
*m = simd4x4f_create( i,j,k, simd4f_create(0, 0, 0, 1) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_add(const simd4x4f* a, const simd4x4f* b, simd4x4f* out) {
|
||||
|
||||
out->x = simd4f_add(a->x, b->x);
|
||||
out->y = simd4f_add(a->y, b->y);
|
||||
out->z = simd4f_add(a->z, b->z);
|
||||
out->w = simd4f_add(a->w, b->w);
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_sub(const simd4x4f* a, const simd4x4f* b, simd4x4f* out) {
|
||||
|
||||
out->x = simd4f_sub(a->x, b->x);
|
||||
out->y = simd4f_sub(a->y, b->y);
|
||||
out->z = simd4f_sub(a->z, b->z);
|
||||
out->w = simd4f_sub(a->w, b->w);
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_mul(const simd4x4f* a, const simd4x4f* b, simd4x4f* out) {
|
||||
|
||||
out->x = simd4f_mul(a->x, b->x);
|
||||
out->y = simd4f_mul(a->y, b->y);
|
||||
out->z = simd4f_mul(a->z, b->z);
|
||||
out->w = simd4f_mul(a->w, b->w);
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_div(simd4x4f* a, simd4x4f* b, simd4x4f* out) {
|
||||
|
||||
out->x = simd4f_div(a->x, b->x);
|
||||
out->y = simd4f_div(a->y, b->y);
|
||||
out->z = simd4f_div(a->z, b->z);
|
||||
out->w = simd4f_div(a->w, b->w);
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline simd4f simd4x4f_inverse(const simd4x4f* a, simd4x4f* out) {
|
||||
|
||||
const simd4f c0 = a->x;
|
||||
const simd4f c1 = a->y;
|
||||
const simd4f c2 = a->z;
|
||||
const simd4f c3 = a->w;
|
||||
|
||||
const simd4f c0_wxyz = simd4f_shuffle_wxyz(c0);
|
||||
const simd4f c0_zwxy = simd4f_shuffle_zwxy(c0);
|
||||
const simd4f c0_yzwx = simd4f_shuffle_yzwx(c0);
|
||||
|
||||
const simd4f c1_wxyz = simd4f_shuffle_wxyz(c1);
|
||||
const simd4f c1_zwxy = simd4f_shuffle_zwxy(c1);
|
||||
const simd4f c1_yzwx = simd4f_shuffle_yzwx(c1);
|
||||
|
||||
const simd4f c2_wxyz = simd4f_shuffle_wxyz(c2);
|
||||
const simd4f c2_zwxy = simd4f_shuffle_zwxy(c2);
|
||||
const simd4f c2_yzwx = simd4f_shuffle_yzwx(c2);
|
||||
|
||||
const simd4f c3_wxyz = simd4f_shuffle_wxyz(c3);
|
||||
const simd4f c3_zwxy = simd4f_shuffle_zwxy(c3);
|
||||
const simd4f c3_yzwx = simd4f_shuffle_yzwx(c3);
|
||||
|
||||
const simd4f c0_wxyz_x_c1 = simd4f_mul(c0_wxyz, c1);
|
||||
const simd4f c0_wxyz_x_c1_yzwx = simd4f_mul(c0_wxyz, c1_yzwx);
|
||||
const simd4f c0_wxyz_x_c1_zwxy = simd4f_mul(c0_wxyz, c1_zwxy);
|
||||
|
||||
const simd4f c2_wxyz_x_c3 = simd4f_mul(c2_wxyz, c3);
|
||||
const simd4f c2_wxyz_x_c3_yzwx = simd4f_mul(c2_wxyz, c3_yzwx);
|
||||
const simd4f c2_wxyz_x_c3_zwxy = simd4f_mul(c2_wxyz, c3_zwxy);
|
||||
|
||||
const simd4f ar1 = simd4f_sub( simd4f_shuffle_wxyz(c2_wxyz_x_c3_zwxy), simd4f_shuffle_zwxy(c2_wxyz_x_c3) );
|
||||
const simd4f ar2 = simd4f_sub( simd4f_shuffle_zwxy(c2_wxyz_x_c3_yzwx), c2_wxyz_x_c3_yzwx );
|
||||
const simd4f ar3 = simd4f_sub( c2_wxyz_x_c3_zwxy, simd4f_shuffle_wxyz(c2_wxyz_x_c3) );
|
||||
|
||||
const simd4f br1 = simd4f_sub( simd4f_shuffle_wxyz(c0_wxyz_x_c1_zwxy), simd4f_shuffle_zwxy(c0_wxyz_x_c1) );
|
||||
const simd4f br2 = simd4f_sub( simd4f_shuffle_zwxy(c0_wxyz_x_c1_yzwx), c0_wxyz_x_c1_yzwx );
|
||||
const simd4f br3 = simd4f_sub( c0_wxyz_x_c1_zwxy, simd4f_shuffle_wxyz(c0_wxyz_x_c1) );
|
||||
|
||||
|
||||
const simd4f c0_sum = simd4f_madd(c0_yzwx, ar3,
|
||||
simd4f_madd(c0_zwxy, ar2,
|
||||
simd4f_mul(c0_wxyz, ar1)));
|
||||
|
||||
const simd4f c1_sum = simd4f_madd(c1_wxyz, ar1,
|
||||
simd4f_madd(c1_zwxy, ar2,
|
||||
simd4f_mul(c1_yzwx, ar3)));
|
||||
|
||||
const simd4f c2_sum = simd4f_madd(c2_yzwx, br3,
|
||||
simd4f_madd(c2_zwxy, br2,
|
||||
simd4f_mul(c2_wxyz, br1)));
|
||||
|
||||
const simd4f c3_sum = simd4f_madd(c3_yzwx, br3,
|
||||
simd4f_madd(c3_zwxy, br2,
|
||||
simd4f_mul(c3_wxyz, br1)));
|
||||
|
||||
|
||||
const simd4f d0 = simd4f_mul(c1_sum, c0);
|
||||
const simd4f d1 = simd4f_add(d0, simd4f_merge_high(d0, d0));
|
||||
const simd4f det = simd4f_sub(d1, simd4f_splat_y(d1));
|
||||
|
||||
const simd4f invdet = simd4f_splat_x( simd4f_div(simd4f_splat(1.0f), det) );
|
||||
|
||||
const simd4f o0 = simd4f_mul( simd4f_flip_sign_0101(c1_sum), invdet );
|
||||
const simd4f o1 = simd4f_mul( simd4f_flip_sign_1010(c0_sum), invdet );
|
||||
const simd4f o2 = simd4f_mul( simd4f_flip_sign_0101(c3_sum), invdet );
|
||||
const simd4f o3 = simd4f_mul( simd4f_flip_sign_1010(c2_sum), invdet );
|
||||
|
||||
const simd4x4f mt = simd4x4f_create(o0, o1, o2, o3);
|
||||
|
||||
simd4x4f_transpose( &mt, out);
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const simd4x4f& v) {
|
||||
os << "simd4x4f(simd4f(" << simd4f_get_x(v.x) << ", "
|
||||
<< simd4f_get_y(v.x) << ", "
|
||||
<< simd4f_get_z(v.x) << ", "
|
||||
<< simd4f_get_w(v.x) << "),\n"
|
||||
<< " simd4f(" << simd4f_get_x(v.y) << ", "
|
||||
<< simd4f_get_y(v.y) << ", "
|
||||
<< simd4f_get_z(v.y) << ", "
|
||||
<< simd4f_get_w(v.y) << "),\n"
|
||||
<< " simd4f(" << simd4f_get_x(v.z) << ", "
|
||||
<< simd4f_get_y(v.z) << ", "
|
||||
<< simd4f_get_z(v.z) << ", "
|
||||
<< simd4f_get_w(v.z) << "),\n"
|
||||
<< " simd4f(" << simd4f_get_x(v.w) << ", "
|
||||
<< simd4f_get_y(v.w) << ", "
|
||||
<< simd4f_get_z(v.w) << ", "
|
||||
<< simd4f_get_w(v.w) << "))";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4X4F_GNU_H
|
||||
#define VECTORIAL_SIMD4X4F_GNU_H
|
||||
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_transpose_inplace(simd4x4f* s) {
|
||||
const _simd4f_union sx = { s->x };
|
||||
const _simd4f_union sy = { s->y };
|
||||
const _simd4f_union sz = { s->z };
|
||||
const _simd4f_union sw = { s->w };
|
||||
|
||||
const simd4f dx = { sx.f[0], sy.f[0], sz.f[0], sw.f[0] };
|
||||
const simd4f dy = { sx.f[1], sy.f[1], sz.f[1], sw.f[1] };
|
||||
const simd4f dz = { sx.f[2], sy.f[2], sz.f[2], sw.f[2] };
|
||||
const simd4f dw = { sx.f[3], sy.f[3], sz.f[3], sw.f[3] };
|
||||
|
||||
s->x = dx;
|
||||
s->y = dy;
|
||||
s->z = dz;
|
||||
s->w = dw;
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_transpose(const simd4x4f *s, simd4x4f *out) {
|
||||
*out=*s;
|
||||
simd4x4f_transpose_inplace(out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4X4F_NEON_H
|
||||
#define VECTORIAL_SIMD4X4F_NEON_H
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_transpose_inplace(simd4x4f* s) {
|
||||
const _simd4f_union sx = { s->x };
|
||||
const _simd4f_union sy = { s->y };
|
||||
const _simd4f_union sz = { s->z };
|
||||
const _simd4f_union sw = { s->w };
|
||||
|
||||
const simd4f dx = simd4f_create( sx.f[0], sy.f[0], sz.f[0], sw.f[0] );
|
||||
const simd4f dy = simd4f_create( sx.f[1], sy.f[1], sz.f[1], sw.f[1] );
|
||||
const simd4f dz = simd4f_create( sx.f[2], sy.f[2], sz.f[2], sw.f[2] );
|
||||
const simd4f dw = simd4f_create( sx.f[3], sy.f[3], sz.f[3], sw.f[3] );
|
||||
|
||||
s->x = dx;
|
||||
s->y = dy;
|
||||
s->z = dz;
|
||||
s->w = dw;
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_transpose(const simd4x4f *s, simd4x4f *out) {
|
||||
*out=*s;
|
||||
simd4x4f_transpose_inplace(out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4X4F_SCALAR_H
|
||||
#define VECTORIAL_SIMD4X4F_SCALAR_H
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_transpose_inplace(simd4x4f *s) {
|
||||
simd4x4f d=*s;
|
||||
s->x.x = d.x.x;
|
||||
s->x.y = d.y.x;
|
||||
s->x.z = d.z.x;
|
||||
s->x.w = d.w.x;
|
||||
|
||||
s->y.x = d.x.y;
|
||||
s->y.y = d.y.y;
|
||||
s->y.z = d.z.y;
|
||||
s->y.w = d.w.y;
|
||||
|
||||
s->z.x = d.x.z;
|
||||
s->z.y = d.y.z;
|
||||
s->z.z = d.z.z;
|
||||
s->z.w = d.w.z;
|
||||
|
||||
s->w.x = d.x.w;
|
||||
s->w.y = d.y.w;
|
||||
s->w.z = d.z.w;
|
||||
s->w.w = d.w.w;
|
||||
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_transpose(const simd4x4f *s, simd4x4f *out) {
|
||||
*out=*s;
|
||||
simd4x4f_transpose_inplace(out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_SIMD4X4F_SSE_H
|
||||
#define VECTORIAL_SIMD4X4F_SSE_H
|
||||
|
||||
|
||||
|
||||
vectorial_inline void simd4x4f_transpose_inplace(simd4x4f *s) {
|
||||
_MM_TRANSPOSE4_PS(s->x, s->y, s->z, s->w);
|
||||
}
|
||||
|
||||
vectorial_inline void simd4x4f_transpose(const simd4x4f *s, simd4x4f *out) {
|
||||
*out=*s;
|
||||
simd4x4f_transpose_inplace(out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_VEC2F_H
|
||||
|
||||
#ifndef VECTORIAL_SIMD4F_H
|
||||
#include "vectorial/simd4f.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace vectorial {
|
||||
|
||||
class vec4f;
|
||||
class vec3f;
|
||||
|
||||
class vec2f {
|
||||
public:
|
||||
|
||||
simd4f value;
|
||||
|
||||
inline vec2f() {}
|
||||
inline vec2f(const vec2f& v) : value(v.value) {}
|
||||
inline vec2f(const simd4f& v) : value(v) {}
|
||||
explicit inline vec2f(float xy) : value( simd4f_splat(xy) ) {}
|
||||
inline vec2f(float x, float y) : value( simd4f_create(x,y,0,0) ) {}
|
||||
explicit inline vec2f(const float *ary) : value( simd4f_uload2(ary) ) { }
|
||||
|
||||
inline float x() const { return simd4f_get_x(value); }
|
||||
inline float y() const { return simd4f_get_y(value); }
|
||||
|
||||
inline void load(const float *ary) { value = simd4f_uload2(ary); }
|
||||
inline void store(float *ary) const { simd4f_ustore2(value, ary); }
|
||||
|
||||
enum { elements = 2 };
|
||||
|
||||
static vec2f zero() { return vec2f(simd4f_zero()); }
|
||||
static vec2f one() { return vec2f(1.0f); }
|
||||
static vec2f xAxis() { return vec2f(1.0f, 0.0f); }
|
||||
static vec2f yAxis() { return vec2f(0.0f, 1.0f); }
|
||||
|
||||
inline vec4f xyzw(float z, float w) const;
|
||||
inline vec4f xy00() const;
|
||||
inline vec4f xy01() const;
|
||||
inline vec3f xyz(float z) const;
|
||||
inline vec3f xy0() const;
|
||||
inline vec2f xy() const;
|
||||
|
||||
};
|
||||
|
||||
vectorial_inline vec2f operator-(const vec2f& lhs) {
|
||||
return vec2f( simd4f_sub(simd4f_zero(), lhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec2f operator+(const vec2f& lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator-(const vec2f& lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator*(const vec2f& lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator/(const vec2f& lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec2f operator+=(vec2f& lhs, const vec2f& rhs) {
|
||||
return lhs = vec2f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator-=(vec2f& lhs, const vec2f& rhs) {
|
||||
return lhs = vec2f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator*=(vec2f& lhs, const vec2f& rhs) {
|
||||
return lhs = vec2f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator/=(vec2f& lhs, const vec2f& rhs) {
|
||||
return lhs = vec2f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline vec2f operator+(const vec2f& lhs, float rhs) {
|
||||
return vec2f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator-(const vec2f& lhs, float rhs) {
|
||||
return vec2f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator*(const vec2f& lhs, float rhs) {
|
||||
return vec2f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator/(const vec2f& lhs, float rhs) {
|
||||
return vec2f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator+(float lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_add(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator-(float lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_sub(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator*(float lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_mul(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator/(float lhs, const vec2f& rhs) {
|
||||
return vec2f( simd4f_div(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec2f operator+=(vec2f& lhs, float rhs) {
|
||||
return lhs = vec2f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator-=(vec2f& lhs, float rhs) {
|
||||
return lhs = vec2f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator*=(vec2f& lhs, float rhs) {
|
||||
return lhs = vec2f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f operator/=(vec2f& lhs, float rhs) {
|
||||
return lhs = vec2f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float dot(const vec2f& lhs, const vec2f& rhs) {
|
||||
return simd4f_get_x( simd4f_dot2(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float length(const vec2f& v) {
|
||||
return simd4f_get_x( simd4f_length2(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline float length_squared(const vec2f& v) {
|
||||
return simd4f_get_x( simd4f_length2_squared(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f normalize(const vec2f& v) {
|
||||
return vec2f( simd4f_normalize2(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f min(const vec2f& a, const vec2f& b) {
|
||||
return vec2f( simd4f_min(a.value, b.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec2f max(const vec2f& a, const vec2f& b) {
|
||||
return vec2f( simd4f_max(a.value, b.value) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
inline ::vectorial::vec2f min(const ::vectorial::vec2f& a, const ::vectorial::vec2f& b) { return ::vectorial::min(a,b); }
|
||||
inline ::vectorial::vec2f max(const ::vectorial::vec2f& a, const ::vectorial::vec2f& b) { return ::vectorial::max(a,b); }
|
||||
}
|
||||
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const vectorial::vec2f& v) {
|
||||
os << "[ " << v.x() << ", "
|
||||
<< v.y() << " ]";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Copyright (c) 2014 Google, Inc.
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_VEC3F_H
|
||||
|
||||
#ifndef VECTORIAL_SIMD4F_H
|
||||
#include "vectorial/simd4f.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace vectorial {
|
||||
|
||||
class vec4f;
|
||||
class vec2f;
|
||||
|
||||
class vec3f {
|
||||
public:
|
||||
|
||||
simd4f value;
|
||||
|
||||
inline vec3f() {}
|
||||
inline vec3f(const vec3f& v) : value(v.value) {}
|
||||
inline vec3f(const simd4f& v) : value(v) {}
|
||||
explicit inline vec3f(float xyz) : value( simd4f_splat(xyz) ) {}
|
||||
inline vec3f(float x, float y, float z) : value( simd4f_create(x,y,z,0) ) {}
|
||||
explicit inline vec3f(const float *ary) : value( simd4f_uload3(ary) ) { }
|
||||
|
||||
inline float x() const { return simd4f_get_x(value); }
|
||||
inline float y() const { return simd4f_get_y(value); }
|
||||
inline float z() const { return simd4f_get_z(value); }
|
||||
|
||||
inline void load(const float *ary) { value = simd4f_uload3(ary); }
|
||||
inline void store(float *ary) const { simd4f_ustore3(value, ary); }
|
||||
|
||||
enum { elements = 3 };
|
||||
|
||||
static vec3f zero() { return vec3f(simd4f_zero()); }
|
||||
static vec3f one() { return vec3f(1.0f); }
|
||||
static vec3f xAxis() { return vec3f(1.0f, 0.0f, 0.0f); }
|
||||
static vec3f yAxis() { return vec3f(0.0f, 1.0f, 0.0f); }
|
||||
static vec3f zAxis() { return vec3f(0.0f, 0.0f, 1.0f); }
|
||||
|
||||
inline vec4f xyz0() const;
|
||||
inline vec4f xyz1() const;
|
||||
inline vec4f xyzw(float w) const;
|
||||
inline vec3f xyz() const;
|
||||
inline vec3f xy0() const;
|
||||
inline vec2f xy() const;
|
||||
};
|
||||
|
||||
vectorial_inline vec3f operator-(const vec3f& lhs) {
|
||||
return vec3f( simd4f_sub(simd4f_zero(), lhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec3f operator+(const vec3f& lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator-(const vec3f& lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator*(const vec3f& lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator/(const vec3f& lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec3f operator+=(vec3f& lhs, const vec3f& rhs) {
|
||||
return lhs = vec3f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator-=(vec3f& lhs, const vec3f& rhs) {
|
||||
return lhs = vec3f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator*=(vec3f& lhs, const vec3f& rhs) {
|
||||
return lhs = vec3f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator/=(vec3f& lhs, const vec3f& rhs) {
|
||||
return lhs = vec3f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline vec3f operator+(const vec3f& lhs, float rhs) {
|
||||
return vec3f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator-(const vec3f& lhs, float rhs) {
|
||||
return vec3f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator*(const vec3f& lhs, float rhs) {
|
||||
return vec3f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator/(const vec3f& lhs, float rhs) {
|
||||
return vec3f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator+(float lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_add(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator-(float lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_sub(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator*(float lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_mul(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator/(float lhs, const vec3f& rhs) {
|
||||
return vec3f( simd4f_div(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec3f operator+=(vec3f& lhs, float rhs) {
|
||||
return lhs = vec3f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator-=(vec3f& lhs, float rhs) {
|
||||
return lhs = vec3f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator*=(vec3f& lhs, float rhs) {
|
||||
return lhs = vec3f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f operator/=(vec3f& lhs, float rhs) {
|
||||
return lhs = vec3f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float dot(const vec3f& lhs, const vec3f& rhs) {
|
||||
return simd4f_dot3_scalar(lhs.value, rhs.value);
|
||||
}
|
||||
|
||||
vectorial_inline vec3f cross(const vec3f& lhs, const vec3f& rhs) {
|
||||
return simd4f_cross3(lhs.value, rhs.value);
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float length(const vec3f& v) {
|
||||
return simd4f_get_x( simd4f_length3(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline float length_squared(const vec3f& v) {
|
||||
return simd4f_get_x( simd4f_length3_squared(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f normalize(const vec3f& v) {
|
||||
return vec3f( simd4f_normalize3(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f min(const vec3f& a, const vec3f& b) {
|
||||
return vec3f( simd4f_min(a.value, b.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec3f max(const vec3f& a, const vec3f& b) {
|
||||
return vec3f( simd4f_max(a.value, b.value) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
inline ::vectorial::vec3f min(const ::vectorial::vec3f& a, const ::vectorial::vec3f& b) { return ::vectorial::min(a,b); }
|
||||
inline ::vectorial::vec3f max(const ::vectorial::vec3f& a, const ::vectorial::vec3f& b) { return ::vectorial::max(a,b); }
|
||||
}
|
||||
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const vectorial::vec3f& v) {
|
||||
os << "[ " << v.x() << ", "
|
||||
<< v.y() << ", "
|
||||
<< v.z() << " ]";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_VEC4F_H
|
||||
#define VECTORIAL_VEC4F_H
|
||||
|
||||
#ifndef VECTORIAL_SIMD4F_H
|
||||
#include "vectorial/simd4f.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace vectorial {
|
||||
|
||||
class vec3f;
|
||||
class vec2f;
|
||||
|
||||
class vec4f {
|
||||
public:
|
||||
|
||||
simd4f value;
|
||||
|
||||
inline vec4f() {}
|
||||
inline vec4f(const vec4f& v) : value(v.value) {}
|
||||
inline vec4f(const simd4f& v) : value(v) {}
|
||||
explicit inline vec4f(float xyzw) : value( simd4f_splat(xyzw) ) {}
|
||||
inline vec4f(float x, float y, float z, float w) : value( simd4f_create(x,y,z,w) ) {}
|
||||
explicit inline vec4f(const float *ary) : value( simd4f_uload4(ary) ) { }
|
||||
|
||||
inline float x() const { return simd4f_get_x(value); }
|
||||
inline float y() const { return simd4f_get_y(value); }
|
||||
inline float z() const { return simd4f_get_z(value); }
|
||||
inline float w() const { return simd4f_get_w(value); }
|
||||
|
||||
inline void load(const float *ary) { value = simd4f_uload4(ary); }
|
||||
inline void store(float *ary) const { simd4f_ustore4(value, ary); }
|
||||
|
||||
enum { elements = 4 };
|
||||
|
||||
|
||||
static vec4f zero() { return vec4f(simd4f_zero()); }
|
||||
static vec4f one() { return vec4f(1.0f); }
|
||||
static vec4f xAxis() { return vec4f(1.0f, 0.0f, 0.0f, 0.0f); }
|
||||
static vec4f yAxis() { return vec4f(0.0f, 1.0f, 0.0f, 0.0f); }
|
||||
static vec4f zAxis() { return vec4f(0.0f, 0.0f, 1.0f, 0.0f); }
|
||||
static vec4f wAxis() { return vec4f(0.0f, 0.0f, 0.0f, 1.0f); }
|
||||
|
||||
|
||||
inline vec3f xyz() const;
|
||||
inline vec2f xy() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
vectorial_inline vec4f operator-(const vec4f& lhs) {
|
||||
return vec4f( simd4f_sub(simd4f_zero(), lhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec4f operator+(const vec4f& lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator-(const vec4f& lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator*(const vec4f& lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator/(const vec4f& lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec4f operator+=(vec4f& lhs, const vec4f& rhs) {
|
||||
return lhs = vec4f( simd4f_add(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator-=(vec4f& lhs, const vec4f& rhs) {
|
||||
return lhs = vec4f( simd4f_sub(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator*=(vec4f& lhs, const vec4f& rhs) {
|
||||
return lhs = vec4f( simd4f_mul(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator/=(vec4f& lhs, const vec4f& rhs) {
|
||||
return lhs = vec4f( simd4f_div(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
vectorial_inline vec4f operator+(const vec4f& lhs, float rhs) {
|
||||
return vec4f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator-(const vec4f& lhs, float rhs) {
|
||||
return vec4f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator*(const vec4f& lhs, float rhs) {
|
||||
return vec4f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator/(const vec4f& lhs, float rhs) {
|
||||
return vec4f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator+(float lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_add(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator-(float lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_sub(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator*(float lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_mul(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator/(float lhs, const vec4f& rhs) {
|
||||
return vec4f( simd4f_div(simd4f_splat(lhs), rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline vec4f operator+=(vec4f& lhs, float rhs) {
|
||||
return lhs = vec4f( simd4f_add(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator-=(vec4f& lhs, float rhs) {
|
||||
return lhs = vec4f( simd4f_sub(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator*=(vec4f& lhs, float rhs) {
|
||||
return lhs = vec4f( simd4f_mul(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f operator/=(vec4f& lhs, float rhs) {
|
||||
return lhs = vec4f( simd4f_div(lhs.value, simd4f_splat(rhs)) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float dot(const vec4f& lhs, const vec4f& rhs) {
|
||||
return simd4f_get_x( simd4f_dot4(lhs.value, rhs.value) );
|
||||
}
|
||||
|
||||
|
||||
vectorial_inline float length(const vec4f& v) {
|
||||
return simd4f_get_x( simd4f_length4(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline float length_squared(const vec4f& v) {
|
||||
return simd4f_get_x( simd4f_length4_squared(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f normalize(const vec4f& v) {
|
||||
return vec4f( simd4f_normalize4(v.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f min(const vec4f& a, const vec4f& b) {
|
||||
return vec4f( simd4f_min(a.value, b.value) );
|
||||
}
|
||||
|
||||
vectorial_inline vec4f max(const vec4f& a, const vec4f& b) {
|
||||
return vec4f( simd4f_max(a.value, b.value) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
inline ::vectorial::vec4f min(const ::vectorial::vec4f& a, const ::vectorial::vec4f& b) { return ::vectorial::min(a,b); }
|
||||
inline ::vectorial::vec4f max(const ::vectorial::vec4f& a, const ::vectorial::vec4f& b) { return ::vectorial::max(a,b); }
|
||||
}
|
||||
|
||||
|
||||
#ifdef VECTORIAL_OSTREAM
|
||||
#include <ostream>
|
||||
|
||||
vectorial_inline std::ostream& operator<<(std::ostream& os, const vectorial::vec4f& v) {
|
||||
os << "[ " << v.x() << ", "
|
||||
<< v.y() << ", "
|
||||
<< v.z() << ", "
|
||||
<< v.w() << " ]";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_VEC_CONVERT_H
|
||||
#define VECTORIAL_VEC_CONVERT_H
|
||||
|
||||
|
||||
namespace vectorial {
|
||||
|
||||
inline vec3f vec4f::xyz() const { return vec3f(value); }
|
||||
inline vec2f vec4f::xy() const { return vec2f(value); }
|
||||
|
||||
inline vec4f vec3f::xyz0() const { return vec4f(simd4f_zero_w(value)); }
|
||||
inline vec4f vec3f::xyz1() const { return xyz0() + vec4f(0.0f, 0.0f, 0.0f, 1.0f); }
|
||||
inline vec4f vec3f::xyzw(float w) const { return xyz0() + vec4f(0.0f, 0.0f, 0.0f, w); }
|
||||
inline vec3f vec3f::xyz() const { return vec3f(value); }
|
||||
inline vec3f vec3f::xy0() const { return vec3f(value) * vec3f(1.0f, 1.0f, 0.0f); }
|
||||
inline vec2f vec3f::xy() const { return vec2f(value); }
|
||||
|
||||
inline vec4f vec2f::xy00() const { return vec4f(simd4f_zero_zw(value)); }
|
||||
inline vec4f vec2f::xy01() const { return xy00() + vec4f(0.0f, 0.0f, 0.0f, 1.0f); }
|
||||
inline vec4f vec2f::xyzw(float z, float w) const { return xy00() + vec4f(0.0f, 0.0f, z, w); }
|
||||
inline vec3f vec2f::xy0() const { return vec3f(simd4f_zero_zw(value)); }
|
||||
inline vec2f vec2f::xy() const { return vec2f(value); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Vectorial
|
||||
Copyright (c) 2010 Mikko Lehtonen
|
||||
Licensed under the terms of the two-clause BSD License (see LICENSE)
|
||||
*/
|
||||
#ifndef VECTORIAL_VECTORIAL_H
|
||||
#define VECTORIAL_VECTORIAL_H
|
||||
|
||||
|
||||
#include "vectorial/vec2f.h"
|
||||
#include "vectorial/vec3f.h"
|
||||
#include "vectorial/vec4f.h"
|
||||
|
||||
#include "vectorial/vec_convert.h"
|
||||
|
||||
#include "vectorial/mat4f.h"
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user