Files
LNXSDK/leenkx/Sources/iron/culling/SimdOps.hx
2026-10-15 02:41:03 -07:00

84 lines
2.2 KiB
Haxe

package iron.culling;
#if cpp
@:include("smmintrin.h")
@:include("emmintrin.h")
@:include("xmmintrin.h")
#end
class SimdOps {
public static inline function dot4(
a0: Float, a1: Float, a2: Float, a3: Float,
b0: Float, b1: Float, b2: Float, b3: Float
): Float {
#if cpp
return untyped __cpp__("_mm_cvtss_f32(_mm_dp_ps(_mm_setr_ps({0}, {1}, {2}, {3}), _mm_setr_ps({4}, {5}, {6}, {7}), 0xF1))",
a0, a1, a2, a3, b0, b1, b2, b3);
#else
return a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
#end
}
public static inline function dot3(
a0: Float, a1: Float, a2: Float,
b0: Float, b1: Float, b2: Float
): Float {
#if cpp
return untyped __cpp__("_mm_cvtss_f32(_mm_dp_ps(_mm_setr_ps({0}, {1}, {2}, 0.0f), _mm_setr_ps({3}, {4}, {5}, 0.0f), 0x71))",
a0, a1, a2, b0, b1, b2);
#else
return a0 * b0 + a1 * b1 + a2 * b2;
#end
}
public static inline function reciprocal(x: Float): Float {
#if cpp
return untyped __cpp__("({ auto _r = _mm_rcp_ss(_mm_set_ss({0})); _mm_cvtss_f32(_mm_add_ss(_mm_mul_ss(_r, _mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(_r, _mm_set_ss({0})))), _r)); })", x);
#else
return 1.0 / x;
#end
}
public static inline function max4f(
a: Float, b: Float, c: Float, d: Float
): Float {
#if cpp
return untyped __cpp__("_mm_cvtss_f32(_mm_max_ss(_mm_max_ss(_mm_set_ss({0}), _mm_set_ss({1})), _mm_max_ss(_mm_set_ss({2}), _mm_set_ss({3}))))",
a, b, c, d);
#else
var m = a;
if (b > m) m = b;
if (c > m) m = c;
if (d > m) m = d;
return m;
#end
}
public static inline function min4f(
a: Float, b: Float, c: Float, d: Float
): Float {
#if cpp
return untyped __cpp__("_mm_cvtss_f32(_mm_min_ss(_mm_min_ss(_mm_set_ss({0}), _mm_set_ss({1})), _mm_min_ss(_mm_set_ss({2}), _mm_set_ss({3}))))",
a, b, c, d);
#else
var m = a;
if (b < m) m = b;
if (c < m) m = c;
if (d < m) m = d;
return m;
#end
}
public static inline function frustumSphereTest6(
planeData: kha.arrays.Float32Array,
cx: Float, cy: Float, cz: Float, radius: Float
): Bool {
for (i in 0...6) {
var base = i * 4;
var dist = dot3(cx, cy, cz, planeData[base], planeData[base + 1], planeData[base + 2]) + planeData[base + 3];
if (dist + radius < 0) return false;
}
return true;
}
}