VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
vector2.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 21.07.2025.
5//
6
7#pragma once
8
9#include "defines.h"
10
11namespace visutwin::canvas
12{
17 struct Vector2
18 {
19 float x, y;
20
21 Vector2() : x(0), y(0)
22 {
23 }
24
25 explicit Vector2(const float s) : x(s), y(s)
26 {
27 }
28
29 Vector2(const float x, const float y) : x(x), y(y)
30 {
31 }
32
33 [[nodiscard]] float dot(const Vector2& other) const
34 {
35#if defined(USE_SIMD_NEON)
36 float32x4_t a = {x, y, 0.0f, 0.0f};
37 float32x4_t b = {other.x, other.y, 0.0f, 0.0f};
38 const float32x4_t m = vmulq_f32(a, b);
39 float32x2_t sum = vadd_f32(vget_low_f32(m), vget_high_f32(m));
40 return vget_lane_f32(sum, 0) + vget_lane_f32(sum, 1);
41#elif defined(USE_SIMD_SSE)
42 __m128 a = _mm_set_ps(0.0f, 0.0f, y, x);
43 __m128 b = _mm_set_ps(0.0f, 0.0f, other.y, other.x);
44 __m128 mul = _mm_mul_ps(a, b);
45 // SSE2 reduction for x*x + y*y
46 __m128 shuf = _mm_shuffle_ps(mul, mul, _MM_SHUFFLE(2, 3, 0, 1));
47 __m128 sums = _mm_add_ps(mul, shuf);
48 __m128 dot = _mm_add_ss(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(1, 1, 1, 1)));
49 return _mm_cvtss_f32(dot);
50#else
51 return x * other.x + y * other.y;
52#endif
53 }
54
55 [[nodiscard]] float length() const
56 {
57 return std::sqrt(dot(*this));
58 }
59
60 Vector2 operator-(const Vector2& other) const
61 {
62#if defined(USE_SIMD_NEON)
63 float32x4_t a = {x, y, 0.0f, 0.0f};
64 float32x4_t b = {other.x, other.y, 0.0f, 0.0f};
65 float32x4_t result = vsubq_f32(a, b);
66 return {vgetq_lane_f32(result, 0), vgetq_lane_f32(result, 1)};
67#elif defined(USE_SIMD_SSE)
68 __m128 a = _mm_set_ps(0.0f, 0.0f, y, x);
69 __m128 b = _mm_set_ps(0.0f, 0.0f, other.y, other.x);
70 __m128 result = _mm_sub_ps(a, b);
71 alignas(16) float res[4];
72 _mm_store_ps(res, result);
73 return { res[0], res[1] };
74#else
75 return { x - other.x, y - other.y };
76#endif
77 }
78
79 Vector2 operator*(float scalar) const
80 {
81#if defined(USE_SIMD_NEON)
82 float32x4_t a = {x, y, 0.0f, 0.0f};
83 float32x4_t s = vdupq_n_f32(scalar);
84 float32x4_t result = vmulq_f32(a, s);
85 return {vgetq_lane_f32(result, 0), vgetq_lane_f32(result, 1)};
86#elif defined(USE_SIMD_SSE)
87 __m128 a = _mm_set_ps(0.0f, 0.0f, y, x);
88 __m128 s = _mm_set1_ps(scalar);
89 __m128 result = _mm_mul_ps(a, s);
90 alignas(16) float res[4];
91 _mm_store_ps(res, result);
92 return { res[0], res[1] };
93#else
94 return { x * scalar, y * scalar };
95#endif
96 }
97 };
98
99 template<typename T>
100 struct Vector2T
101 {
102 T x, y;
103
104 Vector2T() : x(0), y(0)
105 {
106 }
107
108 explicit Vector2T(const T s) : x(s), y(s)
109 {
110 }
111
112 Vector2T(const T x, const T y) : x(x), y(y)
113 {
114 }
115
116 Vector2T<T> operator-(const Vector2T& other) const
117 {
118 return Vector2T<T>(x - other.x, y - other.y);
119 }
120
121 [[nodiscard]] float length() const
122 {
123 return std::sqrt(x * x + y * y);
124 }
125 };
126
129}
Vector2T< uint32_t > Vector2u
Definition vector2.h:127
Vector2T< int32_t > Vector2i
Definition vector2.h:128
float dot(const Vector2 &other) const
Definition vector2.h:33
Vector2 operator*(float scalar) const
Definition vector2.h:79
Vector2(const float s)
Definition vector2.h:25
Vector2(const float x, const float y)
Definition vector2.h:29
float length() const
Definition vector2.h:55
Vector2 operator-(const Vector2 &other) const
Definition vector2.h:60
Vector2T(const T x, const T y)
Definition vector2.h:112
Vector2T< T > operator-(const Vector2T &other) const
Definition vector2.h:116