-
Notifications
You must be signed in to change notification settings - Fork 0
/
cube.h
92 lines (79 loc) · 3.85 KB
/
cube.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once
#include <immintrin.h>
#include "vec.h"
struct Cube {
vec4 m_scale{ 1.f, 1.f, 1.f, 1.f };
vec4 m_translation{ 0.f,0.f,0.f,1.f };
vec4 m_rotation{ 0.f,0.f,0.f,1.f };
inline mat4 GetTransform() const {
mat4 scale = mat4::Scale(m_scale.index<0>(), m_scale.index<1>(), m_scale.index<2>());
mat4 rotation = mat4::Rotation(m_rotation);
mat4 translation = mat4::Translation(m_translation.index<0>(), m_translation.index<1>(), m_translation.index<2>());
return translation * rotation * scale;
}
inline mat4 GetTransformInv() const {
return GetTransform().Inverse();
}
inline bool Collision(const Cube& another) const {
return CollisionSingleSide(another) && another.CollisionSingleSide(*this);
}
inline bool CollisionSingleSide(const Cube& another) const {
const mat4 transform = GetTransformInv() * another.GetTransform();
const mat4 transpose = transform.Transpose();
const vec4 abscol0 = _mm_and_ps(absfourmask, transpose.row0.data);
const vec4 abscol1 = _mm_and_ps(absfourmask, transpose.row1.data);
const vec4 abscol2 = _mm_and_ps(absfourmask, transpose.row2.data);
const vec4 abscol3 = _mm_and_ps(absfourmask, transpose.row3.data);
// vertex face test
{
const vec4 range = abscol0 + abscol1 + abscol2 + fourone;
const vec4 test = range - abscol3;
if (test.HasOneNegative())
return false;
}
// edge edge test
{
const vec4 abscol0shufle = _mm_permute_ps(abscol0.data, 0b11010010);
const vec4 abscol1shufle = _mm_permute_ps(abscol1.data, 0b11010010);
const vec4 abscol2shufle = _mm_permute_ps(abscol2.data, 0b11010010);
const vec4 col0shufle = _mm_permute_ps(transpose.row0.data, 0b11010010);
const vec4 col1shufle = _mm_permute_ps(transpose.row1.data, 0b11010010);
const vec4 col2shufle = _mm_permute_ps(transpose.row2.data, 0b11010010);
const vec4 col3shufle = _mm_permute_ps(transpose.row3.data, 0b11010010);
{
const vec4 threshold = abscol0 + abscol0shufle;
const vec4 range11 = _mm_add_ps(_mm_mul_ps(abscol0.data, abscol1shufle.data), _mm_mul_ps(abscol0shufle.data, abscol1.data));
const vec4 range12 = _mm_add_ps(_mm_mul_ps(abscol0.data, abscol2shufle.data), _mm_mul_ps(abscol0shufle.data, abscol2.data));
const vec4 range1 = range11 + range12;
const vec4 center1 = _mm_sub_ps(_mm_mul_ps(transpose.row0.data, col3shufle.data), _mm_mul_ps(col0shufle.data, transpose.row3.data));
const vec4 abscenter = _mm_and_ps(absfourmask, center1.data);
const vec4 test = threshold + range1 - abscenter;
if (test.HasOneNegative())
return false;
}
{
const vec4 threshold = abscol1 + abscol1shufle;
const vec4 range11 = _mm_add_ps(_mm_mul_ps(abscol1.data, abscol0shufle.data), _mm_mul_ps(abscol1shufle.data, abscol0.data));
const vec4 range12 = _mm_add_ps(_mm_mul_ps(abscol1.data, abscol2shufle.data), _mm_mul_ps(abscol1shufle.data, abscol2.data));
const vec4 range1 = range11 + range12;
const vec4 center1 = _mm_sub_ps(_mm_mul_ps(transpose.row1.data, col3shufle.data), _mm_mul_ps(col1shufle.data, transpose.row3.data));
const vec4 abscenter = _mm_and_ps(absfourmask, center1.data);
const vec4 test = threshold + range1 - abscenter;
if (test.HasOneNegative())
return false;
}
{
const vec4 threshold = abscol2 + abscol2shufle;
const vec4 range11 = _mm_add_ps(_mm_mul_ps(abscol2.data, abscol0shufle.data), _mm_mul_ps(abscol2shufle.data, abscol0.data));
const vec4 range12 = _mm_add_ps(_mm_mul_ps(abscol2.data, abscol1shufle.data), _mm_mul_ps(abscol2shufle.data, abscol1.data));
const vec4 range1 = range11 + range12;
const vec4 center1 = _mm_sub_ps(_mm_mul_ps(transpose.row2.data, col3shufle.data), _mm_mul_ps(col2shufle.data, transpose.row3.data));
const vec4 abscenter = _mm_and_ps(absfourmask, center1.data);
const vec4 test = threshold + range1 - abscenter;
if (test.HasOneNegative())
return false;
}
}
return true;
}
};