Source code for simvx.core.helpers.matrix

"""NumPy matrix helpers for TRS composition and GPU upload."""

import numpy as np


[docs] def mat4_from_trs( pos: tuple[float, float, float] | np.ndarray, rot, scl: tuple[float, float, float] | np.ndarray, ) -> np.ndarray: """Build model matrix from position, rotation quaternion, and scale. Args: pos: Position (x, y, z) rot: Rotation quaternion — Quat or any object with .w/.x/.y/.z scl: Scale (x, y, z) Returns: 4x4 model matrix as numpy array (Translate * Rotate * Scale) """ from ..math import quat_to_mat4, scale, translate return translate(pos) @ quat_to_mat4(rot) @ scale(scl)
[docs] def batch_mat4_from_trs( positions: np.ndarray, rotations: np.ndarray, scales: np.ndarray, ) -> np.ndarray: """Build N model matrices from arrays of positions, quaternions, and scales. Args: positions: (N, 3) float32 positions rotations: (N, 4) float32 quaternions [w, x, y, z] scales: (N, 3) float32 scale factors Returns: (N, 4, 4) float32 model matrices (Translate * Rotate * Scale) """ n = positions.shape[0] w, x, y, z = rotations[:, 0], rotations[:, 1], rotations[:, 2], rotations[:, 3] xx, yy, zz = x * x, y * y, z * z xy, xz, yz = x * y, x * z, y * z wx, wy, wz = w * x, w * y, w * z sx, sy, sz = scales[:, 0], scales[:, 1], scales[:, 2] out = np.zeros((n, 4, 4), dtype=np.float32) out[:, 0, 0] = (1.0 - 2.0 * (yy + zz)) * sx out[:, 0, 1] = (2.0 * (xy - wz)) * sy out[:, 0, 2] = (2.0 * (xz + wy)) * sz out[:, 1, 0] = (2.0 * (xy + wz)) * sx out[:, 1, 1] = (1.0 - 2.0 * (xx + zz)) * sy out[:, 1, 2] = (2.0 * (yz - wx)) * sz out[:, 2, 0] = (2.0 * (xz - wy)) * sx out[:, 2, 1] = (2.0 * (yz + wx)) * sy out[:, 2, 2] = (1.0 - 2.0 * (xx + yy)) * sz out[:, 0, 3] = positions[:, 0] out[:, 1, 3] = positions[:, 1] out[:, 2, 3] = positions[:, 2] out[:, 3, 3] = 1.0 return out
[docs] def mat4_to_bytes(m: np.ndarray) -> bytes: """Convert mat4 to bytes for GPU upload (64 bytes, row-major float32).""" return np.ascontiguousarray(m, dtype=np.float32).tobytes()