1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #pragma once |
4 | |
5 | #include "Prerequisites/BsPrerequisitesUtil.h" |
6 | #include "Math/BsVector4.h" |
7 | #include "Math/BsAABox.h" |
8 | #include "Math/BsSphere.h" |
9 | #include "Math/BsRect2.h" |
10 | |
11 | #define SIMDPP_ARCH_X86_SSE4_1 |
12 | |
13 | #if BS_COMPILER == BS_COMPILER_MSVC |
14 | #pragma warning(disable: 4244) |
15 | #endif |
16 | |
17 | #include "ThirdParty/simdpp/simd.h" |
18 | |
19 | #if BS_COMPILER == BS_COMPILER_MSVC |
20 | #pragma warning(default: 4244) |
21 | #endif |
22 | |
23 | namespace bs |
24 | { |
25 | namespace simd |
26 | { |
27 | using namespace simdpp; |
28 | |
29 | /** @addtogroup Math |
30 | * @{ |
31 | */ |
32 | |
33 | /** |
34 | * Version of bs::AABox suitable for SIMD use. Takes up a bit more memory than standard AABox and is always 16-byte |
35 | * aligned. |
36 | */ |
37 | struct AABox |
38 | { |
39 | /** Center of the bounds, W component unused. */ |
40 | SIMDPP_ALIGN(16) Vector4 center; |
41 | |
42 | /** Extents (half-size) of the bounds, W component unused. */ |
43 | SIMDPP_ALIGN(16) Vector4 extents; |
44 | |
45 | AABox() = default; |
46 | |
47 | /** Initializes bounds from an AABox. */ |
48 | AABox(const bs::AABox& box) |
49 | { |
50 | center = Vector4(box.getCenter()); |
51 | extents = Vector4(box.getHalfSize()); |
52 | } |
53 | |
54 | /** Initializes bounds from a Sphere. */ |
55 | AABox(const Sphere& sphere) |
56 | { |
57 | center = Vector4(sphere.getCenter()); |
58 | |
59 | float radius = sphere.getRadius(); |
60 | extents = Vector4(radius, radius, radius, 0.0f); |
61 | } |
62 | |
63 | /** Initializes bounds from a vector representing the center and equal extents in all directions. */ |
64 | AABox(const Vector3& center, float extent) |
65 | { |
66 | this->center = Vector4(center); |
67 | extents = Vector4(extent, extent, extent, 0.0f); |
68 | } |
69 | |
70 | /** Returns true if the current bounds object intersects the provided object. */ |
71 | bool intersects(const AABox& other) const |
72 | { |
73 | auto myCenter = load<float32x4>(¢er); |
74 | auto otherCenter = load<float32x4>(&other.center); |
75 | |
76 | float32x4 diff = abs(sub(myCenter, otherCenter)); |
77 | |
78 | auto myExtents = simd::load<float32x4>(&extents); |
79 | auto otherExtents = simd::load<float32x4>(&other.extents); |
80 | |
81 | float32x4 extents = add(myExtents, otherExtents); |
82 | |
83 | return test_bits_any(bit_cast<uint32x4>(cmp_gt(diff, extents))) == false; |
84 | } |
85 | }; |
86 | |
87 | /** |
88 | * Version of bs::Rect2 suitable for SIMD use. |
89 | */ |
90 | struct Rect2 |
91 | { |
92 | /** Center of the bounds. Z and W component unused.*/ |
93 | SIMDPP_ALIGN(16) Vector4 center; |
94 | |
95 | /** Extents (half-size) of the bounds. Z and W component unused. */ |
96 | SIMDPP_ALIGN(16) Vector4 extents; |
97 | |
98 | Rect2() = default; |
99 | |
100 | /** Initializes bounds from an Rect2. */ |
101 | Rect2(const bs::Rect2& rect) |
102 | { |
103 | center = Vector4(rect.getCenter().x, rect.getCenter().y, 0.0f, 0.0f); |
104 | extents = Vector4(rect.getHalfSize().x, rect.getHalfSize().y, 0.0f, 0.0f); |
105 | } |
106 | |
107 | /** Initializes bounds from a vector representing the center and equal extents in all directions. */ |
108 | Rect2(const Vector2& center, float extent) |
109 | { |
110 | this->center = Vector4(center.x, center.y, 0.0f, 0.0f); |
111 | extents = Vector4(extent, extent, 0.0f, 0.0f); |
112 | } |
113 | |
114 | /** Returns true if the current bounds object intersects the provided object. */ |
115 | bool overlaps(const Rect2& other) const |
116 | { |
117 | auto myCenter = load<float32x4>(¢er); |
118 | auto otherCenter = load<float32x4>(&other.center); |
119 | |
120 | float32x4 diff = abs(sub(myCenter, otherCenter)); |
121 | |
122 | auto myExtents = simd::load<float32x4>(&extents); |
123 | auto otherExtents = simd::load<float32x4>(&other.extents); |
124 | |
125 | float32x4 extents = add(myExtents, otherExtents); |
126 | |
127 | return test_bits_any(bit_cast<uint32x4>(cmp_gt(diff, extents))) == false; |
128 | } |
129 | }; |
130 | |
131 | /** @} */ |
132 | } |
133 | } |
134 | |