Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to apply transformation matrix to each vec2 in an array? #210

Closed
cspotcode opened this issue Feb 23, 2023 · 3 comments
Closed

Possible to apply transformation matrix to each vec2 in an array? #210

cspotcode opened this issue Feb 23, 2023 · 3 comments
Labels

Comments

@cspotcode
Copy link
Contributor

cspotcode commented Feb 23, 2023

I'm not sure if what I'm asking for is possible, nor if it should be possible.

I'm using pyglm to efficiently scale, rotate, and translate polygons for the purposes of collision detection. I'm hoping that pyglm is faster than pure python. But ultimately, the calculations will never be used for rendering, only for checking polygon-polygon collisions on the CPU.

I'm trying to keep as much as possible within PyGLM arrays so that nothing needs to be unboxed into python. However, I cannot seem to apply a transformation matrix to an array of vec2 points. I'm not sure if this should be possible. The transformation is applied to the first vec2 correctly, then that value is repeated multiple times in the resulting array.

    # Square AABB hitbox from 0,0 to 1,1
    hitbox = glm.array(
        glm.vec2(0., 1.),
        glm.vec2(1., 1.),
        glm.vec2(1., 0.),
        glm.vec2(0., 0.),
    )
    rotation = glm.radians(90)
    scale_x = 1.
    scale_y = 2.

    cos_rotation = glm.cos(rotation)
    sin_rotation = glm.sin(rotation)

    rotation_scale_matrix = glm.mat2x2(
        scale_x * cos_rotation, -scale_x * sin_rotation,
        scale_y * sin_rotation, scale_y * cos_rotation
    )
    hitbox_rotated = hitbox * rotation_scale_matrix

    print(repr(hitbox))
    print(repr(hitbox_rotated))

    # I expect to see the points rotated 90 degrees, approximately:
    # array(vec2(-1, 0), vec2(-1, 1), vec2(0, 1), vec2(0, 0))

    # Instead, I see four repeats of the first item:
    # array(vec2(-1, 0), vec2(-1, 0), vec2(-1, 0), vec2(-1, 0))

    # The zeros are actually 1.22465e-16 but I assume that's fine, just a precision thing
@Zuzu-Typ Zuzu-Typ added the bug label Feb 24, 2023
@Zuzu-Typ
Copy link
Owner

Hi there @cspotcode

This seems to be a bug in the array type. This is certainly not supposed to happen.
The calculation should happen per element, as you would have expected.
I wasn't able to locate the source of the bug yet.

For the time being, I recommend you to use NumPy for the calculations.
NumPy is great at performing the same operation on a lot of data, because it uses special CPU instructions, which PyGLM is not able to utilize, therefore it will also be faster than PyGLM's array would.

To do this, you would edit your code as follows:

import glm
import numpy

# Square AABB hitbox from 0,0 to 1,1
hitbox = glm.array(
	glm.vec2(0., 1.),
	glm.vec2(1., 1.),
	glm.vec2(1., 0.),
	glm.vec2(0., 0.),
)
rotation = glm.radians(90)
scale_x = 1.
scale_y = 2.

cos_rotation = glm.cos(rotation)
sin_rotation = glm.sin(rotation)

rotation_scale_matrix = glm.mat2x2(
	scale_x * cos_rotation, -scale_x * sin_rotation,
	scale_y * sin_rotation, scale_y * cos_rotation
)

hitbox_rotated = glm.array(numpy.array(hitbox) * numpy.matrix(rotation_scale_matrix))

print(repr(hitbox))
print(repr(hitbox_rotated))

Thank you for reporting the bug (:

Cheers,
--Zuzu_Typ--

@cspotcode
Copy link
Contributor Author

Thanks for taking a look, I'm glad to hear this is a bug instead of new API surface.

I actually did use numpy before attempting a switch to pyglm. But since this math is dealing with 8-point hitboxes in a game engine, I guess the numpy overhead was too high for dealing with only 8 points at a time. I think for these tiny arrays, any overhead at all makes it slower than pure python.

Right now the collision code is implemented in pure python, and 3.11 has so far been consistently faster than both pyglm and numpy. But I keep experimenting to see if I can get a speedup with pyglm.

Zuzu-Typ added a commit to cspotcode/PyGLM that referenced this issue Feb 26, 2023
+ Should fix Zuzu-Typ#210
+ Fixed matrix multiplication for `arr * arr`, `mat * arr` and `arr * mat`
@cspotcode
Copy link
Contributor Author

Looks good to me, what does it take for this to be published to pypi?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants