ncca-ngl 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ncca_ngl-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/METADATA +9 -9
- ncca_ngl-0.1.1.dist-info/RECORD +4 -0
- {ncca_ngl-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/WHEEL +1 -2
- ncca/ngl/PrimData/pack_arrays.py +0 -20
- ncca/ngl/__init__.py +0 -100
- ncca/ngl/abstract_vao.py +0 -89
- ncca/ngl/base_mesh.py +0 -170
- ncca/ngl/base_mesh.pyi +0 -11
- ncca/ngl/bbox.py +0 -224
- ncca/ngl/bezier_curve.py +0 -75
- ncca/ngl/first_person_camera.py +0 -174
- ncca/ngl/image.py +0 -94
- ncca/ngl/log.py +0 -44
- ncca/ngl/mat2.py +0 -128
- ncca/ngl/mat3.py +0 -466
- ncca/ngl/mat4.py +0 -456
- ncca/ngl/multi_buffer_vao.py +0 -49
- ncca/ngl/obj.py +0 -416
- ncca/ngl/plane.py +0 -47
- ncca/ngl/primitives.py +0 -706
- ncca/ngl/pyside_event_handling_mixin.py +0 -318
- ncca/ngl/quaternion.py +0 -112
- ncca/ngl/random.py +0 -167
- ncca/ngl/shader.py +0 -229
- ncca/ngl/shader_lib.py +0 -536
- ncca/ngl/shader_program.py +0 -816
- ncca/ngl/simple_index_vao.py +0 -65
- ncca/ngl/simple_vao.py +0 -42
- ncca/ngl/text.py +0 -346
- ncca/ngl/texture.py +0 -75
- ncca/ngl/transform.py +0 -95
- ncca/ngl/util.py +0 -128
- ncca/ngl/vao_factory.py +0 -34
- ncca/ngl/vec2.py +0 -350
- ncca/ngl/vec2_array.py +0 -106
- ncca/ngl/vec3.py +0 -401
- ncca/ngl/vec3_array.py +0 -110
- ncca/ngl/vec4.py +0 -229
- ncca/ngl/vec4_array.py +0 -106
- ncca_ngl-0.1.0.dist-info/RECORD +0 -41
- ncca_ngl-0.1.0.dist-info/top_level.txt +0 -1
- {ncca_ngl-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/licenses/LICENSE.txt +0 -0
ncca/ngl/util.py
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"""Utility math module, contains various useful functions for 3D.
|
|
2
|
-
|
|
3
|
-
Most of these functions are based on functions found in other libraries such as GLM, NGL or GLU
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import math
|
|
7
|
-
|
|
8
|
-
from .mat4 import Mat4
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def clamp(num, low, high):
|
|
12
|
-
"clamp to range min and max will throw ValueError is low>=high"
|
|
13
|
-
if low > high or low == high:
|
|
14
|
-
raise ValueError
|
|
15
|
-
return max(min(num, high), low)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def look_at(eye, look, up):
|
|
19
|
-
"""
|
|
20
|
-
Calculate 4x4 matrix for camera lookAt
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
n = look - eye
|
|
24
|
-
u = up
|
|
25
|
-
v = n.cross(u)
|
|
26
|
-
u = v.cross(n)
|
|
27
|
-
n.normalize()
|
|
28
|
-
v.normalize()
|
|
29
|
-
u.normalize()
|
|
30
|
-
|
|
31
|
-
result = Mat4.identity()
|
|
32
|
-
result.m[0][0] = v.x
|
|
33
|
-
result.m[1][0] = v.y
|
|
34
|
-
result.m[2][0] = v.z
|
|
35
|
-
result.m[0][1] = u.x
|
|
36
|
-
result.m[1][1] = u.y
|
|
37
|
-
result.m[2][1] = u.z
|
|
38
|
-
result.m[0][2] = -n.x
|
|
39
|
-
result.m[1][2] = -n.y
|
|
40
|
-
result.m[2][2] = -n.z
|
|
41
|
-
result.m[3][0] = -eye.dot(v)
|
|
42
|
-
result.m[3][1] = -eye.dot(u)
|
|
43
|
-
result.m[3][2] = eye.dot(n)
|
|
44
|
-
return result
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def perspective(fov, aspect, near, far):
|
|
48
|
-
m = Mat4.zero() # as per glm
|
|
49
|
-
_range = math.tan(math.radians(fov / 2.0)) * near
|
|
50
|
-
left = -_range * aspect
|
|
51
|
-
right = _range * aspect
|
|
52
|
-
bottom = -_range
|
|
53
|
-
top = _range
|
|
54
|
-
m.m[0][0] = (2.0 * near) / (right - left)
|
|
55
|
-
m.m[1][1] = (2.0 * near) / (top - bottom)
|
|
56
|
-
m.m[2][2] = -(far + near) / (far - near)
|
|
57
|
-
m.m[2][3] = -1.0
|
|
58
|
-
m.m[3][2] = -(2.0 * far * near) / (far - near)
|
|
59
|
-
return m
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def ortho(left, right, bottom, top, near, far):
|
|
63
|
-
"""Create an orthographic projection matrix."""
|
|
64
|
-
m = Mat4.identity()
|
|
65
|
-
m.m[0][0] = 2.0 / (right - left)
|
|
66
|
-
m.m[1][1] = 2.0 / (top - bottom)
|
|
67
|
-
m.m[2][2] = -2.0 / (far - near)
|
|
68
|
-
m.m[3][0] = -(right + left) / (right - left)
|
|
69
|
-
m.m[3][1] = -(top + bottom) / (top - bottom)
|
|
70
|
-
m.m[3][2] = -(far + near) / (far - near)
|
|
71
|
-
return m
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# Mat4 result(1.0f);
|
|
75
|
-
# result.m_00= 2.0f / (_right - _left);
|
|
76
|
-
# result.m_11= 2.0f / (_top - _bottom);
|
|
77
|
-
# result.m_22= - 2.0f / (_zFar - _zNear);
|
|
78
|
-
# result.m_30= - (_right + _left) / (_right - _left);
|
|
79
|
-
# result.m_31= - (_top + _bottom) / (_top - _bottom);
|
|
80
|
-
# result.m_32= - (_zFar + _zNear) / (_zFar - _zNear);
|
|
81
|
-
# return result;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def frustum(left, right, bottom, top, near, far):
|
|
85
|
-
"""Create a frustum projection matrix."""
|
|
86
|
-
m = Mat4.zero()
|
|
87
|
-
m.m[0][0] = (2.0 * near) / (right - left)
|
|
88
|
-
m.m[1][1] = (2.0 * near) / (top - bottom)
|
|
89
|
-
m.m[2][0] = (right + left) / (right - left)
|
|
90
|
-
m.m[2][1] = (top + bottom) / (top - bottom)
|
|
91
|
-
m.m[2][2] = -(far + near) / (far - near)
|
|
92
|
-
m.m[2][3] = -1.0
|
|
93
|
-
m.m[3][2] = -(2.0 * far * near) / (far - near)
|
|
94
|
-
return m
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def lerp(a, b, t):
|
|
98
|
-
return a + (b - a) * t
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def calc_normal(p1, p2, p3):
|
|
102
|
-
"""
|
|
103
|
-
Calculates the normal of a triangle defined by three points.
|
|
104
|
-
|
|
105
|
-
This is a Python implementation of the NGL C++ Util::calcNormal function.
|
|
106
|
-
It uses the vector cross product method for clarity and leverages the py-ngl library.
|
|
107
|
-
The order of the cross product is chosen to match the output of the C++ version.
|
|
108
|
-
|
|
109
|
-
Args:
|
|
110
|
-
p1: The first vertex of the triangle.
|
|
111
|
-
p2: The second vertex of the triangle.
|
|
112
|
-
p3: The third vertex of the triangle.
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
The normalized normal vector of the triangle.
|
|
116
|
-
"""
|
|
117
|
-
# Two vectors on the plane of the triangle
|
|
118
|
-
v1 = p3 - p1
|
|
119
|
-
v2 = p2 - p1
|
|
120
|
-
|
|
121
|
-
# The cross product gives the normal vector.
|
|
122
|
-
# The order (v1 x v2) is used to match the C++ implementation's result.
|
|
123
|
-
normal = v1.cross(v2)
|
|
124
|
-
|
|
125
|
-
# Normalize the result to get a unit length normal
|
|
126
|
-
normal.normalize()
|
|
127
|
-
|
|
128
|
-
return normal
|
ncca/ngl/vao_factory.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
|
|
3
|
-
from .multi_buffer_vao import MultiBufferVAO
|
|
4
|
-
from .simple_index_vao import SimpleIndexVAO
|
|
5
|
-
from .simple_vao import SimpleVAO
|
|
6
|
-
from .log import logger
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class VAOType(enum.Enum):
|
|
10
|
-
SIMPLE = "simpleVAO"
|
|
11
|
-
MULTI_BUFFER = "multiBufferVAO"
|
|
12
|
-
SIMPLE_INDEX = "simpleIndexVAO"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class VAOFactory:
|
|
16
|
-
_creators = {}
|
|
17
|
-
|
|
18
|
-
@staticmethod
|
|
19
|
-
def register_vao_creator(name, creator_func):
|
|
20
|
-
VAOFactory._creators[name] = creator_func
|
|
21
|
-
|
|
22
|
-
@staticmethod
|
|
23
|
-
def create_vao(name, mode):
|
|
24
|
-
creator = VAOFactory._creators.get(name)
|
|
25
|
-
if not creator:
|
|
26
|
-
logger.warning(f"VAO type '{name}' not found.")
|
|
27
|
-
raise ValueError(name)
|
|
28
|
-
return creator(mode)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# pre-register the default VAO types
|
|
32
|
-
VAOFactory.register_vao_creator(VAOType.SIMPLE, SimpleVAO)
|
|
33
|
-
VAOFactory.register_vao_creator(VAOType.MULTI_BUFFER, MultiBufferVAO)
|
|
34
|
-
VAOFactory.register_vao_creator(VAOType.SIMPLE_INDEX, SimpleIndexVAO)
|
ncca/ngl/vec2.py
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Simple float only Vec2 class for 3D graphics, very similar to the pyngl ones
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import ctypes
|
|
6
|
-
import math
|
|
7
|
-
|
|
8
|
-
from .util import clamp
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class Vec2:
|
|
12
|
-
"""
|
|
13
|
-
A simple 3D vector class for 3D graphics, I use slots to fix the attributes to x,y,z
|
|
14
|
-
Attributes:
|
|
15
|
-
x (float): The x-coordinate of the vector.
|
|
16
|
-
y (float): The y-coordinate of the vector.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
__slots__ = ["_x", "_y"] # fix the attributes to x,y,z
|
|
20
|
-
|
|
21
|
-
def __init__(self, x=0.0, y=0.0):
|
|
22
|
-
"""
|
|
23
|
-
Initializes a new instance of the Vec2 class.
|
|
24
|
-
|
|
25
|
-
Args:
|
|
26
|
-
x (float, optional): The x-coordinate of the vector. Defaults to 0.0.
|
|
27
|
-
y (float, optional): The y-coordinate of the vector. Defaults to 0.0.
|
|
28
|
-
"""
|
|
29
|
-
self._x = x # x component of vector : float
|
|
30
|
-
self._y = y # y component of vector : float
|
|
31
|
-
|
|
32
|
-
@classmethod
|
|
33
|
-
def sizeof(cls):
|
|
34
|
-
return 2 * ctypes.sizeof(ctypes.c_float)
|
|
35
|
-
|
|
36
|
-
def __iter__(self):
|
|
37
|
-
"""
|
|
38
|
-
Make the Vec2 class iterable.
|
|
39
|
-
Yields:
|
|
40
|
-
float: The x and y components of the vector.
|
|
41
|
-
"""
|
|
42
|
-
yield self.x
|
|
43
|
-
yield self.y
|
|
44
|
-
|
|
45
|
-
def clone(self) -> "Vec2":
|
|
46
|
-
"""
|
|
47
|
-
Create a copy of the vector.
|
|
48
|
-
Returns:
|
|
49
|
-
Vec2: A new instance of Vec2 with the same x and y values.
|
|
50
|
-
"""
|
|
51
|
-
return Vec2(self.x, self.y)
|
|
52
|
-
|
|
53
|
-
def __getitem__(self, index):
|
|
54
|
-
"""
|
|
55
|
-
Get the component of the vector at the given index.
|
|
56
|
-
Args:
|
|
57
|
-
index (int): The index of the component (0 for x, 1 for y, 2 for z).
|
|
58
|
-
Returns:
|
|
59
|
-
float: The value of the component at the given index.
|
|
60
|
-
Raises:
|
|
61
|
-
IndexError: If the index is out of range.
|
|
62
|
-
"""
|
|
63
|
-
components = [self.x, self.y]
|
|
64
|
-
try:
|
|
65
|
-
return components[index]
|
|
66
|
-
except IndexError:
|
|
67
|
-
raise IndexError("Index out of range. Valid indices are 0, 1,")
|
|
68
|
-
|
|
69
|
-
def _validate_and_set(self, v, name):
|
|
70
|
-
"""
|
|
71
|
-
check if v is a float or int
|
|
72
|
-
Args:
|
|
73
|
-
v (number): The value to check.
|
|
74
|
-
Raises:
|
|
75
|
-
ValueError: If v is not a float or int.
|
|
76
|
-
"""
|
|
77
|
-
if not isinstance(v, (int, float)):
|
|
78
|
-
raise ValueError("need float or int")
|
|
79
|
-
else:
|
|
80
|
-
setattr(self, name, v)
|
|
81
|
-
|
|
82
|
-
def __add__(self, rhs):
|
|
83
|
-
"""
|
|
84
|
-
vector addition a+b
|
|
85
|
-
|
|
86
|
-
Args:
|
|
87
|
-
rhs (Vec2): The right-hand side vector to add.
|
|
88
|
-
Returns:
|
|
89
|
-
Vec2: A new vector that is the result of adding this vector and the rhs vector.
|
|
90
|
-
"""
|
|
91
|
-
r = Vec2()
|
|
92
|
-
r.x = self.x + rhs.x
|
|
93
|
-
r.y = self.y + rhs.y
|
|
94
|
-
return r
|
|
95
|
-
|
|
96
|
-
def __iadd__(self, rhs):
|
|
97
|
-
"""
|
|
98
|
-
vector addition a+=b
|
|
99
|
-
|
|
100
|
-
Args:
|
|
101
|
-
rhs (Vec2): The right-hand side vector to add.
|
|
102
|
-
Returns:
|
|
103
|
-
Vec2: returns this vector after adding the rhs vector.
|
|
104
|
-
"""
|
|
105
|
-
self.x += rhs.x
|
|
106
|
-
self.y += rhs.y
|
|
107
|
-
return self
|
|
108
|
-
|
|
109
|
-
def __sub__(self, rhs):
|
|
110
|
-
"""
|
|
111
|
-
vector subtraction a-b
|
|
112
|
-
|
|
113
|
-
Args:
|
|
114
|
-
rhs (Vec2): The right-hand side vector to add.
|
|
115
|
-
Returns:
|
|
116
|
-
Vec2: A new vector that is the result of subtracting this vector and the rhs vector.
|
|
117
|
-
"""
|
|
118
|
-
r = Vec2()
|
|
119
|
-
r.x = self.x - rhs.x
|
|
120
|
-
r.y = self.y - rhs.y
|
|
121
|
-
return r
|
|
122
|
-
|
|
123
|
-
def __isub__(self, rhs):
|
|
124
|
-
"""
|
|
125
|
-
vector subtraction a-=b
|
|
126
|
-
|
|
127
|
-
Args:
|
|
128
|
-
rhs (Vec2): The right-hand side vector to add.
|
|
129
|
-
Returns:
|
|
130
|
-
Vec2: returns this vector after subtracting the rhs vector.
|
|
131
|
-
"""
|
|
132
|
-
self.x -= rhs.x
|
|
133
|
-
self.y -= rhs.y
|
|
134
|
-
return self
|
|
135
|
-
|
|
136
|
-
def __eq__(self, rhs):
|
|
137
|
-
"""
|
|
138
|
-
vector comparison a==b using math.isclose not we only compare to 6 decimal places
|
|
139
|
-
Args:
|
|
140
|
-
rhs (Vec2): The right-hand side vector to compare.
|
|
141
|
-
Returns:
|
|
142
|
-
bool: True if the vectors are close, False otherwise.
|
|
143
|
-
NotImplemented: If the right-hand side is not a Vec2.
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
if not isinstance(rhs, Vec2):
|
|
147
|
-
return NotImplemented
|
|
148
|
-
return math.isclose(self.x, rhs.x) and math.isclose(self.y, rhs.y)
|
|
149
|
-
|
|
150
|
-
def __neq__(self, rhs):
|
|
151
|
-
"""
|
|
152
|
-
vector comparison a!=b using math.isclose not we only compare to 6 decimal places
|
|
153
|
-
Args:
|
|
154
|
-
rhs (Vec2): The right-hand side vector to compare.
|
|
155
|
-
Returns:
|
|
156
|
-
bool: True if the vectors are not close, False otherwise.
|
|
157
|
-
NotImplemented: If the right-hand side is not a Vec2.
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
if not isinstance(rhs, Vec2):
|
|
161
|
-
return NotImplemented
|
|
162
|
-
return not (math.isclose(self.x, rhs.x) and math.isclose(self.y, rhs.y))
|
|
163
|
-
|
|
164
|
-
def __neg__(self):
|
|
165
|
-
"""
|
|
166
|
-
negate a vector -a
|
|
167
|
-
"""
|
|
168
|
-
self.x = -self.x
|
|
169
|
-
self.y = -self.y
|
|
170
|
-
return self
|
|
171
|
-
|
|
172
|
-
def set(self, x, y):
|
|
173
|
-
"""
|
|
174
|
-
set the x,y,z values of the vector
|
|
175
|
-
Args:
|
|
176
|
-
x (float): The x-coordinate of the vector.
|
|
177
|
-
y (float): The y-coordinate of the vector.
|
|
178
|
-
Raises :
|
|
179
|
-
ValueError: if x,y are not float
|
|
180
|
-
"""
|
|
181
|
-
try:
|
|
182
|
-
self.x = float(x)
|
|
183
|
-
self.y = float(y)
|
|
184
|
-
except ValueError:
|
|
185
|
-
raise ValueError(f"Vec2.set {x=} {y=} all need to be float")
|
|
186
|
-
|
|
187
|
-
def dot(self, rhs):
|
|
188
|
-
"""
|
|
189
|
-
dot product of two vectors a.b
|
|
190
|
-
Args:
|
|
191
|
-
rhs (Vec2): The right-hand side vector to dot product with.
|
|
192
|
-
"""
|
|
193
|
-
return self.x * rhs.x + self.y * rhs.y
|
|
194
|
-
|
|
195
|
-
def length(self):
|
|
196
|
-
"""
|
|
197
|
-
length of vector
|
|
198
|
-
Returns:
|
|
199
|
-
float: The length of the vector.
|
|
200
|
-
"""
|
|
201
|
-
return math.sqrt(self.x**2 + self.y**2)
|
|
202
|
-
|
|
203
|
-
def length_squared(self):
|
|
204
|
-
"""
|
|
205
|
-
length of vector squared sometimes used to avoid the sqrt for performance
|
|
206
|
-
Returns:
|
|
207
|
-
float: The length of the vector squared
|
|
208
|
-
"""
|
|
209
|
-
return self.x**2 + self.y**2
|
|
210
|
-
|
|
211
|
-
def inner(self, rhs):
|
|
212
|
-
"""
|
|
213
|
-
inner product of two vectors a.b
|
|
214
|
-
Args:
|
|
215
|
-
rhs (Vec2): The right-hand side vector to inner product with.
|
|
216
|
-
Returns:
|
|
217
|
-
float: The inner product of the two vectors.
|
|
218
|
-
"""
|
|
219
|
-
return (self.x * rhs.x) + (self.y * rhs.y)
|
|
220
|
-
|
|
221
|
-
def null(self):
|
|
222
|
-
"""
|
|
223
|
-
set the vector to zero
|
|
224
|
-
"""
|
|
225
|
-
self.x = 0.0
|
|
226
|
-
self.y = 0.0
|
|
227
|
-
|
|
228
|
-
def cross(self, rhs):
|
|
229
|
-
"""
|
|
230
|
-
cross product of two vectors a x b
|
|
231
|
-
Args:
|
|
232
|
-
rhs (Vec2): The right-hand side vector to cross product with.
|
|
233
|
-
Returns:
|
|
234
|
-
float : 2D cross product or perpendicular dot product.
|
|
235
|
-
"""
|
|
236
|
-
return self.x * rhs.y - self.y * rhs.x
|
|
237
|
-
|
|
238
|
-
def normalize(self):
|
|
239
|
-
"""
|
|
240
|
-
normalize the vector to unit length
|
|
241
|
-
Returns:
|
|
242
|
-
Vec2: A new vector that is the result of normalizing this vector.
|
|
243
|
-
Raises:
|
|
244
|
-
ZeroDivisionError: If the length of the vector is zero.
|
|
245
|
-
"""
|
|
246
|
-
vector_length = self.length()
|
|
247
|
-
try:
|
|
248
|
-
self.x /= vector_length
|
|
249
|
-
self.y /= vector_length
|
|
250
|
-
except ZeroDivisionError:
|
|
251
|
-
raise ZeroDivisionError(
|
|
252
|
-
f"Vec2.normalize {vector_length} length is zero most likely calling normalize on a zero vector"
|
|
253
|
-
)
|
|
254
|
-
return self
|
|
255
|
-
|
|
256
|
-
def reflect(self, n):
|
|
257
|
-
"""
|
|
258
|
-
reflect a vector about a normal
|
|
259
|
-
Args:
|
|
260
|
-
n (Vec2): The normal to reflect about.
|
|
261
|
-
Returns:
|
|
262
|
-
Vec2: A new vector that is the result of reflecting this vector about the normal.
|
|
263
|
-
"""
|
|
264
|
-
d = self.dot(n)
|
|
265
|
-
# I - 2.0 * dot(N, I) * N
|
|
266
|
-
return Vec2(self.x - 2.0 * d * n.x, self.y - 2.0 * d * n.y)
|
|
267
|
-
|
|
268
|
-
def clamp(self, low, high):
|
|
269
|
-
"""
|
|
270
|
-
clamp the vector to a range
|
|
271
|
-
Args:
|
|
272
|
-
low (float): The low end of the range.
|
|
273
|
-
high (float): The high end of the range.
|
|
274
|
-
|
|
275
|
-
"""
|
|
276
|
-
self.x = clamp(self.x, low, high)
|
|
277
|
-
self.y = clamp(self.y, low, high)
|
|
278
|
-
|
|
279
|
-
def __repr__(self):
|
|
280
|
-
"object representation for debugging"
|
|
281
|
-
return f"Vec2 [{self.x},{self.y}]"
|
|
282
|
-
|
|
283
|
-
def __truediv__(self, rhs):
|
|
284
|
-
if isinstance(rhs, (float, int)):
|
|
285
|
-
return Vec2(self.x / rhs, self.y / rhs)
|
|
286
|
-
elif isinstance(rhs, Vec2):
|
|
287
|
-
return Vec2(self.x / rhs.x, self.y / rhs.y)
|
|
288
|
-
else:
|
|
289
|
-
raise ValueError(f"can only do piecewise division with a scalar {rhs=}")
|
|
290
|
-
|
|
291
|
-
def __str__(self):
|
|
292
|
-
"object representation for debugging"
|
|
293
|
-
return f"[{self.x},{self.y}]"
|
|
294
|
-
|
|
295
|
-
def __mul__(self, rhs):
|
|
296
|
-
"""
|
|
297
|
-
piecewise scalar multiplication
|
|
298
|
-
Args:
|
|
299
|
-
rhs (float): The scalar to multiply by.
|
|
300
|
-
Returns:
|
|
301
|
-
Vec2: A new vector that is the result of multiplying this vector by the scalar.
|
|
302
|
-
Raises:
|
|
303
|
-
ValueError: If the right-hand side is not a float.
|
|
304
|
-
"""
|
|
305
|
-
if isinstance(rhs, (float, int)):
|
|
306
|
-
return Vec2(self.x * rhs, self.y * rhs)
|
|
307
|
-
else:
|
|
308
|
-
raise ValueError(f"can only do piecewise multiplication with a scalar {rhs=}")
|
|
309
|
-
|
|
310
|
-
def __rmul__(self, rhs):
|
|
311
|
-
"""
|
|
312
|
-
piecewise scalar multiplication
|
|
313
|
-
Args:
|
|
314
|
-
rhs (float): The scalar to multiply by.
|
|
315
|
-
Returns:
|
|
316
|
-
Vec2: A new vector that is the result of multiplying this vector by the scalar.
|
|
317
|
-
Raises:
|
|
318
|
-
ValueError: If the right-hand side is not a float.
|
|
319
|
-
"""
|
|
320
|
-
return self * rhs
|
|
321
|
-
|
|
322
|
-
def __matmul__(self, rhs):
|
|
323
|
-
"""
|
|
324
|
-
"Vec2 @ Mat2 matrix multiplication"
|
|
325
|
-
Args:
|
|
326
|
-
rhs (Mat2): The matrix to multiply by.
|
|
327
|
-
Returns:
|
|
328
|
-
Vec2: A new vector that is the result of multiplying this vector by the matrix.
|
|
329
|
-
"""
|
|
330
|
-
return Vec2(
|
|
331
|
-
self.x * rhs.m[0][0] + self.y * rhs.m[1][0] + self.z * rhs.m[2][0],
|
|
332
|
-
self.x * rhs.m[0][1] + self.y * rhs.m[1][1] + self.z * rhs.m[2][1],
|
|
333
|
-
self.x * rhs.m[0][2] + self.y * rhs.m[1][2] + self.z * rhs.m[2][2],
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
# Helper function to create properties
|
|
338
|
-
def _create_property(attr_name):
|
|
339
|
-
def getter(self):
|
|
340
|
-
return getattr(self, f"_{attr_name}")
|
|
341
|
-
|
|
342
|
-
def setter(self, value):
|
|
343
|
-
self._validate_and_set(value, f"_{attr_name}")
|
|
344
|
-
|
|
345
|
-
return property(getter, setter)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
# Dynamically add properties for x, y
|
|
349
|
-
for attr in ["x", "y"]:
|
|
350
|
-
setattr(Vec2, attr, _create_property(attr))
|
ncca/ngl/vec2_array.py
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
A container for ngl.Vec2 objects that mimics some of the behavior of a std::vector
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
|
|
7
|
-
from .vec2 import Vec2
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Vec2Array:
|
|
11
|
-
"""
|
|
12
|
-
A class to hold a list of Vec2 objects and perform operations on them.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
def __init__(self, values=None):
|
|
16
|
-
"""
|
|
17
|
-
Initializes the Vec2Array.
|
|
18
|
-
|
|
19
|
-
Args:
|
|
20
|
-
values (iterable, optional): An iterable of Vec2 objects. Defaults to None.
|
|
21
|
-
"""
|
|
22
|
-
self._data = []
|
|
23
|
-
if values is not None:
|
|
24
|
-
for v in values:
|
|
25
|
-
if not isinstance(v, Vec2):
|
|
26
|
-
raise TypeError("All elements must be of type Vec2")
|
|
27
|
-
self._data.append(v)
|
|
28
|
-
|
|
29
|
-
def __getitem__(self, index):
|
|
30
|
-
"""
|
|
31
|
-
Get the Vec2 at the specified index.
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
index (int): The index of the element.
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
Vec2: The Vec2 object at the given index.
|
|
38
|
-
"""
|
|
39
|
-
return self._data[index]
|
|
40
|
-
|
|
41
|
-
def __len__(self):
|
|
42
|
-
"""
|
|
43
|
-
Return the number of elements in the array.
|
|
44
|
-
"""
|
|
45
|
-
return len(self._data)
|
|
46
|
-
|
|
47
|
-
def __iter__(self):
|
|
48
|
-
"""
|
|
49
|
-
Return an iterator for the array.
|
|
50
|
-
"""
|
|
51
|
-
return iter(self._data)
|
|
52
|
-
|
|
53
|
-
def append(self, value):
|
|
54
|
-
"""
|
|
55
|
-
Append a Vec2 object to the array.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
value (Vec2): The Vec2 object to append.
|
|
59
|
-
"""
|
|
60
|
-
if not isinstance(value, Vec2):
|
|
61
|
-
raise TypeError("Only Vec2 objects can be appended")
|
|
62
|
-
self._data.append(value)
|
|
63
|
-
|
|
64
|
-
def extend(self, values):
|
|
65
|
-
"""
|
|
66
|
-
Extend the array with a list of Vec2 objects.
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
values (list): A list of Vec2 objects to extend.
|
|
70
|
-
"""
|
|
71
|
-
if not all(isinstance(v, Vec2) for v in values):
|
|
72
|
-
raise TypeError("All elements must be of type Vec2")
|
|
73
|
-
self._data.extend(values)
|
|
74
|
-
|
|
75
|
-
def to_list(self):
|
|
76
|
-
"""
|
|
77
|
-
Convert the array of Vec2 objects to a single flat list of floats.
|
|
78
|
-
|
|
79
|
-
Returns:
|
|
80
|
-
list: A list of x, y components concatenated.
|
|
81
|
-
"""
|
|
82
|
-
return [comp for vec in self._data for comp in vec]
|
|
83
|
-
|
|
84
|
-
def to_numpy(self):
|
|
85
|
-
"""
|
|
86
|
-
Convert the array of Vec2 objects to a numpy array.
|
|
87
|
-
|
|
88
|
-
Returns:
|
|
89
|
-
numpy.ndarray: A numpy array of the vector data.
|
|
90
|
-
"""
|
|
91
|
-
return np.array(self.to_list(), dtype=np.float32)
|
|
92
|
-
|
|
93
|
-
def __repr__(self):
|
|
94
|
-
return f"Vec2Array({self._data!r})"
|
|
95
|
-
|
|
96
|
-
def __str__(self):
|
|
97
|
-
return str(self._data)
|
|
98
|
-
|
|
99
|
-
def sizeof(self):
|
|
100
|
-
"""
|
|
101
|
-
Return the size of the array in bytes.
|
|
102
|
-
|
|
103
|
-
Returns:
|
|
104
|
-
int: The size of the array in bytes.
|
|
105
|
-
"""
|
|
106
|
-
return len(self._data) * Vec2.sizeof()
|