Created
November 1, 2025 17:54
-
-
Save radicalappdev/ac000ae1a3db3909fcd04595e8a5fff9 to your computer and use it in GitHub Desktop.
Some Helpers I use in Project Graveyard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct Helpers3D { | |
| /// Constrains a quaternion rotation to only the Y axis (up/down rotation). | |
| /// | |
| /// - Parameter rotation: The input quaternion rotation that may contain X, Y, and Z components. | |
| /// - Returns: A new quaternion rotation that only affects the Y axis, ignoring X and Z components. | |
| static func constrainRotationToYAxis(_ rotation: simd_quatf) -> simd_quatf { | |
| let yAngle = yawAngle(from: rotation) | |
| return yAxisRotation(from: yAngle) | |
| } | |
| /// Extracts the yaw (rotation around the Y axis) from a quaternion. | |
| /// | |
| /// - Parameter rotation: The quaternion to inspect. | |
| /// - Returns: The yaw angle in radians within the range [-π, π]. | |
| static func yawAngle(from rotation: simd_quatf) -> Float { | |
| let numerator = 2 * (rotation.vector.w * rotation.vector.y + rotation.vector.x * rotation.vector.z) | |
| let denominator = 1 - 2 * (rotation.vector.y * rotation.vector.y + rotation.vector.z * rotation.vector.z) | |
| let yAngle = atan2(numerator, denominator) | |
| return Float(yAngle) | |
| } | |
| /// Creates a quaternion that rotates around the positive Y axis by the provided angle. | |
| /// | |
| /// - Parameter angle: The yaw angle in radians. | |
| /// - Returns: A quaternion representing the yaw rotation. | |
| static func yAxisRotation(from angle: Float) -> simd_quatf { | |
| return simd_quaternion(angle, SIMD3<Float>(0, 1, 0)) | |
| } | |
| /// Constrains a 3D position within specified limits, keeping Y at a fixed value. | |
| /// | |
| /// - Parameters: | |
| /// - position: The input 3D position to constrain. | |
| /// - limit: The maximum distance from origin for X and Z axes. | |
| /// - fixedY: The fixed Y value to use. Default is 0.0. | |
| /// - Returns: A constrained position with X and Z clamped to the limit and Y set to fixedY. | |
| static func constrainPosition(_ position: SIMD3<Float>, limit: Float, fixedY: Float = 0.0) -> SIMD3<Float> { | |
| let posX = min(max(position.x, -limit), limit) | |
| let posZ = min(max(position.z, -limit), limit) | |
| return SIMD3(x: posX, y: fixedY, z: posZ) | |
| } | |
| /// Constrains a scale value within specified minimum and maximum bounds and returns a uniform 3D scale vector. | |
| /// | |
| /// - Parameters: | |
| /// - scale: The input scale value to constrain. | |
| /// - minScale: The minimum allowed scale value. | |
| /// - maxScale: The maximum allowed scale value. | |
| /// - Returns: A SIMD3 vector with the constrained scale value applied to all axes (X, Y, Z). | |
| static func constrainScale(_ scale: Float, minScale: Float, maxScale: Float) -> SIMD3<Float> { | |
| let constrainedValue = min(max(scale, minScale), maxScale) | |
| return SIMD3(x: constrainedValue, y: constrainedValue, z: constrainedValue) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment