Repository: nfrechette/acl (cpp)

Issue:
Integrate and switch to Realtime Math
The ACL math code has been moved into its own depot Realtime Math (https://github.com/nfrechette/rtm) for easier maintenance and added flexibility.
The types and naming convention changed a bit which will break compilation as such a complete refactor is required and a major version bump as well. Because the code was mostly moved and cleaned up, the risk involved is very low.

The dependency should be added under external, documented, and as a sub-module.


Discussion:

Patch:
diff --git a/cmake/CMakeCompiler.cmake b/cmake/CMakeCompiler.cmake
--- a/cmake/CMakeCompiler.cmake
+++ b/cmake/CMakeCompiler.cmake
@@ -20,7 +20,6 @@ macro(setup_default_compiler_flags _project_name)
 				target_compile_options(${_project_name} PRIVATE "/arch:AVX")
 			endif()
 		else()
-			add_definitions(-DACL_NO_INTRINSICS)
 			add_definitions(-DRTM_NO_INTRINSICS)
 		endif()
 
@@ -49,7 +48,6 @@ macro(setup_default_compiler_flags _project_name)
 					target_compile_options(${_project_name} PRIVATE "-msse4.1")
 				endif()
 			else()
-				add_definitions(-DACL_NO_INTRINSICS)
 				add_definitions(-DRTM_NO_INTRINSICS)
 			endif()
 
diff --git a/docs/misc_integration_details.md b/docs/misc_integration_details.md
--- a/docs/misc_integration_details.md
+++ b/docs/misc_integration_details.md
@@ -4,9 +4,9 @@
 
 A small number of defines are exposed and can be used to finetune the behavior.
 
-### ACL_NO_INTRINSICS
+### RTM_NO_INTRINSICS
 
-This define prevents the usage of intrinsics unless explicitly requested by the integration manually (e.g. you can still defined `ACL_SSE2_INTRINSICS` yourself). Everything will default to pure scalar implementations.
+This define prevents the usage of intrinsics unless explicitly requested by the integration manually (e.g. you can still defined `RTM_SSE2_INTRINSICS` yourself). Everything will default to pure scalar implementations.
 
 ### ACL_USE_POPCOUNT
 
diff --git a/external/README.md b/external/README.md
--- a/external/README.md
+++ b/external/README.md
@@ -4,7 +4,7 @@
 
 ### Realtime Math
 
-[Reamtime Math v1.1.0](https://github.com/nfrechette/rtm/releases/tag/v1.1.0) (MIT License) is used for some math types and functions. Its usage is currently limited but a full transition to use it exclusively will occur for ACL v2.0. Needed only by the SJSON IO reader/writer and the scalar track compression/decompression API.
+[Reamtime Math v1.1.0-develop](https://github.com/nfrechette/rtm/releases/tag/v1.1.0) (MIT License) is used for some math types and functions. Its usage is currently limited but a full transition to use it exclusively will occur for ACL v2.0. Needed only by the SJSON IO reader/writer and the scalar track compression/decompression API.
 
 ## Development dependencies
 
diff --git a/external/rtm b/external/rtm
--- a/external/rtm
+++ b/external/rtm
@@ -1 +1 @@
-Subproject commit f4ec074cc4e5f07c26f71cf7cdf3c5644ec0da46
+Subproject commit 817753c3800d23e9583f25532f707b944d5ce54c
diff --git a/includes/acl/algorithm/uniformly_sampled/decoder.h b/includes/acl/algorithm/uniformly_sampled/decoder.h
--- a/includes/acl/algorithm/uniformly_sampled/decoder.h
+++ b/includes/acl/algorithm/uniformly_sampled/decoder.h
@@ -33,12 +33,13 @@
 #include "acl/core/interpolation_utils.h"
 #include "acl/core/range_reduction_types.h"
 #include "acl/core/utils.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/quat_packing.h"
 #include "acl/decompression/decompress_data.h"
 #include "acl/decompression/output_writer.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -116,12 +117,12 @@ namespace acl
 			{
 				static constexpr size_t k_num_samples_to_interpolate = 2;
 
-				inline static Quat_32 ACL_SIMD_CALL interpolate_rotation(Quat_32Arg0 rotation0, Quat_32Arg1 rotation1, float interpolation_alpha)
+				inline static rtm::quatf RTM_SIMD_CALL interpolate_rotation(rtm::quatf_arg0 rotation0, rtm::quatf_arg1 rotation1, float interpolation_alpha)
 				{
-					return quat_lerp(rotation0, rotation1, interpolation_alpha);
+					return rtm::quat_lerp(rotation0, rotation1, interpolation_alpha);
 				}
 
-				inline static Quat_32 ACL_SIMD_CALL interpolate_rotation(Quat_32Arg0 rotation0, Quat_32Arg1 rotation1, Quat_32Arg2 rotation2, Quat_32Arg3 rotation3, float interpolation_alpha)
+				inline static rtm::quatf RTM_SIMD_CALL interpolate_rotation(rtm::quatf_arg0 rotation0, rtm::quatf_arg1 rotation1, rtm::quatf_arg2 rotation2, rtm::quatf_arg3 rotation3, float interpolation_alpha)
 				{
 					(void)rotation1;
 					(void)rotation2;
@@ -130,12 +131,12 @@ namespace acl
 					return rotation0;	// Not implemented, we use linear interpolation
 				}
 
-				inline static Vector4_32 ACL_SIMD_CALL interpolate_vector4(Vector4_32Arg0 vector0, Vector4_32Arg1 vector1, float interpolation_alpha)
+				inline static rtm::vector4f RTM_SIMD_CALL interpolate_vector4(rtm::vector4f_arg0 vector0, rtm::vector4f_arg1 vector1, float interpolation_alpha)
 				{
-					return vector_lerp(vector0, vector1, interpolation_alpha);
+					return rtm::vector_lerp(vector0, vector1, interpolation_alpha);
 				}
 
-				inline static Vector4_32 ACL_SIMD_CALL interpolate_vector4(Vector4_32Arg0 vector0, Vector4_32Arg1 vector1, Vector4_32Arg2 vector2, Vector4_32Arg3 vector3, float interpolation_alpha)
+				inline static rtm::vector4f RTM_SIMD_CALL interpolate_vector4(rtm::vector4f_arg0 vector0, rtm::vector4f_arg1 vector1, rtm::vector4f_arg2 vector2, rtm::vector4f_arg3 vector3, float interpolation_alpha)
 				{
 					(void)vector1;
 					(void)vector2;
@@ -144,23 +145,23 @@ namespace acl
 					return vector0;		// Not implemented, we use linear interpolation
 				}
 
-				//													//   offsets
-				uint32_t track_index;								//   0 |   0
-				uint32_t constant_track_data_offset;				//   4 |   4
-				uint32_t clip_range_data_offset;					//   8 |   8
+				//														//   offsets
+				uint32_t track_index;									//   0 |   0
+				uint32_t constant_track_data_offset;					//   4 |   4
+				uint32_t clip_range_data_offset;						//   8 |   8
 
-				uint32_t format_per_track_data_offset;				//  12 |  12
-				uint32_t segment_range_data_offset;					//  16 |  16
+				uint32_t format_per_track_data_offset;					//  12 |  12
+				uint32_t segment_range_data_offset;						//  16 |  16
 
-				uint32_t key_frame_byte_offsets[2];					//  20 |  20	// Fixed quantization
-				uint32_t key_frame_bit_offsets[2];					//  28 |  28	// Variable quantization
+				uint32_t key_frame_byte_offsets[2];						//  20 |  20	// Fixed quantization
+				uint32_t key_frame_bit_offsets[2];						//  28 |  28	// Variable quantization
 
-				uint8_t padding[28];								//  36 |  36
+				uint8_t padding[28];									//  36 |  36
 
-				Vector4_32 vectors[k_num_samples_to_interpolate];	//  64 |  64
-				Vector4_32 padding0[2];								//  96 |  96
+				rtm::vector4f vectors[k_num_samples_to_interpolate];	//  64 |  64
+				rtm::vector4f padding0[2];								//  96 |  96
 
-				//										Total size:	   128 | 128
+				//											Total size:	   128 | 128
 			};
 
 			static_assert(sizeof(SamplingContext) == 128, "Unexpected size");
@@ -174,7 +175,7 @@ namespace acl
 				explicit TranslationDecompressionSettingsAdapter(const SettingsType& settings_) : settings(settings_) {}
 
 				constexpr RangeReductionFlags8 get_range_reduction_flag() const { return RangeReductionFlags8::Translations; }
-				inline Vector4_32 ACL_SIMD_CALL get_default_value() const { return vector_zero_32(); }
+				inline rtm::vector4f RTM_SIMD_CALL get_default_value() const { return rtm::vector_zero(); }
 				constexpr VectorFormat8 get_vector_format(const ClipHeader& header) const { return settings.get_translation_format(header.translation_format); }
 				constexpr bool is_vector_format_supported(VectorFormat8 format) const { return settings.is_translation_format_supported(format); }
 
@@ -191,11 +192,11 @@ namespace acl
 			{
 				explicit ScaleDecompressionSettingsAdapter(const SettingsType& settings_, const ClipHeader& header)
 					: settings(settings_)
-					, default_scale(header.default_scale ? vector_set(1.0F) : vector_zero_32())
+					, default_scale(header.default_scale ? rtm::vector_set(1.0F) : rtm::vector_zero())
 				{}
 
 				constexpr RangeReductionFlags8 get_range_reduction_flag() const { return RangeReductionFlags8::Scales; }
-				inline Vector4_32 ACL_SIMD_CALL get_default_value() const { return default_scale; }
+				inline rtm::vector4f RTM_SIMD_CALL get_default_value() const { return default_scale; }
 				constexpr VectorFormat8 get_vector_format(const ClipHeader& header) const { return settings.get_scale_format(header.scale_format); }
 				constexpr bool is_vector_format_supported(VectorFormat8 format) const { return settings.is_scale_format_supported(format); }
 
@@ -205,8 +206,8 @@ namespace acl
 				constexpr bool supports_mixed_packing() const { return settings.supports_mixed_packing(); }
 
 				SettingsType settings;
-				uint8_t padding[get_required_padding<SettingsType, Vector4_32>()];
-				Vector4_32 default_scale;
+				uint8_t padding[get_required_padding<SettingsType, rtm::vector4f>()];
+				rtm::vector4f default_scale;
 			};
 		}
 
@@ -326,7 +327,7 @@ namespace acl
 			//////////////////////////////////////////////////////////////////////////
 			// Decompress a single bone at the current sample time.
 			// Each track entry is optional
-			void decompress_bone(uint16_t sample_bone_index, Quat_32* out_rotation, Vector4_32* out_translation, Vector4_32* out_scale);
+			void decompress_bone(uint16_t sample_bone_index, rtm::quatf* out_rotation, rtm::vector4f* out_translation, rtm::vector4f* out_scale);
 
 			//////////////////////////////////////////////////////////////////////////
 			// Releases the context instance if it contains an allocator reference
@@ -463,7 +464,7 @@ namespace acl
 
 			// Clamp for safety, the caller should normally handle this but in practice, it often isn't the case
 			// TODO: Make it optional via DecompressionSettingsType?
-			sample_time = clamp(sample_time, 0.0F, m_context.clip_duration);
+			sample_time = rtm::scalar_clamp(sample_time, 0.0F, m_context.clip_duration);
 
 			if (m_context.sample_time == sample_time)
 				return;
@@ -583,7 +584,7 @@ namespace acl
 					skip_over_rotation(m_settings, header, m_context, sampling_context);
 				else
 				{
-					const Quat_32 rotation = decompress_and_interpolate_rotation(m_settings, header, m_context, sampling_context);
+					const rtm::quatf rotation = decompress_and_interpolate_rotation(m_settings, header, m_context, sampling_context);
 					writer.write_bone_rotation(bone_index, rotation);
 				}
 
@@ -591,7 +592,7 @@ namespace acl
 					skip_over_vector(translation_adapter, header, m_context, sampling_context);
 				else
 				{
-					const Vector4_32 translation = decompress_and_interpolate_vector(translation_adapter, header, m_context, sampling_context);
+					const rtm::vector4f translation = decompress_and_interpolate_vector(translation_adapter, header, m_context, sampling_context);
 					writer.write_bone_translation(bone_index, translation);
 				}
 
@@ -602,7 +603,7 @@ namespace acl
 				}
 				else
 				{
-					const Vector4_32 scale = header.has_scale ? decompress_and_interpolate_vector(scale_adapter, header, m_context, sampling_context) : scale_adapter.get_default_value();
+					const rtm::vector4f scale = header.has_scale ? decompress_and_interpolate_vector(scale_adapter, header, m_context, sampling_context) : scale_adapter.get_default_value();
 					writer.write_bone_scale(bone_index, scale);
 				}
 			}
@@ -612,7 +613,7 @@ namespace acl
 		}
 
 		template<class DecompressionSettingsType>
-		inline void DecompressionContext<DecompressionSettingsType>::decompress_bone(uint16_t sample_bone_index, Quat_32* out_rotation, Vector4_32* out_translation, Vector4_32* out_scale)
+		inline void DecompressionContext<DecompressionSettingsType>::decompress_bone(uint16_t sample_bone_index, rtm::quatf* out_rotation, rtm::vector4f* out_translation, rtm::vector4f* out_scale)
 		{
 			ACL_ASSERT(m_context.clip != nullptr, "Context is not initialized");
 			ACL_ASSERT(m_context.sample_time >= 0.0f, "Context not set to a valid sample time");
diff --git a/includes/acl/compression/animation_clip.h b/includes/acl/compression/animation_clip.h
--- a/includes/acl/compression/animation_clip.h
+++ b/includes/acl/compression/animation_clip.h
@@ -32,9 +32,10 @@
 #include "acl/core/interpolation_utils.h"
 #include "acl/core/string.h"
 #include "acl/core/utils.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
-#include "acl/math/transform_32.h"
+
+#include <rtm/quatf.h>
+#include <rtm/qvvf.h>
+#include <rtm/vector4f.h>
 
 #include <cstdint>
 
@@ -195,7 +196,7 @@ namespace acl
 		//    - rounding_policy: The rounding policy to use when sampling
 		//    - out_local_pose: An array of at least 'num_transforms' to output the data in
 		//    - num_transforms: The number of transforms in the output array
-		void sample_pose(float sample_time, SampleRoundingPolicy rounding_policy, Transform_32* out_local_pose, uint16_t num_transforms) const
+		void sample_pose(float sample_time, SampleRoundingPolicy rounding_policy, rtm::qvvf* out_local_pose, uint16_t num_transforms) const
 		{
 			ACL_ASSERT(m_num_bones > 0, "Invalid number of bones: %u", m_num_bones);
 			ACL_ASSERT(m_num_bones == num_transforms, "Number of transforms does not match the number of bones: %u != %u", num_transforms, m_num_bones);
@@ -204,7 +205,7 @@ namespace acl
 			const float clip_duration = get_duration();
 
 			// Clamp for safety, the caller should normally handle this but in practice, it often isn't the case
-			sample_time = clamp(sample_time, 0.0F, clip_duration);
+			sample_time = rtm::scalar_clamp(sample_time, 0.0F, clip_duration);
 
 			uint32_t sample_index0;
 			uint32_t sample_index1;
@@ -215,19 +216,19 @@ namespace acl
 			{
 				const AnimatedBone& bone = m_bones[bone_index];
 
-				const Quat_32 rotation0 = quat_normalize(quat_cast(bone.rotation_track.get_sample(sample_index0)));
-				const Quat_32 rotation1 = quat_normalize(quat_cast(bone.rotation_track.get_sample(sample_index1)));
-				const Quat_32 rotation = quat_lerp(rotation0, rotation1, interpolation_alpha);
+				const rtm::quatf rotation0 = rtm::quat_normalize(quat_cast(bone.rotation_track.get_sample(sample_index0)));
+				const rtm::quatf rotation1 = rtm::quat_normalize(quat_cast(bone.rotation_track.get_sample(sample_index1)));
+				const rtm::quatf rotation = rtm::quat_lerp(rotation0, rotation1, interpolation_alpha);
 
-				const Vector4_32 translation0 = vector_cast(bone.translation_track.get_sample(sample_index0));
-				const Vector4_32 translation1 = vector_cast(bone.translation_track.get_sample(sample_index1));
-				const Vector4_32 translation = vector_lerp(translation0, translation1, interpolation_alpha);
+				const rtm::vector4f translation0 = rtm::vector_cast(bone.translation_track.get_sample(sample_index0));
+				const rtm::vector4f translation1 = rtm::vector_cast(bone.translation_track.get_sample(sample_index1));
+				const rtm::vector4f translation = rtm::vector_lerp(translation0, translation1, interpolation_alpha);
 
-				const Vector4_32 scale0 = vector_cast(bone.scale_track.get_sample(sample_index0));
-				const Vector4_32 scale1 = vector_cast(bone.scale_track.get_sample(sample_index1));
-				const Vector4_32 scale = vector_lerp(scale0, scale1, interpolation_alpha);
+				const rtm::vector4f scale0 = rtm::vector_cast(bone.scale_track.get_sample(sample_index0));
+				const rtm::vector4f scale1 = rtm::vector_cast(bone.scale_track.get_sample(sample_index1));
+				const rtm::vector4f scale = rtm::vector_lerp(scale0, scale1, interpolation_alpha);
 
-				out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 			}
 		}
 
@@ -236,7 +237,7 @@ namespace acl
 		//    - sample_time: The time at which to sample the clip
 		//    - out_local_pose: An array of at least 'num_transforms' to output the data in
 		//    - num_transforms: The number of transforms in the output array
-		void sample_pose(float sample_time, Transform_32* out_local_pose, uint16_t num_transforms) const
+		void sample_pose(float sample_time, rtm::qvvf* out_local_pose, uint16_t num_transforms) const
 		{
 			sample_pose(sample_time, SampleRoundingPolicy::None, out_local_pose, num_transforms);
 		}
@@ -336,7 +337,7 @@ namespace acl
 		// bone has a scale sample that isn't equivalent to the default scale.
 		bool has_scale(float threshold) const
 		{
-			const Vector4_32 default_scale = get_default_scale(m_additive_format);
+			const rtm::vector4f default_scale = get_default_scale(m_additive_format);
 
 			for (uint16_t bone_index = 0; bone_index < m_num_bones; ++bone_index)
 			{
@@ -344,25 +345,25 @@ namespace acl
 				const uint32_t num_samples = bone.scale_track.get_num_samples();
 				if (num_samples != 0)
 				{
-					const Vector4_32 scale = vector_cast(bone.scale_track.get_sample(0));
+					const rtm::vector4f scale = rtm::vector_cast(bone.scale_track.get_sample(0));
 
-					Vector4_32 min = scale;
-					Vector4_32 max = scale;
+					rtm::vector4f min = scale;
+					rtm::vector4f max = scale;
 
 					for (uint32_t sample_index = 1; sample_index < num_samples; ++sample_index)
 					{
-						const Vector4_32 sample = vector_cast(bone.scale_track.get_sample(sample_index));
+						const rtm::vector4f sample = rtm::vector_cast(bone.scale_track.get_sample(sample_index));
 
-						min = vector_min(min, sample);
-						max = vector_max(max, sample);
+						min = rtm::vector_min(min, sample);
+						max = rtm::vector_max(max, sample);
 					}
 
-					const Vector4_32 extent = vector_sub(max, min);
-					const bool is_constant = vector_all_less_than3(vector_abs(extent), vector_set(threshold));
+					const rtm::vector4f extent = rtm::vector_sub(max, min);
+					const bool is_constant = rtm::vector_all_less_than3(rtm::vector_abs(extent), rtm::vector_set(threshold));
 					if (!is_constant)
 						return true;	// Not constant means we have scale
 
-					const bool is_default = vector_all_near_equal3(scale, default_scale, threshold);
+					const bool is_default = rtm::vector_all_near_equal3(scale, default_scale, threshold);
 					if (!is_default)
 						return true;	// Constant but not default means we have scale
 				}
diff --git a/includes/acl/compression/animation_track.h b/includes/acl/compression/animation_track.h
--- a/includes/acl/compression/animation_track.h
+++ b/includes/acl/compression/animation_track.h
@@ -28,8 +28,9 @@
 #include "acl/core/iallocator.h"
 #include "acl/core/error.h"
 #include "acl/core/track_types.h"
-#include "acl/math/quat_64.h"
-#include "acl/math/vector4_64.h"
+
+#include <rtm/quatd.h>
+#include <rtm/vector4d.h>
 
 #include <cstdint>
 #include <utility>
@@ -90,7 +91,7 @@ namespace acl
 		//    - type: The track type
 		AnimationTrack(IAllocator& allocator, uint32_t num_samples, float sample_rate, AnimationTrackType8 type)
 			: m_allocator(&allocator)
-			, m_sample_data(allocate_type_array_aligned<double>(allocator, size_t(num_samples) * get_animation_track_sample_size(type), alignof(Vector4_64)))
+			, m_sample_data(allocate_type_array_aligned<double>(allocator, size_t(num_samples) * get_animation_track_sample_size(type), alignof(rtm::vector4d)))
 			, m_num_samples(num_samples)
 			, m_sample_rate(sample_rate)
 			, m_type(type)
@@ -148,7 +149,7 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	// A raw rotation track.
 	//
-	// Holds a track made of 'Quat_64' entries.
+	// Holds a track made of 'rtm::quatd' entries.
 	//////////////////////////////////////////////////////////////////////////
 	class AnimationRotationTrack final : public AnimationTrack
 	{
@@ -165,15 +166,15 @@ namespace acl
 		AnimationRotationTrack(IAllocator& allocator, uint32_t num_samples, uint32_t sample_rate)
 			: AnimationTrack(allocator, num_samples, float(sample_rate), AnimationTrackType8::Rotation)
 		{
-			Quat_64* samples = safe_ptr_cast<Quat_64>(&m_sample_data[0]);
-			std::fill(samples, samples + num_samples, quat_identity_64());
+			rtm::quatd* samples = safe_ptr_cast<rtm::quatd>(&m_sample_data[0]);
+			std::fill(samples, samples + num_samples, rtm::quat_identity());
 		}
 
 		AnimationRotationTrack(IAllocator& allocator, uint32_t num_samples, float sample_rate)
 			: AnimationTrack(allocator, num_samples, sample_rate, AnimationTrackType8::Rotation)
 		{
-			Quat_64* samples = safe_ptr_cast<Quat_64>(&m_sample_data[0]);
-			std::fill(samples, samples + num_samples, quat_identity_64());
+			rtm::quatd* samples = safe_ptr_cast<rtm::quatd>(&m_sample_data[0]);
+			std::fill(samples, samples + num_samples, rtm::quat_identity());
 		}
 
 		AnimationRotationTrack(AnimationRotationTrack&& other)
@@ -188,23 +189,23 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Sets a sample value at a particular index
-		VS2015_HACK_NO_INLINE void set_sample(uint32_t sample_index, const Quat_64& rotation)
+		VS2015_HACK_NO_INLINE void set_sample(uint32_t sample_index, const rtm::quatd& rotation)
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
-			ACL_ASSERT(quat_is_finite(rotation), "Invalid rotation: [%f, %f, %f, %f]", quat_get_x(rotation), quat_get_y(rotation), quat_get_z(rotation), quat_get_w(rotation));
-			ACL_ASSERT(quat_is_normalized(rotation), "Rotation not normalized: [%f, %f, %f, %f]", quat_get_x(rotation), quat_get_y(rotation), quat_get_z(rotation), quat_get_w(rotation));
+			ACL_ASSERT(rtm::quat_is_finite(rotation), "Invalid rotation: [%f, %f, %f, %f]", rtm::quat_get_x(rotation), rtm::quat_get_y(rotation), rtm::quat_get_z(rotation), rtm::quat_get_w(rotation));
+			ACL_ASSERT(rtm::quat_is_normalized(rotation), "Rotation not normalized: [%f, %f, %f, %f]", rtm::quat_get_x(rotation), rtm::quat_get_y(rotation), rtm::quat_get_z(rotation), rtm::quat_get_w(rotation));
 
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 			ACL_ASSERT(sample_size == 4, "Invalid sample size. %u != 4", sample_size);
 
 			double* sample = &m_sample_data[sample_index * sample_size];
-			quat_unaligned_write(rotation, sample);
+			rtm::quat_store(rotation, sample);
 		}
 
 		//////////////////////////////////////////////////////////////////////////
 		// Retrieves a sample value at a particular index
-		Quat_64 get_sample(uint32_t sample_index) const
+		rtm::quatd get_sample(uint32_t sample_index) const
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
@@ -212,7 +213,7 @@ namespace acl
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 
 			const double* sample = &m_sample_data[sample_index * sample_size];
-			return quat_unaligned_load(sample);
+			return rtm::quat_load(sample);
 		}
 
 		AnimationRotationTrack(const AnimationRotationTrack&) = delete;
@@ -260,22 +261,22 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Sets a sample value at a particular index
-		void set_sample(uint32_t sample_index, const Vector4_64& translation)
+		void set_sample(uint32_t sample_index, const rtm::vector4d& translation)
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
-			ACL_ASSERT(vector_is_finite3(translation), "Invalid translation: [%f, %f, %f]", vector_get_x(translation), vector_get_y(translation), vector_get_z(translation));
+			ACL_ASSERT(rtm::vector_is_finite3(translation), "Invalid translation: [%f, %f, %f]", rtm::vector_get_x(translation), rtm::vector_get_y(translation), rtm::vector_get_z(translation));
 
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 			ACL_ASSERT(sample_size == 3, "Invalid sample size. %u != 3", sample_size);
 
 			double* sample = &m_sample_data[sample_index * sample_size];
-			vector_unaligned_write3(translation, sample);
+			rtm::vector_store3(translation, sample);
 		}
 
 		//////////////////////////////////////////////////////////////////////////
 		// Retrieves a sample value at a particular index
-		Vector4_64 get_sample(uint32_t sample_index) const
+		rtm::vector4d get_sample(uint32_t sample_index) const
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
@@ -283,7 +284,7 @@ namespace acl
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 
 			const double* sample = &m_sample_data[sample_index * sample_size];
-			return vector_unaligned_load3(sample);
+			return rtm::vector_load3(sample);
 		}
 
 		AnimationTranslationTrack(const AnimationTranslationTrack&) = delete;
@@ -310,17 +311,17 @@ namespace acl
 		AnimationScaleTrack(IAllocator& allocator, uint32_t num_samples, uint32_t sample_rate)
 			: AnimationTrack(allocator, num_samples, float(sample_rate), AnimationTrackType8::Scale)
 		{
-			Vector4_64 defaultScale = vector_set(1.0);
+			rtm::vector4d defaultScale = rtm::vector_set(1.0);
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
-				vector_unaligned_write3(defaultScale, m_sample_data + (sample_index * 3));
+				rtm::vector_store3(defaultScale, m_sample_data + (sample_index * 3));
 		}
 
 		AnimationScaleTrack(IAllocator& allocator, uint32_t num_samples, float sample_rate)
 			: AnimationTrack(allocator, num_samples, sample_rate, AnimationTrackType8::Scale)
 		{
-			Vector4_64 defaultScale = vector_set(1.0);
+			rtm::vector4d defaultScale = rtm::vector_set(1.0);
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
-				vector_unaligned_write3(defaultScale, m_sample_data + (sample_index * 3));
+				rtm::vector_store3(defaultScale, m_sample_data + (sample_index * 3));
 		}
 
 		AnimationScaleTrack(AnimationScaleTrack&& other)
@@ -335,22 +336,22 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Sets a sample value at a particular index
-		VS2015_HACK_NO_INLINE void set_sample(uint32_t sample_index, const Vector4_64& scale)
+		VS2015_HACK_NO_INLINE void set_sample(uint32_t sample_index, const rtm::vector4d& scale)
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
-			ACL_ASSERT(vector_is_finite3(scale), "Invalid scale: [%f, %f, %f]", vector_get_x(scale), vector_get_y(scale), vector_get_z(scale));
+			ACL_ASSERT(rtm::vector_is_finite3(scale), "Invalid scale: [%f, %f, %f]", rtm::vector_get_x(scale), rtm::vector_get_y(scale), rtm::vector_get_z(scale));
 
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 			ACL_ASSERT(sample_size == 3, "Invalid sample size. %u != 3", sample_size);
 
 			double* sample = &m_sample_data[sample_index * sample_size];
-			vector_unaligned_write3(scale, sample);
+			rtm::vector_store3(scale, sample);
 		}
 
 		//////////////////////////////////////////////////////////////////////////
 		// Retrieves a sample value at a particular index
-		Vector4_64 get_sample(uint32_t sample_index) const
+		rtm::vector4d get_sample(uint32_t sample_index) const
 		{
 			ACL_ASSERT(is_initialized(), "Track is not initialized");
 			ACL_ASSERT(sample_index < m_num_samples, "Invalid sample index. %u >= %u", sample_index, m_num_samples);
@@ -358,7 +359,7 @@ namespace acl
 			const uint32_t sample_size = get_animation_track_sample_size(m_type);
 
 			const double* sample = &m_sample_data[sample_index * sample_size];
-			return vector_unaligned_load3(sample);
+			return rtm::vector_load3(sample);
 		}
 
 		AnimationScaleTrack(const AnimationScaleTrack&) = delete;
diff --git a/includes/acl/compression/compression_settings.h b/includes/acl/compression/compression_settings.h
--- a/includes/acl/compression/compression_settings.h
+++ b/includes/acl/compression/compression_settings.h
@@ -31,7 +31,9 @@
 #include "acl/core/range_reduction_types.h"
 #include "acl/compression/compression_level.h"
 #include "acl/compression/skeleton_error_metric.h"
-#include "acl/math/scalar_32.h"
+
+#include <rtm/anglef.h>
+#include <rtm/scalarf.h>
 
 #include <cstdint>
 
@@ -137,7 +139,7 @@ namespace acl
 		// was chosen. You will typically NEVER need to change this, the value has been
 		// selected to be as safe as possible and is independent of game engine units.
 		// Defaults to '0.00284714461' radians
-		float constant_rotation_threshold_angle;
+		rtm::anglef constant_rotation_threshold_angle;
 
 		//////////////////////////////////////////////////////////////////////////
 		// Threshold value to use when detecting if translation tracks are constant or default.
@@ -168,7 +170,7 @@ namespace acl
 			, range_reduction(RangeReductionFlags8::None)
 			, segmenting()
 			, error_metric(nullptr)
-			, constant_rotation_threshold_angle(0.00284714461F)
+			, constant_rotation_threshold_angle(rtm::radians(0.00284714461F))
 			, constant_translation_threshold(0.001F)
 			, constant_scale_threshold(0.00001F)
 			, error_threshold(0.01F)
@@ -230,16 +232,17 @@ namespace acl
 			if (error_metric == nullptr)
 				return ErrorResult("error_metric cannot be NULL");
 
-			if (constant_rotation_threshold_angle < 0.0F || !is_finite(constant_rotation_threshold_angle))
+			const float rotation_threshold_angle = constant_rotation_threshold_angle.as_radians();
+			if (rotation_threshold_angle < 0.0F || !rtm::scalar_is_finite(rotation_threshold_angle))
 				return ErrorResult("Invalid constant_rotation_threshold_angle");
 
-			if (constant_translation_threshold < 0.0F || !is_finite(constant_translation_threshold))
+			if (constant_translation_threshold < 0.0F || !rtm::scalar_is_finite(constant_translation_threshold))
 				return ErrorResult("Invalid constant_translation_threshold");
 
-			if (constant_scale_threshold < 0.0F || !is_finite(constant_scale_threshold))
+			if (constant_scale_threshold < 0.0F || !rtm::scalar_is_finite(constant_scale_threshold))
 				return ErrorResult("Invalid constant_scale_threshold");
 
-			if (error_threshold < 0.0F || !is_finite(error_threshold))
+			if (error_threshold < 0.0F || !rtm::scalar_is_finite(error_threshold))
 				return ErrorResult("Invalid error_threshold");
 
 			return segmenting.is_valid();
diff --git a/includes/acl/compression/impl/quantize_track_impl.h b/includes/acl/compression/impl/quantize_track_impl.h
--- a/includes/acl/compression/impl/quantize_track_impl.h
+++ b/includes/acl/compression/impl/quantize_track_impl.h
@@ -49,7 +49,7 @@ namespace acl
 				ACL_ASSERT(num_bits > 0, "Cannot decay with 0 bits");
 				ACL_ASSERT(num_bits < 31, "Attempting to decay on too many bits");
 
-				const float max_value_ = safe_to_float((1 << num_bits) - 1);
+				const float max_value_ = rtm::scalar_safe_to_float((1 << num_bits) - 1);
 				max_value = rtm::vector_set(max_value_);
 				inv_max_value = rtm::vector_set(1.0F / max_value_);
 			}
diff --git a/includes/acl/compression/impl/track_bit_rate_database.h b/includes/acl/compression/impl/track_bit_rate_database.h
--- a/includes/acl/compression/impl/track_bit_rate_database.h
+++ b/includes/acl/compression/impl/track_bit_rate_database.h
@@ -29,6 +29,10 @@
 #include "acl/compression/stream/sample_streams.h"
 #include "acl/compression/stream/track_stream.h"
 
+#include <rtm/quatf.h>
+#include <rtm/qvvf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 // 0 = disabled, 1 = enabled
@@ -145,8 +149,8 @@ namespace acl
 
 			void set_segment(const BoneStreams* bone_streams, uint32_t num_transforms, uint32_t num_samples_per_track);
 
-			void sample(const single_track_query& query, float sample_time, Transform_32* out_transforms, uint32_t num_transforms);
-			void sample(const hierarchical_track_query& query, float sample_time, Transform_32* out_transforms, uint32_t num_transforms);
+			void sample(const single_track_query& query, float sample_time, rtm::qvvf* out_transforms, uint32_t num_transforms);
+			void sample(const hierarchical_track_query& query, float sample_time, rtm::qvvf* out_transforms, uint32_t num_transforms);
 
 		private:
 			track_bit_rate_database(const track_bit_rate_database&) = delete;
@@ -157,13 +161,13 @@ namespace acl
 			void find_cache_entries(uint32_t track_index, const BoneBitRate& bit_rates, uint32_t& out_rotation_cache_index, uint32_t& out_translation_cache_index, uint32_t& out_scale_cache_index);
 
 			template<SampleDistribution8 distribution>
-			ACL_FORCE_INLINE Quat_32 ACL_SIMD_CALL sample_rotation(const sample_context& context, uint32_t rotation_cache_index);
+			ACL_FORCE_INLINE rtm::quatf RTM_SIMD_CALL sample_rotation(const sample_context& context, uint32_t rotation_cache_index);
 
 			template<SampleDistribution8 distribution>
-			ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_translation(const sample_context& context, uint32_t translation_cache_index);
+			ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_translation(const sample_context& context, uint32_t translation_cache_index);
 
 			template<SampleDistribution8 distribution>
-			ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_scale(const sample_context& context, uint32_t scale_cache_index);
+			ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_scale(const sample_context& context, uint32_t scale_cache_index);
 
 			struct transform_cache_entry
 			{
@@ -192,7 +196,7 @@ namespace acl
 				static int32_t find_bit_rate_index(const bit_rates_union& bit_rates, uint32_t search_bit_rate);
 			};
 
-			Vector4_32			m_default_scale;
+			rtm::vector4f		m_default_scale;
 
 			IAllocator&			m_allocator;
 			const BoneStreams*	m_mutable_bone_streams;
@@ -327,7 +331,7 @@ namespace acl
 
 			// We allocate a single float buffer to accommodate 4 bit rates for every rot/trans/scale track of each transform.
 			// Each track is padded and aligned to ensure that it starts on a cache line boundary.
-			const uint32_t track_size = align_to<uint32_t>(sizeof(Vector4_32) * num_samples_per_track, 64);
+			const uint32_t track_size = align_to<uint32_t>(sizeof(rtm::vector4f) * num_samples_per_track, 64);
 			m_track_size = track_size;
 
 			const uint32_t data_size = track_size * num_cached_tracks;
@@ -571,18 +575,18 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Quat_32 ACL_SIMD_CALL track_bit_rate_database::sample_rotation(const sample_context& context, uint32_t rotation_cache_index)
+		ACL_FORCE_INLINE rtm::quatf RTM_SIMD_CALL track_bit_rate_database::sample_rotation(const sample_context& context, uint32_t rotation_cache_index)
 		{
 			const uint32_t track_index = context.track_index;
 			const BoneStreams& bone_stream = m_mutable_bone_streams[track_index];
 
-			Quat_32 rotation;
+			rtm::quatf rotation;
 			if (bone_stream.is_rotation_default)
-				rotation = quat_identity_32();
+				rotation = rtm::quat_identity();
 			else if (bone_stream.is_rotation_constant)
 			{
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * rotation_cache_index);
-				Quat_32* cached_samples = safe_ptr_cast<Quat_32>(m_data + (m_track_size * rotation_cache_index));
+				rtm::quatf* cached_samples = safe_ptr_cast<rtm::quatf>(m_data + (m_track_size * rotation_cache_index));
 
 				if (bitset_test(validity_bitset, m_bitref_constant))
 				{
@@ -603,7 +607,7 @@ namespace acl
 
 					// If we are uniform, normalize now. Variable will interpolate and normalize after.
 					if (static_condition<distribution == SampleDistribution8::Uniform>::test())
-						rotation = quat_normalize(rotation);
+						rotation = rtm::quat_normalize(rotation);
 
 					cached_samples[0] = rotation;
 					bitset_set(validity_bitset, m_bitref_constant, true);
@@ -618,7 +622,7 @@ namespace acl
 				const BoneStreams& raw_bone_stream = m_raw_bone_streams[track_index];
 
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * rotation_cache_index);
-				Quat_32* cached_samples = safe_ptr_cast<Quat_32>(m_data + (m_track_size * rotation_cache_index));
+				rtm::quatf* cached_samples = safe_ptr_cast<rtm::quatf>(m_data + (m_track_size * rotation_cache_index));
 
 				uint32_t key0;
 				uint32_t key1;
@@ -637,8 +641,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Quat_32 sample0;
-				Quat_32 sample1;
+				rtm::quatf sample0;
+				rtm::quatf sample1;
 
 				const BitSetIndexRef bitref0(m_bitset_desc, key0);
 				if (bitset_test(validity_bitset, bitref0))
@@ -660,7 +664,7 @@ namespace acl
 
 					// If we are uniform, normalize now. Variable will interpolate and normalize after.
 					if (static_condition<distribution == SampleDistribution8::Uniform>::test())
-						sample0 = quat_normalize(sample0);
+						sample0 = rtm::quat_normalize(sample0);
 
 					cached_samples[key0] = sample0;
 					bitset_set(validity_bitset, bitref0, true);
@@ -698,7 +702,7 @@ namespace acl
 #endif
 					}
 
-					rotation = quat_lerp(sample0, sample1, interpolation_alpha);
+					rotation = rtm::quat_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
 				{
@@ -710,18 +714,18 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL track_bit_rate_database::sample_translation(const sample_context& context, uint32_t translation_cache_index)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL track_bit_rate_database::sample_translation(const sample_context& context, uint32_t translation_cache_index)
 		{
 			const uint32_t track_index = context.track_index;
 			const BoneStreams& bone_stream = m_mutable_bone_streams[track_index];
 
-			Vector4_32 translation;
+			rtm::vector4f translation;
 			if (bone_stream.is_translation_default)
-				translation = vector_zero_32();
+				translation = rtm::vector_zero();
 			else if (bone_stream.is_translation_constant)
 			{
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * translation_cache_index);
-				Vector4_32* cached_samples = safe_ptr_cast<Vector4_32>(m_data + (m_track_size * translation_cache_index));
+				rtm::vector4f* cached_samples = safe_ptr_cast<rtm::vector4f>(m_data + (m_track_size * translation_cache_index));
 
 				if (bitset_test(validity_bitset, m_bitref_constant))
 				{
@@ -750,7 +754,7 @@ namespace acl
 				const BoneStreams& raw_bone_stream = m_raw_bone_streams[track_index];
 
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * translation_cache_index);
-				Vector4_32* cached_samples = safe_ptr_cast<Vector4_32>(m_data + (m_track_size * translation_cache_index));
+				rtm::vector4f* cached_samples = safe_ptr_cast<rtm::vector4f>(m_data + (m_track_size * translation_cache_index));
 
 				uint32_t key0;
 				uint32_t key1;
@@ -769,8 +773,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Vector4_32 sample0;
-				Vector4_32 sample1;
+				rtm::vector4f sample0;
+				rtm::vector4f sample1;
 
 				const BitSetIndexRef bitref0(m_bitset_desc, key0);
 				if (bitset_test(validity_bitset, bitref0))
@@ -826,7 +830,7 @@ namespace acl
 #endif
 					}
 
-					translation = vector_lerp(sample0, sample1, interpolation_alpha);
+					translation = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
 				{
@@ -838,18 +842,18 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL track_bit_rate_database::sample_scale(const sample_context& context, uint32_t scale_cache_index)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL track_bit_rate_database::sample_scale(const sample_context& context, uint32_t scale_cache_index)
 		{
 			const uint32_t track_index = context.track_index;
 			const BoneStreams& bone_stream = m_mutable_bone_streams[track_index];
 
-			Vector4_32 scale;
+			rtm::vector4f scale;
 			if (bone_stream.is_scale_default)
 				scale = m_default_scale;
 			else if (bone_stream.is_scale_constant)
 			{
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * scale_cache_index);
-				Vector4_32* cached_samples = safe_ptr_cast<Vector4_32>(m_data + (m_track_size * scale_cache_index));
+				rtm::vector4f* cached_samples = safe_ptr_cast<rtm::vector4f>(m_data + (m_track_size * scale_cache_index));
 
 				if (bitset_test(validity_bitset, m_bitref_constant))
 				{
@@ -878,7 +882,7 @@ namespace acl
 				const BoneStreams& raw_bone_stream = m_raw_bone_streams[track_index];
 
 				uint32_t* validity_bitset = m_track_entry_bitsets + (m_bitset_desc.get_size() * scale_cache_index);
-				Vector4_32* cached_samples = safe_ptr_cast<Vector4_32>(m_data + (m_track_size * scale_cache_index));
+				rtm::vector4f* cached_samples = safe_ptr_cast<rtm::vector4f>(m_data + (m_track_size * scale_cache_index));
 
 				uint32_t key0;
 				uint32_t key1;
@@ -897,8 +901,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Vector4_32 sample0;
-				Vector4_32 sample1;
+				rtm::vector4f sample0;
+				rtm::vector4f sample1;
 
 				const BitSetIndexRef bitref0(m_bitset_desc, key0);
 				if (bitset_test(validity_bitset, bitref0))
@@ -954,7 +958,7 @@ namespace acl
 #endif
 					}
 
-					scale = vector_lerp(sample0, sample1, interpolation_alpha);
+					scale = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
 				{
@@ -965,7 +969,7 @@ namespace acl
 			return scale;
 		}
 
-		inline void track_bit_rate_database::sample(const single_track_query& query, float sample_time, Transform_32* out_local_pose, uint32_t num_transforms)
+		inline void track_bit_rate_database::sample(const single_track_query& query, float sample_time, rtm::qvvf* out_local_pose, uint32_t num_transforms)
 		{
 			ACL_ASSERT(query.m_database == this, "Query has not been built for this database");
 			ACL_ASSERT(out_local_pose != nullptr, "Cannot write to null output local pose");
@@ -986,9 +990,9 @@ namespace acl
 			context.sample_time = sample_time;
 			context.bit_rates = query.m_bit_rates;
 
-			Quat_32 rotation;
-			Vector4_32 translation;
-			Vector4_32 scale;
+			rtm::quatf rotation;
+			rtm::vector4f translation;
+			rtm::vector4f scale;
 			if (segment_context->distribution == SampleDistribution8::Uniform)
 			{
 				rotation = sample_rotation<SampleDistribution8::Uniform>(context, query.m_rotation_cache_index);
@@ -1002,10 +1006,10 @@ namespace acl
 				scale = sample_scale<SampleDistribution8::Variable>(context, query.m_scale_cache_index);
 			}
 
-			out_local_pose[query.m_track_index] = transform_set(rotation, translation, scale);
+			out_local_pose[query.m_track_index] = rtm::qvv_set(rotation, translation, scale);
 		}
 
-		inline void track_bit_rate_database::sample(const hierarchical_track_query& query, float sample_time, Transform_32* out_local_pose, uint32_t num_transforms)
+		inline void track_bit_rate_database::sample(const hierarchical_track_query& query, float sample_time, rtm::qvvf* out_local_pose, uint32_t num_transforms)
 		{
 			ACL_ASSERT(out_local_pose != nullptr, "Cannot write to null output local pose");
 			ACL_ASSERT(num_transforms > 0, "Cannot write to empty output local pose");
@@ -1034,11 +1038,11 @@ namespace acl
 					context.track_index = current_track_index;
 					context.bit_rates = query.m_bit_rates[current_track_index];
 
-					const Quat_32 rotation = sample_rotation<SampleDistribution8::Uniform>(context, indices.rotation_cache_index);
-					const Vector4_32 translation = sample_translation<SampleDistribution8::Uniform>(context, indices.translation_cache_index);
-					const Vector4_32 scale = sample_scale<SampleDistribution8::Uniform>(context, indices.scale_cache_index);
+					const rtm::quatf rotation = sample_rotation<SampleDistribution8::Uniform>(context, indices.rotation_cache_index);
+					const rtm::vector4f translation = sample_translation<SampleDistribution8::Uniform>(context, indices.translation_cache_index);
+					const rtm::vector4f scale = sample_scale<SampleDistribution8::Uniform>(context, indices.scale_cache_index);
 
-					out_local_pose[current_track_index] = transform_set(rotation, translation, scale);
+					out_local_pose[current_track_index] = rtm::qvv_set(rotation, translation, scale);
 					current_track_index = bone_stream.parent_bone_index;
 				}
 			}
@@ -1053,11 +1057,11 @@ namespace acl
 					context.track_index = current_track_index;
 					context.bit_rates = query.m_bit_rates[current_track_index];
 
-					const Quat_32 rotation = sample_rotation<SampleDistribution8::Variable>(context, indices.rotation_cache_index);
-					const Vector4_32 translation = sample_translation<SampleDistribution8::Variable>(context, indices.translation_cache_index);
-					const Vector4_32 scale = sample_scale<SampleDistribution8::Variable>(context, indices.scale_cache_index);
+					const rtm::quatf rotation = sample_rotation<SampleDistribution8::Variable>(context, indices.rotation_cache_index);
+					const rtm::vector4f translation = sample_translation<SampleDistribution8::Variable>(context, indices.translation_cache_index);
+					const rtm::vector4f scale = sample_scale<SampleDistribution8::Variable>(context, indices.scale_cache_index);
 
-					out_local_pose[current_track_index] = transform_set(rotation, translation, scale);
+					out_local_pose[current_track_index] = rtm::qvv_set(rotation, translation, scale);
 					current_track_index = bone_stream.parent_bone_index;
 				}
 			}
diff --git a/includes/acl/compression/skeleton.h b/includes/acl/compression/skeleton.h
--- a/includes/acl/compression/skeleton.h
+++ b/includes/acl/compression/skeleton.h
@@ -29,7 +29,8 @@
 #include "acl/core/error.h"
 #include "acl/core/iallocator.h"
 #include "acl/core/string.h"
-#include "acl/math/transform_64.h"
+
+#include <rtm/qvvd.h>
 
 #include <cstdint>
 
@@ -136,7 +137,7 @@ namespace acl
 			, bone_chain(nullptr)
 			, vertex_distance(1.0F)
 			, parent_index(k_invalid_bone_index)
-			, bind_transform(transform_identity_64())
+			, bind_transform(rtm::qvv_identity())
 		{
 			(void)padding;
 		}
@@ -189,7 +190,7 @@ namespace acl
 
 		// The bind transform is in its parent's local space
 		// Note that the scale is ignored and this value is only used by the additive error metrics
-		Transform_64	bind_transform;
+		rtm::qvvd		bind_transform;
 	};
 
 	//////////////////////////////////////////////////////////////////////////
@@ -235,9 +236,9 @@ namespace acl
 
 				ACL_ASSERT(bone.bone_chain == nullptr, "Bone chain should be calculated internally");
 				ACL_ASSERT(is_root || bone.parent_index < bone_index, "Bones must be sorted parent first");
-				ACL_ASSERT(quat_is_finite(bone.bind_transform.rotation), "Bind rotation is invalid: [%f, %f, %f, %f]", quat_get_x(bone.bind_transform.rotation), quat_get_y(bone.bind_transform.rotation), quat_get_z(bone.bind_transform.rotation), quat_get_w(bone.bind_transform.rotation));
-				ACL_ASSERT(quat_is_normalized(bone.bind_transform.rotation), "Bind rotation isn't normalized: [%f, %f, %f, %f]", quat_get_x(bone.bind_transform.rotation), quat_get_y(bone.bind_transform.rotation), quat_get_z(bone.bind_transform.rotation), quat_get_w(bone.bind_transform.rotation));
-				ACL_ASSERT(vector_is_finite3(bone.bind_transform.translation), "Bind translation is invalid: [%f, %f, %f]", vector_get_x(bone.bind_transform.translation), vector_get_y(bone.bind_transform.translation), vector_get_z(bone.bind_transform.translation));
+				ACL_ASSERT(rtm::quat_is_finite(bone.bind_transform.rotation), "Bind rotation is invalid: [%f, %f, %f, %f]", rtm::quat_get_x(bone.bind_transform.rotation), rtm::quat_get_y(bone.bind_transform.rotation), rtm::quat_get_z(bone.bind_transform.rotation), rtm::quat_get_w(bone.bind_transform.rotation));
+				ACL_ASSERT(rtm::quat_is_normalized(bone.bind_transform.rotation), "Bind rotation isn't normalized: [%f, %f, %f, %f]", rtm::quat_get_x(bone.bind_transform.rotation), rtm::quat_get_y(bone.bind_transform.rotation), rtm::quat_get_z(bone.bind_transform.rotation), rtm::quat_get_w(bone.bind_transform.rotation));
+				ACL_ASSERT(rtm::vector_is_finite3(bone.bind_transform.translation), "Bind translation is invalid: [%f, %f, %f]", rtm::vector_get_x(bone.bind_transform.translation), rtm::vector_get_y(bone.bind_transform.translation), rtm::vector_get_z(bone.bind_transform.translation));
 
 				// If we have a parent, mark it as not being a leaf bone (it has at least one child)
 				if (!is_root)
@@ -251,7 +252,7 @@ namespace acl
 				m_bones[bone_index] = std::move(bone);
 
 				// Input scale is ignored and always set to [1.0, 1.0, 1.0]
-				m_bones[bone_index].bind_transform.scale = vector_set(1.0);
+				m_bones[bone_index].bind_transform.scale = rtm::vector_set(1.0);
 			}
 
 			m_num_leaf_bones = safe_static_cast<uint16_t>(bitset_count_set_bits(is_leaf_bitset, bone_bitset_desc));
diff --git a/includes/acl/compression/skeleton_error_metric.h b/includes/acl/compression/skeleton_error_metric.h
--- a/includes/acl/compression/skeleton_error_metric.h
+++ b/includes/acl/compression/skeleton_error_metric.h
@@ -27,11 +27,12 @@
 #include "acl/core/additive_utils.h"
 #include "acl/core/compiler_utils.h"
 #include "acl/core/hash.h"
-#include "acl/math/affine_matrix_32.h"
-#include "acl/math/transform_32.h"
-#include "acl/math/scalar_32.h"
 #include "acl/compression/skeleton.h"
 
+#include <rtm/matrix3x4f.h>
+#include <rtm/qvvf.h>
+#include <rtm/scalarf.h>
+
 ACL_IMPL_FILE_PRAGMA_PUSH
 
 namespace acl
@@ -45,11 +46,11 @@ namespace acl
 		virtual const char* get_name() const = 0;
 		virtual uint32_t get_hash() const = 0;
 
-		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const = 0;
-		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const = 0;
+		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const = 0;
+		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const = 0;
 
-		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const = 0;
-		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const = 0;
+		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const = 0;
+		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const = 0;
 	};
 
 	// Uses a mix of Transform_32 and AffineMatrix_32 arithmetic.
@@ -64,7 +65,7 @@ namespace acl
 		virtual const char* get_name() const override { return "TransformMatrixErrorMetric"; }
 		virtual uint32_t get_hash() const override { return hash32("TransformMatrixErrorMetric"); }
 
-		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
@@ -72,53 +73,53 @@ namespace acl
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, bone.vertex_distance);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, bone.vertex_distance);
 
-			const Vector4_32 raw_vtx0 = transform_position(raw_local_pose[bone_index], vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position(lossy_local_pose[bone_index], vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3(vtx0, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3(vtx0, lossy_local_pose[bone_index]);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position(raw_local_pose[bone_index], vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position(lossy_local_pose[bone_index], vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3(vtx1, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3(vtx1, lossy_local_pose[bone_index]);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			const Vector4_32 raw_vtx2 = transform_position(raw_local_pose[bone_index], vtx2);
-			const Vector4_32 lossy_vtx2 = transform_position(lossy_local_pose[bone_index], vtx2);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
+			const rtm::vector4f raw_vtx2 = rtm::qvv_mul_point3(vtx2, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx2 = rtm::qvv_mul_point3(vtx2, lossy_local_pose[bone_index]);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
 
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_local_pose[bone_index], vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_local_pose[bone_index], vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_local_pose[bone_index]);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_local_pose[bone_index], vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_local_pose[bone_index], vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_local_pose[bone_index]);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 
-		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
-			AffineMatrix_32 raw_obj_mtx = matrix_from_transform(raw_local_pose[0]);
-			AffineMatrix_32 lossy_obj_mtx = matrix_from_transform(lossy_local_pose[0]);
+			rtm::matrix3x4f raw_obj_mtx = rtm::matrix_from_qvv(raw_local_pose[0]);
+			rtm::matrix3x4f lossy_obj_mtx = rtm::matrix_from_qvv(lossy_local_pose[0]);
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -126,38 +127,38 @@ namespace acl
 			for (; chain_bone_it != chain_bone_end; ++chain_bone_it)
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
-				raw_obj_mtx = matrix_mul(matrix_from_transform(raw_local_pose[chain_bone_index]), raw_obj_mtx);
-				lossy_obj_mtx = matrix_mul(matrix_from_transform(lossy_local_pose[chain_bone_index]), lossy_obj_mtx);
+				raw_obj_mtx = rtm::matrix_mul(rtm::matrix_from_qvv(raw_local_pose[chain_bone_index]), raw_obj_mtx);
+				lossy_obj_mtx = rtm::matrix_mul(rtm::matrix_from_qvv(lossy_local_pose[chain_bone_index]), lossy_obj_mtx);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, target_bone.vertex_distance);
-
-			const Vector4_32 raw_vtx0 = matrix_mul_position(raw_obj_mtx, vtx0);
-			const Vector4_32 raw_vtx1 = matrix_mul_position(raw_obj_mtx, vtx1);
-			const Vector4_32 raw_vtx2 = matrix_mul_position(raw_obj_mtx, vtx2);
-			const Vector4_32 lossy_vtx0 = matrix_mul_position(lossy_obj_mtx, vtx0);
-			const Vector4_32 lossy_vtx1 = matrix_mul_position(lossy_obj_mtx, vtx1);
-			const Vector4_32 lossy_vtx2 = matrix_mul_position(lossy_obj_mtx, vtx2);
-
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
-
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, target_bone.vertex_distance);
+
+			const rtm::vector4f raw_vtx0 = rtm::matrix_mul_point3(vtx0, raw_obj_mtx);
+			const rtm::vector4f raw_vtx1 = rtm::matrix_mul_point3(vtx1, raw_obj_mtx);
+			const rtm::vector4f raw_vtx2 = rtm::matrix_mul_point3(vtx2, raw_obj_mtx);
+			const rtm::vector4f lossy_vtx0 = rtm::matrix_mul_point3(vtx0, lossy_obj_mtx);
+			const rtm::vector4f lossy_vtx1 = rtm::matrix_mul_point3(vtx1, lossy_obj_mtx);
+			const rtm::vector4f lossy_vtx2 = rtm::matrix_mul_point3(vtx2, lossy_obj_mtx);
+
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
+
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
-			Transform_32 raw_obj_transform = raw_local_pose[0];
-			Transform_32 lossy_obj_transform = lossy_local_pose[0];
+			rtm::qvvf raw_obj_transform = raw_local_pose[0];
+			rtm::qvvf lossy_obj_transform = lossy_local_pose[0];
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -165,24 +166,24 @@ namespace acl
 			for (; chain_bone_it != chain_bone_end; ++chain_bone_it)
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
-				raw_obj_transform = transform_mul_no_scale(raw_local_pose[chain_bone_index], raw_obj_transform);
-				lossy_obj_transform = transform_mul_no_scale(lossy_local_pose[chain_bone_index], lossy_obj_transform);
+				raw_obj_transform = rtm::qvv_mul_no_scale(raw_local_pose[chain_bone_index], raw_obj_transform);
+				lossy_obj_transform = rtm::qvv_mul_no_scale(lossy_local_pose[chain_bone_index], lossy_obj_transform);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_obj_transform, vtx0);
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_obj_transform, vtx1);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_obj_transform, vtx0);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_obj_transform, vtx1);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_obj_transform);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_obj_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_obj_transform);
 
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 	};
 
@@ -194,7 +195,7 @@ namespace acl
 		virtual const char* get_name() const override { return "TransformErrorMetric"; }
 		virtual uint32_t get_hash() const override { return hash32("TransformErrorMetric"); }
 
-		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
@@ -202,53 +203,53 @@ namespace acl
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, bone.vertex_distance);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, bone.vertex_distance);
 
-			const Vector4_32 raw_vtx0 = transform_position(raw_local_pose[bone_index], vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position(lossy_local_pose[bone_index], vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3(vtx0, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3(vtx0, lossy_local_pose[bone_index]);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position(raw_local_pose[bone_index], vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position(lossy_local_pose[bone_index], vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3(vtx1, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3(vtx1, lossy_local_pose[bone_index]);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			const Vector4_32 raw_vtx2 = transform_position(raw_local_pose[bone_index], vtx2);
-			const Vector4_32 lossy_vtx2 = transform_position(lossy_local_pose[bone_index], vtx2);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
+			const rtm::vector4f raw_vtx2 = rtm::qvv_mul_point3(vtx2, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx2 = rtm::qvv_mul_point3(vtx2, lossy_local_pose[bone_index]);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
 
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_local_pose[bone_index], vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_local_pose[bone_index], vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_local_pose[bone_index]);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_local_pose[bone_index], vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_local_pose[bone_index], vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_local_pose[bone_index]);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_local_pose[bone_index]);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 
-		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
-			Transform_32 raw_obj_transform = raw_local_pose[0];
-			Transform_32 lossy_obj_transform = lossy_local_pose[0];
+			rtm::qvvf raw_obj_transform = raw_local_pose[0];
+			rtm::qvvf lossy_obj_transform = lossy_local_pose[0];
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -256,38 +257,38 @@ namespace acl
 			for (; chain_bone_it != chain_bone_end; ++chain_bone_it)
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
-				raw_obj_transform = transform_mul(raw_local_pose[chain_bone_index], raw_obj_transform);
-				lossy_obj_transform = transform_mul(lossy_local_pose[chain_bone_index], lossy_obj_transform);
+				raw_obj_transform = rtm::qvv_mul(raw_local_pose[chain_bone_index], raw_obj_transform);
+				lossy_obj_transform = rtm::qvv_mul(lossy_local_pose[chain_bone_index], lossy_obj_transform);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, target_bone.vertex_distance);
-
-			const Vector4_32 raw_vtx0 = transform_position(raw_obj_transform, vtx0);
-			const Vector4_32 raw_vtx1 = transform_position(raw_obj_transform, vtx1);
-			const Vector4_32 raw_vtx2 = transform_position(raw_obj_transform, vtx2);
-			const Vector4_32 lossy_vtx0 = transform_position(lossy_obj_transform, vtx0);
-			const Vector4_32 lossy_vtx1 = transform_position(lossy_obj_transform, vtx1);
-			const Vector4_32 lossy_vtx2 = transform_position(lossy_obj_transform, vtx2);
-
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
-
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, target_bone.vertex_distance);
+
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3(vtx0, raw_obj_transform);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3(vtx1, raw_obj_transform);
+			const rtm::vector4f raw_vtx2 = rtm::qvv_mul_point3(vtx2, raw_obj_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3(vtx0, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3(vtx1, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx2 = rtm::qvv_mul_point3(vtx2, lossy_obj_transform);
+
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
+
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 			(void)base_local_pose;
 
-			Transform_32 raw_obj_transform = raw_local_pose[0];
-			Transform_32 lossy_obj_transform = lossy_local_pose[0];
+			rtm::qvvf raw_obj_transform = raw_local_pose[0];
+			rtm::qvvf lossy_obj_transform = lossy_local_pose[0];
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -295,24 +296,24 @@ namespace acl
 			for (; chain_bone_it != chain_bone_end; ++chain_bone_it)
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
-				raw_obj_transform = transform_mul_no_scale(raw_local_pose[chain_bone_index], raw_obj_transform);
-				lossy_obj_transform = transform_mul_no_scale(lossy_local_pose[chain_bone_index], lossy_obj_transform);
+				raw_obj_transform = rtm::qvv_mul_no_scale(raw_local_pose[chain_bone_index], raw_obj_transform);
+				lossy_obj_transform = rtm::qvv_mul_no_scale(lossy_local_pose[chain_bone_index], lossy_obj_transform);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_obj_transform, vtx0);
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_obj_transform, vtx1);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_obj_transform, vtx0);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_obj_transform, vtx1);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_obj_transform);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_obj_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_obj_transform);
 
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 	};
 
@@ -337,64 +338,64 @@ namespace acl
 
 		virtual uint32_t get_hash() const override { return hash32(get_name()); }
 
-		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, bone.vertex_distance);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, bone.vertex_distance);
 
-			const Transform_32 raw_transform = apply_additive_to_base(additive_format, base_local_pose[bone_index], raw_local_pose[bone_index]);
-			const Transform_32 lossy_transform = apply_additive_to_base(additive_format, base_local_pose[bone_index], lossy_local_pose[bone_index]);
+			const rtm::qvvf raw_transform = apply_additive_to_base(additive_format, base_local_pose[bone_index], raw_local_pose[bone_index]);
+			const rtm::qvvf lossy_transform = apply_additive_to_base(additive_format, base_local_pose[bone_index], lossy_local_pose[bone_index]);
 
-			const Vector4_32 raw_vtx0 = transform_position(raw_transform, vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position(lossy_transform, vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3(vtx0, raw_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3(vtx0, lossy_transform);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position(raw_transform, vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position(lossy_transform, vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3(vtx1, raw_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3(vtx1, lossy_transform);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			const Vector4_32 raw_vtx2 = transform_position(raw_transform, vtx2);
-			const Vector4_32 lossy_vtx2 = transform_position(lossy_transform, vtx2);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
+			const rtm::vector4f raw_vtx2 = rtm::qvv_mul_point3(vtx2, raw_transform);
+			const rtm::vector4f lossy_vtx2 = rtm::qvv_mul_point3(vtx2, lossy_transform);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
 
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_local_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 
 			const RigidBone& bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, bone.vertex_distance, 0.0F);
 
-			const Transform_32 raw_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[bone_index], raw_local_pose[bone_index]);
-			const Transform_32 lossy_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[bone_index], lossy_local_pose[bone_index]);
+			const rtm::qvvf raw_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[bone_index], raw_local_pose[bone_index]);
+			const rtm::qvvf lossy_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[bone_index], lossy_local_pose[bone_index]);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_transform, vtx0);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_transform, vtx0);
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_transform);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
 
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_transform, vtx1);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_transform, vtx1);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_transform);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 
-		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 
-			Transform_32 raw_obj_transform = apply_additive_to_base(additive_format, base_local_pose[0], raw_local_pose[0]);
-			Transform_32 lossy_obj_transform = apply_additive_to_base(additive_format, base_local_pose[0], lossy_local_pose[0]);
+			rtm::qvvf raw_obj_transform = apply_additive_to_base(additive_format, base_local_pose[0], raw_local_pose[0]);
+			rtm::qvvf lossy_obj_transform = apply_additive_to_base(additive_format, base_local_pose[0], lossy_local_pose[0]);
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -403,37 +404,37 @@ namespace acl
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
 
-				raw_obj_transform = transform_mul(apply_additive_to_base(additive_format, base_local_pose[chain_bone_index], raw_local_pose[chain_bone_index]), raw_obj_transform);
-				lossy_obj_transform = transform_mul(apply_additive_to_base(additive_format, base_local_pose[chain_bone_index], lossy_local_pose[chain_bone_index]), lossy_obj_transform);
+				raw_obj_transform = rtm::qvv_mul(apply_additive_to_base(additive_format, base_local_pose[chain_bone_index], raw_local_pose[chain_bone_index]), raw_obj_transform);
+				lossy_obj_transform = rtm::qvv_mul(apply_additive_to_base(additive_format, base_local_pose[chain_bone_index], lossy_local_pose[chain_bone_index]), lossy_obj_transform);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
 			// Note that because we have scale, we must measure all three axes
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
-			const Vector4_32 vtx2 = vector_set(0.0F, 0.0F, target_bone.vertex_distance);
-
-			const Vector4_32 raw_vtx0 = transform_position(raw_obj_transform, vtx0);
-			const Vector4_32 raw_vtx1 = transform_position(raw_obj_transform, vtx1);
-			const Vector4_32 raw_vtx2 = transform_position(raw_obj_transform, vtx2);
-			const Vector4_32 lossy_vtx0 = transform_position(lossy_obj_transform, vtx0);
-			const Vector4_32 lossy_vtx1 = transform_position(lossy_obj_transform, vtx1);
-			const Vector4_32 lossy_vtx2 = transform_position(lossy_obj_transform, vtx2);
-
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
-			const float vtx2_error = vector_distance3(raw_vtx2, lossy_vtx2);
-
-			return max(max(vtx0_error, vtx1_error), vtx2_error);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx2 = rtm::vector_set(0.0F, 0.0F, target_bone.vertex_distance);
+
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3(vtx0, raw_obj_transform);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3(vtx1, raw_obj_transform);
+			const rtm::vector4f raw_vtx2 = rtm::qvv_mul_point3(vtx2, raw_obj_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3(vtx0, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3(vtx1, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx2 = rtm::qvv_mul_point3(vtx2, lossy_obj_transform);
+
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx2_error = rtm::vector_distance3(raw_vtx2, lossy_vtx2);
+
+			return rtm::scalar_max(rtm::scalar_max(vtx0_error, vtx1_error), vtx2_error);
 		}
 
-		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const Transform_32* raw_local_pose, const Transform_32* base_local_pose, const Transform_32* lossy_local_pose, uint16_t bone_index) const override
+		virtual float calculate_object_bone_error_no_scale(const RigidSkeleton& skeleton, const rtm::qvvf* raw_local_pose, const rtm::qvvf* base_local_pose, const rtm::qvvf* lossy_local_pose, uint16_t bone_index) const override
 		{
 			ACL_ASSERT(bone_index < skeleton.get_num_bones(), "Invalid bone index: %u", bone_index);
 
-			Transform_32 raw_obj_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[0], raw_local_pose[0]);
-			Transform_32 lossy_obj_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[0], lossy_local_pose[0]);
+			rtm::qvvf raw_obj_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[0], raw_local_pose[0]);
+			rtm::qvvf lossy_obj_transform = apply_additive_to_base_no_scale(additive_format, base_local_pose[0], lossy_local_pose[0]);
 
 			const BoneChain bone_chain = skeleton.get_bone_chain(bone_index);
 			auto chain_bone_it = ++bone_chain.begin();	// Skip root bone
@@ -442,24 +443,24 @@ namespace acl
 			{
 				const uint16_t chain_bone_index = *chain_bone_it;
 
-				raw_obj_transform = transform_mul_no_scale(apply_additive_to_base_no_scale(additive_format, base_local_pose[chain_bone_index], raw_local_pose[chain_bone_index]), raw_obj_transform);
-				lossy_obj_transform = transform_mul_no_scale(apply_additive_to_base_no_scale(additive_format, base_local_pose[chain_bone_index], lossy_local_pose[chain_bone_index]), lossy_obj_transform);
+				raw_obj_transform = rtm::qvv_mul_no_scale(apply_additive_to_base_no_scale(additive_format, base_local_pose[chain_bone_index], raw_local_pose[chain_bone_index]), raw_obj_transform);
+				lossy_obj_transform = rtm::qvv_mul_no_scale(apply_additive_to_base_no_scale(additive_format, base_local_pose[chain_bone_index], lossy_local_pose[chain_bone_index]), lossy_obj_transform);
 			}
 
 			const RigidBone& target_bone = skeleton.get_bone(bone_index);
 
-			const Vector4_32 vtx0 = vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
-			const Vector4_32 vtx1 = vector_set(0.0F, target_bone.vertex_distance, 0.0F);
+			const rtm::vector4f vtx0 = rtm::vector_set(target_bone.vertex_distance, 0.0F, 0.0F);
+			const rtm::vector4f vtx1 = rtm::vector_set(0.0F, target_bone.vertex_distance, 0.0F);
 
-			const Vector4_32 raw_vtx0 = transform_position_no_scale(raw_obj_transform, vtx0);
-			const Vector4_32 raw_vtx1 = transform_position_no_scale(raw_obj_transform, vtx1);
-			const Vector4_32 lossy_vtx0 = transform_position_no_scale(lossy_obj_transform, vtx0);
-			const Vector4_32 lossy_vtx1 = transform_position_no_scale(lossy_obj_transform, vtx1);
+			const rtm::vector4f raw_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, raw_obj_transform);
+			const rtm::vector4f raw_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, raw_obj_transform);
+			const rtm::vector4f lossy_vtx0 = rtm::qvv_mul_point3_no_scale(vtx0, lossy_obj_transform);
+			const rtm::vector4f lossy_vtx1 = rtm::qvv_mul_point3_no_scale(vtx1, lossy_obj_transform);
 
-			const float vtx0_error = vector_distance3(raw_vtx0, lossy_vtx0);
-			const float vtx1_error = vector_distance3(raw_vtx1, lossy_vtx1);
+			const float vtx0_error = rtm::vector_distance3(raw_vtx0, lossy_vtx0);
+			const float vtx1_error = rtm::vector_distance3(raw_vtx1, lossy_vtx1);
 
-			return max(vtx0_error, vtx1_error);
+			return rtm::scalar_max(vtx0_error, vtx1_error);
 		}
 	};
 }
diff --git a/includes/acl/compression/stream/clip_context.h b/includes/acl/compression/stream/clip_context.h
--- a/includes/acl/compression/stream/clip_context.h
+++ b/includes/acl/compression/stream/clip_context.h
@@ -33,6 +33,9 @@
 #include "acl/compression/compression_settings.h"
 #include "acl/compression/stream/segment_context.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -97,7 +100,7 @@ namespace acl
 		out_clip_context.additive_format = clip.get_additive_format();
 
 		bool has_scale = false;
-		const Vector4_32 default_scale = get_default_scale(clip.get_additive_format());
+		const rtm::vector4f default_scale = get_default_scale(clip.get_additive_format());
 
 		SegmentContext& segment = out_clip_context.segments[0];
 
@@ -114,28 +117,28 @@ namespace acl
 			bone_stream.parent_bone_index = skel_bone.parent_index;
 			bone_stream.output_index = bone.output_index;
 
-			bone_stream.rotations = RotationTrackStream(allocator, num_samples, sizeof(Quat_32), sample_rate, RotationFormat8::Quat_128);
-			bone_stream.translations = TranslationTrackStream(allocator, num_samples, sizeof(Vector4_32), sample_rate, VectorFormat8::Vector3_96);
-			bone_stream.scales = ScaleTrackStream(allocator, num_samples, sizeof(Vector4_32), sample_rate, VectorFormat8::Vector3_96);
+			bone_stream.rotations = RotationTrackStream(allocator, num_samples, sizeof(rtm::quatf), sample_rate, RotationFormat8::Quat_128);
+			bone_stream.translations = TranslationTrackStream(allocator, num_samples, sizeof(rtm::vector4f), sample_rate, VectorFormat8::Vector3_96);
+			bone_stream.scales = ScaleTrackStream(allocator, num_samples, sizeof(rtm::vector4f), sample_rate, VectorFormat8::Vector3_96);
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				const Quat_32 rotation = quat_normalize(quat_cast(bone.rotation_track.get_sample(sample_index)));
+				const rtm::quatf rotation = rtm::quat_normalize(rtm::quat_cast(bone.rotation_track.get_sample(sample_index)));
 				bone_stream.rotations.set_raw_sample(sample_index, rotation);
 
-				const Vector4_32 translation = vector_cast(bone.translation_track.get_sample(sample_index));
+				const rtm::vector4f translation = rtm::vector_cast(bone.translation_track.get_sample(sample_index));
 				bone_stream.translations.set_raw_sample(sample_index, translation);
 
-				const Vector4_32 scale = vector_cast(bone.scale_track.get_sample(sample_index));
+				const rtm::vector4f scale = rtm::vector_cast(bone.scale_track.get_sample(sample_index));
 				bone_stream.scales.set_raw_sample(sample_index, scale);
 			}
 
 			bone_stream.is_rotation_constant = num_samples == 1;
-			bone_stream.is_rotation_default = bone_stream.is_rotation_constant && quat_near_identity(quat_cast(bone.rotation_track.get_sample(0)), settings.constant_rotation_threshold_angle);
+			bone_stream.is_rotation_default = bone_stream.is_rotation_constant && rtm::quat_near_identity(rtm::quat_cast(bone.rotation_track.get_sample(0)), settings.constant_rotation_threshold_angle);
 			bone_stream.is_translation_constant = num_samples == 1;
-			bone_stream.is_translation_default = bone_stream.is_translation_constant && vector_all_near_equal3(vector_cast(bone.translation_track.get_sample(0)), vector_zero_32(), settings.constant_translation_threshold);
+			bone_stream.is_translation_default = bone_stream.is_translation_constant && rtm::vector_all_near_equal3(rtm::vector_cast(bone.translation_track.get_sample(0)), rtm::vector_zero(), settings.constant_translation_threshold);
 			bone_stream.is_scale_constant = num_samples == 1;
-			bone_stream.is_scale_default = bone_stream.is_scale_constant && vector_all_near_equal3(vector_cast(bone.scale_track.get_sample(0)), default_scale, settings.constant_scale_threshold);
+			bone_stream.is_scale_default = bone_stream.is_scale_constant && rtm::vector_all_near_equal3(rtm::vector_cast(bone.scale_track.get_sample(0)), default_scale, settings.constant_scale_threshold);
 
 			has_scale |= !bone_stream.is_scale_default;
 
diff --git a/includes/acl/compression/stream/compact_constant_streams.h b/includes/acl/compression/stream/compact_constant_streams.h
--- a/includes/acl/compression/stream/compact_constant_streams.h
+++ b/includes/acl/compression/stream/compact_constant_streams.h
@@ -27,16 +27,18 @@
 #include "acl/core/iallocator.h"
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
-#include "acl/math/vector4_32.h"
 #include "acl/compression/stream/clip_context.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
 
 namespace acl
 {
-	inline bool is_rotation_track_constant(const RotationTrackStream& rotations, float threshold_angle)
+	inline bool is_rotation_track_constant(const RotationTrackStream& rotations, rtm::anglef threshold_angle)
 	{
 		// Calculating the average rotation and comparing every rotation in the track to it
 		// to determine if we are within the threshold seems overkill. We can't use the min/max for the range
@@ -44,45 +46,45 @@ namespace acl
 		// the first rotation, and compare everything else to it.
 		auto sample_to_quat = [](const RotationTrackStream& track, uint32_t sample_index)
 		{
-			const Vector4_32 rotation = track.get_raw_sample<Vector4_32>(sample_index);
+			const rtm::vector4f rotation = track.get_raw_sample<rtm::vector4f>(sample_index);
 
 			switch (track.get_rotation_format())
 			{
 			case RotationFormat8::Quat_128:
-				return vector_to_quat(rotation);
+				return rtm::vector_to_quat(rotation);
 			case RotationFormat8::QuatDropW_96:
 			case RotationFormat8::QuatDropW_48:
 			case RotationFormat8::QuatDropW_32:
 			case RotationFormat8::QuatDropW_Variable:
-				return quat_from_positive_w(rotation);
+				return rtm::quat_from_positive_w(rotation);
 			default:
 				ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(track.get_rotation_format()));
-				return vector_to_quat(rotation);
+				return rtm::vector_to_quat(rotation);
 			}
 		};
 
-		const Quat_32 ref_rotation = sample_to_quat(rotations, 0);
-		const Quat_32 inv_ref_rotation = quat_conjugate(ref_rotation);
+		const rtm::quatf ref_rotation = sample_to_quat(rotations, 0);
+		const rtm::quatf inv_ref_rotation = rtm::quat_conjugate(ref_rotation);
 
 		const uint32_t num_samples = rotations.get_num_samples();
 		for (uint32_t sample_index = 1; sample_index < num_samples; ++sample_index)
 		{
-			const Quat_32 rotation = sample_to_quat(rotations, sample_index);
-			const Quat_32 delta = quat_normalize(quat_mul(inv_ref_rotation, rotation));
-			if (!quat_near_identity(delta, threshold_angle))
+			const rtm::quatf rotation = sample_to_quat(rotations, sample_index);
+			const rtm::quatf delta = rtm::quat_normalize(rtm::quat_mul(inv_ref_rotation, rotation));
+			if (!rtm::quat_near_identity(delta, threshold_angle))
 				return false;
 		}
 
 		return true;
 	}
 
-	inline void compact_constant_streams(IAllocator& allocator, ClipContext& clip_context, float rotation_threshold_angle, float translation_threshold, float scale_threshold)
+	inline void compact_constant_streams(IAllocator& allocator, ClipContext& clip_context, rtm::anglef rotation_threshold_angle, float translation_threshold, float scale_threshold)
 	{
 		ACL_ASSERT(clip_context.num_segments == 1, "ClipContext must contain a single segment!");
 		SegmentContext& segment = clip_context.segments[0];
 
 		const uint16_t num_bones = clip_context.num_bones;
-		const Vector4_32 default_scale = get_default_scale(clip_context.additive_format);
+		const rtm::vector4f default_scale = get_default_scale(clip_context.additive_format);
 		uint16_t num_default_bone_scales = 0;
 
 		// When a stream is constant, we only keep the first sample
@@ -91,48 +93,48 @@ namespace acl
 			BoneStreams& bone_stream = segment.bone_streams[bone_index];
 			BoneRanges& bone_range = clip_context.ranges[bone_index];
 
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(Vector4_32), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(Vector4_32));
-			ACL_ASSERT(bone_stream.translations.get_sample_size() == sizeof(Vector4_32), "Unexpected translation sample size. %u != %u", bone_stream.translations.get_sample_size(), sizeof(Vector4_32));
-			ACL_ASSERT(bone_stream.scales.get_sample_size() == sizeof(Vector4_32), "Unexpected scale sample size. %u != %u", bone_stream.scales.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(rtm::vector4f), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(rtm::vector4f));
+			ACL_ASSERT(bone_stream.translations.get_sample_size() == sizeof(rtm::vector4f), "Unexpected translation sample size. %u != %u", bone_stream.translations.get_sample_size(), sizeof(rtm::vector4f));
+			ACL_ASSERT(bone_stream.scales.get_sample_size() == sizeof(rtm::vector4f), "Unexpected scale sample size. %u != %u", bone_stream.scales.get_sample_size(), sizeof(rtm::vector4f));
 
 			if (is_rotation_track_constant(bone_stream.rotations, rotation_threshold_angle))
 			{
 				RotationTrackStream constant_stream(allocator, 1, bone_stream.rotations.get_sample_size(), bone_stream.rotations.get_sample_rate(), bone_stream.rotations.get_rotation_format());
-				Vector4_32 rotation = bone_stream.rotations.get_raw_sample<Vector4_32>(0);
+				rtm::vector4f rotation = bone_stream.rotations.get_raw_sample<rtm::vector4f>(0);
 				constant_stream.set_raw_sample(0, rotation);
 
 				bone_stream.rotations = std::move(constant_stream);
 				bone_stream.is_rotation_constant = true;
-				bone_stream.is_rotation_default = quat_near_identity(vector_to_quat(rotation), rotation_threshold_angle);
+				bone_stream.is_rotation_default = rtm::quat_near_identity(rtm::vector_to_quat(rotation), rotation_threshold_angle);
 
-				bone_range.rotation = TrackStreamRange::from_min_extent(rotation, vector_zero_32());
+				bone_range.rotation = TrackStreamRange::from_min_extent(rotation, rtm::vector_zero());
 			}
 
 			if (bone_range.translation.is_constant(translation_threshold))
 			{
 				TranslationTrackStream constant_stream(allocator, 1, bone_stream.translations.get_sample_size(), bone_stream.translations.get_sample_rate(), bone_stream.translations.get_vector_format());
-				Vector4_32 translation = bone_stream.translations.get_raw_sample<Vector4_32>(0);
+				rtm::vector4f translation = bone_stream.translations.get_raw_sample<rtm::vector4f>(0);
 				constant_stream.set_raw_sample(0, translation);
 
 				bone_stream.translations = std::move(constant_stream);
 				bone_stream.is_translation_constant = true;
-				bone_stream.is_translation_default = vector_all_near_equal3(translation, vector_zero_32(), translation_threshold);
+				bone_stream.is_translation_default = rtm::vector_all_near_equal3(translation, rtm::vector_zero(), translation_threshold);
 
-				bone_range.translation = TrackStreamRange::from_min_extent(translation, vector_zero_32());
+				bone_range.translation = TrackStreamRange::from_min_extent(translation, rtm::vector_zero());
 			}
 
 			if (bone_range.scale.is_constant(scale_threshold))
 			{
 				ScaleTrackStream constant_stream(allocator, 1, bone_stream.scales.get_sample_size(), bone_stream.scales.get_sample_rate(), bone_stream.scales.get_vector_format());
-				Vector4_32 scale = bone_stream.scales.get_raw_sample<Vector4_32>(0);
+				rtm::vector4f scale = bone_stream.scales.get_raw_sample<rtm::vector4f>(0);
 				constant_stream.set_raw_sample(0, scale);
 
 				bone_stream.scales = std::move(constant_stream);
 				bone_stream.is_scale_constant = true;
-				bone_stream.is_scale_default = vector_all_near_equal3(scale, default_scale, scale_threshold);
+				bone_stream.is_scale_default = rtm::vector_all_near_equal3(scale, default_scale, scale_threshold);
 
-				bone_range.scale = TrackStreamRange::from_min_extent(scale, vector_zero_32());
+				bone_range.scale = TrackStreamRange::from_min_extent(scale, rtm::vector_zero());
 
 				num_default_bone_scales += bone_stream.is_scale_default ? 1 : 0;
 			}
diff --git a/includes/acl/compression/stream/convert_rotation_streams.h b/includes/acl/compression/stream/convert_rotation_streams.h
--- a/includes/acl/compression/stream/convert_rotation_streams.h
+++ b/includes/acl/compression/stream/convert_rotation_streams.h
@@ -27,17 +27,18 @@
 #include "acl/core/iallocator.h"
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
 #include "acl/compression/stream/clip_context.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
 
 namespace acl
 {
-	inline Vector4_32 ACL_SIMD_CALL convert_rotation(Vector4_32Arg0 rotation, RotationFormat8 from, RotationFormat8 to)
+	inline rtm::vector4f RTM_SIMD_CALL convert_rotation(rtm::vector4f_arg0 rotation, RotationFormat8 from, RotationFormat8 to)
 	{
 		ACL_ASSERT(from == RotationFormat8::Quat_128, "Source rotation format must be a full precision quaternion");
 		(void)from;
@@ -50,7 +51,7 @@ namespace acl
 			return rotation;
 		case RotationFormat8::QuatDropW_96:
 			// Drop W, we just ensure it is positive and write it back, the W component can be ignored afterwards
-			return quat_to_vector(quat_ensure_positive_w(vector_to_quat(rotation)));
+			return rtm::quat_to_vector(rtm::quat_ensure_positive_w(rtm::vector_to_quat(rotation)));
 		default:
 			ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(to));
 			return rotation;
@@ -63,17 +64,17 @@ namespace acl
 
 		for (BoneStreams& bone_stream : segment.bone_iterator())
 		{
-			// We convert our rotation stream in place. We assume that the original format is Quat_128 stored as Quat_32
-			// For all other formats, we keep the same sample size and either keep Quat_32 or use Vector4_32
-			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(Quat_32), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(Quat_32));
+			// We convert our rotation stream in place. We assume that the original format is Quat_128 stored as rtm::quatf
+			// For all other formats, we keep the same sample size and either keep Quat_32 or use rtm::vector4f
+			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(rtm::quatf), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(rtm::quatf));
 
 			const uint32_t num_samples = bone_stream.rotations.get_num_samples();
 			const float sample_rate = bone_stream.rotations.get_sample_rate();
-			RotationTrackStream converted_stream(allocator, num_samples, sizeof(Quat_32), sample_rate, high_precision_format);
+			RotationTrackStream converted_stream(allocator, num_samples, sizeof(rtm::quatf), sample_rate, high_precision_format);
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				Quat_32 rotation = bone_stream.rotations.get_raw_sample<Quat_32>(sample_index);
+				rtm::quatf rotation = bone_stream.rotations.get_raw_sample<rtm::quatf>(sample_index);
 
 				switch (high_precision_format)
 				{
@@ -82,7 +83,7 @@ namespace acl
 					break;
 				case RotationFormat8::QuatDropW_96:
 					// Drop W, we just ensure it is positive and write it back, the W component can be ignored afterwards
-					rotation = quat_ensure_positive_w(rotation);
+					rotation = rtm::quat_ensure_positive_w(rotation);
 					break;
 				default:
 					ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(high_precision_format));
diff --git a/includes/acl/compression/stream/normalize_streams.h b/includes/acl/compression/stream/normalize_streams.h
--- a/includes/acl/compression/stream/normalize_streams.h
+++ b/includes/acl/compression/stream/normalize_streams.h
@@ -30,10 +30,10 @@
 #include "acl/core/enum_utils.h"
 #include "acl/core/track_types.h"
 #include "acl/core/range_reduction_types.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
 #include "acl/compression/stream/clip_context.h"
 
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -44,16 +44,16 @@ namespace acl
 	{
 		inline TrackStreamRange calculate_track_range(const TrackStream& stream)
 		{
-			Vector4_32 min = vector_set(1e10F);
-			Vector4_32 max = vector_set(-1e10F);
+			rtm::vector4f min = rtm::vector_set(1e10F);
+			rtm::vector4f max = rtm::vector_set(-1e10F);
 
 			const uint32_t num_samples = stream.get_num_samples();
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				const Vector4_32 sample = stream.get_raw_sample<Vector4_32>(sample_index);
+				const rtm::vector4f sample = stream.get_raw_sample<rtm::vector4f>(sample_index);
 
-				min = vector_min(min, sample);
-				max = vector_max(max, sample);
+				min = rtm::vector_min(min, sample);
+				max = rtm::vector_max(max, sample);
 			}
 
 			return TrackStreamRange::from_min_max(min, max);
@@ -91,11 +91,11 @@ namespace acl
 
 	inline void extract_segment_bone_ranges(IAllocator& allocator, ClipContext& clip_context)
 	{
-		const Vector4_32 one = vector_set(1.0F);
-		const Vector4_32 zero = vector_zero_32();
+		const rtm::vector4f one = rtm::vector_set(1.0F);
+		const rtm::vector4f zero = rtm::vector_zero();
 		const float max_range_value_flt = float((1 << k_segment_range_reduction_num_bits_per_component) - 1);
-		const Vector4_32 max_range_value = vector_set(max_range_value_flt);
-		const Vector4_32 inv_max_range_value = vector_set(1.0F / max_range_value_flt);
+		const rtm::vector4f max_range_value = rtm::vector_set(max_range_value_flt);
+		const rtm::vector4f inv_max_range_value = rtm::vector_set(1.0F / max_range_value_flt);
 
 		// Segment ranges are always normalized and live between [0.0 ... 1.0]
 
@@ -104,37 +104,37 @@ namespace acl
 			// In our compressed format, we store the minimum value of the track range quantized on 8 bits.
 			// To get the best accuracy, we pick the value closest to the true minimum that is slightly lower.
 			// This is to ensure that we encompass the lowest value even after quantization.
-			const Vector4_32 range_min = range.get_min();
-			const Vector4_32 scaled_min = vector_mul(range_min, max_range_value);
-			const Vector4_32 quantized_min0 = vector_clamp(vector_floor(scaled_min), zero, max_range_value);
-			const Vector4_32 quantized_min1 = vector_max(vector_sub(quantized_min0, one), zero);
+			const rtm::vector4f range_min = range.get_min();
+			const rtm::vector4f scaled_min = rtm::vector_mul(range_min, max_range_value);
+			const rtm::vector4f quantized_min0 = rtm::vector_clamp(rtm::vector_floor(scaled_min), zero, max_range_value);
+			const rtm::vector4f quantized_min1 = rtm::vector_max(rtm::vector_sub(quantized_min0, one), zero);
 
-			const Vector4_32 padded_range_min0 = vector_mul(quantized_min0, inv_max_range_value);
-			const Vector4_32 padded_range_min1 = vector_mul(quantized_min1, inv_max_range_value);
+			const rtm::vector4f padded_range_min0 = rtm::vector_mul(quantized_min0, inv_max_range_value);
+			const rtm::vector4f padded_range_min1 = rtm::vector_mul(quantized_min1, inv_max_range_value);
 
 			// Check if min0 is below or equal to our original range minimum value, if it is, it is good
 			// enough to use otherwise min1 is guaranteed to be lower.
-			const Vector4_32 is_min0_lower_mask = vector_less_equal(padded_range_min0, range_min);
-			const Vector4_32 padded_range_min = vector_blend(is_min0_lower_mask, padded_range_min0, padded_range_min1);
+			const rtm::mask4i is_min0_lower_mask = rtm::vector_less_equal(padded_range_min0, range_min);
+			const rtm::vector4f padded_range_min = rtm::vector_select(is_min0_lower_mask, padded_range_min0, padded_range_min1);
 
 			// The story is different for the extent. We do not store the max, instead we use the extent
 			// for performance reasons: a single mul/add is required to reconstruct the original value.
 			// Now that our minimum value changed, our extent also changed.
 			// We want to pick the extent value that brings us closest to our original max value while
 			// being slightly larger to encompass it.
-			const Vector4_32 range_max = range.get_max();
-			const Vector4_32 range_extent = vector_sub(range_max, padded_range_min);
-			const Vector4_32 scaled_extent = vector_mul(range_extent, max_range_value);
-			const Vector4_32 quantized_extent0 = vector_clamp(vector_ceil(scaled_extent), zero, max_range_value);
-			const Vector4_32 quantized_extent1 = vector_min(vector_add(quantized_extent0, one), max_range_value);
+			const rtm::vector4f range_max = range.get_max();
+			const rtm::vector4f range_extent = rtm::vector_sub(range_max, padded_range_min);
+			const rtm::vector4f scaled_extent = rtm::vector_mul(range_extent, max_range_value);
+			const rtm::vector4f quantized_extent0 = rtm::vector_clamp(rtm::vector_ceil(scaled_extent), zero, max_range_value);
+			const rtm::vector4f quantized_extent1 = rtm::vector_min(rtm::vector_add(quantized_extent0, one), max_range_value);
 
-			const Vector4_32 padded_range_extent0 = vector_mul(quantized_extent0, inv_max_range_value);
-			const Vector4_32 padded_range_extent1 = vector_mul(quantized_extent1, inv_max_range_value);
+			const rtm::vector4f padded_range_extent0 = rtm::vector_mul(quantized_extent0, inv_max_range_value);
+			const rtm::vector4f padded_range_extent1 = rtm::vector_mul(quantized_extent1, inv_max_range_value);
 
 			// Check if extent0 is above or equal to our original range maximum value, if it is, it is good
 			// enough to use otherwise extent1 is guaranteed to be higher.
-			const Vector4_32 is_extent0_higher_mask = vector_greater_equal(padded_range_extent0, range_max);
-			const Vector4_32 padded_range_extent = vector_blend(is_extent0_higher_mask, padded_range_extent0, padded_range_extent1);
+			const rtm::mask4i is_extent0_higher_mask = rtm::vector_greater_equal(padded_range_extent0, range_max);
+			const rtm::vector4f padded_range_extent = rtm::vector_select(is_extent0_higher_mask, padded_range_extent0, padded_range_extent1);
 
 			return TrackStreamRange::from_min_extent(padded_range_min, padded_range_extent);
 		};
@@ -162,30 +162,30 @@ namespace acl
 		}
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL normalize_sample(Vector4_32Arg0 sample, const TrackStreamRange& range)
+	inline rtm::vector4f RTM_SIMD_CALL normalize_sample(rtm::vector4f_arg0 sample, const TrackStreamRange& range)
 	{
-		const Vector4_32 range_min = range.get_min();
-		const Vector4_32 range_extent = range.get_extent();
-		const Vector4_32 is_range_zero_mask = vector_less_than(range_extent, vector_set(0.000000001F));
+		const rtm::vector4f range_min = range.get_min();
+		const rtm::vector4f range_extent = range.get_extent();
+		const rtm::mask4i is_range_zero_mask = rtm::vector_less_than(range_extent, rtm::vector_set(0.000000001F));
 
-		Vector4_32 normalized_sample = vector_div(vector_sub(sample, range_min), range_extent);
+		rtm::vector4f normalized_sample = rtm::vector_div(rtm::vector_sub(sample, range_min), range_extent);
 		// Clamp because the division might be imprecise
-		normalized_sample = vector_min(normalized_sample, vector_set(1.0F));
-		return vector_blend(is_range_zero_mask, vector_zero_32(), normalized_sample);
+		normalized_sample = rtm::vector_min(normalized_sample, rtm::vector_set(1.0F));
+		return rtm::vector_select(is_range_zero_mask, rtm::vector_zero(), normalized_sample);
 	}
 
 	inline void normalize_rotation_streams(BoneStreams* bone_streams, const BoneRanges* bone_ranges, uint16_t num_bones)
 	{
-		const Vector4_32 one = vector_set(1.0F);
-		const Vector4_32 zero = vector_zero_32();
+		const rtm::vector4f one = rtm::vector_set(1.0F);
+		const rtm::vector4f zero = rtm::vector_zero();
 
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
 			BoneStreams& bone_stream = bone_streams[bone_index];
 			const BoneRanges& bone_range = bone_ranges[bone_index];
 
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(Vector4_32), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(bone_stream.rotations.get_sample_size() == sizeof(rtm::vector4f), "Unexpected rotation sample size. %u != %u", bone_stream.rotations.get_sample_size(), sizeof(rtm::vector4f));
 
 			// Constant or default tracks are not normalized
 			if (bone_stream.is_rotation_constant)
@@ -193,32 +193,32 @@ namespace acl
 
 			const uint32_t num_samples = bone_stream.rotations.get_num_samples();
 
-			const Vector4_32 range_min = bone_range.rotation.get_min();
-			const Vector4_32 range_extent = bone_range.rotation.get_extent();
-			const Vector4_32 is_range_zero_mask = vector_less_than(range_extent, vector_set(0.000000001F));
+			const rtm::vector4f range_min = bone_range.rotation.get_min();
+			const rtm::vector4f range_extent = bone_range.rotation.get_extent();
+			const rtm::mask4i is_range_zero_mask = rtm::vector_less_than(range_extent, rtm::vector_set(0.000000001F));
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
 				// normalized value is between [0.0 .. 1.0]
 				// value = (normalized value * range extent) + range min
 				// normalized value = (value - range min) / range extent
-				const Vector4_32 rotation = bone_stream.rotations.get_raw_sample<Vector4_32>(sample_index);
-				Vector4_32 normalized_rotation = vector_div(vector_sub(rotation, range_min), range_extent);
+				const rtm::vector4f rotation = bone_stream.rotations.get_raw_sample<rtm::vector4f>(sample_index);
+				rtm::vector4f normalized_rotation = rtm::vector_div(rtm::vector_sub(rotation, range_min), range_extent);
 				// Clamp because the division might be imprecise
-				normalized_rotation = vector_min(normalized_rotation, one);
-				normalized_rotation = vector_blend(is_range_zero_mask, zero, normalized_rotation);
+				normalized_rotation = rtm::vector_min(normalized_rotation, one);
+				normalized_rotation = rtm::vector_select(is_range_zero_mask, zero, normalized_rotation);
 
 #if defined(ACL_HAS_ASSERT_CHECKS)
 				switch (bone_stream.rotations.get_rotation_format())
 				{
 				case RotationFormat8::Quat_128:
-					ACL_ASSERT(vector_all_greater_equal(normalized_rotation, zero) && vector_all_less_equal(normalized_rotation, one), "Invalid normalized rotation. 0.0 <= [%f, %f, %f, %f] <= 1.0", vector_get_x(normalized_rotation), vector_get_y(normalized_rotation), vector_get_z(normalized_rotation), vector_get_w(normalized_rotation));
+					ACL_ASSERT(rtm::vector_all_greater_equal(normalized_rotation, zero) && rtm::vector_all_less_equal(normalized_rotation, one), "Invalid normalized rotation. 0.0 <= [%f, %f, %f, %f] <= 1.0", rtm::vector_get_x(normalized_rotation), rtm::vector_get_y(normalized_rotation), rtm::vector_get_z(normalized_rotation), rtm::vector_get_w(normalized_rotation));
 					break;
 				case RotationFormat8::QuatDropW_96:
 				case RotationFormat8::QuatDropW_48:
 				case RotationFormat8::QuatDropW_32:
 				case RotationFormat8::QuatDropW_Variable:
-					ACL_ASSERT(vector_all_greater_equal3(normalized_rotation, zero) && vector_all_less_equal3(normalized_rotation, one), "Invalid normalized rotation. 0.0 <= [%f, %f, %f] <= 1.0", vector_get_x(normalized_rotation), vector_get_y(normalized_rotation), vector_get_z(normalized_rotation));
+					ACL_ASSERT(rtm::vector_all_greater_equal3(normalized_rotation, zero) && rtm::vector_all_less_equal3(normalized_rotation, one), "Invalid normalized rotation. 0.0 <= [%f, %f, %f] <= 1.0", rtm::vector_get_x(normalized_rotation), rtm::vector_get_y(normalized_rotation), rtm::vector_get_z(normalized_rotation));
 					break;
 				}
 #endif
@@ -230,16 +230,16 @@ namespace acl
 
 	inline void normalize_translation_streams(BoneStreams* bone_streams, const BoneRanges* bone_ranges, uint16_t num_bones)
 	{
-		const Vector4_32 one = vector_set(1.0F);
-		const Vector4_32 zero = vector_zero_32();
+		const rtm::vector4f one = rtm::vector_set(1.0F);
+		const rtm::vector4f zero = rtm::vector_zero();
 
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
 			BoneStreams& bone_stream = bone_streams[bone_index];
 			const BoneRanges& bone_range = bone_ranges[bone_index];
 
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(bone_stream.translations.get_sample_size() == sizeof(Vector4_32), "Unexpected translation sample size. %u != %u", bone_stream.translations.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(bone_stream.translations.get_sample_size() == sizeof(rtm::vector4f), "Unexpected translation sample size. %u != %u", bone_stream.translations.get_sample_size(), sizeof(rtm::vector4f));
 
 			// Constant or default tracks are not normalized
 			if (bone_stream.is_translation_constant)
@@ -247,22 +247,22 @@ namespace acl
 
 			const uint32_t num_samples = bone_stream.translations.get_num_samples();
 
-			const Vector4_32 range_min = bone_range.translation.get_min();
-			const Vector4_32 range_extent = bone_range.translation.get_extent();
-			const Vector4_32 is_range_zero_mask = vector_less_than(range_extent, vector_set(0.000000001F));
+			const rtm::vector4f range_min = bone_range.translation.get_min();
+			const rtm::vector4f range_extent = bone_range.translation.get_extent();
+			const rtm::mask4i is_range_zero_mask = rtm::vector_less_than(range_extent, rtm::vector_set(0.000000001F));
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
 				// normalized value is between [0.0 .. 1.0]
 				// value = (normalized value * range extent) + range min
 				// normalized value = (value - range min) / range extent
-				const Vector4_32 translation = bone_stream.translations.get_raw_sample<Vector4_32>(sample_index);
-				Vector4_32 normalized_translation = vector_div(vector_sub(translation, range_min), range_extent);
+				const rtm::vector4f translation = bone_stream.translations.get_raw_sample<rtm::vector4f>(sample_index);
+				rtm::vector4f normalized_translation = rtm::vector_div(rtm::vector_sub(translation, range_min), range_extent);
 				// Clamp because the division might be imprecise
-				normalized_translation = vector_min(normalized_translation, one);
-				normalized_translation = vector_blend(is_range_zero_mask, zero, normalized_translation);
+				normalized_translation = rtm::vector_min(normalized_translation, one);
+				normalized_translation = rtm::vector_select(is_range_zero_mask, zero, normalized_translation);
 
-				ACL_ASSERT(vector_all_greater_equal3(normalized_translation, zero) && vector_all_less_equal3(normalized_translation, one), "Invalid normalized translation. 0.0 <= [%f, %f, %f] <= 1.0", vector_get_x(normalized_translation), vector_get_y(normalized_translation), vector_get_z(normalized_translation));
+				ACL_ASSERT(rtm::vector_all_greater_equal3(normalized_translation, zero) && rtm::vector_all_less_equal3(normalized_translation, one), "Invalid normalized translation. 0.0 <= [%f, %f, %f] <= 1.0", rtm::vector_get_x(normalized_translation), rtm::vector_get_y(normalized_translation), rtm::vector_get_z(normalized_translation));
 
 				bone_stream.translations.set_raw_sample(sample_index, normalized_translation);
 			}
@@ -271,16 +271,16 @@ namespace acl
 
 	inline void normalize_scale_streams(BoneStreams* bone_streams, const BoneRanges* bone_ranges, uint16_t num_bones)
 	{
-		const Vector4_32 one = vector_set(1.0F);
-		const Vector4_32 zero = vector_zero_32();
+		const rtm::vector4f one = rtm::vector_set(1.0F);
+		const rtm::vector4f zero = rtm::vector_zero();
 
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
 			BoneStreams& bone_stream = bone_streams[bone_index];
 			const BoneRanges& bone_range = bone_ranges[bone_index];
 
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(bone_stream.scales.get_sample_size() == sizeof(Vector4_32), "Unexpected scale sample size. %u != %u", bone_stream.scales.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(bone_stream.scales.get_sample_size() == sizeof(rtm::vector4f), "Unexpected scale sample size. %u != %u", bone_stream.scales.get_sample_size(), sizeof(rtm::vector4f));
 
 			// Constant or default tracks are not normalized
 			if (bone_stream.is_scale_constant)
@@ -288,22 +288,22 @@ namespace acl
 
 			const uint32_t num_samples = bone_stream.scales.get_num_samples();
 
-			const Vector4_32 range_min = bone_range.scale.get_min();
-			const Vector4_32 range_extent = bone_range.scale.get_extent();
-			const Vector4_32 is_range_zero_mask = vector_less_than(range_extent, vector_set(0.000000001F));
+			const rtm::vector4f range_min = bone_range.scale.get_min();
+			const rtm::vector4f range_extent = bone_range.scale.get_extent();
+			const rtm::mask4i is_range_zero_mask = rtm::vector_less_than(range_extent, rtm::vector_set(0.000000001F));
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
 				// normalized value is between [0.0 .. 1.0]
 				// value = (normalized value * range extent) + range min
 				// normalized value = (value - range min) / range extent
-				const Vector4_32 scale = bone_stream.scales.get_raw_sample<Vector4_32>(sample_index);
-				Vector4_32 normalized_scale = vector_div(vector_sub(scale, range_min), range_extent);
+				const rtm::vector4f scale = bone_stream.scales.get_raw_sample<rtm::vector4f>(sample_index);
+				rtm::vector4f normalized_scale = rtm::vector_div(rtm::vector_sub(scale, range_min), range_extent);
 				// Clamp because the division might be imprecise
-				normalized_scale = vector_min(normalized_scale, one);
-				normalized_scale = vector_blend(is_range_zero_mask, zero, normalized_scale);
+				normalized_scale = rtm::vector_min(normalized_scale, one);
+				normalized_scale = rtm::vector_select(is_range_zero_mask, zero, normalized_scale);
 
-				ACL_ASSERT(vector_all_greater_equal3(normalized_scale, zero) && vector_all_less_equal3(normalized_scale, one), "Invalid normalized scale. 0.0 <= [%f, %f, %f] <= 1.0", vector_get_x(normalized_scale), vector_get_y(normalized_scale), vector_get_z(normalized_scale));
+				ACL_ASSERT(rtm::vector_all_greater_equal3(normalized_scale, zero) && rtm::vector_all_less_equal3(normalized_scale, one), "Invalid normalized scale. 0.0 <= [%f, %f, %f] <= 1.0", rtm::vector_get_x(normalized_scale), rtm::vector_get_y(normalized_scale), rtm::vector_get_z(normalized_scale));
 
 				bone_stream.scales.set_raw_sample(sample_index, normalized_scale);
 			}
diff --git a/includes/acl/compression/stream/quantize_streams.h b/includes/acl/compression/stream/quantize_streams.h
--- a/includes/acl/compression/stream/quantize_streams.h
+++ b/includes/acl/compression/stream/quantize_streams.h
@@ -28,9 +28,7 @@
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
 #include "acl/core/utils.h"
-#include "acl/math/quat_32.h"
 #include "acl/math/quat_packing.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/vector4_packing.h"
 #include "acl/compression/impl/track_bit_rate_database.h"
 #include "acl/compression/impl/transform_bit_rate_permutations.h"
@@ -41,6 +39,9 @@
 #include "acl/compression/skeleton_error_metric.h"
 #include "acl/compression/compression_settings.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstddef>
 #include <cstdint>
 
@@ -78,9 +79,9 @@ namespace acl
 
 			const BoneStreams* raw_bone_streams;
 
-			Transform_32* additive_local_pose;
-			Transform_32* raw_local_pose;
-			Transform_32* lossy_local_pose;
+			rtm::qvvf* additive_local_pose;
+			rtm::qvvf* raw_local_pose;
+			rtm::qvvf* lossy_local_pose;
 
 			BoneBitRate* bit_rate_per_bone;
 
@@ -108,9 +109,9 @@ namespace acl
 				local_query.bind(database);
 				object_query.bind(database);
 
-				additive_local_pose = clip_.has_additive_base ? allocate_type_array<Transform_32>(allocator, num_bones) : nullptr;
-				raw_local_pose = allocate_type_array<Transform_32>(allocator, num_bones);
-				lossy_local_pose = allocate_type_array<Transform_32>(allocator, num_bones);
+				additive_local_pose = clip_.has_additive_base ? allocate_type_array<rtm::qvvf>(allocator, num_bones) : nullptr;
+				raw_local_pose = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+				lossy_local_pose = allocate_type_array<rtm::qvvf>(allocator, num_bones);
 				bit_rate_per_bone = allocate_type_array<BoneBitRate>(allocator, num_bones);
 			}
 
@@ -141,8 +142,8 @@ namespace acl
 
 		inline void quantize_fixed_rotation_stream(IAllocator& allocator, const RotationTrackStream& raw_stream, RotationFormat8 rotation_format, bool are_rotations_normalized, RotationTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected rotation sample size. %u != %u", raw_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected rotation sample size. %u != %u", raw_stream.get_sample_size(), sizeof(rtm::vector4f));
 
 			const uint32_t num_samples = raw_stream.get_num_samples();
 			const uint32_t rotation_sample_size = get_packed_rotation_size(rotation_format);
@@ -151,25 +152,25 @@ namespace acl
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				const Quat_32 rotation = raw_stream.get_raw_sample<Quat_32>(sample_index);
+				const rtm::quatf rotation = raw_stream.get_raw_sample<rtm::quatf>(sample_index);
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(sample_index);
 
 				switch (rotation_format)
 				{
 				case RotationFormat8::Quat_128:
-					pack_vector4_128(quat_to_vector(rotation), quantized_ptr);
+					pack_vector4_128(rtm::quat_to_vector(rotation), quantized_ptr);
 					break;
 				case RotationFormat8::QuatDropW_96:
-					pack_vector3_96(quat_to_vector(rotation), quantized_ptr);
+					pack_vector3_96(rtm::quat_to_vector(rotation), quantized_ptr);
 					break;
 				case RotationFormat8::QuatDropW_48:
 					if (are_rotations_normalized)
-						pack_vector3_u48_unsafe(quat_to_vector(rotation), quantized_ptr);
+						pack_vector3_u48_unsafe(rtm::quat_to_vector(rotation), quantized_ptr);
 					else
-						pack_vector3_s48_unsafe(quat_to_vector(rotation), quantized_ptr);
+						pack_vector3_s48_unsafe(rtm::quat_to_vector(rotation), quantized_ptr);
 					break;
 				case RotationFormat8::QuatDropW_32:
-					pack_vector3_32(quat_to_vector(rotation), 11, 11, 10, are_rotations_normalized, quantized_ptr);
+					pack_vector3_32(rtm::quat_to_vector(rotation), 11, 11, 10, are_rotations_normalized, quantized_ptr);
 					break;
 				case RotationFormat8::QuatDropW_Variable:
 				default:
@@ -197,8 +198,8 @@ namespace acl
 
 		inline void quantize_variable_rotation_stream(QuantizationContext& context, const RotationTrackStream& raw_clip_stream, const RotationTrackStream& raw_segment_stream, const TrackStreamRange& clip_range, uint8_t bit_rate, bool are_rotations_normalized, RotationTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected rotation sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected rotation sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(rtm::vector4f));
 
 			const uint32_t num_samples = is_constant_bit_rate(bit_rate) ? 1 : raw_segment_stream.get_num_samples();
 			const uint32_t sample_size = sizeof(uint64_t) * 2;
@@ -209,10 +210,10 @@ namespace acl
 			{
 				ACL_ASSERT(are_rotations_normalized, "Cannot drop a constant track if it isn't normalized");
 
-				Vector4_32 rotation = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index);
+				rtm::vector4f rotation = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index);
 				rotation = convert_rotation(rotation, RotationFormat8::Quat_128, RotationFormat8::QuatDropW_Variable);
 
-				const Vector4_32 normalized_rotation = normalize_sample(rotation, clip_range);
+				const rtm::vector4f normalized_rotation = normalize_sample(rotation, clip_range);
 
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(0);
 				pack_vector3_u48_unsafe(normalized_rotation, quantized_ptr);
@@ -227,17 +228,17 @@ namespace acl
 
 					if (is_raw_bit_rate(bit_rate))
 					{
-						Vector4_32 rotation = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index + sample_index);
+						rtm::vector4f rotation = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index + sample_index);
 						rotation = convert_rotation(rotation, RotationFormat8::Quat_128, RotationFormat8::QuatDropW_Variable);
 						pack_vector3_96(rotation, quantized_ptr);
 					}
 					else
 					{
-						const Quat_32 rotation = raw_segment_stream.get_raw_sample<Quat_32>(sample_index);
+						const rtm::quatf rotation = raw_segment_stream.get_raw_sample<rtm::quatf>(sample_index);
 						if (are_rotations_normalized)
-							pack_vector3_uXX_unsafe(quat_to_vector(rotation), num_bits_at_bit_rate, quantized_ptr);
+							pack_vector3_uXX_unsafe(rtm::quat_to_vector(rotation), num_bits_at_bit_rate, quantized_ptr);
 						else
-							pack_vector3_sXX_unsafe(quat_to_vector(rotation), num_bits_at_bit_rate, quantized_ptr);
+							pack_vector3_sXX_unsafe(rtm::quat_to_vector(rotation), num_bits_at_bit_rate, quantized_ptr);
 					}
 				}
 			}
@@ -270,8 +271,8 @@ namespace acl
 
 		inline void quantize_fixed_translation_stream(IAllocator& allocator, const TranslationTrackStream& raw_stream, VectorFormat8 translation_format, TranslationTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected translation sample size. %u != %u", raw_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected translation sample size. %u != %u", raw_stream.get_sample_size(), sizeof(rtm::vector4f));
 			ACL_ASSERT(raw_stream.get_vector_format() == VectorFormat8::Vector3_96, "Expected a Vector3_96 vector format, found: %s", get_vector_format_name(raw_stream.get_vector_format()));
 
 			const uint32_t num_samples = raw_stream.get_num_samples();
@@ -281,7 +282,7 @@ namespace acl
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				const Vector4_32 translation = raw_stream.get_raw_sample<Vector4_32>(sample_index);
+				const rtm::vector4f translation = raw_stream.get_raw_sample<rtm::vector4f>(sample_index);
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(sample_index);
 
 				switch (translation_format)
@@ -323,8 +324,8 @@ namespace acl
 
 		inline void quantize_variable_translation_stream(QuantizationContext& context, const TranslationTrackStream& raw_clip_stream, const TranslationTrackStream& raw_segment_stream, const TrackStreamRange& clip_range, uint8_t bit_rate, TranslationTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected translation sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected translation sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(rtm::vector4f));
 			ACL_ASSERT(raw_segment_stream.get_vector_format() == VectorFormat8::Vector3_96, "Expected a Vector3_96 vector format, found: %s", get_vector_format_name(raw_segment_stream.get_vector_format()));
 
 			const uint32_t num_samples = is_constant_bit_rate(bit_rate) ? 1 : raw_segment_stream.get_num_samples();
@@ -334,8 +335,8 @@ namespace acl
 
 			if (is_constant_bit_rate(bit_rate))
 			{
-				const Vector4_32 translation = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index);
-				const Vector4_32 normalized_translation = normalize_sample(translation, clip_range);
+				const rtm::vector4f translation = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index);
+				const rtm::vector4f normalized_translation = normalize_sample(translation, clip_range);
 
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(0);
 				pack_vector3_u48_unsafe(normalized_translation, quantized_ptr);
@@ -350,12 +351,12 @@ namespace acl
 
 					if (is_raw_bit_rate(bit_rate))
 					{
-						const Vector4_32 translation = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index + sample_index);
+						const rtm::vector4f translation = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index + sample_index);
 						pack_vector3_96(translation, quantized_ptr);
 					}
 					else
 					{
-						const Vector4_32 translation = raw_segment_stream.get_raw_sample<Vector4_32>(sample_index);
+						const rtm::vector4f translation = raw_segment_stream.get_raw_sample<rtm::vector4f>(sample_index);
 						pack_vector3_uXX_unsafe(translation, num_bits_at_bit_rate, quantized_ptr);
 					}
 				}
@@ -387,8 +388,8 @@ namespace acl
 
 		inline void quantize_fixed_scale_stream(IAllocator& allocator, const ScaleTrackStream& raw_stream, VectorFormat8 scale_format, ScaleTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected scale sample size. %u != %u", raw_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected scale sample size. %u != %u", raw_stream.get_sample_size(), sizeof(rtm::vector4f));
 			ACL_ASSERT(raw_stream.get_vector_format() == VectorFormat8::Vector3_96, "Expected a Vector3_96 vector format, found: %s", get_vector_format_name(raw_stream.get_vector_format()));
 
 			const uint32_t num_samples = raw_stream.get_num_samples();
@@ -398,7 +399,7 @@ namespace acl
 
 			for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 			{
-				const Vector4_32 scale = raw_stream.get_raw_sample<Vector4_32>(sample_index);
+				const rtm::vector4f scale = raw_stream.get_raw_sample<rtm::vector4f>(sample_index);
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(sample_index);
 
 				switch (scale_format)
@@ -440,8 +441,8 @@ namespace acl
 
 		inline void quantize_variable_scale_stream(QuantizationContext& context, const ScaleTrackStream& raw_clip_stream, const ScaleTrackStream& raw_segment_stream, const TrackStreamRange& clip_range, uint8_t bit_rate, ScaleTrackStream& out_quantized_stream)
 		{
-			// We expect all our samples to have the same width of sizeof(Vector4_32)
-			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(Vector4_32), "Unexpected scale sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(Vector4_32));
+			// We expect all our samples to have the same width of sizeof(rtm::vector4f)
+			ACL_ASSERT(raw_segment_stream.get_sample_size() == sizeof(rtm::vector4f), "Unexpected scale sample size. %u != %u", raw_segment_stream.get_sample_size(), sizeof(rtm::vector4f));
 			ACL_ASSERT(raw_segment_stream.get_vector_format() == VectorFormat8::Vector3_96, "Expected a Vector3_96 vector format, found: %s", get_vector_format_name(raw_segment_stream.get_vector_format()));
 
 			const uint32_t num_samples = is_constant_bit_rate(bit_rate) ? 1 : raw_segment_stream.get_num_samples();
@@ -451,8 +452,8 @@ namespace acl
 
 			if (is_constant_bit_rate(bit_rate))
 			{
-				const Vector4_32 scale = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index);
-				const Vector4_32 normalized_scale = normalize_sample(scale, clip_range);
+				const rtm::vector4f scale = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index);
+				const rtm::vector4f normalized_scale = normalize_sample(scale, clip_range);
 
 				uint8_t* quantized_ptr = quantized_stream.get_raw_sample_ptr(0);
 				pack_vector3_u48_unsafe(normalized_scale, quantized_ptr);
@@ -467,12 +468,12 @@ namespace acl
 
 					if (is_raw_bit_rate(bit_rate))
 					{
-						const Vector4_32 scale = raw_clip_stream.get_raw_sample<Vector4_32>(context.segment_sample_start_index + sample_index);
+						const rtm::vector4f scale = raw_clip_stream.get_raw_sample<rtm::vector4f>(context.segment_sample_start_index + sample_index);
 						pack_vector3_96(scale, quantized_ptr);
 					}
 					else
 					{
-						const Vector4_32 scale = raw_segment_stream.get_raw_sample<Vector4_32>(sample_index);
+						const rtm::vector4f scale = raw_segment_stream.get_raw_sample<rtm::vector4f>(sample_index);
 						pack_vector3_uXX_unsafe(scale, num_bits_at_bit_rate, quantized_ptr);
 					}
 				}
@@ -517,7 +518,7 @@ namespace acl
 			{
 				// Sample our streams and calculate the error
 				// The sample time is calculated from the full clip duration to be consistent with decompression
-				const float sample_time = min(float(context.segment_sample_start_index + sample_index) / context.sample_rate, context.clip_duration);
+				const float sample_time = rtm::scalar_min(float(context.segment_sample_start_index + sample_index) / context.sample_rate, context.clip_duration);
 
 				sample_stream(context.raw_bone_streams, context.num_bones, sample_time, target_bone_index, context.raw_local_pose);
 
@@ -536,7 +537,7 @@ namespace acl
 				else
 					error = error_metric.calculate_local_bone_error_no_scale(context.skeleton, context.raw_local_pose, context.additive_local_pose, context.lossy_local_pose, target_bone_index);
 
-				max_error = max(max_error, error);
+				max_error = rtm::scalar_max(max_error, error);
 				if (stop_condition == error_scan_stop_condition::until_error_too_high && error >= settings.error_threshold)
 					break;
 			}
@@ -557,7 +558,7 @@ namespace acl
 			{
 				// Sample our streams and calculate the error
 				// The sample time is calculated from the full clip duration to be consistent with decompression
-				const float sample_time = min(float(context.segment_sample_start_index + sample_index) / context.sample_rate, context.clip_duration);
+				const float sample_time = rtm::scalar_min(float(context.segment_sample_start_index + sample_index) / context.sample_rate, context.clip_duration);
 
 				sample_streams_hierarchical(context.raw_bone_streams, context.num_bones, sample_time, target_bone_index, context.raw_local_pose);
 
@@ -576,7 +577,7 @@ namespace acl
 				else
 					error = error_metric.calculate_object_bone_error_no_scale(context.skeleton, context.raw_local_pose, context.additive_local_pose, context.lossy_local_pose, target_bone_index);
 
-				max_error = max(max_error, error);
+				max_error = rtm::scalar_max(max_error, error);
 				if (stop_condition == error_scan_stop_condition::until_error_too_high && error >= settings.error_threshold)
 					break;
 			}
diff --git a/includes/acl/compression/stream/sample_streams.h b/includes/acl/compression/stream/sample_streams.h
--- a/includes/acl/compression/stream/sample_streams.h
+++ b/includes/acl/compression/stream/sample_streams.h
@@ -28,15 +28,16 @@
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
 #include "acl/core/utils.h"
-#include "acl/math/quat_32.h"
 #include "acl/math/quat_packing.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/vector4_packing.h"
-#include "acl/math/transform_32.h"
 #include "acl/compression/stream/track_stream.h"
 #include "acl/compression/stream/normalize_streams.h"
 #include "acl/compression/stream/convert_rotation_streams.h"
 
+#include <rtm/quatf.h>
+#include <rtm/qvvf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -45,7 +46,7 @@ namespace acl
 {
 	namespace impl
 	{
-		inline Vector4_32 ACL_SIMD_CALL load_rotation_sample(const uint8_t* ptr, RotationFormat8 format, uint8_t bit_rate, bool is_normalized)
+		inline rtm::vector4f RTM_SIMD_CALL load_rotation_sample(const uint8_t* ptr, RotationFormat8 format, uint8_t bit_rate, bool is_normalized)
 		{
 			switch (format)
 			{
@@ -77,11 +78,11 @@ namespace acl
 			}
 			default:
 				ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(format));
-				return vector_zero_32();
+				return rtm::vector_zero();
 			}
 		}
 
-		inline Vector4_32 ACL_SIMD_CALL load_vector_sample(const uint8_t* ptr, VectorFormat8 format, uint8_t bit_rate)
+		inline rtm::vector4f RTM_SIMD_CALL load_vector_sample(const uint8_t* ptr, VectorFormat8 format, uint8_t bit_rate)
 		{
 			switch (format)
 			{
@@ -104,29 +105,29 @@ namespace acl
 				}
 			default:
 				ACL_ASSERT(false, "Invalid or unsupported vector format: %s", get_vector_format_name(format));
-				return vector_zero_32();
+				return rtm::vector_zero();
 			}
 		}
 
-		inline Quat_32 ACL_SIMD_CALL rotation_to_quat_32(Vector4_32Arg0 rotation, RotationFormat8 format)
+		inline rtm::quatf RTM_SIMD_CALL rotation_to_quat_32(rtm::vector4f_arg0 rotation, RotationFormat8 format)
 		{
 			switch (format)
 			{
 			case RotationFormat8::Quat_128:
-				return vector_to_quat(rotation);
+				return rtm::vector_to_quat(rotation);
 			case RotationFormat8::QuatDropW_96:
 			case RotationFormat8::QuatDropW_48:
 			case RotationFormat8::QuatDropW_32:
 			case RotationFormat8::QuatDropW_Variable:
-				return quat_from_positive_w(rotation);
+				return rtm::quat_from_positive_w(rotation);
 			default:
 				ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(format));
-				return quat_identity_32();
+				return rtm::quat_identity();
 			}
 		}
 	}
 
-	inline Quat_32 ACL_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, uint32_t sample_index)
+	inline rtm::quatf RTM_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, uint32_t sample_index)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -140,7 +141,7 @@ namespace acl
 
 		const uint8_t* quantized_ptr = bone_steams.rotations.get_raw_sample_ptr(sample_index);
 
-		Vector4_32 packed_rotation = impl::load_rotation_sample(quantized_ptr, format, bit_rate, are_rotations_normalized);
+		rtm::vector4f packed_rotation = impl::load_rotation_sample(quantized_ptr, format, bit_rate, are_rotations_normalized);
 
 		if (are_rotations_normalized && !is_raw_bit_rate(bit_rate))
 		{
@@ -148,31 +149,31 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.rotation.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.rotation.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.rotation.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.rotation.get_extent();
 
-				packed_rotation = vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
+				packed_rotation = rtm::vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.rotation.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.rotation.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.rotation.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.rotation.get_extent();
 
-			packed_rotation = vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
+			packed_rotation = rtm::vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
 		}
 
 		return impl::rotation_to_quat_32(packed_rotation, format);
 	}
 
-	inline Quat_32 ACL_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
+	inline rtm::quatf RTM_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
 		const bool are_rotations_normalized = clip_context->are_rotations_normalized;
 		const RotationFormat8 format = bone_steams.rotations.get_rotation_format();
 
-		Vector4_32 rotation;
+		rtm::vector4f rotation;
 		if (is_constant_bit_rate(bit_rate))
 		{
 			const uint8_t* quantized_ptr = raw_bone_steams.rotations.get_raw_sample_ptr(segment->clip_sample_offset);
@@ -193,7 +194,7 @@ namespace acl
 
 		// Pack and unpack at our desired bit rate
 		const uint32_t num_bits_at_bit_rate = get_num_bits_at_bit_rate(bit_rate);
-		Vector4_32 packed_rotation;
+		rtm::vector4f packed_rotation;
 
 		if (is_constant_bit_rate(bit_rate))
 		{
@@ -201,7 +202,7 @@ namespace acl
 			ACL_ASSERT(segment->are_rotations_normalized, "Cannot drop a constant track if it isn't normalized");
 
 			const BoneRanges& clip_bone_range = segment->clip->ranges[bone_steams.bone_index];
-			const Vector4_32 normalized_rotation = normalize_sample(rotation, clip_bone_range.rotation);
+			const rtm::vector4f normalized_rotation = normalize_sample(rotation, clip_bone_range.rotation);
 
 			packed_rotation = decay_vector3_u48(normalized_rotation);
 		}
@@ -218,24 +219,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.rotation.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.rotation.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.rotation.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.rotation.get_extent();
 
-				packed_rotation = vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
+				packed_rotation = rtm::vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.rotation.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.rotation.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.rotation.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.rotation.get_extent();
 
-			packed_rotation = vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
+			packed_rotation = rtm::vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
 		}
 
 		return impl::rotation_to_quat_32(packed_rotation, format);
 	}
 
-	inline Quat_32 ACL_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, uint32_t sample_index, RotationFormat8 desired_format)
+	inline rtm::quatf RTM_SIMD_CALL get_rotation_sample(const BoneStreams& bone_steams, uint32_t sample_index, RotationFormat8 desired_format)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -243,10 +244,10 @@ namespace acl
 		const uint8_t* quantized_ptr = bone_steams.rotations.get_raw_sample_ptr(sample_index);
 		const RotationFormat8 format = bone_steams.rotations.get_rotation_format();
 
-		const Vector4_32 rotation = impl::load_rotation_sample(quantized_ptr, format, 0, are_rotations_normalized);
+		const rtm::vector4f rotation = impl::load_rotation_sample(quantized_ptr, format, 0, are_rotations_normalized);
 
 		// Pack and unpack in our desired format
-		Vector4_32 packed_rotation;
+		rtm::vector4f packed_rotation;
 
 		switch (desired_format)
 		{
@@ -262,7 +263,7 @@ namespace acl
 			break;
 		default:
 			ACL_ASSERT(false, "Invalid or unsupported rotation format: %s", get_rotation_format_name(desired_format));
-			packed_rotation = vector_zero_32();
+			packed_rotation = rtm::vector_zero();
 			break;
 		}
 
@@ -272,24 +273,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.rotation.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.rotation.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.rotation.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.rotation.get_extent();
 
-				packed_rotation = vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
+				packed_rotation = rtm::vector_mul_add(packed_rotation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.rotation.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.rotation.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.rotation.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.rotation.get_extent();
 
-			packed_rotation = vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
+			packed_rotation = rtm::vector_mul_add(packed_rotation, clip_range_extent, clip_range_min);
 		}
 
 		return impl::rotation_to_quat_32(packed_rotation, format);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, uint32_t sample_index)
+	inline rtm::vector4f RTM_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, uint32_t sample_index)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -303,7 +304,7 @@ namespace acl
 
 		const uint8_t* quantized_ptr = bone_steams.translations.get_raw_sample_ptr(sample_index);
 
-		Vector4_32 packed_translation = impl::load_vector_sample(quantized_ptr, format, bit_rate);
+		rtm::vector4f packed_translation = impl::load_vector_sample(quantized_ptr, format, bit_rate);
 
 		if (are_translations_normalized && !is_raw_bit_rate(bit_rate))
 		{
@@ -311,24 +312,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.translation.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.translation.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.translation.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.translation.get_extent();
 
-				packed_translation = vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
+				packed_translation = rtm::vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.translation.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.translation.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.translation.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.translation.get_extent();
 
-			packed_translation = vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
+			packed_translation = rtm::vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
 		}
 
 		return packed_translation;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
+	inline rtm::vector4f RTM_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -342,19 +343,19 @@ namespace acl
 		else
 			quantized_ptr = bone_steams.translations.get_raw_sample_ptr(sample_index);
 
-		const Vector4_32 translation = impl::load_vector_sample(quantized_ptr, format, 0);
+		const rtm::vector4f translation = impl::load_vector_sample(quantized_ptr, format, 0);
 
 		ACL_ASSERT(clip_context->are_translations_normalized, "Translations must be normalized to support variable bit rates.");
 
 		// Pack and unpack at our desired bit rate
-		Vector4_32 packed_translation;
+		rtm::vector4f packed_translation;
 
 		if (is_constant_bit_rate(bit_rate))
 		{
 			ACL_ASSERT(segment->are_translations_normalized, "Translations must be normalized to support variable bit rates.");
 
 			const BoneRanges& clip_bone_range = segment->clip->ranges[bone_steams.bone_index];
-			const Vector4_32 normalized_translation = normalize_sample(translation, clip_bone_range.translation);
+			const rtm::vector4f normalized_translation = normalize_sample(translation, clip_bone_range.translation);
 
 			packed_translation = decay_vector3_u48(normalized_translation);
 		}
@@ -372,24 +373,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.translation.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.translation.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.translation.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.translation.get_extent();
 
-				packed_translation = vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
+				packed_translation = rtm::vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.translation.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.translation.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.translation.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.translation.get_extent();
 
-			packed_translation = vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
+			packed_translation = rtm::vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
 		}
 
 		return packed_translation;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, uint32_t sample_index, VectorFormat8 desired_format)
+	inline rtm::vector4f RTM_SIMD_CALL get_translation_sample(const BoneStreams& bone_steams, uint32_t sample_index, VectorFormat8 desired_format)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -397,10 +398,10 @@ namespace acl
 		const uint8_t* quantized_ptr = bone_steams.translations.get_raw_sample_ptr(sample_index);
 		const VectorFormat8 format = bone_steams.translations.get_vector_format();
 
-		const Vector4_32 translation = impl::load_vector_sample(quantized_ptr, format, 0);
+		const rtm::vector4f translation = impl::load_vector_sample(quantized_ptr, format, 0);
 
 		// Pack and unpack in our desired format
-		Vector4_32 packed_translation;
+		rtm::vector4f packed_translation;
 
 		switch (desired_format)
 		{
@@ -417,7 +418,7 @@ namespace acl
 			break;
 		default:
 			ACL_ASSERT(false, "Invalid or unsupported vector format: %s", get_vector_format_name(desired_format));
-			packed_translation = vector_zero_32();
+			packed_translation = rtm::vector_zero();
 			break;
 		}
 
@@ -427,24 +428,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				Vector4_32 segment_range_min = segment_bone_range.translation.get_min();
-				Vector4_32 segment_range_extent = segment_bone_range.translation.get_extent();
+				rtm::vector4f segment_range_min = segment_bone_range.translation.get_min();
+				rtm::vector4f segment_range_extent = segment_bone_range.translation.get_extent();
 
-				packed_translation = vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
+				packed_translation = rtm::vector_mul_add(packed_translation, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			Vector4_32 clip_range_min = clip_bone_range.translation.get_min();
-			Vector4_32 clip_range_extent = clip_bone_range.translation.get_extent();
+			rtm::vector4f clip_range_min = clip_bone_range.translation.get_min();
+			rtm::vector4f clip_range_extent = clip_bone_range.translation.get_extent();
 
-			packed_translation = vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
+			packed_translation = rtm::vector_mul_add(packed_translation, clip_range_extent, clip_range_min);
 		}
 
 		return packed_translation;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, uint32_t sample_index)
+	inline rtm::vector4f RTM_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, uint32_t sample_index)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -458,7 +459,7 @@ namespace acl
 
 		const uint8_t* quantized_ptr = bone_steams.scales.get_raw_sample_ptr(sample_index);
 
-		Vector4_32 packed_scale = impl::load_vector_sample(quantized_ptr, format, bit_rate);
+		rtm::vector4f packed_scale = impl::load_vector_sample(quantized_ptr, format, bit_rate);
 
 		if (are_scales_normalized && !is_raw_bit_rate(bit_rate))
 		{
@@ -466,24 +467,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.scale.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.scale.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.scale.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.scale.get_extent();
 
-				packed_scale = vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
+				packed_scale = rtm::vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.scale.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.scale.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.scale.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.scale.get_extent();
 
-			packed_scale = vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
+			packed_scale = rtm::vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
 		}
 
 		return packed_scale;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
+	inline rtm::vector4f RTM_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, const BoneStreams& raw_bone_steams, uint32_t sample_index, uint8_t bit_rate)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -497,19 +498,19 @@ namespace acl
 		else
 			quantized_ptr = bone_steams.scales.get_raw_sample_ptr(sample_index);
 
-		const Vector4_32 scale = impl::load_vector_sample(quantized_ptr, format, 0);
+		const rtm::vector4f scale = impl::load_vector_sample(quantized_ptr, format, 0);
 
 		ACL_ASSERT(clip_context->are_scales_normalized, "Scales must be normalized to support variable bit rates.");
 
 		// Pack and unpack at our desired bit rate
-		Vector4_32 packed_scale;
+		rtm::vector4f packed_scale;
 
 		if (is_constant_bit_rate(bit_rate))
 		{
 			ACL_ASSERT(segment->are_scales_normalized, "Translations must be normalized to support variable bit rates.");
 
 			const BoneRanges& clip_bone_range = segment->clip->ranges[bone_steams.bone_index];
-			const Vector4_32 normalized_scale = normalize_sample(scale, clip_bone_range.scale);
+			const rtm::vector4f normalized_scale = normalize_sample(scale, clip_bone_range.scale);
 
 			packed_scale = decay_vector3_u48(normalized_scale);
 		}
@@ -527,24 +528,24 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				const Vector4_32 segment_range_min = segment_bone_range.scale.get_min();
-				const Vector4_32 segment_range_extent = segment_bone_range.scale.get_extent();
+				const rtm::vector4f segment_range_min = segment_bone_range.scale.get_min();
+				const rtm::vector4f segment_range_extent = segment_bone_range.scale.get_extent();
 
-				packed_scale = vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
+				packed_scale = rtm::vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			const Vector4_32 clip_range_min = clip_bone_range.scale.get_min();
-			const Vector4_32 clip_range_extent = clip_bone_range.scale.get_extent();
+			const rtm::vector4f clip_range_min = clip_bone_range.scale.get_min();
+			const rtm::vector4f clip_range_extent = clip_bone_range.scale.get_extent();
 
-			packed_scale = vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
+			packed_scale = rtm::vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
 		}
 
 		return packed_scale;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, uint32_t sample_index, VectorFormat8 desired_format)
+	inline rtm::vector4f RTM_SIMD_CALL get_scale_sample(const BoneStreams& bone_steams, uint32_t sample_index, VectorFormat8 desired_format)
 	{
 		const SegmentContext* segment = bone_steams.segment;
 		const ClipContext* clip_context = segment->clip;
@@ -552,10 +553,10 @@ namespace acl
 		const uint8_t* quantized_ptr = bone_steams.scales.get_raw_sample_ptr(sample_index);
 		const VectorFormat8 format = bone_steams.scales.get_vector_format();
 
-		const Vector4_32 scale = impl::load_vector_sample(quantized_ptr, format, 0);
+		const rtm::vector4f scale = impl::load_vector_sample(quantized_ptr, format, 0);
 
 		// Pack and unpack in our desired format
-		Vector4_32 packed_scale;
+		rtm::vector4f packed_scale;
 
 		switch (desired_format)
 		{
@@ -582,18 +583,18 @@ namespace acl
 			{
 				const BoneRanges& segment_bone_range = segment->ranges[bone_steams.bone_index];
 
-				Vector4_32 segment_range_min = segment_bone_range.scale.get_min();
-				Vector4_32 segment_range_extent = segment_bone_range.scale.get_extent();
+				rtm::vector4f segment_range_min = segment_bone_range.scale.get_min();
+				rtm::vector4f segment_range_extent = segment_bone_range.scale.get_extent();
 
-				packed_scale = vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
+				packed_scale = rtm::vector_mul_add(packed_scale, segment_range_extent, segment_range_min);
 			}
 
 			const BoneRanges& clip_bone_range = clip_context->ranges[bone_steams.bone_index];
 
-			Vector4_32 clip_range_min = clip_bone_range.scale.get_min();
-			Vector4_32 clip_range_extent = clip_bone_range.scale.get_extent();
+			rtm::vector4f clip_range_min = clip_bone_range.scale.get_min();
+			rtm::vector4f clip_range_extent = clip_bone_range.scale.get_extent();
 
-			packed_scale = vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
+			packed_scale = rtm::vector_mul_add(packed_scale, clip_range_extent, clip_range_min);
 		}
 
 		return packed_scale;
@@ -642,13 +643,13 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Quat_32 ACL_SIMD_CALL sample_rotation(const sample_context& context, const BoneStreams& bone_stream)
+		ACL_FORCE_INLINE rtm::quatf RTM_SIMD_CALL sample_rotation(const sample_context& context, const BoneStreams& bone_stream)
 		{
-			Quat_32 rotation;
+			rtm::quatf rotation;
 			if (bone_stream.is_rotation_default)
-				rotation = quat_identity_32();
+				rotation = rtm::quat_identity();
 			else if (bone_stream.is_rotation_constant)
-				rotation = quat_normalize(get_rotation_sample(bone_stream, 0));
+				rotation = rtm::quat_normalize(get_rotation_sample(bone_stream, 0));
 			else
 			{
 				uint32_t key0;
@@ -668,26 +669,26 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				const Quat_32 sample0 = get_rotation_sample(bone_stream, key0);
+				const rtm::quatf sample0 = get_rotation_sample(bone_stream, key0);
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
 				{
-					const Quat_32 sample1 = get_rotation_sample(bone_stream, key1);
-					rotation = quat_lerp(sample0, sample1, interpolation_alpha);
+					const rtm::quatf sample1 = get_rotation_sample(bone_stream, key1);
+					rotation = rtm::quat_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
-					rotation = quat_normalize(sample0);
+					rotation = rtm::quat_normalize(sample0);
 			}
 
 			return rotation;
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Quat_32 ACL_SIMD_CALL sample_rotation(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_rotation_variable, RotationFormat8 rotation_format)
+		ACL_FORCE_INLINE rtm::quatf RTM_SIMD_CALL sample_rotation(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_rotation_variable, RotationFormat8 rotation_format)
 		{
-			Quat_32 rotation;
+			rtm::quatf rotation;
 			if (bone_stream.is_rotation_default)
-				rotation = quat_identity_32();
+				rotation = rtm::quat_identity();
 			else if (bone_stream.is_rotation_constant)
 			{
 				if (is_rotation_variable)
@@ -695,7 +696,7 @@ namespace acl
 				else
 					rotation = get_rotation_sample(raw_bone_stream, 0, rotation_format);
 
-				rotation = quat_normalize(rotation);
+				rotation = rtm::quat_normalize(rotation);
 			}
 			else
 			{
@@ -716,8 +717,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Quat_32 sample0;
-				Quat_32 sample1;
+				rtm::quatf sample0;
+				rtm::quatf sample1;
 				if (is_rotation_variable)
 				{
 					sample0 = get_rotation_sample(bone_stream, raw_bone_stream, key0, context.bit_rates.rotation);
@@ -734,20 +735,20 @@ namespace acl
 				}
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
-					rotation = quat_lerp(sample0, sample1, interpolation_alpha);
+					rotation = rtm::quat_lerp(sample0, sample1, interpolation_alpha);
 				else
-					rotation = quat_normalize(sample0);
+					rotation = rtm::quat_normalize(sample0);
 			}
 
 			return rotation;
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_translation(const sample_context& context, const BoneStreams& bone_stream)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_translation(const sample_context& context, const BoneStreams& bone_stream)
 		{
-			Vector4_32 translation;
+			rtm::vector4f translation;
 			if (bone_stream.is_translation_default)
-				translation = vector_zero_32();
+				translation = rtm::vector_zero();
 			else if (bone_stream.is_translation_constant)
 				translation = get_translation_sample(bone_stream, 0);
 			else
@@ -769,12 +770,12 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				const Vector4_32 sample0 = get_translation_sample(bone_stream, key0);
+				const rtm::vector4f sample0 = get_translation_sample(bone_stream, key0);
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
 				{
-					const Vector4_32 sample1 = get_translation_sample(bone_stream, key1);
-					translation = vector_lerp(sample0, sample1, interpolation_alpha);
+					const rtm::vector4f sample1 = get_translation_sample(bone_stream, key1);
+					translation = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
 					translation = sample0;
@@ -784,11 +785,11 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_translation(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_translation_variable, VectorFormat8 translation_format)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_translation(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_translation_variable, VectorFormat8 translation_format)
 		{
-			Vector4_32 translation;
+			rtm::vector4f translation;
 			if (bone_stream.is_translation_default)
-				translation = vector_zero_32();
+				translation = rtm::vector_zero();
 			else if (bone_stream.is_translation_constant)
 				translation = get_translation_sample(raw_bone_stream, 0, VectorFormat8::Vector3_96);
 			else
@@ -810,8 +811,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Vector4_32 sample0;
-				Vector4_32 sample1;
+				rtm::vector4f sample0;
+				rtm::vector4f sample1;
 				if (is_translation_variable)
 				{
 					sample0 = get_translation_sample(bone_stream, raw_bone_stream, key0, context.bit_rates.translation);
@@ -828,7 +829,7 @@ namespace acl
 				}
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
-					translation = vector_lerp(sample0, sample1, interpolation_alpha);
+					translation = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				else
 					translation = sample0;
 			}
@@ -837,9 +838,9 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_scale(const sample_context& context, const BoneStreams& bone_stream, Vector4_32Arg0 default_scale)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_scale(const sample_context& context, const BoneStreams& bone_stream, rtm::vector4f_arg0 default_scale)
 		{
-			Vector4_32 scale;
+			rtm::vector4f scale;
 			if (bone_stream.is_scale_default)
 				scale = default_scale;
 			else if (bone_stream.is_scale_constant)
@@ -863,12 +864,12 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				const Vector4_32 sample0 = get_scale_sample(bone_stream, key0);
+				const rtm::vector4f sample0 = get_scale_sample(bone_stream, key0);
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
 				{
-					const Vector4_32 sample1 = get_scale_sample(bone_stream, key1);
-					scale = vector_lerp(sample0, sample1, interpolation_alpha);
+					const rtm::vector4f sample1 = get_scale_sample(bone_stream, key1);
+					scale = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				}
 				else
 					scale = sample0;
@@ -878,9 +879,9 @@ namespace acl
 		}
 
 		template<SampleDistribution8 distribution>
-		ACL_FORCE_INLINE Vector4_32 ACL_SIMD_CALL sample_scale(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_scale_variable, VectorFormat8 scale_format, Vector4_32Arg0 default_scale)
+		ACL_FORCE_INLINE rtm::vector4f RTM_SIMD_CALL sample_scale(const sample_context& context, const BoneStreams& bone_stream, const BoneStreams& raw_bone_stream, bool is_scale_variable, VectorFormat8 scale_format, rtm::vector4f_arg0 default_scale)
 		{
-			Vector4_32 scale;
+			rtm::vector4f scale;
 			if (bone_stream.is_scale_default)
 				scale = default_scale;
 			else if (bone_stream.is_scale_constant)
@@ -904,8 +905,8 @@ namespace acl
 					interpolation_alpha = 0.0F;
 				}
 
-				Vector4_32 sample0;
-				Vector4_32 sample1;
+				rtm::vector4f sample0;
+				rtm::vector4f sample1;
 				if (is_scale_variable)
 				{
 					sample0 = get_scale_sample(bone_stream, raw_bone_stream, key0, context.bit_rates.scale);
@@ -922,7 +923,7 @@ namespace acl
 				}
 
 				if (static_condition<distribution == SampleDistribution8::Variable>::test())
-					scale = vector_lerp(sample0, sample1, interpolation_alpha);
+					scale = rtm::vector_lerp(sample0, sample1, interpolation_alpha);
 				else
 					scale = sample0;
 			}
@@ -931,10 +932,10 @@ namespace acl
 		}
 	}
 
-	inline void sample_streams(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, Transform_32* out_local_pose)
+	inline void sample_streams(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, rtm::qvvf* out_local_pose)
 	{
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -955,11 +956,11 @@ namespace acl
 
 				const BoneStreams& bone_stream = bone_streams[bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, default_scale) : default_scale;
 
-				out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 			}
 		}
 		else
@@ -970,21 +971,21 @@ namespace acl
 
 				const BoneStreams& bone_stream = bone_streams[bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, default_scale) : default_scale;
 
-				out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 			}
 		}
 	}
 
-	inline void sample_stream(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, uint16_t bone_index, Transform_32* out_local_pose)
+	inline void sample_stream(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, uint16_t bone_index, rtm::qvvf* out_local_pose)
 	{
 		(void)num_bones;
 
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -1000,9 +1001,9 @@ namespace acl
 
 		const BoneStreams& bone_stream = bone_streams[bone_index];
 
-		Quat_32 rotation;
-		Vector4_32 translation;
-		Vector4_32 scale;
+		rtm::quatf rotation;
+		rtm::vector4f translation;
+		rtm::vector4f scale;
 		if (segment_context->distribution == SampleDistribution8::Uniform)
 		{
 			rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream);
@@ -1016,15 +1017,15 @@ namespace acl
 			scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, default_scale) : default_scale;
 		}
 
-		out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+		out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 	}
 
-	inline void sample_streams_hierarchical(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, uint16_t bone_index, Transform_32* out_local_pose)
+	inline void sample_streams_hierarchical(const BoneStreams* bone_streams, uint16_t num_bones, float sample_time, uint16_t bone_index, rtm::qvvf* out_local_pose)
 	{
 		(void)num_bones;
 
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -1046,11 +1047,11 @@ namespace acl
 
 				const BoneStreams& bone_stream = bone_streams[current_bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, default_scale) : default_scale;
 
-				out_local_pose[current_bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[current_bone_index] = rtm::qvv_set(rotation, translation, scale);
 				current_bone_index = bone_stream.parent_bone_index;
 			}
 		}
@@ -1063,24 +1064,24 @@ namespace acl
 
 				const BoneStreams& bone_stream = bone_streams[current_bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, default_scale) : default_scale;
 
-				out_local_pose[current_bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[current_bone_index] = rtm::qvv_set(rotation, translation, scale);
 				current_bone_index = bone_stream.parent_bone_index;
 			}
 		}
 	}
 
-	inline void sample_streams(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, Transform_32* out_local_pose)
+	inline void sample_streams(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, rtm::qvvf* out_local_pose)
 	{
 		const bool is_rotation_variable = is_rotation_format_variable(rotation_format);
 		const bool is_translation_variable = is_vector_format_variable(translation_format);
 		const bool is_scale_variable = is_vector_format_variable(scale_format);
 
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -1103,11 +1104,11 @@ namespace acl
 				const BoneStreams& bone_stream = bone_streams[bone_index];
 				const BoneStreams& raw_bone_steam = raw_bone_steams[bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_rotation_variable, rotation_format);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_translation_variable, translation_format);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_scale_variable, scale_format, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_rotation_variable, rotation_format);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_translation_variable, translation_format);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_steam, is_scale_variable, scale_format, default_scale) : default_scale;
 
-				out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 			}
 		}
 		else
@@ -1120,16 +1121,16 @@ namespace acl
 				const BoneStreams& bone_stream = bone_streams[bone_index];
 				const BoneStreams& raw_bone_steam = raw_bone_steams[bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_rotation_variable, rotation_format);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_translation_variable, translation_format);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_scale_variable, scale_format, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_rotation_variable, rotation_format);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_translation_variable, translation_format);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, raw_bone_steam, is_scale_variable, scale_format, default_scale) : default_scale;
 
-				out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 			}
 		}
 	}
 
-	inline void sample_stream(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, uint16_t bone_index, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, Transform_32* out_local_pose)
+	inline void sample_stream(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, uint16_t bone_index, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, rtm::qvvf* out_local_pose)
 	{
 		(void)num_bones;
 
@@ -1138,7 +1139,7 @@ namespace acl
 		const bool is_scale_variable = is_vector_format_variable(scale_format);
 
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -1156,9 +1157,9 @@ namespace acl
 		const BoneStreams& bone_stream = bone_streams[bone_index];
 		const BoneStreams& raw_bone_stream = raw_bone_steams[bone_index];
 
-		Quat_32 rotation;
-		Vector4_32 translation;
-		Vector4_32 scale;
+		rtm::quatf rotation;
+		rtm::vector4f translation;
+		rtm::vector4f scale;
 		if (segment_context->distribution == SampleDistribution8::Uniform)
 		{
 			rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_rotation_variable, rotation_format);
@@ -1172,10 +1173,10 @@ namespace acl
 			scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_scale_variable, scale_format, default_scale) : default_scale;
 		}
 
-		out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+		out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 	}
 
-	inline void sample_streams_hierarchical(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, uint16_t bone_index, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, Transform_32* out_local_pose)
+	inline void sample_streams_hierarchical(const BoneStreams* bone_streams, const BoneStreams* raw_bone_steams, uint16_t num_bones, float sample_time, uint16_t bone_index, const BoneBitRate* bit_rates, RotationFormat8 rotation_format, VectorFormat8 translation_format, VectorFormat8 scale_format, rtm::qvvf* out_local_pose)
 	{
 		(void)num_bones;
 
@@ -1184,7 +1185,7 @@ namespace acl
 		const bool is_scale_variable = is_vector_format_variable(scale_format);
 
 		const SegmentContext* segment_context = bone_streams->segment;
-		const Vector4_32 default_scale = get_default_scale(segment_context->clip->additive_format);
+		const rtm::vector4f default_scale = get_default_scale(segment_context->clip->additive_format);
 		const bool has_scale = segment_context->clip->has_scale;
 
 		uint32_t sample_key;
@@ -1208,11 +1209,11 @@ namespace acl
 				const BoneStreams& bone_stream = bone_streams[current_bone_index];
 				const BoneStreams& raw_bone_stream = raw_bone_steams[current_bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_rotation_variable, rotation_format);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_translation_variable, translation_format);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_scale_variable, scale_format, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_rotation_variable, rotation_format);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_translation_variable, translation_format);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Uniform>(context, bone_stream, raw_bone_stream, is_scale_variable, scale_format, default_scale) : default_scale;
 
-				out_local_pose[current_bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[current_bone_index] = rtm::qvv_set(rotation, translation, scale);
 				current_bone_index = bone_stream.parent_bone_index;
 			}
 		}
@@ -1227,32 +1228,32 @@ namespace acl
 				const BoneStreams& bone_stream = bone_streams[current_bone_index];
 				const BoneStreams& raw_bone_stream = raw_bone_steams[current_bone_index];
 
-				const Quat_32 rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_rotation_variable, rotation_format);
-				const Vector4_32 translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_translation_variable, translation_format);
-				const Vector4_32 scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_scale_variable, scale_format, default_scale) : default_scale;
+				const rtm::quatf rotation = acl_impl::sample_rotation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_rotation_variable, rotation_format);
+				const rtm::vector4f translation = acl_impl::sample_translation<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_translation_variable, translation_format);
+				const rtm::vector4f scale = has_scale ? acl_impl::sample_scale<SampleDistribution8::Variable>(context, bone_stream, raw_bone_stream, is_scale_variable, scale_format, default_scale) : default_scale;
 
-				out_local_pose[current_bone_index] = transform_set(rotation, translation, scale);
+				out_local_pose[current_bone_index] = rtm::qvv_set(rotation, translation, scale);
 				current_bone_index = bone_stream.parent_bone_index;
 			}
 		}
 	}
 
-	inline void sample_streams(const BoneStreams* bone_streams, uint16_t num_bones, uint32_t sample_index, Transform_32* out_local_pose)
+	inline void sample_streams(const BoneStreams* bone_streams, uint16_t num_bones, uint32_t sample_index, rtm::qvvf* out_local_pose)
 	{
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
 			const BoneStreams& bone_stream = bone_streams[bone_index];
 
 			const uint32_t rotation_sample_index = !bone_stream.is_rotation_constant ? sample_index : 0;
-			const Quat_32 rotation = get_rotation_sample(bone_stream, rotation_sample_index);
+			const rtm::quatf rotation = get_rotation_sample(bone_stream, rotation_sample_index);
 
 			const uint32_t translation_sample_index = !bone_stream.is_translation_constant ? sample_index : 0;
-			const Vector4_32 translation = get_translation_sample(bone_stream, translation_sample_index);
+			const rtm::vector4f translation = get_translation_sample(bone_stream, translation_sample_index);
 
 			const uint32_t scale_sample_index = !bone_stream.is_scale_constant ? sample_index : 0;
-			const Vector4_32 scale = get_scale_sample(bone_stream, scale_sample_index);
+			const rtm::vector4f scale = get_scale_sample(bone_stream, scale_sample_index);
 
-			out_local_pose[bone_index] = transform_set(rotation, translation, scale);
+			out_local_pose[bone_index] = rtm::qvv_set(rotation, translation, scale);
 		}
 	}
 }
diff --git a/includes/acl/compression/stream/track_stream.h b/includes/acl/compression/stream/track_stream.h
--- a/includes/acl/compression/stream/track_stream.h
+++ b/includes/acl/compression/stream/track_stream.h
@@ -29,11 +29,12 @@
 #include "acl/core/error.h"
 #include "acl/core/track_types.h"
 #include "acl/core/utils.h"
-#include "acl/math/quat_32.h"
 #include "acl/math/quat_packing.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/vector4_packing.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -58,18 +59,18 @@ namespace acl
 		}
 
 		template<typename SampleType>
-		SampleType ACL_SIMD_CALL get_raw_sample(uint32_t sample_index) const
+		SampleType RTM_SIMD_CALL get_raw_sample(uint32_t sample_index) const
 		{
 			const uint8_t* ptr = get_raw_sample_ptr(sample_index);
 			return *safe_ptr_cast<const SampleType>(ptr);
 		}
 
-#if defined(ACL_NO_INTRINSICS)
+#if defined(RTM_NO_INTRINSICS)
 		template<typename SampleType>
-		void ACL_SIMD_CALL set_raw_sample(uint32_t sample_index, const SampleType& sample)
+		void RTM_SIMD_CALL set_raw_sample(uint32_t sample_index, const SampleType& sample)
 #else
 		template<typename SampleType>
-		void ACL_SIMD_CALL set_raw_sample(uint32_t sample_index, SampleType sample)
+		void RTM_SIMD_CALL set_raw_sample(uint32_t sample_index, SampleType sample)
 #endif
 		{
 			ACL_ASSERT(m_sample_size == sizeof(SampleType), "Unexpected sample size. %u != %u", m_sample_size, sizeof(SampleType));
@@ -291,37 +292,37 @@ namespace acl
 	class TrackStreamRange
 	{
 	public:
-		static TrackStreamRange ACL_SIMD_CALL from_min_max(Vector4_32Arg0 min, Vector4_32Arg1 max)
+		static TrackStreamRange RTM_SIMD_CALL from_min_max(rtm::vector4f_arg0 min, rtm::vector4f_arg1 max)
 		{
-			return TrackStreamRange(min, vector_sub(max, min));
+			return TrackStreamRange(min, rtm::vector_sub(max, min));
 		}
 
-		static TrackStreamRange ACL_SIMD_CALL from_min_extent(Vector4_32Arg0 min, Vector4_32Arg1 extent)
+		static TrackStreamRange RTM_SIMD_CALL from_min_extent(rtm::vector4f_arg0 min, rtm::vector4f_arg1 extent)
 		{
 			return TrackStreamRange(min, extent);
 		}
 
 		TrackStreamRange()
-			: m_min(vector_zero_32())
-			, m_extent(vector_zero_32())
+			: m_min(rtm::vector_zero())
+			, m_extent(rtm::vector_zero())
 		{}
 
-		Vector4_32 ACL_SIMD_CALL get_min() const { return m_min; }
-		Vector4_32 ACL_SIMD_CALL get_max() const { return vector_add(m_min, m_extent); }
+		rtm::vector4f RTM_SIMD_CALL get_min() const { return m_min; }
+		rtm::vector4f RTM_SIMD_CALL get_max() const { return rtm::vector_add(m_min, m_extent); }
 
-		Vector4_32 ACL_SIMD_CALL get_center() const { return vector_add(m_min, vector_mul(m_extent, 0.5F)); }
-		Vector4_32 ACL_SIMD_CALL get_extent() const { return m_extent; }
+		rtm::vector4f RTM_SIMD_CALL get_center() const { return rtm::vector_add(m_min, rtm::vector_mul(m_extent, 0.5F)); }
+		rtm::vector4f RTM_SIMD_CALL get_extent() const { return m_extent; }
 
-		bool is_constant(float threshold) const { return vector_all_less_than(vector_abs(m_extent), vector_set(threshold)); }
+		bool is_constant(float threshold) const { return rtm::vector_all_less_than(rtm::vector_abs(m_extent), rtm::vector_set(threshold)); }
 
 	private:
-		TrackStreamRange(const Vector4_32& min, const Vector4_32& extent)
+		TrackStreamRange(rtm::vector4f_arg0 min, rtm::vector4f_arg1 extent)
 			: m_min(min)
 			, m_extent(extent)
 		{}
 
-		Vector4_32	m_min;
-		Vector4_32	m_extent;
+		rtm::vector4f	m_min;
+		rtm::vector4f	m_extent;
 	};
 
 	struct BoneRanges
diff --git a/includes/acl/compression/stream/write_decompression_stats.h b/includes/acl/compression/stream/write_decompression_stats.h
--- a/includes/acl/compression/stream/write_decompression_stats.h
+++ b/includes/acl/compression/stream/write_decompression_stats.h
@@ -34,6 +34,8 @@
 #include "acl/compression/output_stats.h"
 #include "acl/decompression/default_output_writer.h"
 
+#include <rtm/scalard.h>
+
 #include <algorithm>
 #include <thread>
 #include <chrono>
@@ -66,7 +68,7 @@ namespace acl
 		PlaybackDirection playback_direction, DecompressionFunction decompression_function,
 		CompressedClip* compressed_clips[k_num_decompression_evaluations],
 		DecompressionContextType* contexts[k_num_decompression_evaluations],
-		CPUCacheFlusher* cache_flusher, Transform_32* lossy_pose_transforms)
+		CPUCacheFlusher* cache_flusher, rtm::qvvf* lossy_pose_transforms)
 	{
 		const ClipHeader& clip_header = get_clip_header(*compressed_clips[0]);
 		const float duration = calculate_duration(clip_header.num_samples, clip_header.sample_rate);
@@ -77,7 +79,7 @@ namespace acl
 		for (uint32_t sample_index = 0; sample_index < k_num_decompression_samples; ++sample_index)
 		{
 			const float normalized_sample_time = float(sample_index) / float(k_num_decompression_samples - 1);
-			sample_times[sample_index] = clamp(normalized_sample_time, 0.0F, 1.0F) * duration;
+			sample_times[sample_index] = rtm::scalar_clamp(normalized_sample_time, 0.0F, 1.0F) * duration;
 		}
 
 		switch (playback_direction)
@@ -171,8 +173,8 @@ namespace acl
 					if (are_any_enum_flags_set(logging, StatLogging::ExhaustiveDecompression))
 						data_writer.push(elapsed_ms);
 
-					clip_min_ms = min(clip_min_ms, elapsed_ms);
-					clip_max_ms = max(clip_max_ms, elapsed_ms);
+					clip_min_ms = rtm::scalar_min(clip_min_ms, elapsed_ms);
+					clip_max_ms = rtm::scalar_max(clip_max_ms, elapsed_ms);
 					clip_total_ms += elapsed_ms;
 					clip_time_ms[sample_index] = elapsed_ms;
 				}
@@ -187,9 +189,9 @@ namespace acl
 		};
 	}
 
-	inline void write_memcpy_performance_stats(IAllocator& allocator, sjson::ObjectWriter& writer, CPUCacheFlusher* cache_flusher, Transform_32* lossy_pose_transforms, uint16_t num_bones)
+	inline void write_memcpy_performance_stats(IAllocator& allocator, sjson::ObjectWriter& writer, CPUCacheFlusher* cache_flusher, rtm::qvvf* lossy_pose_transforms, uint16_t num_bones)
 	{
-		Transform_32* memcpy_src_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
+		rtm::qvvf* memcpy_src_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
 
 		double decompression_time_ms = 1000000.0;
 		for (uint32_t pass_index = 0; pass_index < 3; ++pass_index)
@@ -197,7 +199,7 @@ namespace acl
 			if (cache_flusher != nullptr)
 			{
 				cache_flusher->begin_flushing();
-				cache_flusher->flush_buffer(memcpy_src_transforms, sizeof(Transform_32) * num_bones);
+				cache_flusher->flush_buffer(memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
 				cache_flusher->end_flushing();
 
 				// Now that the cache is cold, yield our time slice and wait for a new one
@@ -210,35 +212,35 @@ namespace acl
 				// to help keep it warm and minimize the risk that we'll be interrupted during decompression
 				std::this_thread::sleep_for(std::chrono::nanoseconds(1));
 
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
 			}
 
 			double execution_count;
 			ScopeProfiler timer;
 			if (cache_flusher != nullptr)
 			{
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
 				execution_count = 1.0;
 			}
 			else
 			{
 				// Warm cache is too fast, execute multiple times and divide by the count
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
-				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(Transform_32) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
+				std::memcpy(lossy_pose_transforms, memcpy_src_transforms, sizeof(rtm::qvvf) * num_bones);
 				execution_count = 10.0;
 			}
 			timer.stop();
 
 			const double elapsed_ms = timer.get_elapsed_milliseconds() / execution_count;
-			decompression_time_ms = min(decompression_time_ms, elapsed_ms);
+			decompression_time_ms = rtm::scalar_min(decompression_time_ms, elapsed_ms);
 		}
 
 		writer[cache_flusher != nullptr ? "memcpy_cold" : "memcpy_warm"] = [&](sjson::ObjectWriter& memcpy_writer)
@@ -258,7 +260,7 @@ namespace acl
 		CPUCacheFlusher* cache_flusher = allocate_type<CPUCacheFlusher>(allocator);
 
 		const ClipHeader& clip_header = get_clip_header(*compressed_clips[0]);
-		Transform_32* lossy_pose_transforms = allocate_type_array<Transform_32>(allocator, clip_header.num_bones);
+		rtm::qvvf* lossy_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, clip_header.num_bones);
 
 		const uint32_t num_bytes_per_bone = (4 + 3 + 3) * sizeof(float);	// Rotation, Translation, Scale
 		writer["pose_size"] = uint32_t(clip_header.num_bones) * num_bytes_per_bone;
diff --git a/includes/acl/compression/stream/write_range_data.h b/includes/acl/compression/stream/write_range_data.h
--- a/includes/acl/compression/stream/write_range_data.h
+++ b/includes/acl/compression/stream/write_range_data.h
@@ -30,12 +30,12 @@
 #include "acl/core/enum_utils.h"
 #include "acl/core/track_types.h"
 #include "acl/core/range_reduction_types.h"
-#include "acl/math/quat_32.h"
 #include "acl/math/quat_packing.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/vector4_packing.h"
 #include "acl/compression/stream/clip_context.h"
 
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -68,16 +68,16 @@ namespace acl
 
 	inline void write_range_track_data_impl(const TrackStream& track, const TrackStreamRange& range, bool is_clip_range_data, uint8_t*& out_range_data)
 	{
-		const Vector4_32 range_min = range.get_min();
-		const Vector4_32 range_extent = range.get_extent();
+		const rtm::vector4f range_min = range.get_min();
+		const rtm::vector4f range_extent = range.get_extent();
 
 		if (is_clip_range_data)
 		{
 			const uint32_t range_member_size = sizeof(float) * 3;
 
-			std::memcpy(out_range_data, vector_as_float_ptr(range_min), range_member_size);
+			std::memcpy(out_range_data, &range_min, range_member_size);
 			out_range_data += range_member_size;
-			std::memcpy(out_range_data, vector_as_float_ptr(range_extent), range_member_size);
+			std::memcpy(out_range_data, &range_extent, range_member_size);
 			out_range_data += range_member_size;
 		}
 		else
@@ -123,16 +123,16 @@ namespace acl
 
 			if (are_any_enum_flags_set(range_reduction, RangeReductionFlags8::Rotations) && !bone_stream.is_rotation_constant)
 			{
-				const Vector4_32 range_min = bone_range.rotation.get_min();
-				const Vector4_32 range_extent = bone_range.rotation.get_extent();
+				const rtm::vector4f range_min = bone_range.rotation.get_min();
+				const rtm::vector4f range_extent = bone_range.rotation.get_extent();
 
 				if (is_clip_range_data)
 				{
 					const uint32_t range_member_size = bone_stream.rotations.get_rotation_format() == RotationFormat8::Quat_128 ? (sizeof(float) * 4) : (sizeof(float) * 3);
 
-					std::memcpy(range_data, vector_as_float_ptr(range_min), range_member_size);
+					std::memcpy(range_data, &range_min, range_member_size);
 					range_data += range_member_size;
-					std::memcpy(range_data, vector_as_float_ptr(range_extent), range_member_size);
+					std::memcpy(range_data, &range_extent, range_member_size);
 					range_data += range_member_size;
 				}
 				else
diff --git a/includes/acl/compression/stream/write_stats.h b/includes/acl/compression/stream/write_stats.h
--- a/includes/acl/compression/stream/write_stats.h
+++ b/includes/acl/compression/stream/write_stats.h
@@ -101,9 +101,9 @@ namespace acl
 		const uint16_t num_bones = skeleton.get_num_bones();
 		const bool has_scale = segment_context_has_scale(segment);
 
-		Transform_32* raw_local_pose = allocate_type_array<Transform_32>(allocator, num_bones);
-		Transform_32* base_local_pose = allocate_type_array<Transform_32>(allocator, num_bones);
-		Transform_32* lossy_local_pose = allocate_type_array<Transform_32>(allocator, num_bones);
+		rtm::qvvf* raw_local_pose = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+		rtm::qvvf* base_local_pose = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+		rtm::qvvf* lossy_local_pose = allocate_type_array<rtm::qvvf>(allocator, num_bones);
 
 		const float sample_rate = raw_clip_context.sample_rate;
 		const float ref_duration = calculate_duration(raw_clip_context.num_samples, sample_rate);
@@ -114,7 +114,7 @@ namespace acl
 		{
 			for (uint32_t sample_index = 0; sample_index < segment.num_samples; ++sample_index)
 			{
-				const float sample_time = min(float(segment.clip_sample_offset + sample_index) / sample_rate, ref_duration);
+				const float sample_time = rtm::scalar_min(float(segment.clip_sample_offset + sample_index) / sample_rate, ref_duration);
 
 				sample_streams(raw_clip_context.segments[0].bone_streams, num_bones, sample_time, raw_local_pose);
 				sample_streams(segment.bone_streams, num_bones, sample_time, lossy_local_pose);
diff --git a/includes/acl/compression/stream/write_stream_data.h b/includes/acl/compression/stream/write_stream_data.h
--- a/includes/acl/compression/stream/write_stream_data.h
+++ b/includes/acl/compression/stream/write_stream_data.h
@@ -28,9 +28,6 @@
 #include "acl/core/iallocator.h"
 #include "acl/core/error.h"
 #include "acl/core/compressed_clip.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/quat_packing.h"
-#include "acl/math/vector4_32.h"
 #include "acl/compression/stream/clip_context.h"
 
 #include <cstdint>
diff --git a/includes/acl/compression/track_error.h b/includes/acl/compression/track_error.h
--- a/includes/acl/compression/track_error.h
+++ b/includes/acl/compression/track_error.h
@@ -90,7 +90,7 @@ namespace acl
 		// Regression test
 		for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 		{
-			const float sample_time = min(float(sample_index) / sample_rate, duration);
+			const float sample_time = rtm::scalar_min(float(sample_index) / sample_rate, duration);
 
 			// We use the nearest sample to accurately measure the loss that happened, if any
 			raw_tracks.sample_tracks(sample_time, SampleRoundingPolicy::Nearest, raw_tracks_writer);
diff --git a/includes/acl/compression/utils.h b/includes/acl/compression/utils.h
--- a/includes/acl/compression/utils.h
+++ b/includes/acl/compression/utils.h
@@ -65,17 +65,17 @@ namespace acl
 		const uint32_t additive_num_samples = additive_base_clip != nullptr ? additive_base_clip->get_num_samples() : 0;
 		const float additive_duration = additive_base_clip != nullptr ? additive_base_clip->get_duration() : 0.0F;
 
-		Transform_32* raw_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
-		Transform_32* base_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
-		Transform_32* lossy_pose_transforms = allocate_type_array<Transform_32>(allocator, num_output_bones);
-		Transform_32* lossy_remapped_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
+		rtm::qvvf* raw_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+		rtm::qvvf* base_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+		rtm::qvvf* lossy_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_output_bones);
+		rtm::qvvf* lossy_remapped_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
 
 		BoneError bone_error;
 		DefaultOutputWriter pose_writer(lossy_pose_transforms, num_output_bones);
 
 		for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 		{
-			const float sample_time = min(float(sample_index) / sample_rate, clip_duration);
+			const float sample_time = rtm::scalar_min(float(sample_index) / sample_rate, clip_duration);
 
 			// We use the nearest sample to accurately measure the loss that happened, if any
 			clip.sample_pose(sample_time, SampleRoundingPolicy::Nearest, raw_pose_transforms, num_bones);
@@ -92,7 +92,7 @@ namespace acl
 
 			// Perform remapping by copying the raw pose first and we overwrite with the decompressed pose if
 			// the data is available
-			std::memcpy(lossy_remapped_pose_transforms, raw_pose_transforms, sizeof(Transform_32) * num_bones);
+			std::memcpy(lossy_remapped_pose_transforms, raw_pose_transforms, sizeof(rtm::qvvf) * num_bones);
 			for (uint16_t output_index = 0; output_index < num_output_bones; ++output_index)
 			{
 				const uint16_t bone_index = output_bone_mapping[output_index];
diff --git a/includes/acl/core/additive_utils.h b/includes/acl/core/additive_utils.h
--- a/includes/acl/core/additive_utils.h
+++ b/includes/acl/core/additive_utils.h
@@ -25,8 +25,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 #include "acl/core/compiler_utils.h"
-#include "acl/math/transform_32.h"
-#include "acl/math/transform_64.h"
+
+#include <rtm/qvvd.h>
+#include <rtm/qvvf.h>
 
 #include <cstdint>
 
@@ -106,77 +107,77 @@ namespace acl
 		return false;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL get_default_scale(AdditiveClipFormat8 additive_format)
+	inline rtm::vector4f RTM_SIMD_CALL get_default_scale(AdditiveClipFormat8 additive_format)
 	{
-		return additive_format == AdditiveClipFormat8::Additive1 ? vector_zero_32() : vector_set(1.0F);
+		return additive_format == AdditiveClipFormat8::Additive1 ? rtm::vector_zero() : rtm::vector_set(1.0F);
 	}
 
-	inline Transform_32 ACL_SIMD_CALL transform_add0(Transform_32Arg0 base, Transform_32Arg1 additive)
+	inline rtm::qvvf RTM_SIMD_CALL transform_add0(rtm::qvvf_arg0 base, rtm::qvvf_arg1 additive)
 	{
-		const Quat_32 rotation = quat_mul(additive.rotation, base.rotation);
-		const Vector4_32 translation = vector_add(additive.translation, base.translation);
-		const Vector4_32 scale = vector_mul(additive.scale, base.scale);
-		return transform_set(rotation, translation, scale);
+		const rtm::quatf rotation = rtm::quat_mul(additive.rotation, base.rotation);
+		const rtm::vector4f translation = rtm::vector_add(additive.translation, base.translation);
+		const rtm::vector4f scale = rtm::vector_mul(additive.scale, base.scale);
+		return rtm::qvv_set(rotation, translation, scale);
 	}
 
-	inline Transform_32 ACL_SIMD_CALL transform_add1(Transform_32Arg0 base, Transform_32Arg1 additive)
+	inline rtm::qvvf RTM_SIMD_CALL transform_add1(rtm::qvvf_arg0 base, rtm::qvvf_arg1 additive)
 	{
-		const Quat_32 rotation = quat_mul(additive.rotation, base.rotation);
-		const Vector4_32 translation = vector_add(additive.translation, base.translation);
-		const Vector4_32 scale = vector_mul(vector_add(vector_set(1.0F), additive.scale), base.scale);
-		return transform_set(rotation, translation, scale);
+		const rtm::quatf rotation = rtm::quat_mul(additive.rotation, base.rotation);
+		const rtm::vector4f translation = rtm::vector_add(additive.translation, base.translation);
+		const rtm::vector4f scale = rtm::vector_mul(rtm::vector_add(rtm::vector_set(1.0F), additive.scale), base.scale);
+		return rtm::qvv_set(rotation, translation, scale);
 	}
 
-	inline Transform_32 ACL_SIMD_CALL transform_add_no_scale(Transform_32Arg0 base, Transform_32Arg1 additive)
+	inline rtm::qvvf RTM_SIMD_CALL transform_add_no_scale(rtm::qvvf_arg0 base, rtm::qvvf_arg1 additive)
 	{
-		const Quat_32 rotation = quat_mul(additive.rotation, base.rotation);
-		const Vector4_32 translation = vector_add(additive.translation, base.translation);
-		return transform_set(rotation, translation, vector_set(1.0F));
+		const rtm::quatf rotation = rtm::quat_mul(additive.rotation, base.rotation);
+		const rtm::vector4f translation = rtm::vector_add(additive.translation, base.translation);
+		return rtm::qvv_set(rotation, translation, rtm::vector_set(1.0F));
 	}
 
-	inline Transform_32 ACL_SIMD_CALL apply_additive_to_base(AdditiveClipFormat8 additive_format, Transform_32Arg1 base, Transform_32ArgN additive)
+	inline rtm::qvvf RTM_SIMD_CALL apply_additive_to_base(AdditiveClipFormat8 additive_format, rtm::qvvf_arg0 base, rtm::qvvf_arg1 additive)
 	{
 		switch (additive_format)
 		{
 		default:
 		case AdditiveClipFormat8::None:			return additive;
-		case AdditiveClipFormat8::Relative:		return transform_mul(additive, base);
+		case AdditiveClipFormat8::Relative:		return rtm::qvv_mul(additive, base);
 		case AdditiveClipFormat8::Additive0:	return transform_add0(base, additive);
 		case AdditiveClipFormat8::Additive1:	return transform_add1(base, additive);
 		}
 	}
 
-	inline Transform_32 ACL_SIMD_CALL apply_additive_to_base_no_scale(AdditiveClipFormat8 additive_format, Transform_32Arg1 base, Transform_32ArgN additive)
+	inline rtm::qvvf RTM_SIMD_CALL apply_additive_to_base_no_scale(AdditiveClipFormat8 additive_format, rtm::qvvf_arg0 base, rtm::qvvf_arg1 additive)
 	{
 		switch (additive_format)
 		{
 		default:
 		case AdditiveClipFormat8::None:			return additive;
-		case AdditiveClipFormat8::Relative:		return transform_mul_no_scale(additive, base);
+		case AdditiveClipFormat8::Relative:		return rtm::qvv_mul_no_scale(additive, base);
 		case AdditiveClipFormat8::Additive0:	return transform_add_no_scale(base, additive);
 		case AdditiveClipFormat8::Additive1:	return transform_add_no_scale(base, additive);
 		}
 	}
 
-	inline Transform_64 convert_to_relative(const Transform_64& base, const Transform_64& transform)
+	inline rtm::qvvd convert_to_relative(const rtm::qvvd& base, const rtm::qvvd& transform)
 	{
-		return transform_mul(transform, transform_inverse(base));
+		return rtm::qvv_mul(transform, rtm::qvv_inverse(base));
 	}
 
-	inline Transform_64 convert_to_additive0(const Transform_64& base, const Transform_64& transform)
+	inline rtm::qvvd convert_to_additive0(const rtm::qvvd& base, const rtm::qvvd& transform)
 	{
-		const Quat_64 rotation = quat_mul(transform.rotation, quat_conjugate(base.rotation));
-		const Vector4_64 translation = vector_sub(transform.translation, base.translation);
-		const Vector4_64 scale = vector_div(transform.scale, base.scale);
-		return transform_set(rotation, translation, scale);
+		const rtm::quatd rotation = rtm::quat_mul(transform.rotation, rtm::quat_conjugate(base.rotation));
+		const rtm::vector4d translation = rtm::vector_sub(transform.translation, base.translation);
+		const rtm::vector4d scale = rtm::vector_div(transform.scale, base.scale);
+		return rtm::qvv_set(rotation, translation, scale);
 	}
 
-	inline Transform_64 convert_to_additive1(const Transform_64& base, const Transform_64& transform)
+	inline rtm::qvvd convert_to_additive1(const rtm::qvvd& base, const rtm::qvvd& transform)
 	{
-		const Quat_64 rotation = quat_mul(transform.rotation, quat_conjugate(base.rotation));
-		const Vector4_64 translation = vector_sub(transform.translation, base.translation);
-		const Vector4_64 scale = vector_sub(vector_mul(transform.scale, vector_reciprocal(base.scale)), vector_set(1.0));
-		return transform_set(rotation, translation, scale);
+		const rtm::quatd rotation = rtm::quat_mul(transform.rotation, rtm::quat_conjugate(base.rotation));
+		const rtm::vector4d translation = rtm::vector_sub(transform.translation, base.translation);
+		const rtm::vector4d scale = rtm::vector_sub(rtm::vector_mul(transform.scale, rtm::vector_reciprocal(base.scale)), rtm::vector_set(1.0));
+		return rtm::qvv_set(rotation, translation, scale);
 	}
 }
 
diff --git a/includes/acl/core/bit_manip_utils.h b/includes/acl/core/bit_manip_utils.h
--- a/includes/acl/core/bit_manip_utils.h
+++ b/includes/acl/core/bit_manip_utils.h
@@ -26,11 +26,12 @@
 
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
-#include "acl/math/math.h"
+
+#include <rtm/math.h>
 
 #include <cstdint>
 
-#if !defined(ACL_USE_POPCOUNT) && !defined(ACL_NO_INTRINSICS)
+#if !defined(ACL_USE_POPCOUNT) && !defined(RTM_NO_INTRINSICS)
 	// TODO: Enable this for PlayStation 4 as well, what is the define and can we use it in public code?
 	#if defined(_DURANGO) || defined(_XBOX_ONE)
 		// Enable pop-count type instructions on Xbox One
@@ -42,7 +43,7 @@
 	#include <nmmintrin.h>
 #endif
 
-#if defined(ACL_AVX_INTRINSICS)
+#if defined(RTM_AVX_INTRINSICS)
 	// Use BMI
 	#include <ammintrin.h>		// MSVC uses this header for _andn_u32 BMI intrinsic
 	#include <immintrin.h>		// Intel documentation says _andn_u32 and others are here
@@ -58,7 +59,7 @@ namespace acl
 	{
 #if defined(ACL_USE_POPCOUNT)
 		return (uint8_t)_mm_popcnt_u32(value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		return (uint8_t)vget_lane_u64(vcnt_u8(vcreate_u8(value)), 0);
 #else
 		value = value - ((value >> 1) & 0x55);
@@ -71,7 +72,7 @@ namespace acl
 	{
 #if defined(ACL_USE_POPCOUNT)
 		return (uint16_t)_mm_popcnt_u32(value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		return (uint16_t)vget_lane_u64(vpaddl_u8(vcnt_u8(vcreate_u8(value))), 0);
 #else
 		value = value - ((value >> 1) & 0x5555);
@@ -84,7 +85,7 @@ namespace acl
 	{
 #if defined(ACL_USE_POPCOUNT)
 		return _mm_popcnt_u32(value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		return (uint32_t)vget_lane_u64(vpaddl_u16(vpaddl_u8(vcnt_u8(vcreate_u8(value)))), 0);
 #else
 		value = value - ((value >> 1) & 0x55555555);
@@ -97,7 +98,7 @@ namespace acl
 	{
 #if defined(ACL_USE_POPCOUNT)
 		return _mm_popcnt_u64(value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		return vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vcnt_u8(vcreate_u8(value))))), 0);
 #else
 		value = value - ((value >> 1) & 0x5555555555555555ULL);
diff --git a/includes/acl/core/floating_point_exceptions.h b/includes/acl/core/floating_point_exceptions.h
--- a/includes/acl/core/floating_point_exceptions.h
+++ b/includes/acl/core/floating_point_exceptions.h
@@ -25,7 +25,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 #include "acl/core/compiler_utils.h"
-#include "acl/math/math.h"
+
+#include <rtm/math.h>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
 
@@ -36,9 +37,9 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	struct fp_environment
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		unsigned int exception_mask;
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		// TODO: Implement on ARM. API to do this is not consistent across Android, Windows ARM, and iOS
 		// and on top of it, most ARM CPUs out there do not raise the SIGFPE trap so they are silent
 #endif
@@ -49,7 +50,7 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	inline void enable_fp_exceptions(fp_environment& out_old_env)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		// We only care about SSE and not x87
 		// Clear any exceptions that might have been raised already
 		_MM_SET_EXCEPTION_STATE(0);
@@ -68,7 +69,7 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	inline void disable_fp_exceptions(fp_environment& out_old_env)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		// We only care about SSE and not x87
 		// Cache the exception mask we had so we can restore it later
 		out_old_env.exception_mask = _MM_GET_EXCEPTION_MASK();
@@ -84,7 +85,7 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	inline void restore_fp_exceptions(const fp_environment& env)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		// We only care about SSE and not x87
 		// Clear any exceptions that might have been raised already
 		_MM_SET_EXCEPTION_STATE(0);
diff --git a/includes/acl/core/interpolation_utils.h b/includes/acl/core/interpolation_utils.h
--- a/includes/acl/core/interpolation_utils.h
+++ b/includes/acl/core/interpolation_utils.h
@@ -26,7 +26,8 @@
 
 #include "acl/core/error.h"
 #include "acl/core/compiler_utils.h"
-#include "acl/math/scalar_32.h"
+
+#include <rtm/scalarf.h>
 
 #include <cstdint>
 #include <algorithm>
@@ -76,7 +77,7 @@ namespace acl
 		ACL_ASSERT(num_samples > 0, "Invalid num_samples: %u", num_samples);
 
 		const float sample_rate = duration == 0.0F ? 0.0F : (float(num_samples - 1) / duration);
-		ACL_ASSERT(sample_rate >= 0.0F && is_finite(sample_rate), "Invalid sample_rate: %f", sample_rate);
+		ACL_ASSERT(sample_rate >= 0.0F && rtm::scalar_is_finite(sample_rate), "Invalid sample_rate: %f", sample_rate);
 
 		const float sample_index = sample_time * sample_rate;
 		const uint32_t sample_index0 = static_cast<uint32_t>(sample_index);
@@ -102,7 +103,7 @@ namespace acl
 			out_interpolation_alpha = 1.0F;
 			break;
 		case SampleRoundingPolicy::Nearest:
-			out_interpolation_alpha = floor(interpolation_alpha + 0.5F);
+			out_interpolation_alpha = rtm::scalar_floor(interpolation_alpha + 0.5F);
 			break;
 		}
 	}
@@ -155,7 +156,7 @@ namespace acl
 			out_interpolation_alpha = 1.0F;
 			break;
 		case SampleRoundingPolicy::Nearest:
-			out_interpolation_alpha = floor(interpolation_alpha + 0.5F);
+			out_interpolation_alpha = rtm::scalar_floor(interpolation_alpha + 0.5F);
 			break;
 		}
 	}
diff --git a/includes/acl/core/memory_cache.h b/includes/acl/core/memory_cache.h
--- a/includes/acl/core/memory_cache.h
+++ b/includes/acl/core/memory_cache.h
@@ -26,7 +26,8 @@
 
 #include "acl/core/compiler_utils.h"
 #include "acl/core/iallocator.h"
-#include "acl/math/vector4_32.h"
+
+#include <rtm/vector4f.h>
 
 #include <cstdint>
 
@@ -62,7 +63,7 @@ namespace acl
 			(void)buffer;
 			(void)buffer_size;
 
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 			constexpr size_t k_cache_line_size = 64;
 
 			const uint8_t* buffer_start = reinterpret_cast<const uint8_t*>(buffer);
@@ -84,9 +85,10 @@ namespace acl
 			ACL_ASSERT(m_is_flushing, "begin_flushing() not called");
 			m_is_flushing = false;
 
-#if !defined(ACL_SSE2_INTRINSICS)
+#if !defined(RTM_SSE2_INTRINSICS)
+			const rtm::vector4f one = rtm::vector_set(1.0F);
 			for (size_t entry_index = 0; entry_index < k_num_buffer_entries; ++entry_index)
-				m_buffer[entry_index] = vector_add(m_buffer[entry_index], vector_set(1.0f));
+				m_buffer[entry_index] = rtm::vector_add(m_buffer[entry_index], one);
 #endif
 		}
 
@@ -94,7 +96,7 @@ namespace acl
 		CPUCacheFlusher(const CPUCacheFlusher& other) = delete;
 		CPUCacheFlusher& operator=(const CPUCacheFlusher& other) = delete;
 
-#if !defined(ACL_SSE2_INTRINSICS)
+#if !defined(RTM_SSE2_INTRINSICS)
 		// TODO: get an official CPU cache size
 	#if defined(__ANDROID__)
 		// Nexus 5X has 2MB cache
@@ -104,9 +106,9 @@ namespace acl
 		static constexpr size_t k_cache_size = 9 * 1024 * 1024;
 	#endif
 
-		static constexpr size_t k_num_buffer_entries = k_cache_size / sizeof(Vector4_32);
+		static constexpr size_t k_num_buffer_entries = k_cache_size / sizeof(rtm::vector4f);
 
-		Vector4_32		m_buffer[k_num_buffer_entries];
+		rtm::vector4f	m_buffer[k_num_buffer_entries];
 #endif
 
 		bool	m_is_flushing;
diff --git a/includes/acl/core/utils.h b/includes/acl/core/utils.h
--- a/includes/acl/core/utils.h
+++ b/includes/acl/core/utils.h
@@ -27,7 +27,8 @@
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
 #include "acl/core/memory_utils.h"
-#include "acl/math/scalar_32.h"
+
+#include <rtm/scalarf.h>
 
 #include <cstdint>
 #include <limits>
@@ -56,7 +57,7 @@ namespace acl
 			return 1;	// An infinite duration, we have a single sample (static pose)
 
 		// Otherwise we have at least 1 sample
-		return safe_static_cast<uint32_t>(floor((duration * float(sample_rate)) + 0.5F)) + 1;
+		return safe_static_cast<uint32_t>(rtm::scalar_floor((duration * float(sample_rate)) + 0.5F)) + 1;
 	}
 
 	//////////////////////////////////////////////////////////////////////////
@@ -78,7 +79,7 @@ namespace acl
 			return 1;	// An infinite duration, we have a single sample (static pose)
 
 		// Otherwise we have at least 1 sample
-		return safe_static_cast<uint32_t>(floor((duration * sample_rate) + 0.5F)) + 1;
+		return safe_static_cast<uint32_t>(rtm::scalar_floor((duration * sample_rate) + 0.5F)) + 1;
 	}
 
 	//////////////////////////////////////////////////////////////////////////
diff --git a/includes/acl/decompression/decompress.h b/includes/acl/decompression/decompress.h
--- a/includes/acl/decompression/decompress.h
+++ b/includes/acl/decompression/decompress.h
@@ -34,7 +34,6 @@
 #include "acl/core/track_types.h"
 #include "acl/core/track_writer.h"
 #include "acl/decompression/impl/track_sampling_impl.h"
-#include "acl/math/rtm_casts.h"
 #include "acl/math/vector4_packing.h"
 
 #include <rtm/types.h>
@@ -340,13 +339,13 @@ namespace acl
 					rtm::vector4f value1;
 					if (is_raw_bit_rate(bit_rate))
 					{
-						value0 = vector_acl2rtm(unpack_vector2_64_unsafe(animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector2_64_unsafe(animated_values, track_bit_offset1));
+						value0 = unpack_vector2_64_unsafe(animated_values, track_bit_offset0);
+						value1 = unpack_vector2_64_unsafe(animated_values, track_bit_offset1);
 					}
 					else
 					{
-						value0 = vector_acl2rtm(unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1));
+						value0 = unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0);
+						value1 = unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1);
 
 						const rtm::vector4f range_min = rtm::vector_load(range_values);
 						const rtm::vector4f range_extent = rtm::vector_load(range_values + 2);
@@ -378,13 +377,13 @@ namespace acl
 					rtm::vector4f value1;
 					if (is_raw_bit_rate(bit_rate))
 					{
-						value0 = vector_acl2rtm(unpack_vector3_96_unsafe(animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector3_96_unsafe(animated_values, track_bit_offset1));
+						value0 = unpack_vector3_96_unsafe(animated_values, track_bit_offset0);
+						value1 = unpack_vector3_96_unsafe(animated_values, track_bit_offset1);
 					}
 					else
 					{
-						value0 = vector_acl2rtm(unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1));
+						value0 = unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0);
+						value1 = unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1);
 
 						const rtm::vector4f range_min = rtm::vector_load(range_values);
 						const rtm::vector4f range_extent = rtm::vector_load(range_values + 3);
@@ -416,13 +415,13 @@ namespace acl
 					rtm::vector4f value1;
 					if (is_raw_bit_rate(bit_rate))
 					{
-						value0 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, track_bit_offset1));
+						value0 = unpack_vector4_128_unsafe(animated_values, track_bit_offset0);
+						value1 = unpack_vector4_128_unsafe(animated_values, track_bit_offset1);
 					}
 					else
 					{
-						value0 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1));
+						value0 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0);
+						value1 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1);
 
 						const rtm::vector4f range_min = rtm::vector_load(range_values);
 						const rtm::vector4f range_extent = rtm::vector_load(range_values + 4);
@@ -454,13 +453,13 @@ namespace acl
 					rtm::vector4f value1;
 					if (is_raw_bit_rate(bit_rate))
 					{
-						value0 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, track_bit_offset1));
+						value0 = unpack_vector4_128_unsafe(animated_values, track_bit_offset0);
+						value1 = unpack_vector4_128_unsafe(animated_values, track_bit_offset1);
 					}
 					else
 					{
-						value0 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0));
-						value1 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1));
+						value0 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset0);
+						value1 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, track_bit_offset1);
 
 						const rtm::vector4f range_min = rtm::vector_load(range_values);
 						const rtm::vector4f range_extent = rtm::vector_load(range_values + 4);
@@ -567,13 +566,13 @@ namespace acl
 				rtm::vector4f value1;
 				if (is_raw_bit_rate(bit_rate))
 				{
-					value0 = vector_acl2rtm(unpack_vector2_64_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector2_64_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector2_64_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector2_64_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 				}
 				else
 				{
-					value0 = vector_acl2rtm(unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector2_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 
 					const rtm::vector4f range_min = rtm::vector_load(range_values);
 					const rtm::vector4f range_extent = rtm::vector_load(range_values + num_element_components);
@@ -597,13 +596,13 @@ namespace acl
 				rtm::vector4f value1;
 				if (is_raw_bit_rate(bit_rate))
 				{
-					value0 = vector_acl2rtm(unpack_vector3_96_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector3_96_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector3_96_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector3_96_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 				}
 				else
 				{
-					value0 = vector_acl2rtm(unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector3_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 
 					const rtm::vector4f range_min = rtm::vector_load(range_values);
 					const rtm::vector4f range_extent = rtm::vector_load(range_values + num_element_components);
@@ -627,13 +626,13 @@ namespace acl
 				rtm::vector4f value1;
 				if (is_raw_bit_rate(bit_rate))
 				{
-					value0 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 				}
 				else
 				{
-					value0 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 
 					const rtm::vector4f range_min = rtm::vector_load(range_values);
 					const rtm::vector4f range_extent = rtm::vector_load(range_values + num_element_components);
@@ -657,13 +656,13 @@ namespace acl
 				rtm::vector4f value1;
 				if (is_raw_bit_rate(bit_rate))
 				{
-					value0 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector4_128_unsafe(animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 				}
 				else
 				{
-					value0 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset));
-					value1 = vector_acl2rtm(unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset));
+					value0 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[0] + track_bit_offset);
+					value1 = unpack_vector4_uXX_unsafe(num_bits_per_component, animated_values, m_context.key_frame_bit_offsets[1] + track_bit_offset);
 
 					const rtm::vector4f range_min = rtm::vector_load(range_values);
 					const rtm::vector4f range_extent = rtm::vector_load(range_values + num_element_components);
diff --git a/includes/acl/decompression/decompress_data.h b/includes/acl/decompression/decompress_data.h
--- a/includes/acl/decompression/decompress_data.h
+++ b/includes/acl/decompression/decompress_data.h
@@ -27,6 +27,10 @@
 #include "acl/core/compiler_utils.h"
 #include "acl/core/memory_utils.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+#include <rtm/packing/quatf.h>
+
 ACL_IMPL_FILE_PRAGMA_PUSH
 
 namespace acl
@@ -328,7 +332,7 @@ namespace acl
 
 	template<size_t num_key_frames, class SettingsType, class DecompressionContextType, class SamplingContextType>
 	//ACL_DEPRECATED("Use decompress_and_interpolate_rotation instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_rotations(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Quat_32* out_rotations)
+	inline TimeSeriesType8 decompress_rotations(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::quatf* out_rotations)
 	{
 		TimeSeriesType8 time_series_type;
 
@@ -336,7 +340,7 @@ namespace acl
 		const bool is_sample_default = bitset_test(decomp_context.default_tracks_bitset, track_index_bit_ref);
 		if (is_sample_default)
 		{
-			out_rotations[0] = quat_identity_32();
+			out_rotations[0] = rtm::quat_identity();
 			time_series_type = TimeSeriesType8::ConstantDefault;
 		}
 		else
@@ -345,7 +349,7 @@ namespace acl
 			const bool is_sample_constant = bitset_test(decomp_context.constant_tracks_bitset, track_index_bit_ref);
 			if (is_sample_constant)
 			{
-				Quat_32 rotation;
+				rtm::quatf rotation;
 
 				if (rotation_format == RotationFormat8::Quat_128 && settings.is_rotation_format_supported(RotationFormat8::Quat_128))
 					rotation = unpack_quat_128(decomp_context.constant_track_data + sampling_context.constant_track_data_offset);
@@ -360,7 +364,7 @@ namespace acl
 				else
 				{
 					ACL_ASSERT(false, "Unrecognized rotation format");
-					rotation = quat_identity_32();
+					rotation = rtm::quat_identity();
 				}
 
 				out_rotations[0] = rotation;
@@ -376,7 +380,7 @@ namespace acl
 				const bool are_clip_rotations_normalized = are_any_enum_flags_set(clip_range_reduction, RangeReductionFlags8::Rotations);
 				const bool are_segment_rotations_normalized = are_any_enum_flags_set(segment_range_reduction, RangeReductionFlags8::Rotations);
 
-				Vector4_32 rotations[num_key_frames];
+				rtm::vector4f rotations[num_key_frames];
 				bool ignore_clip_range[num_key_frames] = { false };
 				bool ignore_segment_range[num_key_frames] = { false };
 
@@ -466,10 +470,10 @@ namespace acl
 						{
 							if (!ignore_segment_range[i])
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)));
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)));
 
-								rotations[i] = vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
+								rotations[i] = rtm::vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
 							}
 						}
 					}
@@ -479,20 +483,20 @@ namespace acl
 						{
 							for (size_t i = 0; i < num_key_frames; ++i)
 							{
-								const Vector4_32 segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset, true);
-								const Vector4_32 segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)), true);
+								const rtm::vector4f segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset, true);
+								const rtm::vector4f segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)), true);
 
-								rotations[i] = vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
+								rotations[i] = rtm::vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
 							}
 						}
 						else
 						{
 							for (size_t i = 0; i < num_key_frames; ++i)
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)));
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (decomp_context.num_rotation_components * sizeof(uint8_t)));
 
-								rotations[i] = vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
+								rotations[i] = rtm::vector_mul_add(rotations[i], segment_range_extent, segment_range_min);
 							}
 						}
 					}
@@ -502,13 +506,13 @@ namespace acl
 
 				if (are_clip_rotations_normalized)
 				{
-					const Vector4_32 clip_range_min = vector_unaligned_load_32(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
-					const Vector4_32 clip_range_extent = vector_unaligned_load_32(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (decomp_context.num_rotation_components * sizeof(float)));
+					const rtm::vector4f clip_range_min = rtm::vector_load(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
+					const rtm::vector4f clip_range_extent = rtm::vector_load(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (decomp_context.num_rotation_components * sizeof(float)));
 
 					for (size_t i = 0; i < num_key_frames; ++i)
 					{
 						if (!ignore_clip_range[i])
-							rotations[i] = vector_mul_add(rotations[i], clip_range_extent, clip_range_min);
+							rotations[i] = rtm::vector_mul_add(rotations[i], clip_range_extent, clip_range_min);
 					}
 
 					sampling_context.clip_range_data_offset += decomp_context.num_rotation_components * sizeof(float) * 2;
@@ -517,12 +521,12 @@ namespace acl
 				if (rotation_format == RotationFormat8::Quat_128 && settings.is_rotation_format_supported(RotationFormat8::Quat_128))
 				{
 					for (size_t i = 0; i < num_key_frames; ++i)
-						out_rotations[i] = vector_to_quat(rotations[i]);
+						out_rotations[i] = rtm::vector_to_quat(rotations[i]);
 				}
 				else
 				{
 					for (size_t i = 0; i < num_key_frames; ++i)
-						out_rotations[i] = quat_from_positive_w(rotations[i]);
+						out_rotations[i] = rtm::quat_from_positive_w(rotations[i]);
 				}
 
 				time_series_type = TimeSeriesType8::Varying;
@@ -535,28 +539,28 @@ namespace acl
 
 	template<class SettingsType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_rotation instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_rotation(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Quat_32* out_rotations)
+	inline TimeSeriesType8 decompress_rotation(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::quatf* out_rotations)
 	{
 		return decompress_rotations<1>(settings, header, decomp_context, sampling_context, out_rotations);
 	}
 
 	template<class SettingsType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_rotation instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_rotations_in_two_key_frames(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Quat_32* out_rotations)
+	inline TimeSeriesType8 decompress_rotations_in_two_key_frames(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::quatf* out_rotations)
 	{
 		return decompress_rotations<2>(settings, header, decomp_context, sampling_context, out_rotations);
 	}
 
 	template<class SettingsType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_rotation instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_rotations_in_four_key_frames(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Quat_32* out_rotations)
+	inline TimeSeriesType8 decompress_rotations_in_four_key_frames(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::quatf* out_rotations)
 	{
 		return decompress_rotations<4>(settings, header, decomp_context, sampling_context, out_rotations);
 	}
 
 	template<size_t num_key_frames, class SettingsAdapterType, class DecompressionContextType, class SamplingContextType>
 	//ACL_DEPRECATED("Use decompress_and_interpolate_vector instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_vectors(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Vector4_32* out_vectors)
+	inline TimeSeriesType8 decompress_vectors(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::vector4f* out_vectors)
 	{
 		TimeSeriesType8 time_series_type;
 
@@ -657,10 +661,10 @@ namespace acl
 					{
 						if (format != VectorFormat8::Vector3_Variable || !settings.is_vector_format_supported(VectorFormat8::Vector3_Variable) || !ignore_segment_range[i])
 						{
-							const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
-							const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (3 * sizeof(uint8_t)));
+							const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset);
+							const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[i] + sampling_context.segment_range_data_offset + (3 * sizeof(uint8_t)));
 
-							out_vectors[i] = vector_mul_add(out_vectors[i], segment_range_extent, segment_range_min);
+							out_vectors[i] = rtm::vector_mul_add(out_vectors[i], segment_range_extent, segment_range_min);
 						}
 					}
 
@@ -669,13 +673,13 @@ namespace acl
 
 				if (are_any_enum_flags_set(clip_range_reduction, range_reduction_flag))
 				{
-					const Vector4_32 clip_range_min = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
-					const Vector4_32 clip_range_extent = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (3 * sizeof(float)));
+					const rtm::vector4f clip_range_min = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
+					const rtm::vector4f clip_range_extent = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (3 * sizeof(float)));
 
 					for (size_t i = 0; i < num_key_frames; ++i)
 					{
 						if (!ignore_clip_range[i])
-							out_vectors[i] = vector_mul_add(out_vectors[i], clip_range_extent, clip_range_min);
+							out_vectors[i] = rtm::vector_mul_add(out_vectors[i], clip_range_extent, clip_range_min);
 					}
 
 					sampling_context.clip_range_data_offset += k_clip_range_reduction_vector3_range_size;
@@ -691,37 +695,37 @@ namespace acl
 
 	template<class SettingsAdapterType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_vector instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_vector(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Vector4_32* out_vectors)
+	inline TimeSeriesType8 decompress_vector(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::vector4f* out_vectors)
 	{
 		return decompress_vectors<1>(settings, header, decomp_context, sampling_context, out_vectors);
 	}
 
 	template<class SettingsAdapterType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_vector instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_vectors_in_two_key_frames(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Vector4_32* out_vectors)
+	inline TimeSeriesType8 decompress_vectors_in_two_key_frames(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::vector4f* out_vectors)
 	{
 		return decompress_vectors<2>(settings, header, decomp_context, sampling_context, out_vectors);
 	}
 
 	template<class SettingsAdapterType, class DecompressionContextType, class SamplingContextType>
 	ACL_DEPRECATED("Use decompress_and_interpolate_vector instead, to be removed in v2.0")
-	inline TimeSeriesType8 decompress_vectors_in_four_key_frames(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, Vector4_32* out_vectors)
+	inline TimeSeriesType8 decompress_vectors_in_four_key_frames(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context, rtm::vector4f* out_vectors)
 	{
 		return decompress_vectors<4>(settings, header, decomp_context, sampling_context, out_vectors);
 	}
 
 	template <class SettingsType, class DecompressionContextType, class SamplingContextType>
-	inline Quat_32 ACL_SIMD_CALL decompress_and_interpolate_rotation(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context)
+	inline rtm::quatf RTM_SIMD_CALL decompress_and_interpolate_rotation(const SettingsType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context)
 	{
 		static_assert(SamplingContextType::k_num_samples_to_interpolate == 2 || SamplingContextType::k_num_samples_to_interpolate == 4, "Unsupported number of samples");
 
-		Quat_32 interpolated_rotation;
+		rtm::quatf interpolated_rotation;
 
 		const BitSetIndexRef track_index_bit_ref(decomp_context.bitset_desc, sampling_context.track_index);
 		const bool is_sample_default = bitset_test(decomp_context.default_tracks_bitset, track_index_bit_ref);
 		if (is_sample_default)
 		{
-			interpolated_rotation = quat_identity_32();
+			interpolated_rotation = rtm::quat_identity();
 		}
 		else
 		{
@@ -742,11 +746,11 @@ namespace acl
 				else
 				{
 					ACL_ASSERT(false, "Unrecognized rotation format");
-					interpolated_rotation = quat_identity_32();
+					interpolated_rotation = rtm::quat_identity();
 				}
 
-				ACL_ASSERT(quat_is_finite(interpolated_rotation), "Rotation is not valid!");
-				ACL_ASSERT(quat_is_normalized(interpolated_rotation), "Rotation is not normalized!");
+				ACL_ASSERT(rtm::quat_is_finite(interpolated_rotation), "Rotation is not valid!");
+				ACL_ASSERT(rtm::quat_is_normalized(interpolated_rotation), "Rotation is not normalized!");
 
 				const RotationFormat8 packed_format = is_rotation_format_variable(rotation_format) ? get_highest_variant_precision(get_rotation_variant(rotation_format)) : rotation_format;
 				sampling_context.constant_track_data_offset += get_packed_rotation_size(packed_format);
@@ -761,7 +765,7 @@ namespace acl
 				constexpr size_t num_key_frames = SamplingContextType::k_num_samples_to_interpolate;
 
 				// This part is fairly complex, we'll loop and write to the stack (sampling context)
-				Vector4_32* rotations_as_vec = &sampling_context.vectors[0];
+				rtm::vector4f* rotations_as_vec = &sampling_context.vectors[0];
 
 				// Range ignore flags are used to skip range normalization at the clip and/or segment levels
 				// Each sample has two bits like so: sample 0 clip, sample 0 segment, sample 1 clip, sample 1 segment, etc
@@ -853,10 +857,10 @@ namespace acl
 				// We unroll because even if we work from the stack, with 2 samples the compiler always
 				// unrolls but it fails to keep the values in registers, working from the stack which
 				// is inefficient.
-				Vector4_32 rotation_as_vec0 = rotations_as_vec[0];
-				Vector4_32 rotation_as_vec1 = rotations_as_vec[1];
-				Vector4_32 rotation_as_vec2;
-				Vector4_32 rotation_as_vec3;
+				rtm::vector4f rotation_as_vec0 = rotations_as_vec[0];
+				rtm::vector4f rotation_as_vec1 = rotations_as_vec[1];
+				rtm::vector4f rotation_as_vec2;
+				rtm::vector4f rotation_as_vec3;
 
 				if (static_condition<num_key_frames == 4>::test())
 				{
@@ -881,36 +885,36 @@ namespace acl
 						constexpr uint32_t ignore_mask = 0x00000001U << ((num_key_frames - 1) * 2);
 						if ((range_ignore_flags & (ignore_mask >> 0)) == 0)
 						{
-							const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
-							const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
+							const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
+							const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
 
-							rotation_as_vec0 = vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
+							rotation_as_vec0 = rtm::vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
 						}
 
 						if ((range_ignore_flags & (ignore_mask >> 2)) == 0)
 						{
-							const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
-							const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
+							const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
+							const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
 
-							rotation_as_vec1 = vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
+							rotation_as_vec1 = rtm::vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
 						}
 
 						if (static_condition<num_key_frames == 4>::test())
 						{
 							if ((range_ignore_flags & (ignore_mask >> 4)) == 0)
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
 
-								rotation_as_vec2 = vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
+								rotation_as_vec2 = rtm::vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
 							}
 
 							if ((range_ignore_flags & (ignore_mask >> 8)) == 0)
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
 
-								rotation_as_vec3 = vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
+								rotation_as_vec3 = rtm::vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
 							}
 						}
 					}
@@ -919,66 +923,66 @@ namespace acl
 						if (rotation_format == RotationFormat8::Quat_128 && settings.is_rotation_format_supported(RotationFormat8::Quat_128))
 						{
 							{
-								const Vector4_32 segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[0] + segment_range_min_offset, true);
-								const Vector4_32 segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[0] + segment_range_extent_offset, true);
+								const rtm::vector4f segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[0] + segment_range_min_offset, true);
+								const rtm::vector4f segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[0] + segment_range_extent_offset, true);
 
-								rotation_as_vec0 = vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
+								rotation_as_vec0 = rtm::vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
 							}
 
 							{
-								const Vector4_32 segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[1] + segment_range_min_offset, true);
-								const Vector4_32 segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[1] + segment_range_extent_offset, true);
+								const rtm::vector4f segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[1] + segment_range_min_offset, true);
+								const rtm::vector4f segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[1] + segment_range_extent_offset, true);
 
-								rotation_as_vec1 = vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
+								rotation_as_vec1 = rtm::vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
 							}
 
 							if (static_condition<num_key_frames == 4>::test())
 							{
 								{
-									const Vector4_32 segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[2] + segment_range_min_offset, true);
-									const Vector4_32 segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[2] + segment_range_extent_offset, true);
+									const rtm::vector4f segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[2] + segment_range_min_offset, true);
+									const rtm::vector4f segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[2] + segment_range_extent_offset, true);
 
-									rotation_as_vec2 = vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
+									rotation_as_vec2 = rtm::vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
 								}
 
 								{
-									const Vector4_32 segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[3] + segment_range_min_offset, true);
-									const Vector4_32 segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[3] + segment_range_extent_offset, true);
+									const rtm::vector4f segment_range_min = unpack_vector4_32(decomp_context.segment_range_data[3] + segment_range_min_offset, true);
+									const rtm::vector4f segment_range_extent = unpack_vector4_32(decomp_context.segment_range_data[3] + segment_range_extent_offset, true);
 
-									rotation_as_vec3 = vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
+									rotation_as_vec3 = rtm::vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
 								}
 							}
 						}
 						else
 						{
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
 
-								rotation_as_vec0 = vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
+								rotation_as_vec0 = rtm::vector_mul_add(rotation_as_vec0, segment_range_extent, segment_range_min);
 							}
 
 							{
-								const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
-								const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
+								const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
+								const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
 
-								rotation_as_vec1 = vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
+								rotation_as_vec1 = rtm::vector_mul_add(rotation_as_vec1, segment_range_extent, segment_range_min);
 							}
 
 							if (static_condition<num_key_frames == 4>::test())
 							{
 								{
-									const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
-									const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
+									const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
+									const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
 
-									rotation_as_vec2 = vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
+									rotation_as_vec2 = rtm::vector_mul_add(rotation_as_vec2, segment_range_extent, segment_range_min);
 								}
 
 								{
-									const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
-									const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
+									const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
+									const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
 
-									rotation_as_vec3 = vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
+									rotation_as_vec3 = rtm::vector_mul_add(rotation_as_vec3, segment_range_extent, segment_range_min);
 								}
 							}
 						}
@@ -989,44 +993,44 @@ namespace acl
 
 				if (are_clip_rotations_normalized)
 				{
-					const Vector4_32 clip_range_min = vector_unaligned_load_32(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
-					const Vector4_32 clip_range_extent = vector_unaligned_load_32(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (num_rotation_components * sizeof(float)));
+					const rtm::vector4f clip_range_min = rtm::vector_load(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
+					const rtm::vector4f clip_range_extent = rtm::vector_load(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (num_rotation_components * sizeof(float)));
 
 					constexpr uint32_t ignore_mask = 0x00000002U << ((num_key_frames - 1) * 2);
 					if ((range_ignore_flags & (ignore_mask >> 0)) == 0)
-						rotation_as_vec0 = vector_mul_add(rotation_as_vec0, clip_range_extent, clip_range_min);
+						rotation_as_vec0 = rtm::vector_mul_add(rotation_as_vec0, clip_range_extent, clip_range_min);
 
 					if ((range_ignore_flags & (ignore_mask >> 2)) == 0)
-						rotation_as_vec1 = vector_mul_add(rotation_as_vec1, clip_range_extent, clip_range_min);
+						rotation_as_vec1 = rtm::vector_mul_add(rotation_as_vec1, clip_range_extent, clip_range_min);
 
 					if (static_condition<num_key_frames == 4>::test())
 					{
 						if ((range_ignore_flags & (ignore_mask >> 4)) == 0)
-							rotation_as_vec2 = vector_mul_add(rotation_as_vec2, clip_range_extent, clip_range_min);
+							rotation_as_vec2 = rtm::vector_mul_add(rotation_as_vec2, clip_range_extent, clip_range_min);
 
 						if ((range_ignore_flags & (ignore_mask >> 8)) == 0)
-							rotation_as_vec3 = vector_mul_add(rotation_as_vec3, clip_range_extent, clip_range_min);
+							rotation_as_vec3 = rtm::vector_mul_add(rotation_as_vec3, clip_range_extent, clip_range_min);
 					}
 
 					sampling_context.clip_range_data_offset += num_rotation_components * sizeof(float) * 2;
 				}
 
 				// No-op conversion
-				Quat_32 rotation0 = vector_to_quat(rotation_as_vec0);
-				Quat_32 rotation1 = vector_to_quat(rotation_as_vec1);
-				Quat_32 rotation2 = vector_to_quat(rotation_as_vec2);
-				Quat_32 rotation3 = vector_to_quat(rotation_as_vec3);
+				rtm::quatf rotation0 = rtm::vector_to_quat(rotation_as_vec0);
+				rtm::quatf rotation1 = rtm::vector_to_quat(rotation_as_vec1);
+				rtm::quatf rotation2 = rtm::vector_to_quat(rotation_as_vec2);
+				rtm::quatf rotation3 = rtm::vector_to_quat(rotation_as_vec3);
 
 				if (rotation_format != RotationFormat8::Quat_128 || !settings.is_rotation_format_supported(RotationFormat8::Quat_128))
 				{
 					// We dropped the W component
-					rotation0 = quat_from_positive_w(rotation_as_vec0);
-					rotation1 = quat_from_positive_w(rotation_as_vec1);
+					rotation0 = rtm::quat_from_positive_w(rotation_as_vec0);
+					rotation1 = rtm::quat_from_positive_w(rotation_as_vec1);
 
 					if (static_condition<num_key_frames == 4>::test())
 					{
-						rotation2 = quat_from_positive_w(rotation_as_vec2);
-						rotation3 = quat_from_positive_w(rotation_as_vec3);
+						rotation2 = rtm::quat_from_positive_w(rotation_as_vec2);
+						rotation3 = rtm::quat_from_positive_w(rotation_as_vec3);
 					}
 				}
 
@@ -1035,8 +1039,8 @@ namespace acl
 				else
 					interpolated_rotation = SamplingContextType::interpolate_rotation(rotation0, rotation1, decomp_context.interpolation_alpha);
 
-				ACL_ASSERT(quat_is_finite(interpolated_rotation), "Rotation is not valid!");
-				ACL_ASSERT(quat_is_normalized(interpolated_rotation), "Rotation is not normalized!");
+				ACL_ASSERT(rtm::quat_is_finite(interpolated_rotation), "Rotation is not valid!");
+				ACL_ASSERT(rtm::quat_is_normalized(interpolated_rotation), "Rotation is not normalized!");
 			}
 		}
 
@@ -1045,11 +1049,11 @@ namespace acl
 	}
 
 	template<class SettingsAdapterType, class DecompressionContextType, class SamplingContextType>
-	inline Vector4_32 ACL_SIMD_CALL decompress_and_interpolate_vector(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context)
+	inline rtm::vector4f RTM_SIMD_CALL decompress_and_interpolate_vector(const SettingsAdapterType& settings, const ClipHeader& header, const DecompressionContextType& decomp_context, SamplingContextType& sampling_context)
 	{
 		static_assert(SamplingContextType::k_num_samples_to_interpolate == 2 || SamplingContextType::k_num_samples_to_interpolate == 4, "Unsupported number of samples");
 
-		Vector4_32 interpolated_vector;
+		rtm::vector4f interpolated_vector;
 
 		const BitSetIndexRef track_index_bit_ref(decomp_context.bitset_desc, sampling_context.track_index);
 		const bool is_sample_default = bitset_test(decomp_context.default_tracks_bitset, track_index_bit_ref);
@@ -1064,7 +1068,7 @@ namespace acl
 			{
 				// Constant translation tracks store the remaining sample with full precision
 				interpolated_vector = unpack_vector3_96_unsafe(decomp_context.constant_track_data + sampling_context.constant_track_data_offset);
-				ACL_ASSERT(vector_is_finite3(interpolated_vector), "Vector is not valid!");
+				ACL_ASSERT(rtm::vector_is_finite3(interpolated_vector), "Vector is not valid!");
 
 				sampling_context.constant_track_data_offset += get_packed_vector_size(VectorFormat8::Vector3_96);
 			}
@@ -1077,7 +1081,7 @@ namespace acl
 				constexpr size_t num_key_frames = SamplingContextType::k_num_samples_to_interpolate;
 
 				// This part is fairly complex, we'll loop and write to the stack (sampling context)
-				Vector4_32* vectors = &sampling_context.vectors[0];
+				rtm::vector4f* vectors = &sampling_context.vectors[0];
 
 				// Range ignore flags are used to skip range normalization at the clip and/or segment levels
 				// Each sample has two bits like so: sample 0 clip, sample 0 segment, sample 1 clip, sample 1 segment, etc
@@ -1154,10 +1158,10 @@ namespace acl
 				// We unroll because even if we work from the stack, with 2 samples the compiler always
 				// unrolls but it fails to keep the values in registers, working from the stack which
 				// is inefficient.
-				Vector4_32 vector0 = vectors[0];
-				Vector4_32 vector1 = vectors[1];
-				Vector4_32 vector2;
-				Vector4_32 vector3;
+				rtm::vector4f vector0 = vectors[0];
+				rtm::vector4f vector1 = vectors[1];
+				rtm::vector4f vector2;
+				rtm::vector4f vector3;
 
 				if (static_condition<num_key_frames == 4>::test())
 				{
@@ -1179,36 +1183,36 @@ namespace acl
 					constexpr uint32_t ignore_mask = 0x00000001U << ((num_key_frames - 1) * 2);
 					if ((range_ignore_flags & (ignore_mask >> 0)) == 0)
 					{
-						const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
-						const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
+						const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_min_offset);
+						const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[0] + segment_range_extent_offset);
 
-						vector0 = vector_mul_add(vector0, segment_range_extent, segment_range_min);
+						vector0 = rtm::vector_mul_add(vector0, segment_range_extent, segment_range_min);
 					}
 
 					if ((range_ignore_flags & (ignore_mask >> 2)) == 0)
 					{
-						const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
-						const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
+						const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_min_offset);
+						const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[1] + segment_range_extent_offset);
 
-						vector1 = vector_mul_add(vector1, segment_range_extent, segment_range_min);
+						vector1 = rtm::vector_mul_add(vector1, segment_range_extent, segment_range_min);
 					}
 
 					if (static_condition<num_key_frames == 4>::test())
 					{
 						if ((range_ignore_flags & (ignore_mask >> 4)) == 0)
 						{
-							const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
-							const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
+							const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_min_offset);
+							const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[2] + segment_range_extent_offset);
 
-							vector2 = vector_mul_add(vector2, segment_range_extent, segment_range_min);
+							vector2 = rtm::vector_mul_add(vector2, segment_range_extent, segment_range_min);
 						}
 
 						if ((range_ignore_flags & (ignore_mask >> 8)) == 0)
 						{
-							const Vector4_32 segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
-							const Vector4_32 segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
+							const rtm::vector4f segment_range_min = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_min_offset);
+							const rtm::vector4f segment_range_extent = unpack_vector3_u24_unsafe(decomp_context.segment_range_data[3] + segment_range_extent_offset);
 
-							vector3 = vector_mul_add(vector3, segment_range_extent, segment_range_min);
+							vector3 = rtm::vector_mul_add(vector3, segment_range_extent, segment_range_min);
 						}
 					}
 
@@ -1217,23 +1221,23 @@ namespace acl
 
 				if (are_any_enum_flags_set(clip_range_reduction, range_reduction_flag))
 				{
-					const Vector4_32 clip_range_min = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
-					const Vector4_32 clip_range_extent = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (3 * sizeof(float)));
+					const rtm::vector4f clip_range_min = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset);
+					const rtm::vector4f clip_range_extent = unpack_vector3_96_unsafe(decomp_context.clip_range_data + sampling_context.clip_range_data_offset + (3 * sizeof(float)));
 
 					constexpr uint32_t ignore_mask = 0x00000002U << ((num_key_frames - 1) * 2);
 					if ((range_ignore_flags & (ignore_mask >> 0)) == 0)
-						vector0 = vector_mul_add(vector0, clip_range_extent, clip_range_min);
+						vector0 = rtm::vector_mul_add(vector0, clip_range_extent, clip_range_min);
 
 					if ((range_ignore_flags & (ignore_mask >> 2)) == 0)
-						vector1 = vector_mul_add(vector1, clip_range_extent, clip_range_min);
+						vector1 = rtm::vector_mul_add(vector1, clip_range_extent, clip_range_min);
 
 					if (static_condition<num_key_frames == 4>::test())
 					{
 						if ((range_ignore_flags & (ignore_mask >> 4)) == 0)
-							vector2 = vector_mul_add(vector2, clip_range_extent, clip_range_min);
+							vector2 = rtm::vector_mul_add(vector2, clip_range_extent, clip_range_min);
 
 						if ((range_ignore_flags & (ignore_mask >> 8)) == 0)
-							vector3 = vector_mul_add(vector3, clip_range_extent, clip_range_min);
+							vector3 = rtm::vector_mul_add(vector3, clip_range_extent, clip_range_min);
 					}
 
 					sampling_context.clip_range_data_offset += k_clip_range_reduction_vector3_range_size;
@@ -1244,7 +1248,7 @@ namespace acl
 				else
 					interpolated_vector = SamplingContextType::interpolate_vector4(vector0, vector1, decomp_context.interpolation_alpha);
 
-				ACL_ASSERT(vector_is_finite3(interpolated_vector), "Vector is not valid!");
+				ACL_ASSERT(rtm::vector_is_finite3(interpolated_vector), "Vector is not valid!");
 			}
 		}
 
diff --git a/includes/acl/decompression/default_output_writer.h b/includes/acl/decompression/default_output_writer.h
--- a/includes/acl/decompression/default_output_writer.h
+++ b/includes/acl/decompression/default_output_writer.h
@@ -26,7 +26,8 @@
 
 #include "acl/core/compiler_utils.h"
 #include "acl/decompression/output_writer.h"
-#include "acl/math/math_types.h"
+
+#include <rtm/types.h>
 
 #include <cstdint>
 
@@ -40,7 +41,7 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	struct DefaultOutputWriter : OutputWriter
 	{
-		DefaultOutputWriter(Transform_32* transforms, uint16_t num_transforms)
+		DefaultOutputWriter(rtm::qvvf* transforms, uint16_t num_transforms)
 			: m_transforms(transforms)
 			, m_num_transforms(num_transforms)
 		{
@@ -48,25 +49,25 @@ namespace acl
 			ACL_ASSERT(num_transforms != 0, "Transforms array cannot be empty");
 		}
 
-		void write_bone_rotation(uint16_t bone_index, const Quat_32& rotation)
+		void RTM_SIMD_CALL write_bone_rotation(uint16_t bone_index, rtm::quatf_arg0 rotation)
 		{
 			ACL_ASSERT(bone_index < m_num_transforms, "Invalid bone index. %u >= %u", bone_index, m_num_transforms);
 			m_transforms[bone_index].rotation = rotation;
 		}
 
-		void write_bone_translation(uint16_t bone_index, const Vector4_32& translation)
+		void RTM_SIMD_CALL write_bone_translation(uint16_t bone_index, rtm::vector4f_arg0 translation)
 		{
 			ACL_ASSERT(bone_index < m_num_transforms, "Invalid bone index. %u >= %u", bone_index, m_num_transforms);
 			m_transforms[bone_index].translation = translation;
 		}
 
-		void write_bone_scale(uint16_t bone_index, const Vector4_32& scale)
+		void RTM_SIMD_CALL write_bone_scale(uint16_t bone_index, rtm::vector4f_arg0 scale)
 		{
 			ACL_ASSERT(bone_index < m_num_transforms, "Invalid bone index. %u >= %u", bone_index, m_num_transforms);
 			m_transforms[bone_index].scale = scale;
 		}
 
-		Transform_32* m_transforms;
+		rtm::qvvf* m_transforms;
 		uint16_t m_num_transforms;
 	};
 }
diff --git a/includes/acl/decompression/impl/track_sampling_impl.h b/includes/acl/decompression/impl/track_sampling_impl.h
--- a/includes/acl/decompression/impl/track_sampling_impl.h
+++ b/includes/acl/decompression/impl/track_sampling_impl.h
@@ -61,9 +61,9 @@ namespace acl
 		};
 
 		// Assumes the 'vector_data' is in big-endian order and is padded in order to load up to 16 bytes from it
-		inline rtm::scalarf ACL_SIMD_CALL unpack_scalarf_96_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
+		inline rtm::scalarf RTM_SIMD_CALL unpack_scalarf_96_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
 		{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 			const uint32_t byte_offset = bit_offset / 8;
 			const uint32_t shift_offset = bit_offset % 8;
 			uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -74,7 +74,7 @@ namespace acl
 			const uint32_t x32 = uint32_t(vector_u64);
 
 			return _mm_castsi128_ps(_mm_set1_epi32(x32));
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 			const uint32_t byte_offset = bit_offset / 8;
 			const uint32_t shift_offset = bit_offset % 8;
 			uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -103,7 +103,7 @@ namespace acl
 		}
 
 		// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 16 bytes from it
-		inline rtm::scalarf ACL_SIMD_CALL unpack_scalarf_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
+		inline rtm::scalarf RTM_SIMD_CALL unpack_scalarf_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
 		{
 			ACL_ASSERT(num_bits <= 19, "This function does not support reading more than 19 bits per component");
 
@@ -128,7 +128,7 @@ namespace acl
 				PackedTableEntry(16), PackedTableEntry(17), PackedTableEntry(18), PackedTableEntry(19),
 			};
 
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 			const uint32_t bit_shift = 32 - num_bits;
 			const uint32_t mask = k_packed_constants[num_bits].mask;
 			const __m128 inv_max_value = _mm_load_ps1(&k_packed_constants[num_bits].max_value);
@@ -140,7 +140,7 @@ namespace acl
 
 			const __m128 value = _mm_cvtsi32_ss(inv_max_value, x32 & mask);
 			return _mm_mul_ss(value, inv_max_value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 			const uint32_t bit_shift = 32 - num_bits;
 			const uint32_t mask = k_packed_constants[num_bits].mask;
 			const float inv_max_value = k_packed_constants[num_bits].max_value;
diff --git a/includes/acl/decompression/output_writer.h b/includes/acl/decompression/output_writer.h
--- a/includes/acl/decompression/output_writer.h
+++ b/includes/acl/decompression/output_writer.h
@@ -25,8 +25,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 #include "acl/core/compiler_utils.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
+
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
 
 #include <cstdint>
 
@@ -57,7 +58,7 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Called by the decoder to write out a quaternion rotation value for a specified bone index.
-		void write_bone_rotation(uint16_t bone_index, const Quat_32& rotation)
+		void RTM_SIMD_CALL write_bone_rotation(uint16_t bone_index, rtm::quatf_arg0 rotation)
 		{
 			(void)bone_index;
 			(void)rotation;
@@ -65,7 +66,7 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Called by the decoder to write out a translation value for a specified bone index.
-		void write_bone_translation(uint16_t bone_index, const Vector4_32& translation)
+		void RTM_SIMD_CALL write_bone_translation(uint16_t bone_index, rtm::vector4f_arg0 translation)
 		{
 			(void)bone_index;
 			(void)translation;
@@ -73,7 +74,7 @@ namespace acl
 
 		//////////////////////////////////////////////////////////////////////////
 		// Called by the decoder to write out a scale value for a specified bone index.
-		void write_bone_scale(uint16_t bone_index, const Vector4_32& scale)
+		void RTM_SIMD_CALL write_bone_scale(uint16_t bone_index, rtm::vector4f_arg0 scale)
 		{
 			(void)bone_index;
 			(void)scale;
diff --git a/includes/acl/io/clip_reader.h b/includes/acl/io/clip_reader.h
--- a/includes/acl/io/clip_reader.h
+++ b/includes/acl/io/clip_reader.h
@@ -37,6 +37,9 @@
 #include "acl/core/string.h"
 #include "acl/core/unique_ptr.h"
 
+#include <rtm/quatd.h>
+#include <rtm/vector4d.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -385,7 +388,7 @@ namespace acl
 					goto parsing_error;
 			}
 
-			m_parser.try_read("constant_rotation_threshold_angle", constant_rotation_threshold_angle, double(default_settings.constant_rotation_threshold_angle));
+			m_parser.try_read("constant_rotation_threshold_angle", constant_rotation_threshold_angle, double(default_settings.constant_rotation_threshold_angle.as_radians()));
 			m_parser.try_read("constant_translation_threshold", constant_translation_threshold, double(default_settings.constant_translation_threshold));
 			m_parser.try_read("constant_scale_threshold", constant_scale_threshold, double(default_settings.constant_scale_threshold));
 			m_parser.try_read("error_threshold", error_threshold, double(default_settings.error_threshold));
@@ -440,7 +443,7 @@ namespace acl
 
 				out_settings->segmenting.range_reduction = segmenting_range_reduction;
 
-				out_settings->constant_rotation_threshold_angle = float(constant_rotation_threshold_angle);
+				out_settings->constant_rotation_threshold_angle = rtm::radians(float(constant_rotation_threshold_angle));
 				out_settings->constant_translation_threshold = float(constant_translation_threshold);
 				out_settings->constant_scale_threshold = float(constant_scale_threshold);
 				out_settings->error_threshold = float(error_threshold);
@@ -520,14 +523,14 @@ namespace acl
 			return UInt32ToFloat(value_u32).flt;
 		}
 
-		static Quat_64 hex_to_quat(const sjson::StringView values[4])
+		static rtm::quatd hex_to_quat(const sjson::StringView values[4])
 		{
-			return quat_set(hex_to_double(values[0]), hex_to_double(values[1]), hex_to_double(values[2]), hex_to_double(values[3]));
+			return rtm::quat_set(hex_to_double(values[0]), hex_to_double(values[1]), hex_to_double(values[2]), hex_to_double(values[3]));
 		}
 
-		static Vector4_64 hex_to_vector3(const sjson::StringView values[3])
+		static rtm::vector4d hex_to_vector3(const sjson::StringView values[3])
 		{
-			return vector_set(hex_to_double(values[0]), hex_to_double(values[1]), hex_to_double(values[2]));
+			return rtm::vector_set(hex_to_double(values[0]), hex_to_double(values[1]), hex_to_double(values[2]));
 		}
 
 		static rtm::float4f hex_to_float4f(const sjson::StringView values[4], uint32_t num_components)
@@ -609,15 +612,15 @@ namespace acl
 				{
 					double rotation[4] = { 0.0, 0.0, 0.0, 0.0 };
 					if (m_parser.try_read("bind_rotation", rotation, 4, 0.0) && !counting)
-						bone.bind_transform.rotation = quat_unaligned_load(&rotation[0]);
+						bone.bind_transform.rotation = rtm::quat_load(&rotation[0]);
 
 					double translation[3] = { 0.0, 0.0, 0.0 };
 					if (m_parser.try_read("bind_translation", translation, 3, 0.0) && !counting)
-						bone.bind_transform.translation = vector_unaligned_load3(&translation[0]);
+						bone.bind_transform.translation = rtm::vector_load3(&translation[0]);
 
 					double scale[3] = { 0.0, 0.0, 0.0 };
 					if (m_parser.try_read("bind_scale", scale, 3, 0.0) && !counting)
-						bone.bind_transform.scale = vector_unaligned_load3(&scale[0]);
+						bone.bind_transform.scale = rtm::vector_load3(&scale[0]);
 				}
 
 				if (!m_parser.object_ends())
@@ -943,7 +946,7 @@ namespace acl
 					else
 					{
 						for (uint32_t sample_index = 0; sample_index < m_additive_base_num_samples; ++sample_index)
-							bone.rotation_track.set_sample(sample_index, quat_identity_64());
+							bone.rotation_track.set_sample(sample_index, rtm::quat_identity());
 					}
 
 					if (m_parser.try_array_begins("translations"))
@@ -954,7 +957,7 @@ namespace acl
 					else
 					{
 						for (uint32_t sample_index = 0; sample_index < m_additive_base_num_samples; ++sample_index)
-							bone.translation_track.set_sample(sample_index, vector_zero_64());
+							bone.translation_track.set_sample(sample_index, rtm::vector_zero());
 					}
 
 					if (m_parser.try_array_begins("scales"))
@@ -965,7 +968,7 @@ namespace acl
 					else
 					{
 						for (uint32_t sample_index = 0; sample_index < m_additive_base_num_samples; ++sample_index)
-							bone.scale_track.set_sample(sample_index, vector_set(1.0));
+							bone.scale_track.set_sample(sample_index, rtm::vector_set(1.0));
 					}
 
 					if (!m_parser.object_ends())
@@ -1002,7 +1005,7 @@ namespace acl
 				else
 				{
 					for (uint32_t sample_index = 0; sample_index < m_num_samples; ++sample_index)
-						bone.rotation_track.set_sample(sample_index, quat_identity_64());
+						bone.rotation_track.set_sample(sample_index, rtm::quat_identity());
 				}
 
 				if (m_parser.try_array_begins("translations"))
@@ -1013,7 +1016,7 @@ namespace acl
 				else
 				{
 					for (uint32_t sample_index = 0; sample_index < m_num_samples; ++sample_index)
-						bone.translation_track.set_sample(sample_index, vector_zero_64());
+						bone.translation_track.set_sample(sample_index, rtm::vector_zero());
 				}
 
 				if (m_parser.try_array_begins("scales"))
@@ -1024,7 +1027,7 @@ namespace acl
 				else
 				{
 					for (uint32_t sample_index = 0; sample_index < m_num_samples; ++sample_index)
-						bone.scale_track.set_sample(sample_index, vector_set(1.0));
+						bone.scale_track.set_sample(sample_index, rtm::vector_set(1.0));
 				}
 
 				if (!m_parser.object_ends())
@@ -1047,7 +1050,7 @@ namespace acl
 				if (!m_parser.array_begins())
 					return false;
 
-				Quat_64 rotation;
+				rtm::quatd rotation;
 
 				if (m_is_binary_exact)
 				{
@@ -1063,7 +1066,7 @@ namespace acl
 					if (!m_parser.read(values, 4))
 						return false;
 
-					rotation = quat_unaligned_load(values);
+					rotation = rtm::quat_load(values);
 				}
 
 				if (!m_parser.array_ends())
@@ -1082,7 +1085,7 @@ namespace acl
 				if (!m_parser.array_begins())
 					return false;
 
-				Vector4_64 translation;
+				rtm::vector4d translation;
 
 				if (m_is_binary_exact)
 				{
@@ -1098,7 +1101,7 @@ namespace acl
 					if (!m_parser.read(values, 3))
 						return false;
 
-					translation = vector_unaligned_load3(values);
+					translation = rtm::vector_load3(values);
 				}
 
 				if (!m_parser.array_ends())
@@ -1117,7 +1120,7 @@ namespace acl
 				if (!m_parser.array_begins())
 					return false;
 
-				Vector4_64 scale;
+				rtm::vector4d scale;
 
 				if (m_is_binary_exact)
 				{
@@ -1133,7 +1136,7 @@ namespace acl
 					if (!m_parser.read(values, 3))
 						return false;
 
-					scale = vector_unaligned_load3(values);
+					scale = rtm::vector_load3(values);
 				}
 
 				if (!m_parser.array_ends())
diff --git a/includes/acl/io/clip_writer.h b/includes/acl/io/clip_writer.h
--- a/includes/acl/io/clip_writer.h
+++ b/includes/acl/io/clip_writer.h
@@ -34,6 +34,9 @@
 #include "acl/core/iallocator.h"
 #include "acl/core/error.h"
 
+#include <rtm/quatd.h>
+#include <rtm/vector4d.h>
+
 #include <cstdint>
 #include <cinttypes>
 #include <cstdio>
@@ -118,7 +121,7 @@ namespace acl
 					segmenting_writer["scale_range_reduction"] = are_any_enum_flags_set(settings.segmenting.range_reduction, RangeReductionFlags8::Scales);
 				};
 
-				settings_writer["constant_rotation_threshold_angle"] = settings.constant_rotation_threshold_angle;
+				settings_writer["constant_rotation_threshold_angle"] = settings.constant_rotation_threshold_angle.as_radians();
 				settings_writer["constant_translation_threshold"] = settings.constant_translation_threshold;
 				settings_writer["constant_scale_threshold"] = settings.constant_scale_threshold;
 				settings_writer["error_threshold"] = settings.error_threshold;
@@ -147,34 +150,34 @@ namespace acl
 						bone_writer["parent"] = bone.is_root() ? "" : parent_bone.name.c_str();
 						bone_writer["vertex_distance"] = bone.vertex_distance;
 
-						if (!quat_near_identity(bone.bind_transform.rotation))
+						if (!rtm::quat_near_identity(bone.bind_transform.rotation))
 						{
 							bone_writer["bind_rotation"] = [&](sjson::ArrayWriter& rot_writer)
 							{
-								rot_writer.push(format_hex_double(quat_get_x(bone.bind_transform.rotation), buffer, sizeof(buffer)));
-								rot_writer.push(format_hex_double(quat_get_y(bone.bind_transform.rotation), buffer, sizeof(buffer)));
-								rot_writer.push(format_hex_double(quat_get_z(bone.bind_transform.rotation), buffer, sizeof(buffer)));
-								rot_writer.push(format_hex_double(quat_get_w(bone.bind_transform.rotation), buffer, sizeof(buffer)));
+								rot_writer.push(format_hex_double(rtm::quat_get_x(bone.bind_transform.rotation), buffer, sizeof(buffer)));
+								rot_writer.push(format_hex_double(rtm::quat_get_y(bone.bind_transform.rotation), buffer, sizeof(buffer)));
+								rot_writer.push(format_hex_double(rtm::quat_get_z(bone.bind_transform.rotation), buffer, sizeof(buffer)));
+								rot_writer.push(format_hex_double(rtm::quat_get_w(bone.bind_transform.rotation), buffer, sizeof(buffer)));
 							};
 						}
 
-						if (!vector_all_near_equal3(bone.bind_transform.translation, vector_zero_64()))
+						if (!rtm::vector_all_near_equal3(bone.bind_transform.translation, rtm::vector_zero()))
 						{
 							bone_writer["bind_translation"] = [&](sjson::ArrayWriter& trans_writer)
 							{
-								trans_writer.push(format_hex_double(vector_get_x(bone.bind_transform.translation), buffer, sizeof(buffer)));
-								trans_writer.push(format_hex_double(vector_get_y(bone.bind_transform.translation), buffer, sizeof(buffer)));
-								trans_writer.push(format_hex_double(vector_get_z(bone.bind_transform.translation), buffer, sizeof(buffer)));
+								trans_writer.push(format_hex_double(rtm::vector_get_x(bone.bind_transform.translation), buffer, sizeof(buffer)));
+								trans_writer.push(format_hex_double(rtm::vector_get_y(bone.bind_transform.translation), buffer, sizeof(buffer)));
+								trans_writer.push(format_hex_double(rtm::vector_get_z(bone.bind_transform.translation), buffer, sizeof(buffer)));
 							};
 						}
 
-						if (!vector_all_near_equal3(bone.bind_transform.scale, vector_set(1.0)))
+						if (!rtm::vector_all_near_equal3(bone.bind_transform.scale, rtm::vector_set(1.0)))
 						{
 							bone_writer["bind_scale"] = [&](sjson::ArrayWriter& scale_writer)
 							{
-								scale_writer.push(format_hex_double(vector_get_x(bone.bind_transform.scale), buffer, sizeof(buffer)));
-								scale_writer.push(format_hex_double(vector_get_y(bone.bind_transform.scale), buffer, sizeof(buffer)));
-								scale_writer.push(format_hex_double(vector_get_z(bone.bind_transform.scale), buffer, sizeof(buffer)));
+								scale_writer.push(format_hex_double(rtm::vector_get_x(bone.bind_transform.scale), buffer, sizeof(buffer)));
+								scale_writer.push(format_hex_double(rtm::vector_get_y(bone.bind_transform.scale), buffer, sizeof(buffer)));
+								scale_writer.push(format_hex_double(rtm::vector_get_z(bone.bind_transform.scale), buffer, sizeof(buffer)));
 							};
 						}
 					});
@@ -209,13 +212,13 @@ namespace acl
 
 							for (uint32_t sample_index = 0; sample_index < num_rotation_samples; ++sample_index)
 							{
-								const Quat_64 rotation = bone.rotation_track.get_sample(sample_index);
+								const rtm::quatd rotation = bone.rotation_track.get_sample(sample_index);
 								rotations_writer.push([&](sjson::ArrayWriter& rot_writer)
 								{
-									rot_writer.push(format_hex_double(quat_get_x(rotation), buffer, sizeof(buffer)));
-									rot_writer.push(format_hex_double(quat_get_y(rotation), buffer, sizeof(buffer)));
-									rot_writer.push(format_hex_double(quat_get_z(rotation), buffer, sizeof(buffer)));
-									rot_writer.push(format_hex_double(quat_get_w(rotation), buffer, sizeof(buffer)));
+									rot_writer.push(format_hex_double(rtm::quat_get_x(rotation), buffer, sizeof(buffer)));
+									rot_writer.push(format_hex_double(rtm::quat_get_y(rotation), buffer, sizeof(buffer)));
+									rot_writer.push(format_hex_double(rtm::quat_get_z(rotation), buffer, sizeof(buffer)));
+									rot_writer.push(format_hex_double(rtm::quat_get_w(rotation), buffer, sizeof(buffer)));
 								});
 								rotations_writer.push_newline();
 							}
@@ -229,12 +232,12 @@ namespace acl
 
 							for (uint32_t sample_index = 0; sample_index < num_translation_samples; ++sample_index)
 							{
-								const Vector4_64 translation = bone.translation_track.get_sample(sample_index);
+								const rtm::vector4d translation = bone.translation_track.get_sample(sample_index);
 								translations_writer.push([&](sjson::ArrayWriter& trans_writer)
 								{
-									trans_writer.push(format_hex_double(vector_get_x(translation), buffer, sizeof(buffer)));
-									trans_writer.push(format_hex_double(vector_get_y(translation), buffer, sizeof(buffer)));
-									trans_writer.push(format_hex_double(vector_get_z(translation), buffer, sizeof(buffer)));
+									trans_writer.push(format_hex_double(rtm::vector_get_x(translation), buffer, sizeof(buffer)));
+									trans_writer.push(format_hex_double(rtm::vector_get_y(translation), buffer, sizeof(buffer)));
+									trans_writer.push(format_hex_double(rtm::vector_get_z(translation), buffer, sizeof(buffer)));
 								});
 								translations_writer.push_newline();
 							}
@@ -248,12 +251,12 @@ namespace acl
 
 							for (uint32_t sample_index = 0; sample_index < num_scale_samples; ++sample_index)
 							{
-								const Vector4_64 scale = bone.scale_track.get_sample(sample_index);
+								const rtm::vector4d scale = bone.scale_track.get_sample(sample_index);
 								scales_writer.push([&](sjson::ArrayWriter& scale_writer)
 								{
-									scale_writer.push(format_hex_double(vector_get_x(scale), buffer, sizeof(buffer)));
-									scale_writer.push(format_hex_double(vector_get_y(scale), buffer, sizeof(buffer)));
-									scale_writer.push(format_hex_double(vector_get_z(scale), buffer, sizeof(buffer)));
+									scale_writer.push(format_hex_double(rtm::vector_get_x(scale), buffer, sizeof(buffer)));
+									scale_writer.push(format_hex_double(rtm::vector_get_y(scale), buffer, sizeof(buffer)));
+									scale_writer.push(format_hex_double(rtm::vector_get_z(scale), buffer, sizeof(buffer)));
 								});
 								scales_writer.push_newline();
 							}
diff --git a/includes/acl/math/affine_matrix_32.h b/includes/acl/math/affine_matrix_32.h
deleted file mode 100644
--- a/includes/acl/math/affine_matrix_32.h
+++ /dev/null
@@ -1,380 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/math/math.h"
-#include "acl/math/vector4_32.h"
-#include "acl/math/quat_32.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// An 4x4 affine matrix represents a 3D rotation, 3D translation, and 3D scale.
-	// It properly deals with skew/shear when present but once scale with mirroring is combined,
-	// it cannot be safely extracted back.
-	//
-	// Affine matrices have their last column always equal to [0, 0, 0, 1]
-	//
-	// X axis == forward
-	// Y axis == right
-	// Z axis == up
-	//////////////////////////////////////////////////////////////////////////
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_set(Vector4_32Arg0 x_axis, Vector4_32Arg1 y_axis, Vector4_32Arg2 z_axis, Vector4_32Arg3 w_axis)
-	{
-		ACL_ASSERT(vector_get_w(x_axis) == 0.0F, "X axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(y_axis) == 0.0F, "Y axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(z_axis) == 0.0F, "Z axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(w_axis) == 1.0F, "W axis does not have a W component == 1.0");
-		return AffineMatrix_32{x_axis, y_axis, z_axis, w_axis};
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_set(Quat_32Arg0 quat, Vector4_32Arg1 translation, Vector4_32Arg2 scale)
-	{
-		ACL_ASSERT(quat_is_normalized(quat), "Quaternion is not normalized");
-
-		const float x2 = quat_get_x(quat) + quat_get_x(quat);
-		const float y2 = quat_get_y(quat) + quat_get_y(quat);
-		const float z2 = quat_get_z(quat) + quat_get_z(quat);
-		const float xx = quat_get_x(quat) * x2;
-		const float xy = quat_get_x(quat) * y2;
-		const float xz = quat_get_x(quat) * z2;
-		const float yy = quat_get_y(quat) * y2;
-		const float yz = quat_get_y(quat) * z2;
-		const float zz = quat_get_z(quat) * z2;
-		const float wx = quat_get_w(quat) * x2;
-		const float wy = quat_get_w(quat) * y2;
-		const float wz = quat_get_w(quat) * z2;
-
-		Vector4_32 x_axis = vector_mul(vector_set(1.0F - (yy + zz), xy + wz, xz - wy, 0.0F), vector_get_x(scale));
-		Vector4_32 y_axis = vector_mul(vector_set(xy - wz, 1.0F - (xx + zz), yz + wx, 0.0F), vector_get_y(scale));
-		Vector4_32 z_axis = vector_mul(vector_set(xz + wy, yz - wx, 1.0F - (xx + yy), 0.0F), vector_get_z(scale));
-		Vector4_32 w_axis = vector_set(vector_get_x(translation), vector_get_y(translation), vector_get_z(translation), 1.0F);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_identity_32()
-	{
-		return matrix_set(vector_set(1.0F, 0.0F, 0.0F, 0.0F), vector_set(0.0F, 1.0F, 0.0F, 0.0F), vector_set(0.0F, 0.0F, 1.0F, 0.0F), vector_set(0.0F, 0.0F, 0.0F, 1.0F));
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_cast(const AffineMatrix_64& input)
-	{
-		return matrix_set(vector_cast(input.x_axis), vector_cast(input.y_axis), vector_cast(input.z_axis), vector_cast(input.w_axis));
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_from_quat(Quat_32Arg0 quat)
-	{
-		ACL_ASSERT(quat_is_normalized(quat), "Quaternion is not normalized");
-
-		const float x2 = quat_get_x(quat) + quat_get_x(quat);
-		const float y2 = quat_get_y(quat) + quat_get_y(quat);
-		const float z2 = quat_get_z(quat) + quat_get_z(quat);
-		const float xx = quat_get_x(quat) * x2;
-		const float xy = quat_get_x(quat) * y2;
-		const float xz = quat_get_x(quat) * z2;
-		const float yy = quat_get_y(quat) * y2;
-		const float yz = quat_get_y(quat) * z2;
-		const float zz = quat_get_z(quat) * z2;
-		const float wx = quat_get_w(quat) * x2;
-		const float wy = quat_get_w(quat) * y2;
-		const float wz = quat_get_w(quat) * z2;
-
-		Vector4_32 x_axis = vector_set(1.0F - (yy + zz), xy + wz, xz - wy, 0.0F);
-		Vector4_32 y_axis = vector_set(xy - wz, 1.0F - (xx + zz), yz + wx, 0.0F);
-		Vector4_32 z_axis = vector_set(xz + wy, yz - wx, 1.0F - (xx + yy), 0.0F);
-		Vector4_32 w_axis = vector_set(0.0F, 0.0F, 0.0F, 1.0F);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_from_translation(Vector4_32Arg0 translation)
-	{
-		return matrix_set(vector_set(1.0F, 0.0F, 0.0F, 0.0F), vector_set(0.0F, 1.0F, 0.0F, 0.0F), vector_set(0.0F, 0.0F, 1.0F, 0.0F), vector_set(vector_get_x(translation), vector_get_y(translation), vector_get_z(translation), 1.0F));
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_from_scale(Vector4_32Arg0 scale)
-	{
-		return matrix_set(vector_set(vector_get_x(scale), 0.0F, 0.0F, 0.0F), vector_set(0.0F, vector_get_y(scale), 0.0F, 0.0F), vector_set(0.0F, 0.0F, vector_get_z(scale), 0.0F), vector_set(0.0F, 0.0F, 0.0F, 1.0F));
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_from_transform(Transform_32Arg0 transform)
-	{
-		return matrix_set(transform.rotation, transform.translation, transform.scale);
-	}
-
-	inline const Vector4_32& matrix_get_axis(const AffineMatrix_32& input, MatrixAxis axis)
-	{
-		switch (axis)
-		{
-		case MatrixAxis::X: return input.x_axis;
-		case MatrixAxis::Y: return input.y_axis;
-		case MatrixAxis::Z: return input.z_axis;
-		case MatrixAxis::W: return input.w_axis;
-		default:
-			ACL_ASSERT(false, "Invalid matrix axis");
-			return input.x_axis;
-		}
-	}
-
-	inline Vector4_32& matrix_get_axis(AffineMatrix_32& input, MatrixAxis axis)
-	{
-		switch (axis)
-		{
-		case MatrixAxis::X: return input.x_axis;
-		case MatrixAxis::Y: return input.y_axis;
-		case MatrixAxis::Z: return input.z_axis;
-		case MatrixAxis::W: return input.w_axis;
-		default:
-			ACL_ASSERT(false, "Invalid matrix axis");
-			return input.x_axis;
-		}
-	}
-
-	constexpr Vector4_32 ACL_SIMD_CALL matrix_get_axis(Vector4_32Arg0 x_axis, Vector4_32Arg1 y_axis, Vector4_32Arg2 z_axis, Vector4_32Arg3 w_axis, MatrixAxis axis)
-	{
-		return axis == MatrixAxis::X ? x_axis : (axis == MatrixAxis::Y ? y_axis : (axis == MatrixAxis::Z ? z_axis : w_axis));
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_from_matrix(AffineMatrix_32Arg0 input)
-	{
-		if (vector_all_near_equal3(input.x_axis, vector_zero_32()) || vector_all_near_equal3(input.y_axis, vector_zero_32()) || vector_all_near_equal3(input.z_axis, vector_zero_32()))
-		{
-			// Zero scale not supported, return the identity
-			return quat_identity_32();
-		}
-
-		const float mtx_trace = vector_get_x(input.x_axis) + vector_get_y(input.y_axis) + vector_get_z(input.z_axis);
-		if (mtx_trace > 0.0F)
-		{
-			const float inv_trace = sqrt_reciprocal(mtx_trace + 1.0F);
-			const float half_inv_trace = inv_trace * 0.5F;
-
-			const float x = (vector_get_z(input.y_axis) - vector_get_y(input.z_axis)) * half_inv_trace;
-			const float y = (vector_get_x(input.z_axis) - vector_get_z(input.x_axis)) * half_inv_trace;
-			const float z = (vector_get_y(input.x_axis) - vector_get_x(input.y_axis)) * half_inv_trace;
-			const float w = reciprocal(inv_trace) * 0.5F;
-
-			return quat_normalize(quat_set(x, y, z, w));
-		}
-		else
-		{
-			int8_t best_axis = 0;
-			if (vector_get_y(input.y_axis) > vector_get_x(input.x_axis))
-				best_axis = 1;
-			if (vector_get_z(input.z_axis) > vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(best_axis)))
-				best_axis = 2;
-
-			const int8_t next_best_axis = (best_axis + 1) % 3;
-			const int8_t next_next_best_axis = (next_best_axis + 1) % 3;
-
-			const float mtx_pseudo_trace = 1.0F +
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(best_axis)) -
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(next_best_axis)) -
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(next_next_best_axis));
-
-			const float inv_pseudo_trace = sqrt_reciprocal(mtx_pseudo_trace);
-			const float half_inv_pseudo_trace = inv_pseudo_trace * 0.5F;
-
-			float quat_values[4];
-			quat_values[best_axis] = reciprocal(inv_pseudo_trace) * 0.5F;
-			quat_values[next_best_axis] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(next_best_axis)) +
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(best_axis)));
-			quat_values[next_next_best_axis] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(next_next_best_axis)) +
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(best_axis)));
-			quat_values[3] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(next_next_best_axis)) -
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(next_best_axis)));
-
-			return quat_normalize(quat_unaligned_load(&quat_values[0]));
-		}
-	}
-
-	// Multiplication order is as follow: local_to_world = matrix_mul(local_to_object, object_to_world)
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_mul(AffineMatrix_32Arg0 lhs, AffineMatrix_32ArgN rhs)
-	{
-		Vector4_32 tmp = vector_mul(vector_mix_xxxx(lhs.x_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.x_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.x_axis), rhs.z_axis, tmp);
-		Vector4_32 x_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.y_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.y_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.y_axis), rhs.z_axis, tmp);
-		Vector4_32 y_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.z_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.z_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.z_axis), rhs.z_axis, tmp);
-		Vector4_32 z_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.w_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.w_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.w_axis), rhs.z_axis, tmp);
-		Vector4_32 w_axis = vector_add(rhs.w_axis, tmp);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL matrix_mul_position(AffineMatrix_32Arg0 lhs, Vector4_32Arg4 rhs)
-	{
-		Vector4_32 tmp0;
-		Vector4_32 tmp1;
-
-		tmp0 = vector_mul(vector_mix_xxxx(rhs), lhs.x_axis);
-		tmp0 = vector_mul_add(vector_mix_yyyy(rhs), lhs.y_axis, tmp0);
-		tmp1 = vector_mul_add(vector_mix_zzzz(rhs), lhs.z_axis, lhs.w_axis);
-
-		return vector_add(tmp0, tmp1);
-	}
-
-	namespace math_impl
-	{
-		// Note: This is a generic matrix 4x4 transpose, the resulting matrix is no longer
-		// affine because the last column is no longer [0,0,0,1]
-		inline AffineMatrix_32 ACL_SIMD_CALL matrix_transpose(AffineMatrix_32Arg0 input)
-		{
-			Vector4_32 tmp0 = vector_mix_xyab(input.x_axis, input.y_axis);
-			Vector4_32 tmp1 = vector_mix_zwcd(input.x_axis, input.y_axis);
-			Vector4_32 tmp2 = vector_mix_xyab(input.z_axis, input.w_axis);
-			Vector4_32 tmp3 = vector_mix_zwcd(input.z_axis, input.w_axis);
-
-			Vector4_32 x_axis = vector_mix_xzac(tmp0, tmp2);
-			Vector4_32 y_axis = vector_mix_ywbd(tmp0, tmp2);
-			Vector4_32 z_axis = vector_mix_xzac(tmp1, tmp3);
-			Vector4_32 w_axis = vector_mix_ywbd(tmp1, tmp3);
-			return AffineMatrix_32{ x_axis, y_axis, z_axis, w_axis };
-		}
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_inverse(AffineMatrix_32Arg0 input)
-	{
-		// TODO: This is a generic matrix inverse function, implement the affine version?
-		AffineMatrix_32 input_transposed = math_impl::matrix_transpose(input);
-
-		Vector4_32 v00 = vector_mix_xxyy(input_transposed.z_axis);
-		Vector4_32 v01 = vector_mix_xxyy(input_transposed.x_axis);
-		Vector4_32 v02 = vector_mix_xzac(input_transposed.z_axis, input_transposed.x_axis);
-		Vector4_32 v10 = vector_mix_zwzw(input_transposed.w_axis);
-		Vector4_32 v11 = vector_mix_zwzw(input_transposed.y_axis);
-		Vector4_32 v12 = vector_mix_ywbd(input_transposed.w_axis, input_transposed.y_axis);
-
-		Vector4_32 d0 = vector_mul(v00, v10);
-		Vector4_32 d1 = vector_mul(v01, v11);
-		Vector4_32 d2 = vector_mul(v02, v12);
-
-		v00 = vector_mix_zwzw(input_transposed.z_axis);
-		v01 = vector_mix_zwzw(input_transposed.x_axis);
-		v02 = vector_mix_ywbd(input_transposed.z_axis, input_transposed.x_axis);
-		v10 = vector_mix_xxyy(input_transposed.w_axis);
-		v11 = vector_mix_xxyy(input_transposed.y_axis);
-		v12 = vector_mix_xzac(input_transposed.w_axis, input_transposed.y_axis);
-
-		d0 = vector_neg_mul_sub(v00, v10, d0);
-		d1 = vector_neg_mul_sub(v01, v11, d1);
-		d2 = vector_neg_mul_sub(v02, v12, d2);
-
-		v00 = vector_mix_yzxy(input_transposed.y_axis);
-		v01 = vector_mix_zxyx(input_transposed.x_axis);
-		v02 = vector_mix_yzxy(input_transposed.w_axis);
-		Vector4_32 v03 = vector_mix_zxyx(input_transposed.z_axis);
-		v10 = vector_mix_bywx(d0, d2);
-		v11 = vector_mix_wbyz(d0, d2);
-		v12 = vector_mix_dywx(d1, d2);
-		Vector4_32 v13 = vector_mix_wdyz(d1, d2);
-
-		Vector4_32 c0 = vector_mul(v00, v10);
-		Vector4_32 c2 = vector_mul(v01, v11);
-		Vector4_32 c4 = vector_mul(v02, v12);
-		Vector4_32 c6 = vector_mul(v03, v13);
-
-		v00 = vector_mix_zwyz(input_transposed.y_axis);
-		v01 = vector_mix_wzwy(input_transposed.x_axis);
-		v02 = vector_mix_zwyz(input_transposed.w_axis);
-		v03 = vector_mix_wzwy(input_transposed.z_axis);
-		v10 = vector_mix_wxya(d0, d2);
-		v11 = vector_mix_zyax(d0, d2);
-		v12 = vector_mix_wxyc(d1, d2);
-		v13 = vector_mix_zycx(d1, d2);
-
-		c0 = vector_neg_mul_sub(v00, v10, c0);
-		c2 = vector_neg_mul_sub(v01, v11, c2);
-		c4 = vector_neg_mul_sub(v02, v12, c4);
-		c6 = vector_neg_mul_sub(v03, v13, c6);
-
-		v00 = vector_mix_wxwx(input_transposed.y_axis);
-		v01 = vector_mix_ywxz(input_transposed.x_axis);
-		v02 = vector_mix_wxwx(input_transposed.w_axis);
-		v03 = vector_mix_ywxz(input_transposed.z_axis);
-		v10 = vector_mix_zbaz(d0, d2);
-		v11 = vector_mix_bxwa(d0, d2);
-		v12 = vector_mix_zdcz(d1, d2);
-		v13 = vector_mix_dxwc(d1, d2);
-
-		Vector4_32 c1 = vector_neg_mul_sub(v00, v10, c0);
-		c0 = vector_mul_add(v00, v10, c0);
-		Vector4_32 c3 = vector_mul_add(v01, v11, c2);
-		c2 = vector_neg_mul_sub(v01, v11, c2);
-		Vector4_32 c5 = vector_neg_mul_sub(v02, v12, c4);
-		c4 = vector_mul_add(v02, v12, c4);
-		Vector4_32 c7 = vector_mul_add(v03, v13, c6);
-		c6 = vector_neg_mul_sub(v03, v13, c6);
-
-		Vector4_32 x_axis = vector_mix_xbzd(c0, c1);
-		Vector4_32 y_axis = vector_mix_xbzd(c2, c3);
-		Vector4_32 z_axis = vector_mix_xbzd(c4, c5);
-		Vector4_32 w_axis = vector_mix_xbzd(c6, c7);
-
-		float det = vector_dot(x_axis, input_transposed.x_axis);
-		Vector4_32 inv_det = vector_set(reciprocal(det));
-
-		x_axis = vector_mul(x_axis, inv_det);
-		y_axis = vector_mul(y_axis, inv_det);
-		z_axis = vector_mul(z_axis, inv_det);
-		w_axis = vector_mul(w_axis, inv_det);
-
-#if defined(ACL_NO_INTRINSICS)
-		w_axis = vector_set(vector_get_x(w_axis), vector_get_y(w_axis), vector_get_z(w_axis), 1.0f);
-#endif
-
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_32 ACL_SIMD_CALL matrix_remove_scale(AffineMatrix_32Arg0 input)
-	{
-		AffineMatrix_32 result;
-		result.x_axis = vector_normalize3(input.x_axis);
-		result.y_axis = vector_normalize3(input.y_axis);
-		result.z_axis = vector_normalize3(input.z_axis);
-		result.w_axis = input.w_axis;
-		return result;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/affine_matrix_64.h b/includes/acl/math/affine_matrix_64.h
deleted file mode 100644
--- a/includes/acl/math/affine_matrix_64.h
+++ /dev/null
@@ -1,381 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/math/math.h"
-#include "acl/math/vector4_64.h"
-#include "acl/math/quat_64.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// An 4x4 affine matrix represents a 3D rotation, 3D translation, and 3D scale.
-	// It properly deals with skew/shear when present but once scale with mirroring is combined,
-	// it cannot be safely extracted back.
-	//
-	// Affine matrices have their last column always equal to [0, 0, 0, 1]
-	//
-	// X axis == forward
-	// Y axis == right
-	// Z axis == up
-	//////////////////////////////////////////////////////////////////////////
-
-	inline AffineMatrix_64 matrix_set(const Vector4_64& x_axis, const Vector4_64& y_axis, const Vector4_64& z_axis, const Vector4_64& w_axis)
-	{
-		ACL_ASSERT(vector_get_w(x_axis) == 0.0, "X axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(y_axis) == 0.0, "Y axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(z_axis) == 0.0, "Z axis does not have a W component == 0.0");
-		ACL_ASSERT(vector_get_w(w_axis) == 1.0, "W axis does not have a W component == 1.0");
-		return AffineMatrix_64{x_axis, y_axis, z_axis, w_axis};
-	}
-
-	inline AffineMatrix_64 matrix_set(const Quat_64& quat, const Vector4_64& translation, const Vector4_64& scale)
-	{
-		ACL_ASSERT(quat_is_normalized(quat), "Quaternion is not normalized");
-
-		const double x2 = quat_get_x(quat) + quat_get_x(quat);
-		const double y2 = quat_get_y(quat) + quat_get_y(quat);
-		const double z2 = quat_get_z(quat) + quat_get_z(quat);
-		const double xx = quat_get_x(quat) * x2;
-		const double xy = quat_get_x(quat) * y2;
-		const double xz = quat_get_x(quat) * z2;
-		const double yy = quat_get_y(quat) * y2;
-		const double yz = quat_get_y(quat) * z2;
-		const double zz = quat_get_z(quat) * z2;
-		const double wx = quat_get_w(quat) * x2;
-		const double wy = quat_get_w(quat) * y2;
-		const double wz = quat_get_w(quat) * z2;
-
-		Vector4_64 x_axis = vector_mul(vector_set(1.0 - (yy + zz), xy + wz, xz - wy, 0.0), vector_get_x(scale));
-		Vector4_64 y_axis = vector_mul(vector_set(xy - wz, 1.0 - (xx + zz), yz + wx, 0.0), vector_get_y(scale));
-		Vector4_64 z_axis = vector_mul(vector_set(xz + wy, yz - wx, 1.0 - (xx + yy), 0.0), vector_get_z(scale));
-		Vector4_64 w_axis = vector_set(vector_get_x(translation), vector_get_y(translation), vector_get_z(translation), 1.0);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_64 matrix_identity_64()
-	{
-		return matrix_set(vector_set(1.0, 0.0, 0.0, 0.0), vector_set(0.0, 1.0, 0.0, 0.0), vector_set(0.0, 0.0, 1.0, 0.0), vector_set(0.0, 0.0, 0.0, 1.0));
-	}
-
-	inline AffineMatrix_64 matrix_cast(const AffineMatrix_32& input)
-	{
-		return matrix_set(vector_cast(input.x_axis), vector_cast(input.y_axis), vector_cast(input.z_axis), vector_cast(input.w_axis));
-	}
-
-	inline AffineMatrix_64 matrix_from_quat(const Quat_64& quat)
-	{
-		ACL_ASSERT(quat_is_normalized(quat), "Quaternion is not normalized");
-
-		const double x2 = quat_get_x(quat) + quat_get_x(quat);
-		const double y2 = quat_get_y(quat) + quat_get_y(quat);
-		const double z2 = quat_get_z(quat) + quat_get_z(quat);
-		const double xx = quat_get_x(quat) * x2;
-		const double xy = quat_get_x(quat) * y2;
-		const double xz = quat_get_x(quat) * z2;
-		const double yy = quat_get_y(quat) * y2;
-		const double yz = quat_get_y(quat) * z2;
-		const double zz = quat_get_z(quat) * z2;
-		const double wx = quat_get_w(quat) * x2;
-		const double wy = quat_get_w(quat) * y2;
-		const double wz = quat_get_w(quat) * z2;
-
-		Vector4_64 x_axis = vector_set(1.0 - (yy + zz), xy + wz, xz - wy, 0.0);
-		Vector4_64 y_axis = vector_set(xy - wz, 1.0 - (xx + zz), yz + wx, 0.0);
-		Vector4_64 z_axis = vector_set(xz + wy, yz - wx, 1.0 - (xx + yy), 0.0);
-		Vector4_64 w_axis = vector_set(0.0, 0.0, 0.0, 1.0);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_64 matrix_from_translation(const Vector4_64& translation)
-	{
-		return matrix_set(vector_set(1.0, 0.0, 0.0, 0.0), vector_set(0.0, 1.0, 0.0, 0.0), vector_set(0.0, 0.0, 1.0, 0.0), vector_set(vector_get_x(translation), vector_get_y(translation), vector_get_z(translation), 1.0));
-	}
-
-	inline AffineMatrix_64 matrix_from_scale(const Vector4_64& scale)
-	{
-		ACL_ASSERT(!vector_any_near_equal3(scale, vector_zero_64()), "Scale cannot be zero");
-		return matrix_set(vector_set(vector_get_x(scale), 0.0, 0.0, 0.0), vector_set(0.0, vector_get_y(scale), 0.0, 0.0), vector_set(0.0, 0.0, vector_get_z(scale), 0.0), vector_set(0.0, 0.0, 0.0, 1.0));
-	}
-
-	inline AffineMatrix_64 matrix_from_transform(const Transform_64& transform)
-	{
-		return matrix_set(transform.rotation, transform.translation, transform.scale);
-	}
-
-	inline const Vector4_64& matrix_get_axis(const AffineMatrix_64& input, MatrixAxis axis)
-	{
-		switch (axis)
-		{
-		case MatrixAxis::X: return input.x_axis;
-		case MatrixAxis::Y: return input.y_axis;
-		case MatrixAxis::Z: return input.z_axis;
-		case MatrixAxis::W: return input.w_axis;
-		default:
-			ACL_ASSERT(false, "Invalid matrix axis");
-			return input.x_axis;
-		}
-	}
-
-	inline Vector4_64& matrix_get_axis(AffineMatrix_64& input, MatrixAxis axis)
-	{
-		switch (axis)
-		{
-		case MatrixAxis::X: return input.x_axis;
-		case MatrixAxis::Y: return input.y_axis;
-		case MatrixAxis::Z: return input.z_axis;
-		case MatrixAxis::W: return input.w_axis;
-		default:
-			ACL_ASSERT(false, "Invalid matrix axis");
-			return input.x_axis;
-		}
-	}
-
-	constexpr const Vector4_64& matrix_get_axis(const Vector4_64& x_axis, const Vector4_64& y_axis, const Vector4_64& z_axis, const Vector4_64& w_axis, MatrixAxis axis)
-	{
-		return axis == MatrixAxis::X ? x_axis : (axis == MatrixAxis::Y ? y_axis : (axis == MatrixAxis::Z ? z_axis : w_axis));
-	}
-
-	inline Quat_64 quat_from_matrix(const AffineMatrix_64& input)
-	{
-		if (vector_all_near_equal3(input.x_axis, vector_zero_64()) || vector_all_near_equal3(input.y_axis, vector_zero_64()) || vector_all_near_equal3(input.z_axis, vector_zero_64()))
-		{
-			// Zero scale not supported, return the identity
-			return quat_identity_64();
-		}
-
-		const double mtx_trace = vector_get_x(input.x_axis) + vector_get_y(input.y_axis) + vector_get_z(input.z_axis);
-		if (mtx_trace > 0.0)
-		{
-			const double inv_trace = sqrt_reciprocal(mtx_trace + 1.0);
-			const double half_inv_trace = inv_trace * 0.5;
-
-			const double x = (vector_get_z(input.y_axis) - vector_get_y(input.z_axis)) * half_inv_trace;
-			const double y = (vector_get_x(input.z_axis) - vector_get_z(input.x_axis)) * half_inv_trace;
-			const double z = (vector_get_y(input.x_axis) - vector_get_x(input.y_axis)) * half_inv_trace;
-			const double w = reciprocal(inv_trace) * 0.5;
-
-			return quat_normalize(quat_set(x, y, z, w));
-		}
-		else
-		{
-			int8_t best_axis = 0;
-			if (vector_get_y(input.y_axis) > vector_get_x(input.x_axis))
-				best_axis = 1;
-			if (vector_get_z(input.z_axis) > vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(best_axis)))
-				best_axis = 2;
-
-			const int8_t next_best_axis = (best_axis + 1) % 3;
-			const int8_t next_next_best_axis = (next_best_axis + 1) % 3;
-
-			const double mtx_pseudo_trace = 1.0 +
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(best_axis)) -
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(next_best_axis)) -
-				vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(next_next_best_axis));
-
-			const double inv_pseudo_trace = sqrt_reciprocal(mtx_pseudo_trace);
-			const double half_inv_pseudo_trace = inv_pseudo_trace * 0.5;
-
-			double quat_values[4];
-			quat_values[best_axis] = reciprocal(inv_pseudo_trace) * 0.5;
-			quat_values[next_best_axis] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(next_best_axis)) +
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(best_axis)));
-			quat_values[next_next_best_axis] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(best_axis)), VectorMix(next_next_best_axis)) +
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(best_axis)));
-			quat_values[3] = half_inv_pseudo_trace *
-				(vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_best_axis)), VectorMix(next_next_best_axis)) -
-					vector_get_component(matrix_get_axis(input.x_axis, input.y_axis, input.z_axis, input.w_axis, MatrixAxis(next_next_best_axis)), VectorMix(next_best_axis)));
-
-			return quat_normalize(quat_unaligned_load(&quat_values[0]));
-		}
-	}
-
-	// Multiplication order is as follow: local_to_world = matrix_mul(local_to_object, object_to_world)
-	inline AffineMatrix_64 matrix_mul(const AffineMatrix_64& lhs, const AffineMatrix_64& rhs)
-	{
-		Vector4_64 tmp = vector_mul(vector_mix_xxxx(lhs.x_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.x_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.x_axis), rhs.z_axis, tmp);
-		Vector4_64 x_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.y_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.y_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.y_axis), rhs.z_axis, tmp);
-		Vector4_64 y_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.z_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.z_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.z_axis), rhs.z_axis, tmp);
-		Vector4_64 z_axis = tmp;
-
-		tmp = vector_mul(vector_mix_xxxx(lhs.w_axis), rhs.x_axis);
-		tmp = vector_mul_add(vector_mix_yyyy(lhs.w_axis), rhs.y_axis, tmp);
-		tmp = vector_mul_add(vector_mix_zzzz(lhs.w_axis), rhs.z_axis, tmp);
-		Vector4_64 w_axis = vector_add(rhs.w_axis, tmp);
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline Vector4_64 matrix_mul_position(const AffineMatrix_64& lhs, const Vector4_64& rhs)
-	{
-		Vector4_64 tmp0;
-		Vector4_64 tmp1;
-
-		tmp0 = vector_mul(vector_mix_xxxx(rhs), lhs.x_axis);
-		tmp0 = vector_mul_add(vector_mix_yyyy(rhs), lhs.y_axis, tmp0);
-		tmp1 = vector_mul_add(vector_mix_zzzz(rhs), lhs.z_axis, lhs.w_axis);
-
-		return vector_add(tmp0, tmp1);
-	}
-
-	namespace math_impl
-	{
-		// Note: This is a generic matrix 4x4 transpose, the resulting matrix is no longer
-		// affine because the last column is no longer [0,0,0,1]
-		inline AffineMatrix_64 matrix_transpose(const AffineMatrix_64& input)
-		{
-			Vector4_64 tmp0 = vector_mix_xyab(input.x_axis, input.y_axis);
-			Vector4_64 tmp1 = vector_mix_zwcd(input.x_axis, input.y_axis);
-			Vector4_64 tmp2 = vector_mix_xyab(input.z_axis, input.w_axis);
-			Vector4_64 tmp3 = vector_mix_zwcd(input.z_axis, input.w_axis);
-
-			Vector4_64 x_axis = vector_mix_xzac(tmp0, tmp2);
-			Vector4_64 y_axis = vector_mix_ywbd(tmp0, tmp2);
-			Vector4_64 z_axis = vector_mix_xzac(tmp1, tmp3);
-			Vector4_64 w_axis = vector_mix_ywbd(tmp1, tmp3);
-			return AffineMatrix_64{ x_axis, y_axis, z_axis, w_axis };
-		}
-	}
-
-	inline AffineMatrix_64 matrix_inverse(const AffineMatrix_64& input)
-	{
-		// TODO: This is a generic matrix inverse function, implement the affine version?
-		AffineMatrix_64 input_transposed = math_impl::matrix_transpose(input);
-
-		Vector4_64 v00 = vector_mix_xxyy(input_transposed.z_axis);
-		Vector4_64 v01 = vector_mix_xxyy(input_transposed.x_axis);
-		Vector4_64 v02 = vector_mix_xzac(input_transposed.z_axis, input_transposed.x_axis);
-		Vector4_64 v10 = vector_mix_zwzw(input_transposed.w_axis);
-		Vector4_64 v11 = vector_mix_zwzw(input_transposed.y_axis);
-		Vector4_64 v12 = vector_mix_ywbd(input_transposed.w_axis, input_transposed.y_axis);
-
-		Vector4_64 d0 = vector_mul(v00, v10);
-		Vector4_64 d1 = vector_mul(v01, v11);
-		Vector4_64 d2 = vector_mul(v02, v12);
-
-		v00 = vector_mix_zwzw(input_transposed.z_axis);
-		v01 = vector_mix_zwzw(input_transposed.x_axis);
-		v02 = vector_mix_ywbd(input_transposed.z_axis, input_transposed.x_axis);
-		v10 = vector_mix_xxyy(input_transposed.w_axis);
-		v11 = vector_mix_xxyy(input_transposed.y_axis);
-		v12 = vector_mix_xzac(input_transposed.w_axis, input_transposed.y_axis);
-
-		d0 = vector_neg_mul_sub(v00, v10, d0);
-		d1 = vector_neg_mul_sub(v01, v11, d1);
-		d2 = vector_neg_mul_sub(v02, v12, d2);
-
-		v00 = vector_mix_yzxy(input_transposed.y_axis);
-		v01 = vector_mix_zxyx(input_transposed.x_axis);
-		v02 = vector_mix_yzxy(input_transposed.w_axis);
-		Vector4_64 v03 = vector_mix_zxyx(input_transposed.z_axis);
-		v10 = vector_mix_bywx(d0, d2);
-		v11 = vector_mix_wbyz(d0, d2);
-		v12 = vector_mix_dywx(d1, d2);
-		Vector4_64 v13 = vector_mix_wdyz(d1, d2);
-
-		Vector4_64 c0 = vector_mul(v00, v10);
-		Vector4_64 c2 = vector_mul(v01, v11);
-		Vector4_64 c4 = vector_mul(v02, v12);
-		Vector4_64 c6 = vector_mul(v03, v13);
-
-		v00 = vector_mix_zwyz(input_transposed.y_axis);
-		v01 = vector_mix_wzwy(input_transposed.x_axis);
-		v02 = vector_mix_zwyz(input_transposed.w_axis);
-		v03 = vector_mix_wzwy(input_transposed.z_axis);
-		v10 = vector_mix_wxya(d0, d2);
-		v11 = vector_mix_zyax(d0, d2);
-		v12 = vector_mix_wxyc(d1, d2);
-		v13 = vector_mix_zycx(d1, d2);
-
-		c0 = vector_neg_mul_sub(v00, v10, c0);
-		c2 = vector_neg_mul_sub(v01, v11, c2);
-		c4 = vector_neg_mul_sub(v02, v12, c4);
-		c6 = vector_neg_mul_sub(v03, v13, c6);
-
-		v00 = vector_mix_wxwx(input_transposed.y_axis);
-		v01 = vector_mix_ywxz(input_transposed.x_axis);
-		v02 = vector_mix_wxwx(input_transposed.w_axis);
-		v03 = vector_mix_ywxz(input_transposed.z_axis);
-		v10 = vector_mix_zbaz(d0, d2);
-		v11 = vector_mix_bxwa(d0, d2);
-		v12 = vector_mix_zdcz(d1, d2);
-		v13 = vector_mix_dxwc(d1, d2);
-
-		Vector4_64 c1 = vector_neg_mul_sub(v00, v10, c0);
-		c0 = vector_mul_add(v00, v10, c0);
-		Vector4_64 c3 = vector_mul_add(v01, v11, c2);
-		c2 = vector_neg_mul_sub(v01, v11, c2);
-		Vector4_64 c5 = vector_neg_mul_sub(v02, v12, c4);
-		c4 = vector_mul_add(v02, v12, c4);
-		Vector4_64 c7 = vector_mul_add(v03, v13, c6);
-		c6 = vector_neg_mul_sub(v03, v13, c6);
-
-		Vector4_64 x_axis = vector_mix_xbzd(c0, c1);
-		Vector4_64 y_axis = vector_mix_xbzd(c2, c3);
-		Vector4_64 z_axis = vector_mix_xbzd(c4, c5);
-		Vector4_64 w_axis = vector_mix_xbzd(c6, c7);
-
-		double det = vector_dot(x_axis, input_transposed.x_axis);
-		Vector4_64 inv_det = vector_set(reciprocal(det));
-
-		x_axis = vector_mul(x_axis, inv_det);
-		y_axis = vector_mul(y_axis, inv_det);
-		z_axis = vector_mul(z_axis, inv_det);
-		w_axis = vector_mul(w_axis, inv_det);
-
-#if defined(ACL_NO_INTRINSICS)
-		w_axis = vector_set(vector_get_x(w_axis), vector_get_y(w_axis), vector_get_z(w_axis), 1.0);
-#endif
-
-		return matrix_set(x_axis, y_axis, z_axis, w_axis);
-	}
-
-	inline AffineMatrix_64 matrix_remove_scale(const AffineMatrix_64& input)
-	{
-		AffineMatrix_64 result;
-		result.x_axis = vector_normalize3(input.x_axis);
-		result.y_axis = vector_normalize3(input.y_axis);
-		result.z_axis = vector_normalize3(input.z_axis);
-		result.w_axis = input.w_axis;
-		return result;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/math.h b/includes/acl/math/math.h
deleted file mode 100644
--- a/includes/acl/math/math.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-//#define ACL_NO_INTRINSICS
-
-#if !defined(ACL_NO_INTRINSICS)
-	#if defined(__AVX__)
-		#define ACL_AVX_INTRINSICS
-		#define ACL_SSE4_INTRINSICS
-		#define ACL_SSE3_INTRINSICS
-		#define ACL_SSE2_INTRINSICS
-	#endif
-
-	#if defined(__SSE4_1__)
-		#define ACL_SSE4_INTRINSICS
-		#define ACL_SSE3_INTRINSICS
-		#define ACL_SSE2_INTRINSICS
-	#endif
-
-	#if defined(__SSSE3__)
-		#define ACL_SSE3_INTRINSICS
-		#define ACL_SSE2_INTRINSICS
-	#endif
-
-	#if defined(__SSE2__) || defined(_M_IX86) || defined(_M_X64)
-		#define ACL_SSE2_INTRINSICS
-	#endif
-
-	#if defined(__ARM_NEON) || defined(_M_ARM) || defined(_M_ARM64)
-		#define ACL_NEON_INTRINSICS
-
-		#if defined(__aarch64__) || defined(_M_ARM64)
-			#define ACL_NEON64_INTRINSICS
-		#endif
-	#endif
-
-	#if !defined(ACL_SSE2_INTRINSICS) && !defined(ACL_NEON_INTRINSICS)
-		#define ACL_NO_INTRINSICS
-	#endif
-#endif
-
-#if defined(ACL_SSE2_INTRINSICS)
-	#include <xmmintrin.h>
-	#include <emmintrin.h>
-
-	// With MSVC and SSE2, we can use the __vectorcall calling convention to pass vector types and aggregates by value through registers
-	// for improved code generation
-	#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_MANAGED) && !defined(_M_CEE) && (!defined(_M_IX86_FP) || (_M_IX86_FP > 1)) && !defined(ACL_SIMD_CALL)
-		#if ((_MSC_FULL_VER >= 170065501) && (_MSC_VER < 1800)) || (_MSC_FULL_VER >= 180020418)
-			#define ACL_USE_VECTORCALL
-		#endif
-	#endif
-#endif
-
-#if defined(ACL_SSE3_INTRINSICS)
-	#include <pmmintrin.h>
-#endif
-
-#if defined(ACL_SSE4_INTRINSICS)
-	#include <smmintrin.h>
-#endif
-
-#if defined(ACL_AVX_INTRINSICS)
-	#include <immintrin.h>
-#endif
-
-#if defined(ACL_NEON64_INTRINSICS) && defined(_M_ARM64)
-	// MSVC specific header
-	#include <arm64_neon.h>
-#elif defined(ACL_NEON_INTRINSICS)
-	#include <arm_neon.h>
-#endif
-
-#if !defined(ACL_SIMD_CALL)
-	#if defined(ACL_USE_VECTORCALL)
-		#define ACL_SIMD_CALL __vectorcall
-	#else
-		#define ACL_SIMD_CALL
-	#endif
-#endif
-
-#include "acl/math/math_types.h"
diff --git a/includes/acl/math/math_types.h b/includes/acl/math/math_types.h
deleted file mode 100644
--- a/includes/acl/math/math_types.h
+++ /dev/null
@@ -1,279 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/math/math.h"
-
-#include <cstdint>
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	namespace math_impl
-	{
-		union Converter
-		{
-			double dbl;
-			uint64_t u64;
-			float flt[2];
-
-			explicit constexpr Converter(uint64_t value) : u64(value) {}
-			explicit constexpr Converter(double value) : dbl(value) {}
-			explicit constexpr Converter(float value) : flt{value, value} {}
-
-			constexpr operator double() const { return dbl; }
-			constexpr operator float() const { return flt[0]; }
-		};
-
-		constexpr Converter get_mask_value(bool is_true)
-		{
-			return Converter(is_true ? uint64_t(0xFFFFFFFFFFFFFFFFULL) : uint64_t(0));
-		}
-
-		constexpr double select(double mask, double if_true, double if_false)
-		{
-			return Converter(mask).u64 == 0 ? if_false : if_true;
-		}
-
-		constexpr float select(float mask, float if_true, float if_false)
-		{
-			return Converter(mask).u64 == 0 ? if_false : if_true;
-		}
-	}
-
-#if defined(ACL_SSE2_INTRINSICS)
-	typedef __m128 Quat_32;
-	typedef __m128 Vector4_32;
-
-	struct Quat_64
-	{
-		__m128d xy;
-		__m128d zw;
-	};
-
-	struct Vector4_64
-	{
-		__m128d xy;
-		__m128d zw;
-	};
-#elif defined(ACL_NEON_INTRINSICS)
-	typedef float32x4_t Quat_32;
-	typedef float32x4_t Vector4_32;
-
-	struct alignas(16) Quat_64
-	{
-		double x;
-		double y;
-		double z;
-		double w;
-	};
-
-	struct alignas(16) Vector4_64
-	{
-		double x;
-		double y;
-		double z;
-		double w;
-	};
-#else
-	struct alignas(16) Quat_32
-	{
-		float x;
-		float y;
-		float z;
-		float w;
-	};
-
-	struct alignas(16) Vector4_32
-	{
-		float x;
-		float y;
-		float z;
-		float w;
-	};
-
-	struct alignas(16) Quat_64
-	{
-		double x;
-		double y;
-		double z;
-		double w;
-	};
-
-	struct alignas(16) Vector4_64
-	{
-		double x;
-		double y;
-		double z;
-		double w;
-	};
-#endif
-
-	struct Transform_32
-	{
-		Quat_32		rotation;
-		Vector4_32	translation;
-		Vector4_32	scale;
-	};
-
-	struct Transform_64
-	{
-		Quat_64		rotation;
-		Vector4_64	translation;
-		Vector4_64	scale;
-	};
-
-	struct AffineMatrix_32
-	{
-		Vector4_32	x_axis;
-		Vector4_32	y_axis;
-		Vector4_32	z_axis;
-		Vector4_32	w_axis;
-	};
-
-	struct AffineMatrix_64
-	{
-		Vector4_64	x_axis;
-		Vector4_64	y_axis;
-		Vector4_64	z_axis;
-		Vector4_64	w_axis;
-	};
-
-	enum class VectorMix
-	{
-		X = 0,
-		Y = 1,
-		Z = 2,
-		W = 3,
-
-		A = 4,
-		B = 5,
-		C = 6,
-		D = 7,
-	};
-
-	enum class MatrixAxis
-	{
-		X = 0,
-		Y = 1,
-		Z = 2,
-		W = 3,
-	};
-
-	// The result is sometimes required as part of an immediate for an intrinsic
-	// and as such we much know the value at compile time and constexpr isn't always evaluated.
-	// Required at least on GCC 5 in Debug
-	#define IS_VECTOR_MIX_ARG_XYZW(arg) (int32_t(arg) >= int32_t(VectorMix::X) && int32_t(arg) <= int32_t(VectorMix::W))
-	#define IS_VECTOR_MIX_ARG_ABCD(arg) (int32_t(arg) >= int32_t(VectorMix::A) && int32_t(arg) <= int32_t(VectorMix::D))
-	#define GET_VECTOR_MIX_COMPONENT_INDEX(arg) (IS_VECTOR_MIX_ARG_XYZW(arg) ? int8_t(arg) : (int8_t(arg) - 4))
-
-	namespace math_impl
-	{
-		constexpr bool is_vector_mix_arg_xyzw(VectorMix arg) { return int32_t(arg) >= int32_t(VectorMix::X) && int32_t(arg) <= int32_t(VectorMix::W); }
-		constexpr bool is_vector_mix_arg_abcd(VectorMix arg) { return int32_t(arg) >= int32_t(VectorMix::A) && int32_t(arg) <= int32_t(VectorMix::D); }
-		constexpr int8_t get_vector_mix_component_index(VectorMix arg) { return is_vector_mix_arg_xyzw(arg) ? int8_t(arg) : (int8_t(arg) - 4); }
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-
-#if defined(ACL_USE_VECTORCALL)
-	// On x64 with __vectorcall, the first 6x vector4 arguments can be passed by value in a register, everything else afterwards is passed by const&
-	using Vector4_32Arg0 = const Vector4_32;
-	using Vector4_32Arg1 = const Vector4_32;
-	using Vector4_32Arg2 = const Vector4_32;
-	using Vector4_32Arg3 = const Vector4_32;
-	using Vector4_32Arg4 = const Vector4_32;
-	using Vector4_32Arg5 = const Vector4_32;
-	using Vector4_32ArgN = const Vector4_32&;
-
-	using Quat_32Arg0 = const Quat_32;
-	using Quat_32Arg1 = const Quat_32;
-	using Quat_32Arg2 = const Quat_32;
-	using Quat_32Arg3 = const Quat_32;
-	using Quat_32Arg4 = const Quat_32;
-	using Quat_32Arg5 = const Quat_32;
-	using Quat_32ArgN = const Quat_32&;
-
-	// With __vectorcall, vector aggregates are also passed by register
-	using Transform_32Arg0 = const Transform_32;
-	using Transform_32Arg1 = const Transform_32;
-	using Transform_32ArgN = const Transform_32&;
-
-	using AffineMatrix_32Arg0 = const AffineMatrix_32;
-	using AffineMatrix_32ArgN = const AffineMatrix_32&;
-#elif defined(ACL_NEON_INTRINSICS)
-	// On ARM NEON, the first 4x vector4 arguments can be passed by value in a register, everything else afterwards is passed by const&
-	using Vector4_32Arg0 = const Vector4_32;
-	using Vector4_32Arg1 = const Vector4_32;
-	using Vector4_32Arg2 = const Vector4_32;
-	using Vector4_32Arg3 = const Vector4_32;
-	using Vector4_32Arg4 = const Vector4_32&;
-	using Vector4_32Arg5 = const Vector4_32&;
-	using Vector4_32ArgN = const Vector4_32&;
-
-	using Quat_32Arg0 = const Quat_32;
-	using Quat_32Arg1 = const Quat_32;
-	using Quat_32Arg2 = const Quat_32;
-	using Quat_32Arg3 = const Quat_32;
-	using Quat_32Arg4 = const Quat_32&;
-	using Quat_32Arg5 = const Quat_32&;
-	using Quat_32ArgN = const Quat_32&;
-
-	using Transform_32Arg0 = const Transform_32&;
-	using Transform_32Arg1 = const Transform_32&;
-	using Transform_32ArgN = const Transform_32&;
-
-	using AffineMatrix_32Arg0 = const AffineMatrix_32&;
-	using AffineMatrix_32ArgN = const AffineMatrix_32&;
-#else
-	// On every other platform, everything is passed by const&
-	using Vector4_32Arg0 = const Vector4_32&;
-	using Vector4_32Arg1 = const Vector4_32&;
-	using Vector4_32Arg2 = const Vector4_32&;
-	using Vector4_32Arg3 = const Vector4_32&;
-	using Vector4_32Arg4 = const Vector4_32&;
-	using Vector4_32Arg5 = const Vector4_32&;
-	using Vector4_32ArgN = const Vector4_32&;
-
-	using Quat_32Arg0 = const Quat_32&;
-	using Quat_32Arg1 = const Quat_32&;
-	using Quat_32Arg2 = const Quat_32&;
-	using Quat_32Arg3 = const Quat_32&;
-	using Quat_32Arg4 = const Quat_32&;
-	using Quat_32Arg5 = const Quat_32&;
-	using Quat_32ArgN = const Quat_32&;
-
-	using Transform_32Arg0 = const Transform_32&;
-	using Transform_32Arg1 = const Transform_32&;
-	using Transform_32ArgN = const Transform_32&;
-
-	using AffineMatrix_32Arg0 = const AffineMatrix_32&;
-	using AffineMatrix_32ArgN = const AffineMatrix_32&;
-#endif
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/quat_32.h b/includes/acl/math/quat_32.h
deleted file mode 100644
--- a/includes/acl/math/quat_32.h
+++ /dev/null
@@ -1,598 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/core/memory_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/scalar_32.h"
-#include "acl/math/vector4_32.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	inline Quat_32 ACL_SIMD_CALL quat_set(float x, float y, float z, float w)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_set_ps(w, z, y, x);
-#elif defined(ACL_NEON_INTRINSICS)
-#if 1
-		float32x2_t V0 = vcreate_f32(((uint64_t)*(const uint32_t*)&x) | ((uint64_t)(*(const uint32_t*)&y) << 32));
-		float32x2_t V1 = vcreate_f32(((uint64_t)*(const uint32_t*)&z) | ((uint64_t)(*(const uint32_t*)&w) << 32));
-		return vcombine_f32(V0, V1);
-#else
-		float __attribute__((aligned(16))) data[4] = { x, y, z, w };
-		return vld1q_f32(data);
-#endif
-#else
-		return Quat_32{ x, y, z, w };
-#endif
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_unaligned_load(const float* input)
-	{
-		ACL_ASSERT(is_aligned(input), "Invalid alignment");
-		return quat_set(input[0], input[1], input[2], input[3]);
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_identity_32()
-	{
-		return quat_set(0.0F, 0.0F, 0.0F, 1.0F);
-	}
-
-	inline Quat_32 ACL_SIMD_CALL vector_to_quat(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS) || defined(ACL_NEON_INTRINSICS)
-		return input;
-#else
-		return Quat_32{ input.x, input.y, input.z, input.w };
-#endif
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_cast(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_shuffle_ps(_mm_cvtpd_ps(input.xy), _mm_cvtpd_ps(input.zw), _MM_SHUFFLE(1, 0, 1, 0));
-#else
-		return quat_set(float(input.x), float(input.y), float(input.z), float(input.w));
-#endif
-	}
-
-	inline float ACL_SIMD_CALL quat_get_x(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(input);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 0);
-#else
-		return input.x;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL quat_get_y(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(1, 1, 1, 1)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 1);
-#else
-		return input.y;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL quat_get_z(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(2, 2, 2, 2)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 2);
-#else
-		return input.z;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL quat_get_w(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(3, 3, 3, 3)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 3);
-#else
-		return input.w;
-#endif
-	}
-
-	inline void ACL_SIMD_CALL quat_unaligned_write(Quat_32Arg0 input, float* output)
-	{
-		output[0] = quat_get_x(input);
-		output[1] = quat_get_y(input);
-		output[2] = quat_get_z(input);
-		output[3] = quat_get_w(input);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	inline Quat_32 ACL_SIMD_CALL quat_conjugate(Quat_32Arg0 input)
-	{
-		return quat_set(-quat_get_x(input), -quat_get_y(input), -quat_get_z(input), quat_get_w(input));
-	}
-
-	// Multiplication order is as follow: local_to_world = quat_mul(local_to_object, object_to_world)
-	inline Quat_32 ACL_SIMD_CALL quat_mul(Quat_32Arg0 lhs, Quat_32Arg1 rhs)
-	{
-#if defined(ACL_SSE4_INTRINSICS) && 0
-		// TODO: Profile this, the accuracy is the same as with SSE2, should be binary exact
-		constexpr __m128 signs_x = { 1.0F,  1.0F,  1.0F, -1.0F };
-		constexpr __m128 signs_y = { 1.0F, -1.0F,  1.0F,  1.0F };
-		constexpr __m128 signs_z = { 1.0F,  1.0F, -1.0F,  1.0F };
-		constexpr __m128 signs_w = { 1.0F, -1.0F, -1.0F, -1.0F };
-		// x = dot(rhs.wxyz, lhs.xwzy * signs_x)
-		// y = dot(rhs.wxyz, lhs.yzwx * signs_y)
-		// z = dot(rhs.wxyz, lhs.zyxw * signs_z)
-		// w = dot(rhs.wxyz, lhs.wxyz * signs_w)
-		__m128 rhs_wxyz = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(2, 1, 0, 3));
-		__m128 lhs_xwzy = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(1, 2, 3, 0));
-		__m128 lhs_yzwx = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(0, 3, 2, 1));
-		__m128 lhs_zyxw = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(3, 0, 1, 2));
-		__m128 lhs_wxyz = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(2, 1, 0, 3));
-		__m128 x = _mm_dp_ps(rhs_wxyz, _mm_mul_ps(lhs_xwzy, signs_x), 0xFF);
-		__m128 y = _mm_dp_ps(rhs_wxyz, _mm_mul_ps(lhs_yzwx, signs_y), 0xFF);
-		__m128 z = _mm_dp_ps(rhs_wxyz, _mm_mul_ps(lhs_zyxw, signs_z), 0xFF);
-		__m128 w = _mm_dp_ps(rhs_wxyz, _mm_mul_ps(lhs_wxyz, signs_w), 0xFF);
-		__m128 xxyy = _mm_shuffle_ps(x, y, _MM_SHUFFLE(0, 0, 0, 0));
-		__m128 zzww = _mm_shuffle_ps(z, w, _MM_SHUFFLE(0, 0, 0, 0));
-		return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0));
-#elif defined(ACL_SSE2_INTRINSICS)
-		constexpr __m128 control_wzyx = {  0.0F, -0.0F,  0.0F, -0.0F };
-		constexpr __m128 control_zwxy = {  0.0F,  0.0F, -0.0F, -0.0F };
-		constexpr __m128 control_yxwz = { -0.0F,  0.0F,  0.0F, -0.0F };
-
-		__m128 r_xxxx = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(0, 0, 0, 0));
-		__m128 r_yyyy = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(1, 1, 1, 1));
-		__m128 r_zzzz = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(2, 2, 2, 2));
-		__m128 r_wwww = _mm_shuffle_ps(rhs, rhs, _MM_SHUFFLE(3, 3, 3, 3));
-
-		__m128 lxrw_lyrw_lzrw_lwrw = _mm_mul_ps(r_wwww, lhs);
-		__m128 l_wzyx = _mm_shuffle_ps(lhs, lhs, _MM_SHUFFLE(0, 1, 2, 3));
-
-		__m128 lwrx_lzrx_lyrx_lxrx = _mm_mul_ps(r_xxxx, l_wzyx);
-		__m128 l_zwxy = _mm_shuffle_ps(l_wzyx, l_wzyx, _MM_SHUFFLE(2, 3, 0, 1));
-
-		__m128 lwrx_nlzrx_lyrx_nlxrx = _mm_xor_ps(lwrx_lzrx_lyrx_lxrx, control_wzyx);
-
-		__m128 lzry_lwry_lxry_lyry = _mm_mul_ps(r_yyyy, l_zwxy);
-		__m128 l_yxwz = _mm_shuffle_ps(l_zwxy, l_zwxy, _MM_SHUFFLE(0, 1, 2, 3));
-
-		__m128 lzry_lwry_nlxry_nlyry = _mm_xor_ps(lzry_lwry_lxry_lyry, control_zwxy);
-
-		__m128 lyrz_lxrz_lwrz_lzrz = _mm_mul_ps(r_zzzz, l_yxwz);
-		__m128 result0 = _mm_add_ps(lxrw_lyrw_lzrw_lwrw, lwrx_nlzrx_lyrx_nlxrx);
-
-		__m128 nlyrz_lxrz_lwrz_wlzrz = _mm_xor_ps(lyrz_lxrz_lwrz_lzrz, control_yxwz);
-		__m128 result1 = _mm_add_ps(lzry_lwry_nlxry_nlyry, nlyrz_lxrz_lwrz_wlzrz);
-		return _mm_add_ps(result0, result1);
-#elif defined(ACL_NEON_INTRINSICS)
-		alignas(16) constexpr float control_wzyx_f[4] = {  1.0F, -1.0F,  1.0F, -1.0F };
-		alignas(16) constexpr float control_zwxy_f[4] = {  1.0F,  1.0F, -1.0F, -1.0F };
-		alignas(16) constexpr float control_yxwz_f[4] = { -1.0F,  1.0F,  1.0F, -1.0F };
-
-		const float32x4_t control_wzyx = *reinterpret_cast<const float32x4_t*>(&control_wzyx_f[0]);
-		const float32x4_t control_zwxy = *reinterpret_cast<const float32x4_t*>(&control_zwxy_f[0]);
-		const float32x4_t control_yxwz = *reinterpret_cast<const float32x4_t*>(&control_yxwz_f[0]);
-
-		float32x2_t r_xy = vget_low_f32(rhs);
-		float32x2_t r_zw = vget_high_f32(rhs);
-
-		float32x4_t lxrw_lyrw_lzrw_lwrw = vmulq_lane_f32(lhs, r_zw, 1);
-
-		float32x4_t l_yxwz = vrev64q_f32(lhs);
-		float32x4_t l_wzyx = vcombine_f32(vget_high_f32(l_yxwz), vget_low_f32(l_yxwz));
-		float32x4_t lwrx_lzrx_lyrx_lxrx = vmulq_lane_f32(l_wzyx, r_xy, 0);
-
-#if defined(RTM_NEON64_INTRINSICS)
-		float32x4_t result0 = vfmaq_f32(lxrw_lyrw_lzrw_lwrw, lwrx_lzrx_lyrx_lxrx, control_wzyx);
-#else
-		float32x4_t result0 = vmlaq_f32(lxrw_lyrw_lzrw_lwrw, lwrx_lzrx_lyrx_lxrx, control_wzyx);
-#endif
-
-		float32x4_t l_zwxy = vrev64q_f32(l_wzyx);
-		float32x4_t lzry_lwry_lxry_lyry = vmulq_lane_f32(l_zwxy, r_xy, 1);
-
-#if defined(RTM_NEON64_INTRINSICS)
-		float32x4_t result1 = vfmaq_f32(result0, lzry_lwry_lxry_lyry, control_zwxy);
-#else
-		float32x4_t result1 = vmlaq_f32(result0, lzry_lwry_lxry_lyry, control_zwxy);
-#endif
-
-		float32x4_t lyrz_lxrz_lwrz_lzrz = vmulq_lane_f32(l_yxwz, r_zw, 0);
-
-#if defined(RTM_NEON64_INTRINSICS)
-		return vfmaq_f32(result1, lyrz_lxrz_lwrz_lzrz, control_yxwz);
-#else
-		return vmlaq_f32(result1, lyrz_lxrz_lwrz_lzrz, control_yxwz);
-#endif
-#else
-		float lhs_x = quat_get_x(lhs);
-		float lhs_y = quat_get_y(lhs);
-		float lhs_z = quat_get_z(lhs);
-		float lhs_w = quat_get_w(lhs);
-
-		float rhs_x = quat_get_x(rhs);
-		float rhs_y = quat_get_y(rhs);
-		float rhs_z = quat_get_z(rhs);
-		float rhs_w = quat_get_w(rhs);
-
-		float x = (rhs_w * lhs_x) + (rhs_x * lhs_w) + (rhs_y * lhs_z) - (rhs_z * lhs_y);
-		float y = (rhs_w * lhs_y) - (rhs_x * lhs_z) + (rhs_y * lhs_w) + (rhs_z * lhs_x);
-		float z = (rhs_w * lhs_z) + (rhs_x * lhs_y) - (rhs_y * lhs_x) + (rhs_z * lhs_w);
-		float w = (rhs_w * lhs_w) - (rhs_x * lhs_x) - (rhs_y * lhs_y) - (rhs_z * lhs_z);
-
-		return quat_set(x, y, z, w);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL quat_rotate(Quat_32Arg0 rotation, Vector4_32Arg1 vector)
-	{
-		Quat_32 vector_quat = quat_set(vector_get_x(vector), vector_get_y(vector), vector_get_z(vector), 0.0F);
-		Quat_32 inv_rotation = quat_conjugate(rotation);
-		return quat_to_vector(quat_mul(quat_mul(inv_rotation, vector_quat), rotation));
-	}
-
-	inline float ACL_SIMD_CALL quat_length_squared(Quat_32Arg0 input)
-	{
-		return vector_length_squared(quat_to_vector(input));
-	}
-
-	inline float ACL_SIMD_CALL quat_length(Quat_32Arg0 input)
-	{
-		return vector_length(quat_to_vector(input));
-	}
-
-	inline float ACL_SIMD_CALL quat_length_reciprocal(Quat_32Arg0 input)
-	{
-		return vector_length_reciprocal(quat_to_vector(input));
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_normalize(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// We first calculate the dot product to get the length squared: dot(input, input)
-		__m128 x2_y2_z2_w2 = _mm_mul_ps(input, input);
-		__m128 z2_w2_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 3, 2));
-		__m128 x2z2_y2w2_0_0 = _mm_add_ps(x2_y2_z2_w2, z2_w2_0_0);
-		__m128 y2w2_0_0_0 = _mm_shuffle_ps(x2z2_y2w2_0_0, x2z2_y2w2_0_0, _MM_SHUFFLE(0, 0, 0, 1));
-		__m128 x2y2z2w2_0_0_0 = _mm_add_ps(x2z2_y2w2_0_0, y2w2_0_0_0);
-
-		// Keep the dot product result as a scalar within the first lane, it is faster to
-		// calculate the reciprocal square root of a single lane VS all 4 lanes
-		__m128 dot = x2y2z2w2_0_0_0;
-
-		// Calculate the reciprocal square root to get the inverse length of our vector
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		__m128 half = _mm_set_ss(0.5F);
-		__m128 input_half_v = _mm_mul_ss(dot, half);
-		__m128 x0 = _mm_rsqrt_ss(dot);
-
-		// First iteration
-		__m128 x1 = _mm_mul_ss(x0, x0);
-		x1 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x1));
-		x1 = _mm_add_ss(_mm_mul_ss(x0, x1), x0);
-
-		// Second iteration
-		__m128 x2 = _mm_mul_ss(x1, x1);
-		x2 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x2));
-		x2 = _mm_add_ss(_mm_mul_ss(x1, x2), x1);
-
-		// Broadcast the vector length reciprocal to all 4 lanes in order to multiply it with the vector
-		__m128 inv_len = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(0, 0, 0, 0));
-
-		// Multiply the rotation by it's inverse length in order to normalize it
-		return _mm_mul_ps(input, inv_len);
-#elif defined (ACL_NEON_INTRINSICS)
-		// Use sqrt/div/mul to normalize because the sqrt/div are faster than rsqrt
-		float inv_len = 1.0F / sqrt(vector_length_squared(input));
-		return vector_mul(input, inv_len);
-#else
-		// Reciprocal is more accurate to normalize with
-		float inv_len = quat_length_reciprocal(input);
-		return vector_to_quat(vector_mul(quat_to_vector(input), inv_len));
-#endif
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_lerp(Quat_32Arg0 start, Quat_32Arg1 end, float alpha)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// Calculate the vector4 dot product: dot(start, end)
-		__m128 dot;
-#if defined(ACL_SSE4_INTRINSICS)
-		// The dpps instruction isn't as accurate but we don't care here, we only need the sign of the
-		// dot product. If both rotations are on opposite ends of the hypersphere, the result will be
-		// very negative. If we are on the edge, the rotations are nearly opposite but not quite which
-		// means that the linear interpolation here will have terrible accuracy to begin with. It is designed
-		// for interpolating rotations that are reasonably close together. The bias check is mainly necessary
-		// because the W component is often kept positive which flips the sign.
-		// Using the dpps instruction reduces the number of registers that we need and helps the function get
-		// inlined.
-		dot = _mm_dp_ps(start, end, 0xFF);
-#else
-		{
-			__m128 x2_y2_z2_w2 = _mm_mul_ps(start, end);
-			__m128 z2_w2_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 3, 2));
-			__m128 x2z2_y2w2_0_0 = _mm_add_ps(x2_y2_z2_w2, z2_w2_0_0);
-			__m128 y2w2_0_0_0 = _mm_shuffle_ps(x2z2_y2w2_0_0, x2z2_y2w2_0_0, _MM_SHUFFLE(0, 0, 0, 1));
-			__m128 x2y2z2w2_0_0_0 = _mm_add_ps(x2z2_y2w2_0_0, y2w2_0_0_0);
-			// Shuffle the dot product to all SIMD lanes, there is no _mm_and_ss and loading
-			// the constant from memory with the 'and' instruction is faster, it uses fewer registers
-			// and fewer instructions
-			dot = _mm_shuffle_ps(x2y2z2w2_0_0_0, x2y2z2w2_0_0_0, _MM_SHUFFLE(0, 0, 0, 0));
-		}
-#endif
-
-		// Calculate the bias, if the dot product is positive or zero, there is no bias
-		// but if it is negative, we want to flip the 'end' rotation XYZW components
-		__m128 bias = _mm_and_ps(dot, _mm_set_ps1(-0.0F));
-
-		// Lerp the rotation after applying the bias
-		__m128 interpolated_rotation = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(_mm_xor_ps(end, bias), start), _mm_set_ps1(alpha)), start);
-
-		// Now we need to normalize the resulting rotation. We first calculate the
-		// dot product to get the length squared: dot(interpolated_rotation, interpolated_rotation)
-		__m128 x2_y2_z2_w2 = _mm_mul_ps(interpolated_rotation, interpolated_rotation);
-		__m128 z2_w2_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 3, 2));
-		__m128 x2z2_y2w2_0_0 = _mm_add_ps(x2_y2_z2_w2, z2_w2_0_0);
-		__m128 y2w2_0_0_0 = _mm_shuffle_ps(x2z2_y2w2_0_0, x2z2_y2w2_0_0, _MM_SHUFFLE(0, 0, 0, 1));
-		__m128 x2y2z2w2_0_0_0 = _mm_add_ps(x2z2_y2w2_0_0, y2w2_0_0_0);
-
-		// Keep the dot product result as a scalar within the first lane, it is faster to
-		// calculate the reciprocal square root of a single lane VS all 4 lanes
-		dot = x2y2z2w2_0_0_0;
-
-		// Calculate the reciprocal square root to get the inverse length of our vector
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		__m128 half = _mm_set_ss(0.5F);
-		__m128 input_half_v = _mm_mul_ss(dot, half);
-		__m128 x0 = _mm_rsqrt_ss(dot);
-
-		// First iteration
-		__m128 x1 = _mm_mul_ss(x0, x0);
-		x1 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x1));
-		x1 = _mm_add_ss(_mm_mul_ss(x0, x1), x0);
-
-		// Second iteration
-		__m128 x2 = _mm_mul_ss(x1, x1);
-		x2 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x2));
-		x2 = _mm_add_ss(_mm_mul_ss(x1, x2), x1);
-
-		// Broadcast the vector length reciprocal to all 4 lanes in order to multiply it with the vector
-		__m128 inv_len = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(0, 0, 0, 0));
-
-		// Multiply the rotation by it's inverse length in order to normalize it
-		return _mm_mul_ps(interpolated_rotation, inv_len);
-#elif defined (ACL_NEON64_INTRINSICS)
-		// On ARM64 with NEON, we load 1.0 once and use it twice which is faster than
-		// using a AND/XOR with the bias (same number of instructions)
-		float dot = vector_dot(start, end);
-		float bias = dot >= 0.0F ? 1.0F : -1.0F;
-		Vector4_32 interpolated_rotation = vector_neg_mul_sub(vector_neg_mul_sub(end, bias, start), alpha, start);
-		// Use sqrt/div/mul to normalize because the sqrt/div are faster than rsqrt
-		float inv_len = 1.0F / sqrt(vector_length_squared(interpolated_rotation));
-		return vector_mul(interpolated_rotation, inv_len);
-#elif defined(ACL_NEON_INTRINSICS)
-		// Calculate the vector4 dot product: dot(start, end)
-		float32x4_t x2_y2_z2_w2 = vmulq_f32(start, end);
-		float32x2_t x2_y2 = vget_low_f32(x2_y2_z2_w2);
-		float32x2_t z2_w2 = vget_high_f32(x2_y2_z2_w2);
-		float32x2_t x2z2_y2w2 = vadd_f32(x2_y2, z2_w2);
-		float32x2_t x2y2z2w2 = vpadd_f32(x2z2_y2w2, x2z2_y2w2);
-
-		// Calculate the bias, if the dot product is positive or zero, there is no bias
-		// but if it is negative, we want to flip the 'end' rotation XYZW components
-		// On ARM-v7-A, the AND/XOR trick is faster than the cmp/fsel
-		uint32x2_t bias = vand_u32(vreinterpret_u32_f32(x2y2z2w2), vdup_n_u32(0x80000000U));
-
-		// Lerp the rotation after applying the bias
-		float32x4_t end_biased = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(end), vcombine_u32(bias, bias)));
-		float32x4_t interpolated_rotation = vmlaq_n_f32(start, vsubq_f32(end_biased, start), alpha);
-
-		// Now we need to normalize the resulting rotation. We first calculate the
-		// dot product to get the length squared: dot(interpolated_rotation, interpolated_rotation)
-		x2_y2_z2_w2 = vmulq_f32(interpolated_rotation, interpolated_rotation);
-		x2_y2 = vget_low_f32(x2_y2_z2_w2);
-		z2_w2 = vget_high_f32(x2_y2_z2_w2);
-		x2z2_y2w2 = vadd_f32(x2_y2, z2_w2);
-		x2y2z2w2 = vpadd_f32(x2z2_y2w2, x2z2_y2w2);
-
-		float dot = vget_lane_f32(x2y2z2w2, 0);
-
-		// Use sqrt/div/mul to normalize because the sqrt/div are faster than rsqrt
-		float inv_len = 1.0F / sqrt(dot);
-		return vector_mul(interpolated_rotation, inv_len);
-#else
-		// To ensure we take the shortest path, we apply a bias if the dot product is negative
-		Vector4_32 start_vector = quat_to_vector(start);
-		Vector4_32 end_vector = quat_to_vector(end);
-		float dot = vector_dot(start_vector, end_vector);
-		float bias = dot >= 0.0F ? 1.0F : -1.0F;
-		Vector4_32 interpolated_rotation = vector_neg_mul_sub(vector_neg_mul_sub(end_vector, bias, start_vector), alpha, start_vector);
-		// TODO: Test with this instead: Rotation = (B * Alpha) + (A * (Bias * (1.f - Alpha)));
-		//Vector4_32 value = vector_add(vector_mul(end_vector, alpha), vector_mul(start_vector, bias * (1.0f - alpha)));
-		return quat_normalize(vector_to_quat(interpolated_rotation));
-#endif
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_neg(Quat_32Arg0 input)
-	{
-#if defined(ACL_NEON_INTRINSICS)
-		return vnegq_f32(input);
-#else
-		return vector_to_quat(vector_mul(quat_to_vector(input), -1.0F));
-#endif
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_ensure_positive_w(Quat_32Arg0 input)
-	{
-		return quat_get_w(input) >= 0.0F ? input : quat_neg(input);
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_from_positive_w(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE4_INTRINSICS)
-		__m128 x2y2z2 = _mm_mul_ps(input, input);
-		__m128 one = _mm_set_ss(1.0F);
-		__m128 w_squared = _mm_sub_ss(_mm_sub_ss(_mm_sub_ss(one, x2y2z2), _mm_shuffle_ps(x2y2z2, x2y2z2, _MM_SHUFFLE(1, 1, 1, 1))), _mm_shuffle_ps(x2y2z2, x2y2z2, _MM_SHUFFLE(2, 2, 2, 2)));
-		w_squared = _mm_andnot_ps(_mm_set_ss(-0.0F), w_squared);
-		__m128 w = _mm_sqrt_ss(w_squared);
-		return _mm_insert_ps(input, w, 0x30);
-#elif defined(ACL_SSE2_INTRINSICS)
-		__m128 x2y2z2 = _mm_mul_ps(input, input);
-		__m128 one = _mm_set_ss(1.0F);
-		__m128 w_squared = _mm_sub_ss(_mm_sub_ss(_mm_sub_ss(one, x2y2z2), _mm_shuffle_ps(x2y2z2, x2y2z2, _MM_SHUFFLE(1, 1, 1, 1))), _mm_shuffle_ps(x2y2z2, x2y2z2, _MM_SHUFFLE(2, 2, 2, 2)));
-		w_squared = _mm_andnot_ps(_mm_set_ss(-0.0F), w_squared);
-		__m128 w = _mm_sqrt_ss(w_squared);
-		__m128 input_wyzx = _mm_shuffle_ps(input, input, _MM_SHUFFLE(0, 2, 1, 3));
-		__m128 result_wyzx = _mm_move_ss(input_wyzx, w);
-		return _mm_shuffle_ps(result_wyzx, result_wyzx, _MM_SHUFFLE(0, 2, 1, 3));
-#elif defined(ACL_NEON_INTRINSICS) && 0
-		// TODO: This is slower on ARMv7-A, measure again on ARM64, fewer instructions but the first
-		// sub is dependent on the result of the mul where the C impl below pipelines a bit better it seems
-		float32x4_t x2y2z2 = vmulq_f32(input, input);
-		float w_squared = ((1.0F - vgetq_lane_f32(x2y2z2, 0)) - vgetq_lane_f32(x2y2z2, 1)) - vgetq_lane_f32(x2y2z2, 2);
-		float w = acl::sqrt(acl::abs(w_squared));
-		return vsetq_lane_f32(w, input, 3);
-#else
-		// Operation order is important here, due to rounding, ((1.0 - (X*X)) - Y*Y) - Z*Z is more accurate than 1.0 - dot3(xyz, xyz)
-		float w_squared = ((1.0F - vector_get_x(input) * vector_get_x(input)) - vector_get_y(input) * vector_get_y(input)) - vector_get_z(input) * vector_get_z(input);
-		// w_squared can be negative either due to rounding or due to quantization imprecision, we take the absolute value
-		// to ensure the resulting quaternion is always normalized with a positive W component
-		float w = sqrt(abs(w_squared));
-		return quat_set(vector_get_x(input), vector_get_y(input), vector_get_z(input), w);
-#endif
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Conversion to/from axis/angle/euler
-
-	inline void ACL_SIMD_CALL quat_to_axis_angle(Quat_32Arg0 input, Vector4_32& out_axis, float& out_angle)
-	{
-		constexpr float epsilon = 1.0E-8F;
-		constexpr float epsilon_squared = epsilon * epsilon;
-
-		out_angle = acos(quat_get_w(input)) * 2.0F;
-
-		float scale_sq = max(1.0F - quat_get_w(input) * quat_get_w(input), 0.0F);
-		out_axis = scale_sq >= epsilon_squared ? vector_div(vector_set(quat_get_x(input), quat_get_y(input), quat_get_z(input)), vector_set(sqrt(scale_sq))) : vector_set(1.0F, 0.0F, 0.0F);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL quat_get_axis(Quat_32Arg0 input)
-	{
-		constexpr float epsilon = 1.0E-8F;
-		constexpr float epsilon_squared = epsilon * epsilon;
-
-		float scale_sq = max(1.0F - quat_get_w(input) * quat_get_w(input), 0.0F);
-		return scale_sq >= epsilon_squared ? vector_div(vector_set(quat_get_x(input), quat_get_y(input), quat_get_z(input)), vector_set(sqrt(scale_sq))) : vector_set(1.0F, 0.0F, 0.0F);
-	}
-
-	inline float ACL_SIMD_CALL quat_get_angle(Quat_32Arg0 input)
-	{
-		return acos(quat_get_w(input)) * 2.0F;
-	}
-
-	inline Quat_32 ACL_SIMD_CALL quat_from_axis_angle(Vector4_32Arg0 axis, float angle)
-	{
-		float s;
-		float c;
-		sincos(0.5F * angle, s, c);
-
-		return quat_set(s * vector_get_x(axis), s * vector_get_y(axis), s * vector_get_z(axis), c);
-	}
-
-	// Pitch is around the Y axis (right)
-	// Yaw is around the Z axis (up)
-	// Roll is around the X axis (forward)
-	inline Quat_32 ACL_SIMD_CALL quat_from_euler(float pitch, float yaw, float roll)
-	{
-		float sp;
-		float sy;
-		float sr;
-		float cp;
-		float cy;
-		float cr;
-
-		sincos(pitch * 0.5F, sp, cp);
-		sincos(yaw * 0.5F, sy, cy);
-		sincos(roll * 0.5F, sr, cr);
-
-		return quat_set(cr * sp * sy - sr * cp * cy,
-			-cr * sp * cy - sr * cp * sy,
-			cr * cp * sy - sr * sp * cy,
-			cr * cp * cy + sr * sp * sy);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	inline bool ACL_SIMD_CALL quat_is_finite(Quat_32Arg0 input)
-	{
-		return is_finite(quat_get_x(input)) && is_finite(quat_get_y(input)) && is_finite(quat_get_z(input)) && is_finite(quat_get_w(input));
-	}
-
-	inline bool ACL_SIMD_CALL quat_is_normalized(Quat_32Arg0 input, float threshold = 0.00001F)
-	{
-		float length_squared = quat_length_squared(input);
-		return abs(length_squared - 1.0F) < threshold;
-	}
-
-	inline bool ACL_SIMD_CALL quat_near_equal(Quat_32Arg0 lhs, Quat_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_all_near_equal(quat_to_vector(lhs), quat_to_vector(rhs), threshold);
-	}
-
-	inline bool ACL_SIMD_CALL quat_near_identity(Quat_32Arg0 input, float threshold_angle = 0.00284714461F)
-	{
-		// Because of floating point precision, we cannot represent very small rotations.
-		// The closest float to 1.0 that is not 1.0 itself yields:
-		// acos(0.99999994f) * 2.0f  = 0.000690533954 rad
-		//
-		// An error threshold of 1.e-6f is used by default.
-		// acos(1.f - 1.e-6f) * 2.0f = 0.00284714461 rad
-		// acos(1.f - 1.e-7f) * 2.0f = 0.00097656250 rad
-		//
-		// We don't really care about the angle value itself, only if it's close to 0.
-		// This will happen whenever quat.w is close to 1.0.
-		// If the quat.w is close to -1.0, the angle will be near 2*PI which is close to
-		// a negative 0 rotation. By forcing quat.w to be positive, we'll end up with
-		// the shortest path.
-		const float positive_w_angle = acos(abs(quat_get_w(input))) * 2.0F;
-		return positive_w_angle < threshold_angle;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/quat_64.h b/includes/acl/math/quat_64.h
deleted file mode 100644
--- a/includes/acl/math/quat_64.h
+++ /dev/null
@@ -1,307 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/core/memory_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/scalar_64.h"
-#include "acl/math/vector4_64.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	inline Quat_64 quat_set(double x, double y, double z, double w)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Quat_64{ _mm_set_pd(y, x), _mm_set_pd(w, z) };
-#else
-		return Quat_64{ x, y, z, w };
-#endif
-	}
-
-	inline Quat_64 quat_unaligned_load(const double* input)
-	{
-		return quat_set(input[0], input[1], input[2], input[3]);
-	}
-
-	inline Quat_64 quat_identity_64()
-	{
-		return quat_set(0.0, 0.0, 0.0, 1.0);
-	}
-
-	inline Quat_64 vector_to_quat(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Quat_64{ input.xy, input.zw };
-#else
-		return Quat_64{ input.x, input.y, input.z, input.w };
-#endif
-	}
-
-	inline Quat_64 quat_cast(const Quat_32& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Quat_64{ _mm_cvtps_pd(input), _mm_cvtps_pd(_mm_shuffle_ps(input, input, _MM_SHUFFLE(3, 2, 3, 2))) };
-#elif defined(ACL_NEON_INTRINSICS)
-		return Quat_64{ double(vgetq_lane_f32(input, 0)), double(vgetq_lane_f32(input, 1)), double(vgetq_lane_f32(input, 2)), double(vgetq_lane_f32(input, 3)) };
-#else
-		return Quat_64{ double(input.x), double(input.y), double(input.z), double(input.w) };
-#endif
-	}
-
-	inline double quat_get_x(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(input.xy);
-#else
-		return input.x;
-#endif
-	}
-
-	inline double quat_get_y(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(_mm_shuffle_pd(input.xy, input.xy, 1));
-#else
-		return input.y;
-#endif
-	}
-
-	inline double quat_get_z(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(input.zw);
-#else
-		return input.z;
-#endif
-	}
-
-	inline double quat_get_w(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(_mm_shuffle_pd(input.zw, input.zw, 1));
-#else
-		return input.w;
-#endif
-	}
-
-	inline void quat_unaligned_write(const Quat_64& input, double* output)
-	{
-		output[0] = quat_get_x(input);
-		output[1] = quat_get_y(input);
-		output[2] = quat_get_z(input);
-		output[3] = quat_get_w(input);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	inline Quat_64 quat_conjugate(const Quat_64& input)
-	{
-		return quat_set(-quat_get_x(input), -quat_get_y(input), -quat_get_z(input), quat_get_w(input));
-	}
-
-	// Multiplication order is as follow: local_to_world = quat_mul(local_to_object, object_to_world)
-	inline Quat_64 quat_mul(const Quat_64& lhs, const Quat_64& rhs)
-	{
-		double lhs_x = quat_get_x(lhs);
-		double lhs_y = quat_get_y(lhs);
-		double lhs_z = quat_get_z(lhs);
-		double lhs_w = quat_get_w(lhs);
-
-		double rhs_x = quat_get_x(rhs);
-		double rhs_y = quat_get_y(rhs);
-		double rhs_z = quat_get_z(rhs);
-		double rhs_w = quat_get_w(rhs);
-
-		double x = (rhs_w * lhs_x) + (rhs_x * lhs_w) + (rhs_y * lhs_z) - (rhs_z * lhs_y);
-		double y = (rhs_w * lhs_y) - (rhs_x * lhs_z) + (rhs_y * lhs_w) + (rhs_z * lhs_x);
-		double z = (rhs_w * lhs_z) + (rhs_x * lhs_y) - (rhs_y * lhs_x) + (rhs_z * lhs_w);
-		double w = (rhs_w * lhs_w) - (rhs_x * lhs_x) - (rhs_y * lhs_y) - (rhs_z * lhs_z);
-
-		return quat_set(x, y, z, w);
-	}
-
-	inline Vector4_64 quat_rotate(const Quat_64& rotation, const Vector4_64& vector)
-	{
-		Quat_64 vector_quat = quat_set(vector_get_x(vector), vector_get_y(vector), vector_get_z(vector), 0.0);
-		Quat_64 inv_rotation = quat_conjugate(rotation);
-		return quat_to_vector(quat_mul(quat_mul(inv_rotation, vector_quat), rotation));
-	}
-
-	inline double quat_length_squared(const Quat_64& input)
-	{
-		// TODO: Use dot instruction
-		return (quat_get_x(input) * quat_get_x(input)) + (quat_get_y(input) * quat_get_y(input)) + (quat_get_z(input) * quat_get_z(input)) + (quat_get_w(input) * quat_get_w(input));
-	}
-
-	inline double quat_length(const Quat_64& input)
-	{
-		// TODO: Use intrinsics to avoid scalar coercion
-		return sqrt(quat_length_squared(input));
-	}
-
-	inline double quat_length_reciprocal(const Quat_64& input)
-	{
-		// TODO: Use recip instruction
-		return 1.0 / quat_length(input);
-	}
-
-	inline Quat_64 quat_normalize(const Quat_64& input)
-	{
-		// TODO: Use high precision recip sqrt function and vector_mul
-		double length = quat_length(input);
-		//float length_recip = quat_length_reciprocal(input);
-		Vector4_64 input_vector = quat_to_vector(input);
-		//return vector_to_quat(vector_mul(input_vector, length_recip));
-		return vector_to_quat(vector_div(input_vector, vector_set(length)));
-	}
-
-	inline Quat_64 quat_lerp(const Quat_64& start, const Quat_64& end, double alpha)
-	{
-		// To ensure we take the shortest path, we apply a bias if the dot product is negative
-		Vector4_64 start_vector = quat_to_vector(start);
-		Vector4_64 end_vector = quat_to_vector(end);
-		double dot = vector_dot(start_vector, end_vector);
-		double bias = dot >= 0.0 ? 1.0 : -1.0;
-		// TODO: Test with this instead: Rotation = (B * Alpha) + (A * (Bias * (1.f - Alpha)));
-		Vector4_64 value = vector_add(start_vector, vector_mul(vector_sub(vector_mul(end_vector, bias), start_vector), alpha));
-		//Vector4_64 value = vector_add(vector_mul(end_vector, alpha), vector_mul(start_vector, bias * (1.0 - alpha)));
-		return quat_normalize(vector_to_quat(value));
-	}
-
-	inline Quat_64 quat_neg(const Quat_64& input)
-	{
-		return vector_to_quat(vector_mul(quat_to_vector(input), -1.0));
-	}
-
-	inline Quat_64 quat_ensure_positive_w(const Quat_64& input)
-	{
-		return quat_get_w(input) >= 0.0 ? input : quat_neg(input);
-	}
-
-	inline Quat_64 quat_from_positive_w(const Vector4_64& input)
-	{
-		// Operation order is important here, due to rounding, ((1.0 - (X*X)) - Y*Y) - Z*Z is more accurate than 1.0 - dot3(xyz, xyz)
-		double w_squared = ((1.0 - vector_get_x(input) * vector_get_x(input)) - vector_get_y(input) * vector_get_y(input)) - vector_get_z(input) * vector_get_z(input);
-		// w_squared can be negative either due to rounding or due to quantization imprecision, we take the absolute value
-		// to ensure the resulting quaternion is always normalized with a positive W component
-		double w = sqrt(abs(w_squared));
-		return quat_set(vector_get_x(input), vector_get_y(input), vector_get_z(input), w);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Conversion to/from axis/angle/euler
-
-	inline void quat_to_axis_angle(const Quat_64& input, Vector4_64& out_axis, double& out_angle)
-	{
-		constexpr double epsilon = 1.0e-8;
-		constexpr double epsilon_squared = epsilon * epsilon;
-
-		out_angle = acos(quat_get_w(input)) * 2.0;
-
-		double scale_sq = max(1.0 - quat_get_w(input) * quat_get_w(input), 0.0);
-		out_axis = scale_sq >= epsilon_squared ? vector_div(vector_set(quat_get_x(input), quat_get_y(input), quat_get_z(input)), vector_set(sqrt(scale_sq))) : vector_set(1.0, 0.0, 0.0);
-	}
-
-	inline Vector4_64 quat_get_axis(const Quat_64& input)
-	{
-		constexpr double epsilon = 1.0e-8;
-		constexpr double epsilon_squared = epsilon * epsilon;
-
-		double scale_sq = max(1.0 - quat_get_w(input) * quat_get_w(input), 0.0);
-		return scale_sq >= epsilon_squared ? vector_div(vector_set(quat_get_x(input), quat_get_y(input), quat_get_z(input)), vector_set(sqrt(scale_sq))) : vector_set(1.0, 0.0, 0.0);
-	}
-
-	inline double quat_get_angle(const Quat_64& input)
-	{
-		return acos(quat_get_w(input)) * 2.0;
-	}
-
-	inline Quat_64 quat_from_axis_angle(const Vector4_64& axis, double angle)
-	{
-		double s;
-		double c;
-		sincos(0.5 * angle, s, c);
-
-		return quat_set(s * vector_get_x(axis), s * vector_get_y(axis), s * vector_get_z(axis), c);
-	}
-
-	// Pitch is around the Y axis (right)
-	// Yaw is around the Z axis (up)
-	// Roll is around the X axis (forward)
-	inline Quat_64 quat_from_euler(double pitch, double yaw, double roll)
-	{
-		double sp;
-		double sy;
-		double sr;
-		double cp;
-		double cy;
-		double cr;
-
-		sincos(pitch * 0.5, sp, cp);
-		sincos(yaw * 0.5, sy, cy);
-		sincos(roll * 0.5, sr, cr);
-
-		return quat_set(cr * sp * sy - sr * cp * cy,
-			-cr * sp * cy - sr * cp * sy,
-			cr * cp * sy - sr * sp * cy,
-			cr * cp * cy + sr * sp * sy);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	inline bool quat_is_finite(const Quat_64& input)
-	{
-		return is_finite(quat_get_x(input)) && is_finite(quat_get_y(input)) && is_finite(quat_get_z(input)) && is_finite(quat_get_w(input));
-	}
-
-	inline bool quat_is_normalized(const Quat_64& input, double threshold = 0.00001)
-	{
-		double length_squared = quat_length_squared(input);
-		return abs(length_squared - 1.0) < threshold;
-	}
-
-	inline bool quat_near_equal(const Quat_64& lhs, const Quat_64& rhs, double threshold = 0.00001)
-	{
-		return vector_all_near_equal(quat_to_vector(lhs), quat_to_vector(rhs), threshold);
-	}
-
-	inline bool quat_near_identity(const Quat_64& input, double threshold_angle = 0.00284714461)
-	{
-		// See the Quat_32 version of quat_near_identity for details.
-		const double positive_w_angle = acos(abs(quat_get_w(input))) * 2.0;
-		return positive_w_angle < threshold_angle;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/quat_packing.h b/includes/acl/math/quat_packing.h
--- a/includes/acl/math/quat_packing.h
+++ b/includes/acl/math/quat_packing.h
@@ -28,69 +28,71 @@
 #include "acl/core/error.h"
 #include "acl/core/memory_utils.h"
 #include "acl/core/track_types.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/scalar_packing.h"
 #include "acl/math/vector4_packing.h"
 
+#include <rtm/quatf.h>
+#include <rtm/vector4f.h>
+#include <rtm/packing/quatf.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
 
 namespace acl
 {
-	inline void ACL_SIMD_CALL pack_quat_128(Quat_32Arg0 rotation, uint8_t* out_rotation_data)
+	inline void RTM_SIMD_CALL pack_quat_128(rtm::quatf_arg0 rotation, uint8_t* out_rotation_data)
 	{
-		pack_vector4_128(quat_to_vector(rotation), out_rotation_data);
+		pack_vector4_128(rtm::quat_to_vector(rotation), out_rotation_data);
 	}
 
-	inline Quat_32 ACL_SIMD_CALL unpack_quat_128(const uint8_t* data_ptr)
+	inline rtm::quatf RTM_SIMD_CALL unpack_quat_128(const uint8_t* data_ptr)
 	{
-		return vector_to_quat(unpack_vector4_128(data_ptr));
+		return rtm::vector_to_quat(unpack_vector4_128(data_ptr));
 	}
 
-	inline void ACL_SIMD_CALL pack_quat_96(Quat_32Arg0 rotation, uint8_t* out_rotation_data)
+	inline void RTM_SIMD_CALL pack_quat_96(rtm::quatf_arg0 rotation, uint8_t* out_rotation_data)
 	{
-		Vector4_32 rotation_xyz = quat_to_vector(quat_ensure_positive_w(rotation));
+		rtm::vector4f rotation_xyz = rtm::quat_to_vector(rtm::quat_ensure_positive_w(rotation));
 		pack_vector3_96(rotation_xyz, out_rotation_data);
 	}
 
 	// Assumes the 'data_ptr' is padded in order to load up to 16 bytes from it
-	inline Quat_32 ACL_SIMD_CALL unpack_quat_96_unsafe(const uint8_t* data_ptr)
+	inline rtm::quatf RTM_SIMD_CALL unpack_quat_96_unsafe(const uint8_t* data_ptr)
 	{
-		Vector4_32 rotation_xyz = unpack_vector3_96_unsafe(data_ptr);
-		return quat_from_positive_w(rotation_xyz);
+		rtm::vector4f rotation_xyz = unpack_vector3_96_unsafe(data_ptr);
+		return rtm::quat_from_positive_w(rotation_xyz);
 	}
 
 	ACL_DEPRECATED("Use unpack_quat_96_unsafe instead, to be removed in v2.0")
-	inline Quat_32 ACL_SIMD_CALL unpack_quat_96(const uint8_t* data_ptr)
+	inline rtm::quatf RTM_SIMD_CALL unpack_quat_96(const uint8_t* data_ptr)
 	{
-		Vector4_32 rotation_xyz = vector_unaligned_load3_32(data_ptr);
-		return quat_from_positive_w(rotation_xyz);
+		rtm::vector4f rotation_xyz = rtm::vector_load3(data_ptr);
+		return rtm::quat_from_positive_w(rotation_xyz);
 	}
 
-	inline void ACL_SIMD_CALL pack_quat_48(Quat_32Arg0 rotation, uint8_t* out_rotation_data)
+	inline void RTM_SIMD_CALL pack_quat_48(rtm::quatf_arg0 rotation, uint8_t* out_rotation_data)
 	{
-		Vector4_32 rotation_xyz = quat_to_vector(quat_ensure_positive_w(rotation));
+		rtm::vector4f rotation_xyz = rtm::quat_to_vector(rtm::quat_ensure_positive_w(rotation));
 		pack_vector3_s48_unsafe(rotation_xyz, out_rotation_data);
 	}
 
-	inline Quat_32 ACL_SIMD_CALL unpack_quat_48(const uint8_t* data_ptr)
+	inline rtm::quatf RTM_SIMD_CALL unpack_quat_48(const uint8_t* data_ptr)
 	{
-		Vector4_32 rotation_xyz = unpack_vector3_s48_unsafe(data_ptr);
-		return quat_from_positive_w(rotation_xyz);
+		rtm::vector4f rotation_xyz = unpack_vector3_s48_unsafe(data_ptr);
+		return rtm::quat_from_positive_w(rotation_xyz);
 	}
 
-	inline void ACL_SIMD_CALL pack_quat_32(Quat_32Arg0 rotation, uint8_t* out_rotation_data)
+	inline void RTM_SIMD_CALL pack_quat_32(rtm::quatf_arg0 rotation, uint8_t* out_rotation_data)
 	{
-		Vector4_32 rotation_xyz = quat_to_vector(quat_ensure_positive_w(rotation));
+		rtm::vector4f rotation_xyz = rtm::quat_to_vector(rtm::quat_ensure_positive_w(rotation));
 		pack_vector3_32(rotation_xyz, 11, 11, 10, false, out_rotation_data);
 	}
 
-	inline Quat_32 ACL_SIMD_CALL unpack_quat_32(const uint8_t* data_ptr)
+	inline rtm::quatf RTM_SIMD_CALL unpack_quat_32(const uint8_t* data_ptr)
 	{
-		Vector4_32 rotation_xyz = unpack_vector3_32(11, 11, 10, false, data_ptr);
-		return quat_from_positive_w(rotation_xyz);
+		rtm::vector4f rotation_xyz = unpack_vector3_32(11, 11, 10, false, data_ptr);
+		return rtm::quat_from_positive_w(rotation_xyz);
 	}
 
 	//////////////////////////////////////////////////////////////////////////
diff --git a/includes/acl/math/rtm_casts.h b/includes/acl/math/rtm_casts.h
deleted file mode 100644
--- a/includes/acl/math/rtm_casts.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2019 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/math/vector4_32.h"
-
-#include <rtm/vector4f.h>
-
-#include <cstdint>
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Casts an ACL Vector4_32 into a RTM vector4f.
-	// When SIMD intrinsics are enabled, this is a no-op.
-	inline rtm::vector4f RTM_SIMD_CALL vector_acl2rtm(Vector4_32Arg0 value)
-	{
-#if defined(RTM_SSE2_INTRINSICS) || defined(RTM_NEON_INTRINSICS)
-		return value;
-#else
-		return rtm::vector4f{value.x, value.y, value.z, value.w};
-#endif
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Casts a RTM vector4f into an ACL Vector4_32.
-	// When SIMD intrinsics are enabled, this is a no-op.
-	inline Vector4_32 RTM_SIMD_CALL vector_rtm2acl(rtm::vector4f_arg0 value)
-	{
-#if defined(RTM_SSE2_INTRINSICS) || defined(RTM_NEON_INTRINSICS)
-		return value;
-#else
-		return Vector4_32{value.x, value.y, value.z, value.w};
-#endif
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/scalar_32.h b/includes/acl/math/scalar_32.h
deleted file mode 100644
--- a/includes/acl/math/scalar_32.h
+++ /dev/null
@@ -1,215 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/math/math.h"
-
-#include <algorithm>
-#include <cmath>
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	// TODO: Get a higher precision number
-	constexpr float k_pi_32 = 3.141592654F;
-
-	inline float floor(float input)
-	{
-#if defined(ACL_SSE4_INTRINSICS)
-		const __m128 value = _mm_set_ps1(input);
-		return _mm_cvtss_f32(_mm_round_ss(value, value, 0x9));
-#else
-		return std::floor(input);
-#endif
-	}
-
-	inline float ceil(float input)
-	{
-#if defined(ACL_SSE4_INTRINSICS)
-		const __m128 value = _mm_set_ps1(input);
-		return _mm_cvtss_f32(_mm_round_ss(value, value, 0xA));
-#else
-		return std::ceil(input);
-#endif
-	}
-
-	inline float clamp(float input, float min, float max)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_min_ss(_mm_max_ss(_mm_set_ps1(input), _mm_set_ps1(min)), _mm_set_ps1(max)));
-#else
-		return std::min(std::max(input, min), max);
-#endif
-	}
-
-	inline float abs(float input)
-	{
-		return std::fabs(input);
-	}
-
-	inline float sqrt(float input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ps1(input)));
-#else
-		return std::sqrt(input);
-#endif
-	}
-
-#if defined(_MSC_VER) && _MSC_VER >= 1920 && defined(_M_X64) && defined(ACL_SSE2_INTRINSICS) && !defined(ACL_AVX_INTRINSICS)
-	// HACK!!! Visual Studio 2019 has a code generation bug triggered by the code below, disable optimizations for now
-	// Bug only happens with x64 SSE2, not with AVX nor with x86
-	#pragma optimize("", off)
-#endif
-	inline float sqrt_reciprocal(float input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		__m128 input_v = _mm_set_ss(input);
-		__m128 half = _mm_set_ss(0.5F);
-		__m128 input_half_v = _mm_mul_ss(input_v, half);
-		__m128 x0 = _mm_rsqrt_ss(input_v);
-
-		// First iteration
-		__m128 x1 = _mm_mul_ss(x0, x0);
-		x1 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x1));
-		x1 = _mm_add_ss(_mm_mul_ss(x0, x1), x0);
-
-		// Second iteration
-		__m128 x2 = _mm_mul_ss(x1, x1);
-		x2 = _mm_sub_ss(half, _mm_mul_ss(input_half_v, x2));
-		x2 = _mm_add_ss(_mm_mul_ss(x1, x2), x1);
-
-		return _mm_cvtss_f32(x2);
-#else
-		return 1.0F / sqrt(input);
-#endif
-	}
-#if defined(_MSC_VER) && _MSC_VER >= 1920 && defined(_M_X64) && defined(ACL_SSE2_INTRINSICS) && !defined(ACL_AVX_INTRINSICS)
-	// HACK!!! See comment above
-	#pragma optimize("", on)
-#endif
-
-	inline float reciprocal(float input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		__m128 input_v = _mm_set_ps1(input);
-		__m128 x0 = _mm_rcp_ss(input_v);
-
-		// First iteration
-		__m128 x1 = _mm_sub_ss(_mm_add_ss(x0, x0), _mm_mul_ss(input_v, _mm_mul_ss(x0, x0)));
-
-		// Second iteration
-		__m128 x2 = _mm_sub_ss(_mm_add_ss(x1, x1), _mm_mul_ss(input_v, _mm_mul_ss(x1, x1)));
-
-		return _mm_cvtss_f32(x2);
-#else
-		return 1.0F / input;
-#endif
-	}
-
-	inline float sin(float angle)
-	{
-		return std::sin(angle);
-	}
-
-	inline float cos(float angle)
-	{
-		return std::cos(angle);
-	}
-
-	inline void sincos(float angle, float& out_sin, float& out_cos)
-	{
-		out_sin = sin(angle);
-		out_cos = cos(angle);
-	}
-
-	inline float acos(float value)
-	{
-		return std::acos(value);
-	}
-
-	inline float atan2(float left, float right)
-	{
-		return std::atan2(left, right);
-	}
-
-	inline float min(float left, float right)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_min_ss(_mm_set_ps1(left), _mm_set_ps1(right)));
-#else
-		return std::min(left, right);
-#endif
-	}
-
-	inline float max(float left, float right)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_max_ss(_mm_set_ps1(left), _mm_set_ps1(right)));
-#else
-		return std::max(left, right);
-#endif
-	}
-
-	constexpr float deg2rad(float deg)
-	{
-		return (deg / 180.0F) * k_pi_32;
-	}
-
-	inline bool scalar_near_equal(float lhs, float rhs, float threshold)
-	{
-		return abs(lhs - rhs) < threshold;
-	}
-
-	inline bool is_finite(float input)
-	{
-		return std::isfinite(input);
-	}
-
-	inline float symmetric_round(float input)
-	{
-		return input >= 0.0F ? floor(input + 0.5F) : ceil(input - 0.5F);
-	}
-
-	inline float fraction(float value)
-	{
-		return value - floor(value);
-	}
-
-	template<typename SrcIntegralType>
-	inline float safe_to_float(SrcIntegralType input)
-	{
-		float input_f = float(input);
-		ACL_ASSERT(SrcIntegralType(input_f) == input, "Convertion to float would result in truncation");
-		return input_f;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/scalar_64.h b/includes/acl/math/scalar_64.h
deleted file mode 100644
--- a/includes/acl/math/scalar_64.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/math/math.h"
-
-#include <algorithm>
-#include <cmath>
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	// TODO: Get a higher precision number
-	constexpr double k_pi_64 = 3.141592654;
-
-	inline double floor(double input)
-	{
-		return std::floor(input);
-	}
-
-	inline double ceil(double input)
-	{
-		return std::ceil(input);
-	}
-
-	inline double clamp(double input, double min, double max)
-	{
-		return std::min(std::max(input, min), max);
-	}
-
-	inline double abs(double input)
-	{
-		return std::fabs(input);
-	}
-
-	inline double sqrt(double input)
-	{
-		return std::sqrt(input);
-	}
-
-	inline double sqrt_reciprocal(double input)
-	{
-		// TODO: Use recip instruction
-		return 1.0 / sqrt(input);
-	}
-
-	inline double reciprocal(double input)
-	{
-		return 1.0 / input;
-	}
-
-	inline double sin(double angle)
-	{
-		return std::sin(angle);
-	}
-
-	inline double cos(double angle)
-	{
-		return std::cos(angle);
-	}
-
-	inline void sincos(double angle, double& out_sin, double& out_cos)
-	{
-		out_sin = sin(angle);
-		out_cos = cos(angle);
-	}
-
-	inline double acos(double value)
-	{
-		return std::acos(value);
-	}
-
-	inline double atan2(double left, double right)
-	{
-		return std::atan2(left, right);
-	}
-
-	inline double min(double left, double right)
-	{
-		return std::min(left, right);
-	}
-
-	inline double max(double left, double right)
-	{
-		return std::max(left, right);
-	}
-
-	constexpr double deg2rad(double deg)
-	{
-		return (deg / 180.0) * k_pi_64;
-	}
-
-	inline bool scalar_near_equal(double lhs, double rhs, double threshold)
-	{
-		return abs(lhs - rhs) < threshold;
-	}
-
-	inline bool is_finite(double input)
-	{
-		return std::isfinite(input);
-	}
-
-	inline double symmetric_round(double input)
-	{
-		return input >= 0.0 ? floor(input + 0.5) : ceil(input - 0.5);
-	}
-
-	inline double fraction(double value)
-	{
-		return value - floor(value);
-	}
-
-	template<typename SrcIntegralType>
-	inline double safe_to_double(SrcIntegralType input)
-	{
-		double input_f = double(input);
-		ACL_ASSERT(SrcIntegralType(input_f) == input, "Convertion to double would result in truncation");
-		return input_f;
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/scalar_packing.h b/includes/acl/math/scalar_packing.h
--- a/includes/acl/math/scalar_packing.h
+++ b/includes/acl/math/scalar_packing.h
@@ -26,7 +26,8 @@
 
 #include "acl/core/compiler_utils.h"
 #include "acl/core/error.h"
-#include "acl/math/scalar_32.h"
+
+#include <rtm/scalarf.h>
 
 #include <cstdint>
 
@@ -39,7 +40,7 @@ namespace acl
 		ACL_ASSERT(num_bits < 31, "Attempting to pack on too many bits");
 		ACL_ASSERT(input >= 0.0F && input <= 1.0F, "Expected normalized unsigned input value: %f", input);
 		const uint32_t max_value = (1 << num_bits) - 1;
-		return static_cast<uint32_t>(symmetric_round(input * safe_to_float(max_value)));
+		return static_cast<uint32_t>(rtm::scalar_symmetric_round(input * rtm::scalar_safe_to_float(max_value)));
 	}
 
 	inline float unpack_scalar_unsigned(uint32_t input, uint8_t num_bits)
@@ -48,8 +49,8 @@ namespace acl
 		const uint32_t max_value = (1 << num_bits) - 1;
 		ACL_ASSERT(input <= max_value, "Input value too large: %ull", input);
 		// For performance reasons, unpacking is faster when multiplying with the reciprocal
-		const float inv_max_value = 1.0F / safe_to_float(max_value);
-		return safe_to_float(input) * inv_max_value;
+		const float inv_max_value = 1.0F / rtm::scalar_safe_to_float(max_value);
+		return rtm::scalar_safe_to_float(input) * inv_max_value;
 	}
 
 	inline uint32_t pack_scalar_signed(float input, uint8_t num_bits)
diff --git a/includes/acl/math/transform_32.h b/includes/acl/math/transform_32.h
deleted file mode 100644
--- a/includes/acl/math/transform_32.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/quat_32.h"
-#include "acl/math/vector4_32.h"
-#include "acl/math/affine_matrix_32.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	constexpr Transform_32 ACL_SIMD_CALL transform_set(Quat_32Arg0 rotation, Vector4_32Arg1 translation, Vector4_32Arg2 scale)
-	{
-		return Transform_32{ rotation, translation, scale };
-	}
-
-	inline Transform_32 ACL_SIMD_CALL transform_identity_32()
-	{
-		return transform_set(quat_identity_32(), vector_zero_32(), vector_set(1.0F));
-	}
-
-	inline Transform_32 ACL_SIMD_CALL transform_cast(const Transform_64& input)
-	{
-		return Transform_32{ quat_cast(input.rotation), vector_cast(input.translation), vector_cast(input.scale) };
-	}
-
-	// Multiplication order is as follow: local_to_world = transform_mul(local_to_object, object_to_world)
-	// NOTE: When scale is present, multiplication will not properly handle skew/shear, use affine matrices instead
-	inline Transform_32 ACL_SIMD_CALL transform_mul(Transform_32Arg0 lhs, Transform_32Arg1 rhs)
-	{
-		const Vector4_32 min_scale = vector_min(lhs.scale, rhs.scale);
-		const Vector4_32 scale = vector_mul(lhs.scale, rhs.scale);
-
-		if (vector_any_less_than3(min_scale, vector_zero_32()))
-		{
-			// If we have negative scale, we go through a matrix
-			const AffineMatrix_32 lhs_mtx = matrix_from_transform(lhs);
-			const AffineMatrix_32 rhs_mtx = matrix_from_transform(rhs);
-			AffineMatrix_32 result_mtx = matrix_mul(lhs_mtx, rhs_mtx);
-			result_mtx = matrix_remove_scale(result_mtx);
-
-			const Vector4_32 sign = vector_sign(scale);
-			result_mtx.x_axis = vector_mul(result_mtx.x_axis, vector_mix_xxxx(sign));
-			result_mtx.y_axis = vector_mul(result_mtx.y_axis, vector_mix_yyyy(sign));
-			result_mtx.z_axis = vector_mul(result_mtx.z_axis, vector_mix_zzzz(sign));
-
-			const Quat_32 rotation = quat_from_matrix(result_mtx);
-			const Vector4_32 translation = result_mtx.w_axis;
-			return transform_set(rotation, translation, scale);
-		}
-		else
-		{
-			const Quat_32 rotation = quat_mul(lhs.rotation, rhs.rotation);
-			const Vector4_32 translation = vector_add(quat_rotate(rhs.rotation, vector_mul(lhs.translation, rhs.scale)), rhs.translation);
-			return transform_set(rotation, translation, scale);
-		}
-	}
-
-	// Multiplication order is as follow: local_to_world = transform_mul(local_to_object, object_to_world)
-	inline Transform_32 ACL_SIMD_CALL transform_mul_no_scale(Transform_32Arg0 lhs, Transform_32Arg1 rhs)
-	{
-		const Quat_32 rotation = quat_mul(lhs.rotation, rhs.rotation);
-		const Vector4_32 translation = vector_add(quat_rotate(rhs.rotation, lhs.translation), rhs.translation);
-		return transform_set(rotation, translation, vector_set(1.0F));
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL transform_position(Transform_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-		return vector_add(quat_rotate(lhs.rotation, vector_mul(lhs.scale, rhs)), lhs.translation);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL transform_position_no_scale(Transform_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-		return vector_add(quat_rotate(lhs.rotation, rhs), lhs.translation);
-	}
-
-	inline Transform_32 ACL_SIMD_CALL transform_inverse(Transform_32Arg0 input)
-	{
-		const Quat_32 inv_rotation = quat_conjugate(input.rotation);
-		const Vector4_32 inv_scale = vector_reciprocal(input.scale);
-		const Vector4_32 inv_translation = vector_neg(quat_rotate(inv_rotation, vector_mul(input.translation, inv_scale)));
-		return transform_set(inv_rotation, inv_translation, inv_scale);
-	}
-
-	inline Transform_32 ACL_SIMD_CALL transform_inverse_no_scale(Transform_32Arg0 input)
-	{
-		const Quat_32 inv_rotation = quat_conjugate(input.rotation);
-		const Vector4_32 inv_translation = vector_neg(quat_rotate(inv_rotation, input.translation));
-		return transform_set(inv_rotation, inv_translation, vector_set(1.0F));
-	}
-
-	inline Transform_32 ACL_SIMD_CALL transform_normalize(Transform_32Arg0 input)
-	{
-		const Quat_32 rotation = quat_normalize(input.rotation);
-		return transform_set(rotation, input.translation, input.scale);
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/transform_64.h b/includes/acl/math/transform_64.h
deleted file mode 100644
--- a/includes/acl/math/transform_64.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/quat_64.h"
-#include "acl/math/vector4_64.h"
-#include "acl/math/affine_matrix_64.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	constexpr Transform_64 transform_set(const Quat_64& rotation, const Vector4_64& translation, const Vector4_64& scale)
-	{
-		return Transform_64{ rotation, translation, scale };
-	}
-
-	inline Transform_64 transform_identity_64()
-	{
-		return transform_set(quat_identity_64(), vector_zero_64(), vector_set(1.0));
-	}
-
-	inline Transform_64 transform_cast(const Transform_32& input)
-	{
-		return Transform_64{ quat_cast(input.rotation), vector_cast(input.translation), vector_cast(input.scale) };
-	}
-
-	// Multiplication order is as follow: local_to_world = transform_mul(local_to_object, object_to_world)
-	// NOTE: When scale is present, multiplication will not properly handle skew/shear, use affine matrices instead
-	inline Transform_64 transform_mul(const Transform_64& lhs, const Transform_64& rhs)
-	{
-		const Vector4_64 min_scale = vector_min(lhs.scale, rhs.scale);
-		const Vector4_64 scale = vector_mul(lhs.scale, rhs.scale);
-
-		if (vector_any_less_than3(min_scale, vector_zero_64()))
-		{
-			// If we have negative scale, we go through a matrix
-			const AffineMatrix_64 lhs_mtx = matrix_from_transform(lhs);
-			const AffineMatrix_64 rhs_mtx = matrix_from_transform(rhs);
-			AffineMatrix_64 result_mtx = matrix_mul(lhs_mtx, rhs_mtx);
-			result_mtx = matrix_remove_scale(result_mtx);
-
-			const Vector4_64 sign = vector_sign(scale);
-			result_mtx.x_axis = vector_mul(result_mtx.x_axis, vector_mix_xxxx(sign));
-			result_mtx.y_axis = vector_mul(result_mtx.y_axis, vector_mix_yyyy(sign));
-			result_mtx.z_axis = vector_mul(result_mtx.z_axis, vector_mix_zzzz(sign));
-
-			const Quat_64 rotation = quat_from_matrix(result_mtx);
-			const Vector4_64 translation = result_mtx.w_axis;
-			return transform_set(rotation, translation, scale);
-		}
-		else
-		{
-			const Quat_64 rotation = quat_mul(lhs.rotation, rhs.rotation);
-			const Vector4_64 translation = vector_add(quat_rotate(rhs.rotation, vector_mul(lhs.translation, rhs.scale)), rhs.translation);
-			return transform_set(rotation, translation, scale);
-		}
-	}
-
-	// Multiplication order is as follow: local_to_world = transform_mul(local_to_object, object_to_world)
-	inline Transform_64 transform_mul_no_scale(const Transform_64& lhs, const Transform_64& rhs)
-	{
-		const Quat_64 rotation = quat_mul(lhs.rotation, rhs.rotation);
-		const Vector4_64 translation = vector_add(quat_rotate(rhs.rotation, lhs.translation), rhs.translation);
-		return transform_set(rotation, translation, vector_set(1.0));
-	}
-
-	inline Vector4_64 transform_position(const Transform_64& lhs, const Vector4_64& rhs)
-	{
-		return vector_add(quat_rotate(lhs.rotation, vector_mul(lhs.scale, rhs)), lhs.translation);
-	}
-
-	inline Vector4_64 transform_position_no_scale(const Transform_64& lhs, const Vector4_64& rhs)
-	{
-		return vector_add(quat_rotate(lhs.rotation, rhs), lhs.translation);
-	}
-
-	inline Transform_64 transform_inverse(const Transform_64& input)
-	{
-		const Quat_64 inv_rotation = quat_conjugate(input.rotation);
-		const Vector4_64 inv_scale = vector_reciprocal(input.scale);
-		const Vector4_64 inv_translation = vector_neg(quat_rotate(inv_rotation, vector_mul(input.translation, inv_scale)));
-		return transform_set(inv_rotation, inv_translation, inv_scale);
-	}
-
-	inline Transform_64 transform_inverse_no_scale(const Transform_64& input)
-	{
-		const Quat_64 inv_rotation = quat_conjugate(input.rotation);
-		const Vector4_64 inv_translation = vector_neg(quat_rotate(inv_rotation, input.translation));
-		return transform_set(inv_rotation, inv_translation, vector_set(1.0));
-	}
-
-	inline Transform_64 transform_normalize(const Transform_64& input)
-	{
-		const Quat_64 rotation = quat_normalize(input.rotation);
-		return transform_set(rotation, input.translation, input.scale);
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/vector4_32.h b/includes/acl/math/vector4_32.h
deleted file mode 100644
--- a/includes/acl/math/vector4_32.h
+++ /dev/null
@@ -1,968 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/core/memory_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/scalar_32.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	inline Vector4_32 ACL_SIMD_CALL vector_set(float x, float y, float z, float w)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_set_ps(w, z, y, x);
-#elif defined(ACL_NEON_INTRINSICS)
-#if 1
-		float32x2_t V0 = vcreate_f32(((uint64_t)*(const uint32_t*)&x) | ((uint64_t)(*(const uint32_t*)&y) << 32));
-		float32x2_t V1 = vcreate_f32(((uint64_t)*(const uint32_t*)&z) | ((uint64_t)(*(const uint32_t*)&w) << 32));
-		return vcombine_f32(V0, V1);
-#else
-		float __attribute__((aligned(16))) data[4] = { x, y, z, w };
-		return vld1q_f32(data);
-#endif
-#else
-		return Vector4_32{ x, y, z, w };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_set(float x, float y, float z)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_set_ps(0.0F, z, y, x);
-#elif defined(ACL_NEON_INTRINSICS)
-#if 1
-		float32x2_t V0 = vcreate_f32(((uint64_t)*(const uint32_t*)&x) | ((uint64_t)(*(const uint32_t*)&y) << 32));
-		float32x2_t V1 = vcreate_f32((uint64_t)*(const uint32_t*)&z);
-		return vcombine_f32(V0, V1);
-#else
-		float __attribute__((aligned(16))) data[4] = { x, y, z };
-		return vld1q_f32(data);
-#endif
-#else
-		return Vector4_32{ x, y, z, 0.0f };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_set(float xyzw)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_set_ps1(xyzw);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vdupq_n_f32(xyzw);
-#else
-		return Vector4_32{ xyzw, xyzw, xyzw, xyzw };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_unaligned_load(const float* input)
-	{
-		return vector_set(input[0], input[1], input[2], input[3]);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_unaligned_load3(const float* input)
-	{
-		return vector_set(input[0], input[1], input[2], 0.0F);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_unaligned_load_32(const uint8_t* input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_loadu_ps((const float*)input);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vreinterpretq_f32_u8(vld1q_u8(input));
-#else
-		Vector4_32 result;
-		std::memcpy(&result, input, sizeof(Vector4_32));
-		return result;
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_unaligned_load3_32(const uint8_t* input)
-	{
-		float input_f[3];
-		std::memcpy(&input_f[0], input, sizeof(float) * 3);
-		return vector_set(input_f[0], input_f[1], input_f[2], 0.0F);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_zero_32()
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_setzero_ps();
-#else
-		return vector_set(0.0F);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL quat_to_vector(Quat_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS) || defined(ACL_NEON_INTRINSICS)
-		return input;
-#else
-		return Vector4_32{ input.x, input.y, input.z, input.w };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_cast(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_shuffle_ps(_mm_cvtpd_ps(input.xy), _mm_cvtpd_ps(input.zw), _MM_SHUFFLE(1, 0, 1, 0));
-#else
-		return vector_set(float(input.x), float(input.y), float(input.z), float(input.w));
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_get_x(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(input);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 0);
-#else
-		return input.x;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_get_y(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(1, 1, 1, 1)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 1);
-#else
-		return input.y;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_get_z(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(2, 2, 2, 2)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 2);
-#else
-		return input.z;
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_get_w(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtss_f32(_mm_shuffle_ps(input, input, _MM_SHUFFLE(3, 3, 3, 3)));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vgetq_lane_f32(input, 3);
-#else
-		return input.w;
-#endif
-	}
-
-	template<VectorMix component_index>
-	inline float ACL_SIMD_CALL vector_get_component(Vector4_32Arg0 input)
-	{
-		switch (component_index)
-		{
-		case VectorMix::A:
-		case VectorMix::X: return vector_get_x(input);
-		case VectorMix::B:
-		case VectorMix::Y: return vector_get_y(input);
-		case VectorMix::C:
-		case VectorMix::Z: return vector_get_z(input);
-		case VectorMix::D:
-		case VectorMix::W: return vector_get_w(input);
-		default:
-			ACL_ASSERT(false, "Invalid component index");
-			return 0.0F;
-		}
-	}
-
-	inline float ACL_SIMD_CALL vector_get_component(Vector4_32Arg0 input, VectorMix component_index)
-	{
-		switch (component_index)
-		{
-		case VectorMix::A:
-		case VectorMix::X: return vector_get_x(input);
-		case VectorMix::B:
-		case VectorMix::Y: return vector_get_y(input);
-		case VectorMix::C:
-		case VectorMix::Z: return vector_get_z(input);
-		case VectorMix::D:
-		case VectorMix::W: return vector_get_w(input);
-		default:
-			ACL_ASSERT(false, "Invalid component index");
-			return 0.0F;
-		}
-	}
-
-	inline const float* ACL_SIMD_CALL vector_as_float_ptr(const Vector4_32& input)
-	{
-		return reinterpret_cast<const float*>(&input);
-	}
-
-	inline void ACL_SIMD_CALL vector_unaligned_write(Vector4_32Arg0 input, float* output)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		_mm_storeu_ps(output, input);
-#else
-		output[0] = vector_get_x(input);
-		output[1] = vector_get_y(input);
-		output[2] = vector_get_z(input);
-		output[3] = vector_get_w(input);
-#endif
-	}
-
-	inline void ACL_SIMD_CALL vector_unaligned_write3(Vector4_32Arg0 input, float* output)
-	{
-		output[0] = vector_get_x(input);
-		output[1] = vector_get_y(input);
-		output[2] = vector_get_z(input);
-	}
-
-	inline void ACL_SIMD_CALL vector_unaligned_write(Vector4_32Arg0 input, uint8_t* output)
-	{
-		std::memcpy(output, &input, sizeof(Vector4_32));
-	}
-
-	inline void ACL_SIMD_CALL vector_unaligned_write3(Vector4_32Arg0 input, uint8_t* output)
-	{
-		std::memcpy(output, &input, sizeof(float) * 3);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	inline Vector4_32 ACL_SIMD_CALL vector_add(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_add_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vaddq_f32(lhs, rhs);
-#else
-		return vector_set(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_sub(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_sub_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vsubq_f32(lhs, rhs);
-#else
-		return vector_set(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mul(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_mul_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmulq_f32(lhs, rhs);
-#else
-		return vector_set(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mul(Vector4_32Arg0 lhs, float rhs)
-	{
-#if defined(ACL_NEON_INTRINSICS)
-		return vmulq_n_f32(lhs, rhs);
-#else
-		return vector_mul(lhs, vector_set(rhs));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_div(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_div_ps(lhs, rhs);
-#elif defined (ACL_NEON64_INTRINSICS)
-		return vdivq_f32(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		float32x4_t x0 = vrecpeq_f32(rhs);
-
-		// First iteration
-		float32x4_t x1 = vmulq_f32(x0, vrecpsq_f32(x0, rhs));
-
-		// Second iteration
-		float32x4_t x2 = vmulq_f32(x1, vrecpsq_f32(x1, rhs));
-		return vmulq_f32(lhs, x2);
-#else
-		return vector_set(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_max(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_max_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmaxq_f32(lhs, rhs);
-#else
-		return vector_set(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z), max(lhs.w, rhs.w));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_min(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_min_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vminq_f32(lhs, rhs);
-#else
-		return vector_set(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z), min(lhs.w, rhs.w));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_clamp(Vector4_32Arg0 input, Vector4_32Arg1 min, Vector4_32Arg2 max)
-	{
-		return vector_min(max, vector_max(min, input));
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_abs(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return vector_max(vector_sub(_mm_setzero_ps(), input), input);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vabsq_f32(input);
-#else
-		return vector_set(abs(input.x), abs(input.y), abs(input.z), abs(input.w));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_neg(Vector4_32Arg0 input)
-	{
-#if defined(ACL_NEON_INTRINSICS)
-		return vnegq_f32(input);
-#else
-		return vector_mul(input, -1.0F);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_reciprocal(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		__m128 x0 = _mm_rcp_ps(input);
-
-		// First iteration
-		__m128 x1 = _mm_sub_ps(_mm_add_ps(x0, x0), _mm_mul_ps(input, _mm_mul_ps(x0, x0)));
-
-		// Second iteration
-		__m128 x2 = _mm_sub_ps(_mm_add_ps(x1, x1), _mm_mul_ps(input, _mm_mul_ps(x1, x1)));
-		return x2;
-#elif defined(ACL_NEON_INTRINSICS)
-		// Perform two passes of Newton-Raphson iteration on the hardware estimate
-		float32x4_t x0 = vrecpeq_f32(input);
-
-		// First iteration
-		float32x4_t x1 = vmulq_f32(x0, vrecpsq_f32(x0, input));
-
-		// Second iteration
-		float32x4_t x2 = vmulq_f32(x1, vrecpsq_f32(x1, input));
-		return x2;
-#else
-		return vector_div(vector_set(1.0F), input);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_ceil(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE4_INTRINSICS)
-		return _mm_ceil_ps(input);
-#else
-		return vector_set(ceil(vector_get_x(input)), ceil(vector_get_y(input)), ceil(vector_get_z(input)), ceil(vector_get_w(input)));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_floor(Vector4_32Arg0 input)
-	{
-#if defined(ACL_SSE4_INTRINSICS)
-		return _mm_floor_ps(input);
-#else
-		return vector_set(floor(vector_get_x(input)), floor(vector_get_y(input)), floor(vector_get_z(input)), floor(vector_get_w(input)));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_cross3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-		return vector_set(vector_get_y(lhs) * vector_get_z(rhs) - vector_get_z(lhs) * vector_get_y(rhs),
-						  vector_get_z(lhs) * vector_get_x(rhs) - vector_get_x(lhs) * vector_get_z(rhs),
-						  vector_get_x(lhs) * vector_get_y(rhs) - vector_get_y(lhs) * vector_get_x(rhs));
-	}
-
-	inline float ACL_SIMD_CALL vector_dot(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE4_INTRINSICS) && 0
-		// SSE4 dot product instruction isn't precise enough
-		return _mm_cvtss_f32(_mm_dp_ps(lhs, rhs, 0xFF));
-#elif defined(ACL_SSE2_INTRINSICS)
-		__m128 x2_y2_z2_w2 = _mm_mul_ps(lhs, rhs);
-		__m128 z2_w2_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 3, 2));
-		__m128 x2z2_y2w2_0_0 = _mm_add_ps(x2_y2_z2_w2, z2_w2_0_0);
-		__m128 y2w2_0_0_0 = _mm_shuffle_ps(x2z2_y2w2_0_0, x2z2_y2w2_0_0, _MM_SHUFFLE(0, 0, 0, 1));
-		__m128 x2y2z2w2_0_0_0 = _mm_add_ps(x2z2_y2w2_0_0, y2w2_0_0_0);
-		return _mm_cvtss_f32(x2y2z2w2_0_0_0);
-#elif defined(ACL_NEON_INTRINSICS)
-		float32x4_t x2_y2_z2_w2 = vmulq_f32(lhs, rhs);
-		float32x2_t x2_y2 = vget_low_f32(x2_y2_z2_w2);
-		float32x2_t z2_w2 = vget_high_f32(x2_y2_z2_w2);
-		float32x2_t x2z2_y2w2 = vadd_f32(x2_y2, z2_w2);
-		float32x2_t x2y2z2w2 = vpadd_f32(x2z2_y2w2, x2z2_y2w2);
-		return vget_lane_f32(x2y2z2w2, 0);
-#else
-		return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs)) + (vector_get_w(lhs) * vector_get_w(rhs));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_vdot(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE4_INTRINSICS) && 0
-		// SSE4 dot product instruction isn't precise enough
-		return _mm_dp_ps(lhs, rhs, 0xFF);
-#elif defined(ACL_SSE2_INTRINSICS)
-		__m128 x2_y2_z2_w2 = _mm_mul_ps(lhs, rhs);
-		__m128 z2_w2_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 3, 2));
-		__m128 x2z2_y2w2_0_0 = _mm_add_ps(x2_y2_z2_w2, z2_w2_0_0);
-		__m128 y2w2_0_0_0 = _mm_shuffle_ps(x2z2_y2w2_0_0, x2z2_y2w2_0_0, _MM_SHUFFLE(0, 0, 0, 1));
-		__m128 x2y2z2w2_0_0_0 = _mm_add_ps(x2z2_y2w2_0_0, y2w2_0_0_0);
-		return _mm_shuffle_ps(x2y2z2w2_0_0_0, x2y2z2w2_0_0_0, _MM_SHUFFLE(0, 0, 0, 0));
-#elif defined(ACL_NEON_INTRINSICS)
-		float32x4_t x2_y2_z2_w2 = vmulq_f32(lhs, rhs);
-		float32x2_t x2_y2 = vget_low_f32(x2_y2_z2_w2);
-		float32x2_t z2_w2 = vget_high_f32(x2_y2_z2_w2);
-		float32x2_t x2z2_y2w2 = vadd_f32(x2_y2, z2_w2);
-		float32x2_t x2y2z2w2 = vpadd_f32(x2z2_y2w2, x2z2_y2w2);
-		return vcombine_f32(x2y2z2w2, x2y2z2w2);
-#else
-		return vector_set(vector_dot(lhs, rhs));
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_dot3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE4_INTRINSICS) && 0
-		// SSE4 dot product instruction isn't precise enough
-		return _mm_cvtss_f32(_mm_dp_ps(lhs, rhs, 0x7F));
-#elif defined(ACL_SSE2_INTRINSICS)
-		__m128 x2_y2_z2_w2 = _mm_mul_ps(lhs, rhs);
-		__m128 y2_0_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 0, 1));
-		__m128 x2y2_0_0_0 = _mm_add_ss(x2_y2_z2_w2, y2_0_0_0);
-		__m128 z2_0_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, _MM_SHUFFLE(0, 0, 0, 2));
-		__m128 x2y2z2_0_0_0 = _mm_add_ss(x2y2_0_0_0, z2_0_0_0);
-		return _mm_cvtss_f32(x2y2z2_0_0_0);
-#elif defined(ACL_NEON_INTRINSICS)
-		float32x4_t x2_y2_z2_w2 = vmulq_f32(lhs, rhs);
-		float32x2_t x2_y2 = vget_low_f32(x2_y2_z2_w2);
-		float32x2_t z2_w2 = vget_high_f32(x2_y2_z2_w2);
-		float32x2_t x2y2_x2y2 = vpadd_f32(x2_y2, x2_y2);
-		float32x2_t z2_z2 = vdup_lane_f32(z2_w2, 0);
-		float32x2_t x2y2z2_x2y2z2 = vadd_f32(x2y2_x2y2, z2_z2);
-		return vget_lane_f32(x2y2z2_x2y2z2, 0);
-#else
-		return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs));
-#endif
-	}
-
-	inline float ACL_SIMD_CALL vector_length_squared(Vector4_32Arg0 input)
-	{
-		return vector_dot(input, input);
-	}
-
-	inline float ACL_SIMD_CALL vector_length_squared3(Vector4_32Arg0 input)
-	{
-		return vector_dot3(input, input);
-	}
-
-	inline float ACL_SIMD_CALL vector_length(Vector4_32Arg0 input)
-	{
-		return sqrt(vector_length_squared(input));
-	}
-
-	inline float ACL_SIMD_CALL vector_length3(Vector4_32Arg0 input)
-	{
-		return sqrt(vector_length_squared3(input));
-	}
-
-	inline float ACL_SIMD_CALL vector_length_reciprocal(Vector4_32Arg0 input)
-	{
-		return sqrt_reciprocal(vector_length_squared(input));
-	}
-
-	inline float ACL_SIMD_CALL vector_length_reciprocal3(Vector4_32Arg0 input)
-	{
-		return sqrt_reciprocal(vector_length_squared3(input));
-	}
-
-	inline float ACL_SIMD_CALL vector_distance3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-		return vector_length3(vector_sub(rhs, lhs));
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_normalize3(Vector4_32Arg0 input, float threshold = 1.0E-8F)
-	{
-		// Reciprocal is more accurate to normalize with
-		const float len_sq = vector_length_squared3(input);
-		if (len_sq >= threshold)
-			return vector_mul(input, sqrt_reciprocal(len_sq));
-		else
-			return input;
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_fraction(Vector4_32Arg0 input)
-	{
-		return vector_set(fraction(vector_get_x(input)), fraction(vector_get_y(input)), fraction(vector_get_z(input)), fraction(vector_get_w(input)));
-	}
-
-	// output = (input * scale) + offset
-	inline Vector4_32 ACL_SIMD_CALL vector_mul_add(Vector4_32Arg0 input, Vector4_32Arg1 scale, Vector4_32Arg2 offset)
-	{
-#if defined(ACL_NEON64_INTRINSICS)
-		return vfmaq_f32(offset, input, scale);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmlaq_f32(offset, input, scale);
-#else
-		return vector_add(vector_mul(input, scale), offset);
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mul_add(Vector4_32Arg0 input, float scale, Vector4_32Arg2 offset)
-	{
-#if defined(ACL_NEON64_INTRINSICS)
-		return vfmaq_n_f32(offset, input, scale);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmlaq_n_f32(offset, input, scale);
-#else
-		return vector_add(vector_mul(input, scale), offset);
-#endif
-	}
-
-	// output = offset - (input * scale)
-	inline Vector4_32 ACL_SIMD_CALL vector_neg_mul_sub(Vector4_32Arg0 input, Vector4_32Arg1 scale, Vector4_32Arg2 offset)
-	{
-#if defined(ACL_NEON64_INTRINSICS)
-		return vfmsq_f32(offset, input, scale);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmlsq_f32(offset, input, scale);
-#else
-		return vector_sub(offset, vector_mul(input, scale));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_neg_mul_sub(Vector4_32Arg0 input, float scale, Vector4_32Arg2 offset)
-	{
-#if defined(ACL_NEON64_INTRINSICS)
-		return vfmsq_n_f32(offset, input, scale);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vmlsq_n_f32(offset, input, scale);
-#else
-		return vector_sub(offset, vector_mul(input, scale));
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_lerp(Vector4_32Arg0 start, Vector4_32Arg1 end, float alpha)
-	{
-		return vector_mul_add(vector_sub(end, start), alpha, start);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	inline Vector4_32 ACL_SIMD_CALL vector_less_than(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cmplt_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vcltq_f32(lhs, rhs);
-#else
-		return Vector4_32{ math_impl::get_mask_value(lhs.x < rhs.x), math_impl::get_mask_value(lhs.y < rhs.y), math_impl::get_mask_value(lhs.z < rhs.z), math_impl::get_mask_value(lhs.w < rhs.w) };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_less_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cmple_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vcleq_f32(lhs, rhs);
-#else
-		return Vector4_32{ math_impl::get_mask_value(lhs.x <= rhs.x), math_impl::get_mask_value(lhs.y <= rhs.y), math_impl::get_mask_value(lhs.z <= rhs.z), math_impl::get_mask_value(lhs.w <= rhs.w) };
-#endif
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_greater_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cmpge_ps(lhs, rhs);
-#elif defined(ACL_NEON_INTRINSICS)
-		return vcgeq_f32(lhs, rhs);
-#else
-		return Vector4_32{ math_impl::get_mask_value(lhs.x >= rhs.x), math_impl::get_mask_value(lhs.y >= rhs.y), math_impl::get_mask_value(lhs.z >= rhs.z), math_impl::get_mask_value(lhs.w >= rhs.w) };
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_less_than(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmplt_ps(lhs, rhs)) == 0xF;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcltq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) == 0xFFFFFFFFU;
-#else
-		return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z && lhs.w < rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_less_than3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmplt_ps(lhs, rhs)) & 0x7) == 0x7;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcltq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) == 0x00FFFFFFU;
-#else
-		return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_less_than(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmplt_ps(lhs, rhs)) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcltq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) != 0;
-#else
-		return lhs.x < rhs.x || lhs.y < rhs.y || lhs.z < rhs.z || lhs.w < rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_less_than3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmplt_ps(lhs, rhs)) & 0x7) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcltq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) != 0;
-#else
-		return lhs.x < rhs.x || lhs.y < rhs.y || lhs.z < rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_less_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmple_ps(lhs, rhs)) == 0xF;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcleq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) == 0xFFFFFFFFU;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z && lhs.w <= rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_less_equal2(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmple_ps(lhs, rhs)) & 0x3) == 0x3;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x2_t mask = vcle_f32(vget_low_f32(lhs), vget_low_f32(rhs));
-		return vget_lane_u64(mask, 0) == 0xFFFFFFFFFFFFFFFFULL;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_less_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmple_ps(lhs, rhs)) & 0x7) == 0x7;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcleq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) == 0x00FFFFFFU;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_less_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmple_ps(lhs, rhs)) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcleq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) != 0;
-#else
-		return lhs.x <= rhs.x || lhs.y <= rhs.y || lhs.z <= rhs.z || lhs.w <= rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_less_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmple_ps(lhs, rhs)) & 0x7) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcleq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) != 0;
-#else
-		return lhs.x <= rhs.x || lhs.y <= rhs.y || lhs.z <= rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_greater_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmpge_ps(lhs, rhs)) == 0xF;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcgeq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) == 0xFFFFFFFFU;
-#else
-		return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z && lhs.w >= rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_greater_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmpge_ps(lhs, rhs)) & 0x7) == 0x7;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcgeq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) == 0x00FFFFFFU;
-#else
-		return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_greater_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_movemask_ps(_mm_cmpge_ps(lhs, rhs)) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcgeq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) != 0;
-#else
-		return lhs.x >= rhs.x || lhs.y >= rhs.y || lhs.z >= rhs.z || lhs.w >= rhs.w;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_greater_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return (_mm_movemask_ps(_mm_cmpge_ps(lhs, rhs)) & 0x7) != 0;
-#elif defined(ACL_NEON_INTRINSICS)
-		uint32x4_t mask = vcgeq_f32(lhs, rhs);
-		uint8x8x2_t mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15 = vzip_u8(vget_low_u8(mask), vget_high_u8(mask));
-		uint16x4x2_t mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15 = vzip_u16(mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[0], mask_0_8_1_9_2_10_3_11_4_12_5_13_6_14_7_15.val[1]);
-		return (vget_lane_u32(mask_0_8_4_12_1_9_5_13_2_10_6_14_3_11_7_15.val[0], 0) & 0x00FFFFFFU) != 0;
-#else
-		return lhs.x >= rhs.x || lhs.y >= rhs.y || lhs.z >= rhs.z;
-#endif
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_near_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_all_less_equal(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_near_equal2(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_all_less_equal2(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool ACL_SIMD_CALL vector_all_near_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_all_less_equal3(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_near_equal(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_any_less_equal(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool ACL_SIMD_CALL vector_any_near_equal3(Vector4_32Arg0 lhs, Vector4_32Arg1 rhs, float threshold = 0.00001F)
-	{
-		return vector_any_less_equal3(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool ACL_SIMD_CALL vector_is_finite(Vector4_32Arg0 input)
-	{
-		return is_finite(vector_get_x(input)) && is_finite(vector_get_y(input)) && is_finite(vector_get_z(input)) && is_finite(vector_get_w(input));
-	}
-
-	inline bool ACL_SIMD_CALL vector_is_finite3(Vector4_32Arg0 input)
-	{
-		return is_finite(vector_get_x(input)) && is_finite(vector_get_y(input)) && is_finite(vector_get_z(input));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Swizzling, permutations, and mixing
-
-	inline Vector4_32 ACL_SIMD_CALL vector_blend(Vector4_32Arg0 mask, Vector4_32Arg1 if_true, Vector4_32Arg2 if_false)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_or_ps(_mm_andnot_ps(mask, if_false), _mm_and_ps(if_true, mask));
-#elif defined(ACL_NEON_INTRINSICS)
-		return vbslq_f32(mask, if_true, if_false);
-#else
-		return Vector4_32{ math_impl::select(mask.x, if_true.x, if_false.x), math_impl::select(mask.y, if_true.y, if_false.y), math_impl::select(mask.z, if_true.z, if_false.z), math_impl::select(mask.w, if_true.w, if_false.w) };
-#endif
-	}
-
-	template<VectorMix comp0, VectorMix comp1, VectorMix comp2, VectorMix comp3>
-	inline Vector4_32 ACL_SIMD_CALL vector_mix(Vector4_32Arg0 input0, Vector4_32Arg1 input1)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		// All four components come from input 0
-		if (math_impl::is_vector_mix_arg_xyzw(comp0) && math_impl::is_vector_mix_arg_xyzw(comp1) && math_impl::is_vector_mix_arg_xyzw(comp2) && math_impl::is_vector_mix_arg_xyzw(comp3))
-			return _mm_shuffle_ps(input0, input0, _MM_SHUFFLE(int(comp3) % 4, int(comp2) % 4, int(comp1) % 4, int(comp0) % 4));
-
-		// All four components come from input 1
-		if (math_impl::is_vector_mix_arg_abcd(comp0) && math_impl::is_vector_mix_arg_abcd(comp1) && math_impl::is_vector_mix_arg_abcd(comp2) && math_impl::is_vector_mix_arg_abcd(comp3))
-			return _mm_shuffle_ps(input1, input1, _MM_SHUFFLE(int(comp3) % 4, int(comp2) % 4, int(comp1) % 4, int(comp0) % 4));
-
-		// First two components come from input 0, second two come from input 1
-		if (math_impl::is_vector_mix_arg_xyzw(comp0) && math_impl::is_vector_mix_arg_xyzw(comp1) && math_impl::is_vector_mix_arg_abcd(comp2) && math_impl::is_vector_mix_arg_abcd(comp3))
-			return _mm_shuffle_ps(input0, input1, _MM_SHUFFLE(int(comp3) % 4, int(comp2) % 4, int(comp1) % 4, int(comp0) % 4));
-
-		// First two components come from input 1, second two come from input 0
-		if (math_impl::is_vector_mix_arg_abcd(comp0) && math_impl::is_vector_mix_arg_abcd(comp1) && math_impl::is_vector_mix_arg_xyzw(comp2) && math_impl::is_vector_mix_arg_xyzw(comp3))
-			return _mm_shuffle_ps(input1, input0, _MM_SHUFFLE(int(comp3) % 4, int(comp2) % 4, int(comp1) % 4, int(comp0) % 4));
-
-		// Low words from both inputs are interleaved
-		if (static_condition<comp0 == VectorMix::X && comp1 == VectorMix::A && comp2 == VectorMix::Y && comp3 == VectorMix::B>::test())
-			return _mm_unpacklo_ps(input0, input1);
-
-		// Low words from both inputs are interleaved
-		if (static_condition<comp0 == VectorMix::A && comp1 == VectorMix::X && comp2 == VectorMix::B && comp3 == VectorMix::Y>::test())
-			return _mm_unpacklo_ps(input1, input0);
-
-		// High words from both inputs are interleaved
-		if (static_condition<comp0 == VectorMix::Z && comp1 == VectorMix::C && comp2 == VectorMix::W && comp3 == VectorMix::D>::test())
-			return _mm_unpackhi_ps(input0, input1);
-
-		// High words from both inputs are interleaved
-		if (static_condition<comp0 == VectorMix::C && comp1 == VectorMix::Z && comp2 == VectorMix::D && comp3 == VectorMix::W>::test())
-			return _mm_unpackhi_ps(input1, input0);
-#endif	// defined(ACL_SSE2_INTRINSICS)
-
-		// Slow code path, not yet optimized or not using intrinsics
-		const float x = math_impl::is_vector_mix_arg_xyzw(comp0) ? vector_get_component<comp0>(input0) : vector_get_component<comp0>(input1);
-		const float y = math_impl::is_vector_mix_arg_xyzw(comp1) ? vector_get_component<comp1>(input0) : vector_get_component<comp1>(input1);
-		const float z = math_impl::is_vector_mix_arg_xyzw(comp2) ? vector_get_component<comp2>(input0) : vector_get_component<comp2>(input1);
-		const float w = math_impl::is_vector_mix_arg_xyzw(comp3) ? vector_get_component<comp3>(input0) : vector_get_component<comp3>(input1);
-		return vector_set(x, y, z, w);
-	}
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xxxx(Vector4_32Arg0 input) { return vector_mix<VectorMix::X, VectorMix::X, VectorMix::X, VectorMix::X>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_yyyy(Vector4_32Arg0 input) { return vector_mix<VectorMix::Y, VectorMix::Y, VectorMix::Y, VectorMix::Y>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zzzz(Vector4_32Arg0 input) { return vector_mix<VectorMix::Z, VectorMix::Z, VectorMix::Z, VectorMix::Z>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wwww(Vector4_32Arg0 input) { return vector_mix<VectorMix::W, VectorMix::W, VectorMix::W, VectorMix::W>(input, input); }
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xxyy(Vector4_32Arg0 input) { return vector_mix<VectorMix::X, VectorMix::X, VectorMix::Y, VectorMix::Y>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xzyw(Vector4_32Arg0 input) { return vector_mix<VectorMix::X, VectorMix::Z, VectorMix::Y, VectorMix::W>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_yzxy(Vector4_32Arg0 input) { return vector_mix<VectorMix::Y, VectorMix::Z, VectorMix::X, VectorMix::Y>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_ywxz(Vector4_32Arg0 input) { return vector_mix<VectorMix::Y, VectorMix::W, VectorMix::X, VectorMix::Z>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zxyx(Vector4_32Arg0 input) { return vector_mix<VectorMix::Z, VectorMix::X, VectorMix::Y, VectorMix::X>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zwyz(Vector4_32Arg0 input) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::Y, VectorMix::Z>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zwzw(Vector4_32Arg0 input) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::Z, VectorMix::W>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wxwx(Vector4_32Arg0 input) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::W, VectorMix::X>(input, input); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wzwy(Vector4_32Arg0 input) { return vector_mix<VectorMix::W, VectorMix::Z, VectorMix::W, VectorMix::Y>(input, input); }
-
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xyab(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::X, VectorMix::Y, VectorMix::A, VectorMix::B>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xzac(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::X, VectorMix::Z, VectorMix::A, VectorMix::C>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xbxb(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::X, VectorMix::B, VectorMix::X, VectorMix::B>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_xbzd(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::X, VectorMix::B, VectorMix::Z, VectorMix::D>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_ywbd(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Y, VectorMix::W, VectorMix::B, VectorMix::D>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zyax(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Z, VectorMix::Y, VectorMix::A, VectorMix::X>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zycx(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Z, VectorMix::Y, VectorMix::C, VectorMix::X>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zwcd(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::C, VectorMix::D>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zbaz(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Z, VectorMix::B, VectorMix::A, VectorMix::Z>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_zdcz(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::Z, VectorMix::D, VectorMix::C, VectorMix::Z>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wxya(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::Y, VectorMix::A>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wxyc(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::Y, VectorMix::C>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wbyz(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::W, VectorMix::B, VectorMix::Y, VectorMix::Z>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_wdyz(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::W, VectorMix::D, VectorMix::Y, VectorMix::Z>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_bxwa(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::B, VectorMix::X, VectorMix::W, VectorMix::A>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_bywx(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::B, VectorMix::Y, VectorMix::W, VectorMix::X>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_dxwc(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::D, VectorMix::X, VectorMix::W, VectorMix::C>(input0, input1); }
-	inline Vector4_32 ACL_SIMD_CALL vector_mix_dywx(Vector4_32Arg0 input0, Vector4_32Arg1 input1) { return vector_mix<VectorMix::D, VectorMix::Y, VectorMix::W, VectorMix::X>(input0, input1); }
-
-	//////////////////////////////////////////////////////////////////////////
-	// Misc
-
-	inline Vector4_32 ACL_SIMD_CALL vector_sign(Vector4_32Arg0 input)
-	{
-		Vector4_32 mask = vector_greater_equal(input, vector_zero_32());
-		return vector_blend(mask, vector_set(1.0F), vector_set(-1.0F));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Returns per component the rounded input using a symmetric algorithm.
-	// symmetric_round(1.5) = 2.0
-	// symmetric_round(1.2) = 1.0
-	// symmetric_round(-1.5) = -2.0
-	// symmetric_round(-1.2) = -1.0
-	//////////////////////////////////////////////////////////////////////////
-	inline Vector4_32 ACL_SIMD_CALL vector_symmetric_round(Vector4_32Arg0 input)
-	{
-		const Vector4_32 half = vector_set(0.5F);
-		const Vector4_32 floored = vector_floor(vector_add(input, half));
-		const Vector4_32 ceiled = vector_ceil(vector_sub(input, half));
-		const Vector4_32 is_greater_equal = vector_greater_equal(input, vector_zero_32());
-		return vector_blend(is_greater_equal, floored, ceiled);
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/vector4_64.h b/includes/acl/math/vector4_64.h
deleted file mode 100644
--- a/includes/acl/math/vector4_64.h
+++ /dev/null
@@ -1,767 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2017 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "acl/core/compiler_utils.h"
-#include "acl/core/error.h"
-#include "acl/core/memory_utils.h"
-#include "acl/math/math.h"
-#include "acl/math/scalar_64.h"
-
-ACL_IMPL_FILE_PRAGMA_PUSH
-
-namespace acl
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	inline Vector4_64 vector_set(double x, double y, double z, double w)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_set_pd(y, x), _mm_set_pd(w, z) };
-#else
-		return Vector4_64{ x, y, z, w };
-#endif
-	}
-
-	inline Vector4_64 vector_set(double x, double y, double z)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_set_pd(y, x), _mm_set_pd(0.0, z) };
-#else
-		return Vector4_64{ x, y, z, 0.0 };
-#endif
-	}
-
-	inline Vector4_64 vector_set(double xyzw)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xyzw_pd = _mm_set1_pd(xyzw);
-		return Vector4_64{ xyzw_pd, xyzw_pd };
-#else
-		return Vector4_64{ xyzw, xyzw, xyzw, xyzw };
-#endif
-	}
-
-	inline Vector4_64 vector_unaligned_load(const double* input)
-	{
-		ACL_ASSERT(is_aligned_to(input, 4), "Invalid alignment");
-		return vector_set(input[0], input[1], input[2], input[3]);
-	}
-
-	inline Vector4_64 vector_unaligned_load3(const double* input)
-	{
-		ACL_ASSERT(is_aligned_to(input, 4), "Invalid alignment");
-		return vector_set(input[0], input[1], input[2], 0.0);
-	}
-
-	inline Vector4_64 vector_unaligned_load_64(const uint8_t* input)
-	{
-		Vector4_64 result;
-		std::memcpy(&result, input, sizeof(Vector4_64));
-		return result;
-	}
-
-	inline Vector4_64 vector_unaligned_load3_64(const uint8_t* input)
-	{
-		double input_f[3];
-		std::memcpy(&input_f[0], input, sizeof(double) * 3);
-		return vector_set(input_f[0], input_f[1], input_f[2], 0.0);
-	}
-
-	inline Vector4_64 vector_zero_64()
-	{
-		return vector_set(0.0, 0.0, 0.0, 0.0);
-	}
-
-	inline Vector4_64 quat_to_vector(const Quat_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ input.xy, input.zw };
-#else
-		return Vector4_64{ input.x, input.y, input.z, input.w };
-#endif
-	}
-
-	inline Vector4_64 vector_cast(const Vector4_32& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_cvtps_pd(input), _mm_cvtps_pd(_mm_shuffle_ps(input, input, _MM_SHUFFLE(3, 2, 3, 2))) };
-#elif defined(ACL_NEON_INTRINSICS)
-		return Vector4_64{ double(vgetq_lane_f32(input, 0)), double(vgetq_lane_f32(input, 1)), double(vgetq_lane_f32(input, 2)), double(vgetq_lane_f32(input, 3)) };
-#else
-		return Vector4_64{ double(input.x), double(input.y), double(input.z), double(input.w) };
-#endif
-	}
-
-	inline double vector_get_x(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(input.xy);
-#else
-		return input.x;
-#endif
-	}
-
-	inline double vector_get_y(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(_mm_shuffle_pd(input.xy, input.xy, 1));
-#else
-		return input.y;
-#endif
-	}
-
-	inline double vector_get_z(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(input.zw);
-#else
-		return input.z;
-#endif
-	}
-
-	inline double vector_get_w(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return _mm_cvtsd_f64(_mm_shuffle_pd(input.zw, input.zw, 1));
-#else
-		return input.w;
-#endif
-	}
-
-	template<VectorMix component_index>
-	inline double vector_get_component(const Vector4_64& input)
-	{
-		switch (component_index)
-		{
-		case VectorMix::A:
-		case VectorMix::X: return vector_get_x(input);
-		case VectorMix::B:
-		case VectorMix::Y: return vector_get_y(input);
-		case VectorMix::C:
-		case VectorMix::Z: return vector_get_z(input);
-		case VectorMix::D:
-		case VectorMix::W: return vector_get_w(input);
-		default:
-			ACL_ASSERT(false, "Invalid component index");
-			return 0.0;
-		}
-	}
-
-	inline double vector_get_component(const Vector4_64& input, VectorMix component_index)
-	{
-		switch (component_index)
-		{
-		case VectorMix::A:
-		case VectorMix::X: return vector_get_x(input);
-		case VectorMix::B:
-		case VectorMix::Y: return vector_get_y(input);
-		case VectorMix::C:
-		case VectorMix::Z: return vector_get_z(input);
-		case VectorMix::D:
-		case VectorMix::W: return vector_get_w(input);
-		default:
-			ACL_ASSERT(false, "Invalid component index");
-			return 0.0;
-		}
-	}
-
-	inline const double* vector_as_double_ptr(const Vector4_64& input)
-	{
-		return reinterpret_cast<const double*>(&input);
-	}
-
-	inline void vector_unaligned_write(const Vector4_64& input, double* output)
-	{
-		ACL_ASSERT(is_aligned_to(output, 4), "Invalid alignment");
-		output[0] = vector_get_x(input);
-		output[1] = vector_get_y(input);
-		output[2] = vector_get_z(input);
-		output[3] = vector_get_w(input);
-	}
-
-	inline void vector_unaligned_write3(const Vector4_64& input, double* output)
-	{
-		ACL_ASSERT(is_aligned_to(output, 4), "Invalid alignment");
-		output[0] = vector_get_x(input);
-		output[1] = vector_get_y(input);
-		output[2] = vector_get_z(input);
-	}
-
-	inline void vector_unaligned_write(const Vector4_64& input, uint8_t* output)
-	{
-		std::memcpy(output, &input, sizeof(Vector4_64));
-	}
-
-	inline void vector_unaligned_write3(const Vector4_64& input, uint8_t* output)
-	{
-		std::memcpy(output, &input, sizeof(double) * 3);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	inline Vector4_64 vector_add(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_add_pd(lhs.xy, rhs.xy), _mm_add_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
-#endif
-	}
-
-	inline Vector4_64 vector_sub(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_sub_pd(lhs.xy, rhs.xy), _mm_sub_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
-#endif
-	}
-
-	inline Vector4_64 vector_mul(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_mul_pd(lhs.xy, rhs.xy), _mm_mul_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
-#endif
-	}
-
-	inline Vector4_64 vector_mul(const Vector4_64& lhs, double rhs)
-	{
-		return vector_mul(lhs, vector_set(rhs));
-	}
-
-	inline Vector4_64 vector_div(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_div_pd(lhs.xy, rhs.xy), _mm_div_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w);
-#endif
-	}
-
-	inline Vector4_64 vector_max(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_max_pd(lhs.xy, rhs.xy), _mm_max_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z), max(lhs.w, rhs.w));
-#endif
-	}
-
-	inline Vector4_64 vector_min(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		return Vector4_64{ _mm_min_pd(lhs.xy, rhs.xy), _mm_min_pd(lhs.zw, rhs.zw) };
-#else
-		return vector_set(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z), min(lhs.w, rhs.w));
-#endif
-	}
-
-	inline Vector4_64 vector_clamp(const Vector4_64& input, const Vector4_64& min, const Vector4_64& max)
-	{
-		return vector_min(max, vector_max(min, input));
-	}
-
-	inline Vector4_64 vector_abs(const Vector4_64& input)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		Vector4_64 zero{ _mm_setzero_pd(), _mm_setzero_pd() };
-		return vector_max(vector_sub(zero, input), input);
-#else
-		return vector_set(abs(input.x), abs(input.y), abs(input.z), abs(input.w));
-#endif
-	}
-
-	inline Vector4_64 vector_neg(const Vector4_64& input)
-	{
-		return vector_mul(input, -1.0);
-	}
-
-	inline Vector4_64 vector_reciprocal(const Vector4_64& input)
-	{
-		return vector_div(vector_set(1.0), input);
-	}
-
-	inline Vector4_64 vector_ceil(const Vector4_64& input)
-	{
-		return vector_set(ceil(vector_get_x(input)), ceil(vector_get_y(input)), ceil(vector_get_z(input)), ceil(vector_get_w(input)));
-	}
-
-	inline Vector4_64 vector_floor(const Vector4_64& input)
-	{
-		return vector_set(floor(vector_get_x(input)), floor(vector_get_y(input)), floor(vector_get_z(input)), floor(vector_get_w(input)));
-	}
-
-	inline Vector4_64 vector_cross3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-		return vector_set(vector_get_y(lhs) * vector_get_z(rhs) - vector_get_z(lhs) * vector_get_y(rhs),
-						  vector_get_z(lhs) * vector_get_x(rhs) - vector_get_x(lhs) * vector_get_z(rhs),
-						  vector_get_x(lhs) * vector_get_y(rhs) - vector_get_y(lhs) * vector_get_x(rhs));
-	}
-
-	inline double vector_dot(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-		return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs)) + (vector_get_w(lhs) * vector_get_w(rhs));
-	}
-
-	inline Vector4_64 vector_vdot(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-		return vector_set(vector_dot(lhs, rhs));
-	}
-
-	inline double vector_dot3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-		return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs));
-	}
-
-	inline double vector_length_squared(const Vector4_64& input)
-	{
-		return vector_dot(input, input);
-	}
-
-	inline double vector_length_squared3(const Vector4_64& input)
-	{
-		return vector_dot3(input, input);
-	}
-
-	inline double vector_length(const Vector4_64& input)
-	{
-		return sqrt(vector_length_squared(input));
-	}
-
-	inline double vector_length3(const Vector4_64& input)
-	{
-		return sqrt(vector_length_squared3(input));
-	}
-
-	inline double vector_length_reciprocal(const Vector4_64& input)
-	{
-		return 1.0 / vector_length(input);
-	}
-
-	inline double vector_length_reciprocal3(const Vector4_64& input)
-	{
-		return 1.0 / vector_length3(input);
-	}
-
-	inline double vector_distance3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-		return vector_length3(vector_sub(rhs, lhs));
-	}
-
-	inline Vector4_64 vector_normalize3(const Vector4_64& input, double threshold = 1.0e-8)
-	{
-		// Reciprocal is more accurate to normalize with
-		const double len_sq = vector_length_squared3(input);
-		if (len_sq >= threshold)
-			return vector_mul(input, sqrt_reciprocal(len_sq));
-		else
-			return input;
-	}
-
-	inline Vector4_64 vector_fraction(const Vector4_64& input)
-	{
-		return vector_set(fraction(vector_get_x(input)), fraction(vector_get_y(input)), fraction(vector_get_z(input)), fraction(vector_get_w(input)));
-	}
-
-	// output = (input * scale) + offset
-	inline Vector4_64 vector_mul_add(const Vector4_64& input, const Vector4_64& scale, const Vector4_64& offset)
-	{
-		return vector_add(vector_mul(input, scale), offset);
-	}
-
-	inline Vector4_64 vector_mul_add(const Vector4_64& input, double scale, const Vector4_64& offset)
-	{
-		return vector_add(vector_mul(input, scale), offset);
-	}
-
-	// output = offset - (input * scale)
-	inline Vector4_64 vector_neg_mul_sub(const Vector4_64& input, const Vector4_64& scale, const Vector4_64& offset)
-	{
-		return vector_sub(offset, vector_mul(input, scale));
-	}
-
-	inline Vector4_64 vector_neg_mul_sub(const Vector4_64& input, double scale, const Vector4_64& offset)
-	{
-		return vector_sub(offset, vector_mul(input, scale));
-	}
-
-	inline Vector4_64 vector_lerp(const Vector4_64& start, const Vector4_64& end, double alpha)
-	{
-		return vector_mul_add(vector_sub(end, start), alpha, start);
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	inline Vector4_64 vector_less_than(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmplt_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmplt_pd(lhs.zw, rhs.zw);
-		return Vector4_64{xy_lt_pd, zw_lt_pd};
-#else
-		return Vector4_64{math_impl::get_mask_value(lhs.x < rhs.x), math_impl::get_mask_value(lhs.y < rhs.y), math_impl::get_mask_value(lhs.z < rhs.z), math_impl::get_mask_value(lhs.w < rhs.w)};
-#endif
-	}
-
-	inline Vector4_64 vector_less_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmple_pd(lhs.zw, rhs.zw);
-		return Vector4_64{ xy_lt_pd, zw_lt_pd };
-#else
-		return Vector4_64{ math_impl::get_mask_value(lhs.x <= rhs.x), math_impl::get_mask_value(lhs.y <= rhs.y), math_impl::get_mask_value(lhs.z <= rhs.z), math_impl::get_mask_value(lhs.w <= rhs.w) };
-#endif
-	}
-
-	inline Vector4_64 vector_greater_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_ge_pd = _mm_cmpge_pd(lhs.xy, rhs.xy);
-		__m128d zw_ge_pd = _mm_cmpge_pd(lhs.zw, rhs.zw);
-		return Vector4_64{ xy_ge_pd, zw_ge_pd };
-#else
-		return Vector4_64{ math_impl::get_mask_value(lhs.x >= rhs.x), math_impl::get_mask_value(lhs.y >= rhs.y), math_impl::get_mask_value(lhs.z >= rhs.z), math_impl::get_mask_value(lhs.w >= rhs.w) };
-#endif
-	}
-
-	inline bool vector_all_less_than(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmplt_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmplt_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_lt_pd) & _mm_movemask_pd(zw_lt_pd)) == 3;
-#else
-		return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z && lhs.w < rhs.w;
-#endif
-	}
-
-	inline bool vector_all_less_than3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmplt_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmplt_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_lt_pd) == 3 && (_mm_movemask_pd(zw_lt_pd) & 1) == 1;
-#else
-		return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z;
-#endif
-	}
-
-	inline bool vector_any_less_than(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmplt_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmplt_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_lt_pd) | _mm_movemask_pd(zw_lt_pd)) != 0;
-#else
-		return lhs.x < rhs.x || lhs.y < rhs.y || lhs.z < rhs.z || lhs.w < rhs.w;
-#endif
-	}
-
-	inline bool vector_any_less_than3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_lt_pd = _mm_cmplt_pd(lhs.xy, rhs.xy);
-		__m128d zw_lt_pd = _mm_cmplt_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_lt_pd) != 0 || (_mm_movemask_pd(zw_lt_pd) & 0x1) != 0;
-#else
-		return lhs.x < rhs.x || lhs.y < rhs.y || lhs.z < rhs.z;
-#endif
-	}
-
-	inline bool vector_all_less_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_le_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		__m128d zw_le_pd = _mm_cmple_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_le_pd) & _mm_movemask_pd(zw_le_pd)) == 3;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z && lhs.w <= rhs.w;
-#endif
-	}
-
-	inline bool vector_all_less_equal2(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_le_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		return _mm_movemask_pd(xy_le_pd) == 3;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y;
-#endif
-	}
-
-	inline bool vector_all_less_equal3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_le_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		__m128d zw_le_pd = _mm_cmple_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_le_pd) == 3 && (_mm_movemask_pd(zw_le_pd) & 1) != 0;
-#else
-		return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z;
-#endif
-	}
-
-	inline bool vector_any_less_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_le_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		__m128d zw_le_pd = _mm_cmple_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_le_pd) | _mm_movemask_pd(zw_le_pd)) != 0;
-#else
-		return lhs.x <= rhs.x || lhs.y <= rhs.y || lhs.z <= rhs.z || lhs.w <= rhs.w;
-#endif
-	}
-
-	inline bool vector_any_less_equal3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_le_pd = _mm_cmple_pd(lhs.xy, rhs.xy);
-		__m128d zw_le_pd = _mm_cmple_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_le_pd) != 0 || (_mm_movemask_pd(zw_le_pd) & 1) != 0;
-#else
-		return lhs.x <= rhs.x || lhs.y <= rhs.y || lhs.z <= rhs.z;
-#endif
-	}
-
-	inline bool vector_all_greater_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_ge_pd = _mm_cmpge_pd(lhs.xy, rhs.xy);
-		__m128d zw_ge_pd = _mm_cmpge_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_ge_pd) & _mm_movemask_pd(zw_ge_pd)) == 3;
-#else
-		return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z && lhs.w >= rhs.w;
-#endif
-	}
-
-	inline bool vector_all_greater_equal3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_ge_pd = _mm_cmpge_pd(lhs.xy, rhs.xy);
-		__m128d zw_ge_pd = _mm_cmpge_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_ge_pd) == 3 && (_mm_movemask_pd(zw_ge_pd) & 1) != 0;
-#else
-		return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z;
-#endif
-	}
-
-	inline bool vector_any_greater_equal(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_ge_pd = _mm_cmpge_pd(lhs.xy, rhs.xy);
-		__m128d zw_ge_pd = _mm_cmpge_pd(lhs.zw, rhs.zw);
-		return (_mm_movemask_pd(xy_ge_pd) | _mm_movemask_pd(zw_ge_pd)) != 0;
-#else
-		return lhs.x >= rhs.x || lhs.y >= rhs.y || lhs.z >= rhs.z || lhs.w >= rhs.w;
-#endif
-	}
-
-	inline bool vector_any_greater_equal3(const Vector4_64& lhs, const Vector4_64& rhs)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy_ge_pd = _mm_cmpge_pd(lhs.xy, rhs.xy);
-		__m128d zw_ge_pd = _mm_cmpge_pd(lhs.zw, rhs.zw);
-		return _mm_movemask_pd(xy_ge_pd) != 0 || (_mm_movemask_pd(zw_ge_pd) & 1) != 0;
-#else
-		return lhs.x >= rhs.x || lhs.y >= rhs.y || lhs.z >= rhs.z;
-#endif
-	}
-
-	inline bool vector_all_near_equal(const Vector4_64& lhs, const Vector4_64& rhs, double threshold = 0.00001)
-	{
-		return vector_all_less_equal(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool vector_all_near_equal2(const Vector4_64& lhs, const Vector4_64& rhs, double threshold = 0.00001)
-	{
-		return vector_all_less_equal2(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool vector_all_near_equal3(const Vector4_64& lhs, const Vector4_64& rhs, double threshold = 0.00001)
-	{
-		return vector_all_less_equal3(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool vector_any_near_equal(const Vector4_64& lhs, const Vector4_64& rhs, double threshold = 0.00001)
-	{
-		return vector_any_less_equal(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool vector_any_near_equal3(const Vector4_64& lhs, const Vector4_64& rhs, double threshold = 0.00001)
-	{
-		return vector_any_less_equal3(vector_abs(vector_sub(lhs, rhs)), vector_set(threshold));
-	}
-
-	inline bool vector_is_finite(const Vector4_64& input)
-	{
-		return is_finite(vector_get_x(input)) && is_finite(vector_get_y(input)) && is_finite(vector_get_z(input)) && is_finite(vector_get_w(input));
-	}
-
-	inline bool vector_is_finite3(const Vector4_64& input)
-	{
-		return is_finite(vector_get_x(input)) && is_finite(vector_get_y(input)) && is_finite(vector_get_z(input));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Swizzling, permutations, and mixing
-
-	inline Vector4_64 vector_blend(const Vector4_64& mask, const Vector4_64& if_true, const Vector4_64& if_false)
-	{
-#if defined(ACL_SSE2_INTRINSICS)
-		__m128d xy = _mm_or_pd(_mm_andnot_pd(mask.xy, if_false.xy), _mm_and_pd(if_true.xy, mask.xy));
-		__m128d zw = _mm_or_pd(_mm_andnot_pd(mask.zw, if_false.zw), _mm_and_pd(if_true.zw, mask.zw));
-		return Vector4_64{ xy, zw };
-#else
-		return Vector4_64{ math_impl::select(mask.x, if_true.x, if_false.x), math_impl::select(mask.y, if_true.y, if_false.y), math_impl::select(mask.z, if_true.z, if_false.z), math_impl::select(mask.w, if_true.w, if_false.w) };
-#endif
-	}
-
-	template<VectorMix comp0, VectorMix comp1, VectorMix comp2, VectorMix comp3>
-	inline Vector4_64 vector_mix(const Vector4_64& input0, const Vector4_64& input1)
-	{
-		if (math_impl::is_vector_mix_arg_xyzw(comp0) && math_impl::is_vector_mix_arg_xyzw(comp1) && math_impl::is_vector_mix_arg_xyzw(comp2) && math_impl::is_vector_mix_arg_xyzw(comp3))
-		{
-			// All four components come from input 0
-			return vector_set(vector_get_component(input0, comp0), vector_get_component(input0, comp1), vector_get_component(input0, comp2), vector_get_component(input0, comp3));
-		}
-
-		if (math_impl::is_vector_mix_arg_abcd(comp0) && math_impl::is_vector_mix_arg_abcd(comp1) && math_impl::is_vector_mix_arg_abcd(comp2) && math_impl::is_vector_mix_arg_abcd(comp3))
-		{
-			// All four components come from input 1
-			return vector_set(vector_get_component(input1, comp0), vector_get_component(input1, comp1), vector_get_component(input1, comp2), vector_get_component(input1, comp3));
-		}
-
-		if (static_condition<(comp0 == VectorMix::X || comp0 == VectorMix::Y) && (comp1 == VectorMix::X || comp1 == VectorMix::Y) && (comp2 == VectorMix::A || comp2 == VectorMix::B) && (comp3 == VectorMix::A && comp3 == VectorMix::B)>::test())
-		{
-			// First two components come from input 0, second two come from input 1
-			return vector_set(vector_get_component(input0, comp0), vector_get_component(input0, comp1), vector_get_component(input1, comp2), vector_get_component(input1, comp3));
-		}
-
-		if (static_condition<(comp0 == VectorMix::A || comp0 == VectorMix::B) && (comp1 == VectorMix::A && comp1 == VectorMix::B) && (comp2 == VectorMix::X || comp2 == VectorMix::Y) && (comp3 == VectorMix::X || comp3 == VectorMix::Y)>::test())
-		{
-			// First two components come from input 1, second two come from input 0
-			return vector_set(vector_get_component(input1, comp0), vector_get_component(input1, comp1), vector_get_component(input0, comp2), vector_get_component(input0, comp3));
-		}
-
-		if (static_condition<comp0 == VectorMix::X && comp1 == VectorMix::A && comp2 == VectorMix::Y && comp3 == VectorMix::B>::test())
-		{
-			// Low words from both inputs are interleaved
-			return vector_set(vector_get_component(input0, comp0), vector_get_component(input1, comp1), vector_get_component(input0, comp2), vector_get_component(input1, comp3));
-		}
-
-		if (static_condition<comp0 == VectorMix::A && comp1 == VectorMix::X && comp2 == VectorMix::B && comp3 == VectorMix::Y>::test())
-		{
-			// Low words from both inputs are interleaved
-			return vector_set(vector_get_component(input1, comp0), vector_get_component(input0, comp1), vector_get_component(input1, comp2), vector_get_component(input0, comp3));
-		}
-
-		if (static_condition<comp0 == VectorMix::Z && comp1 == VectorMix::C && comp2 == VectorMix::W && comp3 == VectorMix::D>::test())
-		{
-			// High words from both inputs are interleaved
-			return vector_set(vector_get_component(input0, comp0), vector_get_component(input1, comp1), vector_get_component(input0, comp2), vector_get_component(input1, comp3));
-		}
-
-		if (static_condition<comp0 == VectorMix::C && comp1 == VectorMix::Z && comp2 == VectorMix::D && comp3 == VectorMix::W>::test())
-		{
-			// High words from both inputs are interleaved
-			return vector_set(vector_get_component(input1, comp0), vector_get_component(input0, comp1), vector_get_component(input1, comp2), vector_get_component(input0, comp3));
-		}
-
-		// Slow code path, not yet optimized
-		//ACL_ASSERT(false, "vector_mix permutation not handled");
-		const double x = math_impl::is_vector_mix_arg_xyzw(comp0) ? vector_get_component<comp0>(input0) : vector_get_component<comp0>(input1);
-		const double y = math_impl::is_vector_mix_arg_xyzw(comp1) ? vector_get_component<comp1>(input0) : vector_get_component<comp1>(input1);
-		const double z = math_impl::is_vector_mix_arg_xyzw(comp2) ? vector_get_component<comp2>(input0) : vector_get_component<comp2>(input1);
-		const double w = math_impl::is_vector_mix_arg_xyzw(comp3) ? vector_get_component<comp3>(input0) : vector_get_component<comp3>(input1);
-		return vector_set(x, y, z, w);
-	}
-
-	inline Vector4_64 vector_mix_xxxx(const Vector4_64& input) { return vector_mix<VectorMix::X, VectorMix::X, VectorMix::X, VectorMix::X>(input, input); }
-	inline Vector4_64 vector_mix_yyyy(const Vector4_64& input) { return vector_mix<VectorMix::Y, VectorMix::Y, VectorMix::Y, VectorMix::Y>(input, input); }
-	inline Vector4_64 vector_mix_zzzz(const Vector4_64& input) { return vector_mix<VectorMix::Z, VectorMix::Z, VectorMix::Z, VectorMix::Z>(input, input); }
-	inline Vector4_64 vector_mix_wwww(const Vector4_64& input) { return vector_mix<VectorMix::W, VectorMix::W, VectorMix::W, VectorMix::W>(input, input); }
-
-	inline Vector4_64 vector_mix_xxyy(const Vector4_64& input) { return vector_mix<VectorMix::X, VectorMix::X, VectorMix::Y, VectorMix::Y>(input, input); }
-	inline Vector4_64 vector_mix_xzyw(const Vector4_64& input) { return vector_mix<VectorMix::X, VectorMix::Z, VectorMix::Y, VectorMix::W>(input, input); }
-	inline Vector4_64 vector_mix_yzxy(const Vector4_64& input) { return vector_mix<VectorMix::Y, VectorMix::Z, VectorMix::X, VectorMix::Y>(input, input); }
-	inline Vector4_64 vector_mix_ywxz(const Vector4_64& input) { return vector_mix<VectorMix::Y, VectorMix::W, VectorMix::X, VectorMix::Z>(input, input); }
-	inline Vector4_64 vector_mix_zxyx(const Vector4_64& input) { return vector_mix<VectorMix::Z, VectorMix::X, VectorMix::Y, VectorMix::X>(input, input); }
-	inline Vector4_64 vector_mix_zwyz(const Vector4_64& input) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::Y, VectorMix::Z>(input, input); }
-	inline Vector4_64 vector_mix_zwzw(const Vector4_64& input) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::Z, VectorMix::W>(input, input); }
-	inline Vector4_64 vector_mix_wxwx(const Vector4_64& input) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::W, VectorMix::X>(input, input); }
-	inline Vector4_64 vector_mix_wzwy(const Vector4_64& input) { return vector_mix<VectorMix::W, VectorMix::Z, VectorMix::W, VectorMix::Y>(input, input); }
-
-	inline Vector4_64 vector_mix_xyab(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::X, VectorMix::Y, VectorMix::A, VectorMix::B>(input0, input1); }
-	inline Vector4_64 vector_mix_xzac(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::X, VectorMix::Z, VectorMix::A, VectorMix::C>(input0, input1); }
-	inline Vector4_64 vector_mix_xbxb(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::X, VectorMix::B, VectorMix::X, VectorMix::B>(input0, input1); }
-	inline Vector4_64 vector_mix_xbzd(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::X, VectorMix::B, VectorMix::Z, VectorMix::D>(input0, input1); }
-	inline Vector4_64 vector_mix_ywbd(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Y, VectorMix::W, VectorMix::B, VectorMix::D>(input0, input1); }
-	inline Vector4_64 vector_mix_zyax(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Z, VectorMix::Y, VectorMix::A, VectorMix::X>(input0, input1); }
-	inline Vector4_64 vector_mix_zycx(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Z, VectorMix::Y, VectorMix::C, VectorMix::X>(input0, input1); }
-	inline Vector4_64 vector_mix_zwcd(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Z, VectorMix::W, VectorMix::C, VectorMix::D>(input0, input1); }
-	inline Vector4_64 vector_mix_zbaz(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Z, VectorMix::B, VectorMix::A, VectorMix::Z>(input0, input1); }
-	inline Vector4_64 vector_mix_zdcz(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::Z, VectorMix::D, VectorMix::C, VectorMix::Z>(input0, input1); }
-	inline Vector4_64 vector_mix_wxya(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::Y, VectorMix::A>(input0, input1); }
-	inline Vector4_64 vector_mix_wxyc(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::W, VectorMix::X, VectorMix::Y, VectorMix::C>(input0, input1); }
-	inline Vector4_64 vector_mix_wbyz(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::W, VectorMix::B, VectorMix::Y, VectorMix::Z>(input0, input1); }
-	inline Vector4_64 vector_mix_wdyz(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::W, VectorMix::D, VectorMix::Y, VectorMix::Z>(input0, input1); }
-	inline Vector4_64 vector_mix_bxwa(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::B, VectorMix::X, VectorMix::W, VectorMix::A>(input0, input1); }
-	inline Vector4_64 vector_mix_bywx(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::B, VectorMix::Y, VectorMix::W, VectorMix::X>(input0, input1); }
-	inline Vector4_64 vector_mix_dxwc(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::D, VectorMix::X, VectorMix::W, VectorMix::C>(input0, input1); }
-	inline Vector4_64 vector_mix_dywx(const Vector4_64& input0, const Vector4_64& input1) { return vector_mix<VectorMix::D, VectorMix::Y, VectorMix::W, VectorMix::X>(input0, input1); }
-
-	//////////////////////////////////////////////////////////////////////////
-	// Misc
-
-	inline Vector4_64 vector_sign(const Vector4_64& input)
-	{
-		Vector4_64 mask = vector_greater_equal(input, vector_zero_64());
-		return vector_blend(mask, vector_set(1.0), vector_set(-1.0));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Returns per component the rounded input using a symmetric algorithm.
-	// symmetric_round(1.5) = 2.0
-	// symmetric_round(1.2) = 1.0
-	// symmetric_round(-1.5) = -2.0
-	// symmetric_round(-1.2) = -1.0
-	//////////////////////////////////////////////////////////////////////////
-	inline Vector4_64 vector_symmetric_round(const Vector4_64& input)
-	{
-		const Vector4_64 half = vector_set(0.5);
-		const Vector4_64 floored = vector_floor(vector_add(input, half));
-		const Vector4_64 ceiled = vector_ceil(vector_sub(input, half));
-		const Vector4_64 is_greater_equal = vector_greater_equal(input, vector_zero_64());
-		return vector_blend(is_greater_equal, floored, ceiled);
-	}
-}
-
-ACL_IMPL_FILE_PRAGMA_POP
diff --git a/includes/acl/math/vector4_packing.h b/includes/acl/math/vector4_packing.h
--- a/includes/acl/math/vector4_packing.h
+++ b/includes/acl/math/vector4_packing.h
@@ -28,9 +28,10 @@
 #include "acl/core/error.h"
 #include "acl/core/memory_utils.h"
 #include "acl/core/track_types.h"
-#include "acl/math/vector4_32.h"
 #include "acl/math/scalar_packing.h"
 
+#include <rtm/vector4f.h>
+
 #include <cstdint>
 
 ACL_IMPL_FILE_PRAGMA_PUSH
@@ -40,20 +41,20 @@ namespace acl
 	//////////////////////////////////////////////////////////////////////////
 	// vector4 packing and decay
 
-	inline void ACL_SIMD_CALL pack_vector4_128(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector4_128(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		vector_unaligned_write(vector, out_vector_data);
+		rtm::vector_store(vector, out_vector_data);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector4_128(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector4_128(const uint8_t* vector_data)
 	{
-		return vector_unaligned_load_32(vector_data);
+		return rtm::vector_load(vector_data);
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector4_128_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector4_128_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -85,7 +86,7 @@ namespace acl
 		const uint32_t w32 = uint32_t(vector_u64);
 
 		return _mm_castsi128_ps(_mm_set_epi32(w32, z32, y32, x32));
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -154,16 +155,16 @@ namespace acl
 		const float z = aligned_load<float>(&z64);
 		const float w = aligned_load<float>(&w64);
 
-		return vector_set(x, y, z, w);
+		return rtm::vector_set(x, y, z, w);
 #endif
 	}
 
-	inline void ACL_SIMD_CALL pack_vector4_64(Vector4_32Arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector4_64(rtm::vector4f_arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), 16) : pack_scalar_signed(vector_get_x(vector), 16);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), 16) : pack_scalar_signed(vector_get_y(vector), 16);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), 16) : pack_scalar_signed(vector_get_z(vector), 16);
-		uint32_t vector_w = is_unsigned ? pack_scalar_unsigned(vector_get_w(vector), 16) : pack_scalar_signed(vector_get_w(vector), 16);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), 16) : pack_scalar_signed(rtm::vector_get_x(vector), 16);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), 16) : pack_scalar_signed(rtm::vector_get_y(vector), 16);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), 16) : pack_scalar_signed(rtm::vector_get_z(vector), 16);
+		uint32_t vector_w = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_w(vector), 16) : pack_scalar_signed(rtm::vector_get_w(vector), 16);
 
 		uint16_t* data = safe_ptr_cast<uint16_t>(out_vector_data);
 		data[0] = safe_static_cast<uint16_t>(vector_x);
@@ -172,7 +173,7 @@ namespace acl
 		data[3] = safe_static_cast<uint16_t>(vector_w);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector4_64(const uint8_t* vector_data, bool is_unsigned)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector4_64(const uint8_t* vector_data, bool is_unsigned)
 	{
 		const uint16_t* data_ptr_u16 = safe_ptr_cast<const uint16_t>(vector_data);
 		uint16_t x16 = data_ptr_u16[0];
@@ -183,15 +184,15 @@ namespace acl
 		float y = is_unsigned ? unpack_scalar_unsigned(y16, 16) : unpack_scalar_signed(y16, 16);
 		float z = is_unsigned ? unpack_scalar_unsigned(z16, 16) : unpack_scalar_signed(z16, 16);
 		float w = is_unsigned ? unpack_scalar_unsigned(w16, 16) : unpack_scalar_signed(w16, 16);
-		return vector_set(x, y, z, w);
+		return rtm::vector_set(x, y, z, w);
 	}
 
-	inline void ACL_SIMD_CALL pack_vector4_32(Vector4_32Arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector4_32(rtm::vector4f_arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), 8) : pack_scalar_signed(vector_get_x(vector), 8);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), 8) : pack_scalar_signed(vector_get_y(vector), 8);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), 8) : pack_scalar_signed(vector_get_z(vector), 8);
-		uint32_t vector_w = is_unsigned ? pack_scalar_unsigned(vector_get_w(vector), 8) : pack_scalar_signed(vector_get_w(vector), 8);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), 8) : pack_scalar_signed(rtm::vector_get_x(vector), 8);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), 8) : pack_scalar_signed(rtm::vector_get_y(vector), 8);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), 8) : pack_scalar_signed(rtm::vector_get_z(vector), 8);
+		uint32_t vector_w = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_w(vector), 8) : pack_scalar_signed(rtm::vector_get_w(vector), 8);
 
 		out_vector_data[0] = safe_static_cast<uint8_t>(vector_x);
 		out_vector_data[1] = safe_static_cast<uint8_t>(vector_y);
@@ -199,7 +200,7 @@ namespace acl
 		out_vector_data[3] = safe_static_cast<uint8_t>(vector_w);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector4_32(const uint8_t* vector_data, bool is_unsigned)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector4_32(const uint8_t* vector_data, bool is_unsigned)
 	{
 		uint8_t x8 = vector_data[0];
 		uint8_t y8 = vector_data[1];
@@ -209,16 +210,16 @@ namespace acl
 		float y = is_unsigned ? unpack_scalar_unsigned(y8, 8) : unpack_scalar_signed(y8, 8);
 		float z = is_unsigned ? unpack_scalar_unsigned(z8, 8) : unpack_scalar_signed(z8, 8);
 		float w = is_unsigned ? unpack_scalar_unsigned(w8, 8) : unpack_scalar_signed(w8, 8);
-		return vector_set(x, y, z, w);
+		return rtm::vector_set(x, y, z, w);
 	}
 
 	// Packs data in big-endian order and assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector4_uXX_unsafe(Vector4_32Arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector4_uXX_unsafe(rtm::vector4f_arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_unsigned(vector_get_x(vector), num_bits);
-		uint32_t vector_y = pack_scalar_unsigned(vector_get_y(vector), num_bits);
-		uint32_t vector_z = pack_scalar_unsigned(vector_get_z(vector), num_bits);
-		uint32_t vector_w = pack_scalar_unsigned(vector_get_w(vector), num_bits);
+		uint32_t vector_x = pack_scalar_unsigned(rtm::vector_get_x(vector), num_bits);
+		uint32_t vector_y = pack_scalar_unsigned(rtm::vector_get_y(vector), num_bits);
+		uint32_t vector_z = pack_scalar_unsigned(rtm::vector_get_z(vector), num_bits);
+		uint32_t vector_w = pack_scalar_unsigned(rtm::vector_get_w(vector), num_bits);
 
 		uint64_t vector_u64 = static_cast<uint64_t>(vector_x) << (64 - num_bits * 1);
 		vector_u64 |= static_cast<uint64_t>(vector_y) << (64 - num_bits * 2);
@@ -233,7 +234,7 @@ namespace acl
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector4_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector4_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		ACL_ASSERT(num_bits <= 19, "This function does not support reading more than 19 bits per component");
 
@@ -258,7 +259,7 @@ namespace acl
 			PackedTableEntry(16), PackedTableEntry(17), PackedTableEntry(18), PackedTableEntry(19),
 		};
 
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		const __m128i mask = _mm_castps_si128(_mm_load_ps1((const float*)&k_packed_constants[num_bits].mask));
 		const __m128 inv_max_value = _mm_load_ps1(&k_packed_constants[num_bits].max_value);
@@ -293,7 +294,7 @@ namespace acl
 		int_value = _mm_and_si128(int_value, mask);
 		const __m128 value = _mm_cvtepi32_ps(int_value);
 		return _mm_mul_ps(value, inv_max_value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		uint32x4_t mask = vdupq_n_u32(k_packed_constants[num_bits].mask);
 		float inv_max_value = k_packed_constants[num_bits].max_value;
@@ -361,14 +362,14 @@ namespace acl
 		vector_u32 = byte_swap(vector_u32);
 		const uint32_t w32 = (vector_u32 >> (bit_shift - (bit_offset % 8))) & mask;
 
-		return vector_mul(vector_set(float(x32), float(y32), float(z32), float(w32)), inv_max_value);
+		return rtm::vector_mul(rtm::vector_set(float(x32), float(y32), float(z32), float(w32)), inv_max_value);
 #endif
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector2_64_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector2_64_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -387,7 +388,7 @@ namespace acl
 
 		// TODO: Convert to u64 first before set1_epi64 or equivalent?
 		return _mm_castsi128_ps(_mm_set_epi32(y32, x32, y32, x32));
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -426,28 +427,28 @@ namespace acl
 		const float x = aligned_load<float>(&x64);
 		const float y = aligned_load<float>(&y64);
 
-		return vector_set(x, y, x, y);
+		return rtm::vector_set(x, y, x, y);
 #endif
 	}
 
 	//////////////////////////////////////////////////////////////////////////
 	// vector3 packing and decay
 
-	inline void ACL_SIMD_CALL pack_vector3_96(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_96(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		vector_unaligned_write3(vector, out_vector_data);
+		rtm::vector_store3(vector, out_vector_data);
 	}
 
 	// Assumes the 'vector_data' is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_96_unsafe(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_96_unsafe(const uint8_t* vector_data)
 	{
-		return vector_unaligned_load_32(vector_data);
+		return rtm::vector_load(vector_data);
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_96_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_96_unsafe(const uint8_t* vector_data, uint32_t bit_offset)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -472,7 +473,7 @@ namespace acl
 		const uint32_t z32 = uint32_t(vector_u64);
 
 		return _mm_castsi128_ps(_mm_set_epi32(x32, z32, y32, x32));
-#elif defined(ACL_NEON64_INTRINSICS) && defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 8
+#elif defined(RTM_NEON64_INTRINSICS) && defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 8
 		// Clang 3.8 has a bug in its codegen and we have to use a slightly slower impl to avoid it
 		// This is a pretty old version but UE 4.23 still uses it on android
 		const uint32_t byte_offset = bit_offset / 8;
@@ -493,7 +494,7 @@ namespace acl
 
 		const uint32x4_t xyz32 = vcombine_u32(xy32, vreinterpret_u32_u64(z64));
 		return vreinterpretq_f32_u32(xyz32);
-#elif defined(ACL_NEON64_INTRINSICS)
+#elif defined(RTM_NEON64_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset + 0);
@@ -516,7 +517,7 @@ namespace acl
 		const uint32x2_t z = vcreate_u32(z64);
 		const uint32x4_t value_u32 = vcombine_u32(xy, z);
 		return vreinterpretq_f32_u32(value_u32);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t byte_offset = bit_offset / 8;
 		const uint32_t shift_offset = bit_offset % 8;
 
@@ -563,13 +564,13 @@ namespace acl
 		const float y = aligned_load<float>(&y64);
 		const float z = aligned_load<float>(&z64);
 
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 #endif
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and is padded in order to load up to 16 bytes from it
 	ACL_DEPRECATED("Use unpack_vector3_96_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_96(const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_96(const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		uint32_t byte_offset = bit_offset / 8;
 		uint64_t vector_u64 = unaligned_load<uint64_t>(vector_data + byte_offset);
@@ -601,21 +602,21 @@ namespace acl
 		const float y = aligned_load<float>(&y64);
 		const float z = aligned_load<float>(&z64);
 
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
 	ACL_DEPRECATED("Use unpack_vector3_96_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_96(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_96(const uint8_t* vector_data)
 	{
-		return vector_unaligned_load3_32(vector_data);
+		return rtm::vector_load3(vector_data);
 	}
 
 	// Assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_u48_unsafe(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_u48_unsafe(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_unsigned(vector_get_x(vector), 16);
-		uint32_t vector_y = pack_scalar_unsigned(vector_get_y(vector), 16);
-		uint32_t vector_z = pack_scalar_unsigned(vector_get_z(vector), 16);
+		uint32_t vector_x = pack_scalar_unsigned(rtm::vector_get_x(vector), 16);
+		uint32_t vector_y = pack_scalar_unsigned(rtm::vector_get_y(vector), 16);
+		uint32_t vector_z = pack_scalar_unsigned(rtm::vector_get_z(vector), 16);
 
 		uint16_t* data = safe_ptr_cast<uint16_t>(out_vector_data);
 		data[0] = safe_static_cast<uint16_t>(vector_x);
@@ -624,11 +625,11 @@ namespace acl
 	}
 
 	// Assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_s48_unsafe(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_s48_unsafe(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_signed(vector_get_x(vector), 16);
-		uint32_t vector_y = pack_scalar_signed(vector_get_y(vector), 16);
-		uint32_t vector_z = pack_scalar_signed(vector_get_z(vector), 16);
+		uint32_t vector_x = pack_scalar_signed(rtm::vector_get_x(vector), 16);
+		uint32_t vector_y = pack_scalar_signed(rtm::vector_get_y(vector), 16);
+		uint32_t vector_z = pack_scalar_signed(rtm::vector_get_z(vector), 16);
 
 		uint16_t* data = safe_ptr_cast<uint16_t>(out_vector_data);
 		data[0] = safe_static_cast<uint16_t>(vector_x);
@@ -637,11 +638,11 @@ namespace acl
 	}
 
 	ACL_DEPRECATED("Use pack_vector3_u48_unsafe and pack_vector3_s48_unsafe instead, to be removed in v2.0")
-	inline void ACL_SIMD_CALL pack_vector3_48(Vector4_32Arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_48(rtm::vector4f_arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), 16) : pack_scalar_signed(vector_get_x(vector), 16);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), 16) : pack_scalar_signed(vector_get_y(vector), 16);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), 16) : pack_scalar_signed(vector_get_z(vector), 16);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), 16) : pack_scalar_signed(rtm::vector_get_x(vector), 16);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), 16) : pack_scalar_signed(rtm::vector_get_y(vector), 16);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), 16) : pack_scalar_signed(rtm::vector_get_z(vector), 16);
 
 		uint16_t* data = safe_ptr_cast<uint16_t>(out_vector_data);
 		data[0] = safe_static_cast<uint16_t>(vector_x);
@@ -650,15 +651,15 @@ namespace acl
 	}
 
 	// Assumes the 'vector_data' is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_u48_unsafe(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_u48_unsafe(const uint8_t* vector_data)
 	{
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		__m128i zero = _mm_setzero_si128();
 		__m128i x16y16z16 = _mm_loadu_si128((const __m128i*)vector_data);
 		__m128i x32y32z32 = _mm_unpacklo_epi16(x16y16z16, zero);
 		__m128 value = _mm_cvtepi32_ps(x32y32z32);
 		return _mm_mul_ps(value, _mm_set_ps1(1.0F / 65535.0F));
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		uint8x8_t x8y8z8 = vld1_u8(vector_data);
 		uint16x4_t x16y16z16 = vreinterpret_u16_u8(x8y8z8);
 		uint32x4_t x32y32z32 = vmovl_u16(x16y16z16);
@@ -673,19 +674,19 @@ namespace acl
 		float x = unpack_scalar_unsigned(x16, 16);
 		float y = unpack_scalar_unsigned(y16, 16);
 		float z = unpack_scalar_unsigned(z16, 16);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 #endif
 	}
 
 	// Assumes the 'vector_data' is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_s48_unsafe(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_s48_unsafe(const uint8_t* vector_data)
 	{
-		const Vector4_32 unsigned_value = unpack_vector3_u48_unsafe(vector_data);
-		return vector_neg_mul_sub(unsigned_value, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f unsigned_value = unpack_vector3_u48_unsafe(vector_data);
+		return rtm::vector_neg_mul_sub(unsigned_value, -2.0F, rtm::vector_set(-1.0F));
 	}
 
 	ACL_DEPRECATED("Use unpack_vector3_u48_unsafe and unpack_vector3_s48_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_48(const uint8_t* vector_data, bool is_unsigned)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_48(const uint8_t* vector_data, bool is_unsigned)
 	{
 		const uint16_t* data_ptr_u16 = safe_ptr_cast<const uint16_t>(vector_data);
 		uint16_t x16 = data_ptr_u16[0];
@@ -694,43 +695,43 @@ namespace acl
 		float x = is_unsigned ? unpack_scalar_unsigned(x16, 16) : unpack_scalar_signed(x16, 16);
 		float y = is_unsigned ? unpack_scalar_unsigned(y16, 16) : unpack_scalar_signed(y16, 16);
 		float z = is_unsigned ? unpack_scalar_unsigned(z16, 16) : unpack_scalar_signed(z16, 16);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_u48(Vector4_32Arg0 input)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_u48(rtm::vector4f_arg0 input)
 	{
-		ACL_ASSERT(vector_all_greater_equal3(input, vector_zero_32()) && vector_all_less_equal3(input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(input), vector_get_y(input), vector_get_z(input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(input, rtm::vector_zero()) && rtm::vector_all_less_equal3(input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(input), rtm::vector_get_y(input), rtm::vector_get_z(input));
 
 		const float max_value = float((1 << 16) - 1);
 		const float inv_max_value = 1.0F / max_value;
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
 		return decayed;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_s48(Vector4_32Arg0 input)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_s48(rtm::vector4f_arg0 input)
 	{
-		const Vector4_32 half = vector_set(0.5F);
-		const Vector4_32 unsigned_input = vector_mul_add(input, half, half);
+		const rtm::vector4f half = rtm::vector_set(0.5F);
+		const rtm::vector4f unsigned_input = rtm::vector_mul_add(input, half, half);
 
-		ACL_ASSERT(vector_all_greater_equal3(unsigned_input, vector_zero_32()) && vector_all_less_equal3(unsigned_input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(unsigned_input), vector_get_y(unsigned_input), vector_get_z(unsigned_input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(unsigned_input, rtm::vector_zero()) && rtm::vector_all_less_equal3(unsigned_input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(unsigned_input), rtm::vector_get_y(unsigned_input), rtm::vector_get_z(unsigned_input));
 
-		const float max_value = safe_to_float((1 << 16) - 1);
+		const float max_value = rtm::scalar_safe_to_float((1 << 16) - 1);
 		const float inv_max_value = 1.0F / max_value;
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(unsigned_input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
-		return vector_neg_mul_sub(decayed, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(unsigned_input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
+		return rtm::vector_neg_mul_sub(decayed, -2.0F, rtm::vector_set(-1.0F));
 	}
 
-	inline void ACL_SIMD_CALL pack_vector3_32(Vector4_32Arg0 vector, uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_32(rtm::vector4f_arg0 vector, uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, uint8_t* out_vector_data)
 	{
 		ACL_ASSERT(XBits + YBits + ZBits == 32, "Sum of XYZ bits does not equal 32!");
 
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), XBits) : pack_scalar_signed(vector_get_x(vector), XBits);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), YBits) : pack_scalar_signed(vector_get_y(vector), YBits);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), ZBits) : pack_scalar_signed(vector_get_z(vector), ZBits);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), XBits) : pack_scalar_signed(rtm::vector_get_x(vector), XBits);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), YBits) : pack_scalar_signed(rtm::vector_get_y(vector), YBits);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), ZBits) : pack_scalar_signed(rtm::vector_get_z(vector), ZBits);
 
 		uint32_t vector_u32 = (vector_x << (YBits + ZBits)) | (vector_y << ZBits) | vector_z;
 
@@ -740,42 +741,42 @@ namespace acl
 		data[1] = safe_static_cast<uint16_t>(vector_u32 & 0xFFFF);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_u32(Vector4_32Arg0 input, uint8_t XBits, uint8_t YBits, uint8_t ZBits)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_u32(rtm::vector4f_arg0 input, uint8_t XBits, uint8_t YBits, uint8_t ZBits)
 	{
 		ACL_ASSERT(XBits + YBits + ZBits == 32, "Sum of XYZ bits does not equal 32!");
-		ACL_ASSERT(vector_all_greater_equal3(input, vector_zero_32()) && vector_all_less_equal(input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(input), vector_get_y(input), vector_get_z(input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(input, rtm::vector_zero()) && rtm::vector_all_less_equal(input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(input), rtm::vector_get_y(input), rtm::vector_get_z(input));
 
 		const float max_value_x = float((1 << XBits) - 1);
 		const float max_value_y = float((1 << YBits) - 1);
 		const float max_value_z = float((1 << ZBits) - 1);
-		const Vector4_32 max_value = vector_set(max_value_x, max_value_y, max_value_z, max_value_z);
-		const Vector4_32 inv_max_value = vector_reciprocal(max_value);
+		const rtm::vector4f max_value = rtm::vector_set(max_value_x, max_value_y, max_value_z, max_value_z);
+		const rtm::vector4f inv_max_value = rtm::vector_reciprocal(max_value);
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
 		return decayed;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_s32(Vector4_32Arg0 input, uint8_t XBits, uint8_t YBits, uint8_t ZBits)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_s32(rtm::vector4f_arg0 input, uint8_t XBits, uint8_t YBits, uint8_t ZBits)
 	{
-		const Vector4_32 half = vector_set(0.5F);
-		const Vector4_32 unsigned_input = vector_mul_add(input, half, half);
+		const rtm::vector4f half = rtm::vector_set(0.5F);
+		const rtm::vector4f unsigned_input = rtm::vector_mul_add(input, half, half);
 
 		ACL_ASSERT(XBits + YBits + ZBits == 32, "Sum of XYZ bits does not equal 32!");
-		ACL_ASSERT(vector_all_greater_equal3(unsigned_input, vector_zero_32()) && vector_all_less_equal(unsigned_input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(unsigned_input), vector_get_y(unsigned_input), vector_get_z(unsigned_input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(unsigned_input, rtm::vector_zero()) && rtm::vector_all_less_equal(unsigned_input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(unsigned_input), rtm::vector_get_y(unsigned_input), rtm::vector_get_z(unsigned_input));
 
 		const float max_value_x = float((1 << XBits) - 1);
 		const float max_value_y = float((1 << YBits) - 1);
 		const float max_value_z = float((1 << ZBits) - 1);
-		const Vector4_32 max_value = vector_set(max_value_x, max_value_y, max_value_z, max_value_z);
-		const Vector4_32 inv_max_value = vector_reciprocal(max_value);
+		const rtm::vector4f max_value = rtm::vector_set(max_value_x, max_value_y, max_value_z, max_value_z);
+		const rtm::vector4f inv_max_value = rtm::vector_reciprocal(max_value);
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(unsigned_input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
-		return vector_neg_mul_sub(decayed, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(unsigned_input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
+		return rtm::vector_neg_mul_sub(decayed, -2.0F, rtm::vector_set(-1.0F));
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_32(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_32(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data)
 	{
 		ACL_ASSERT(XBits + YBits + ZBits == 32, "Sum of XYZ bits does not equal 32!");
 
@@ -788,15 +789,15 @@ namespace acl
 		float x = is_unsigned ? unpack_scalar_unsigned(x32, XBits) : unpack_scalar_signed(x32, XBits);
 		float y = is_unsigned ? unpack_scalar_unsigned(y32, YBits) : unpack_scalar_signed(y32, YBits);
 		float z = is_unsigned ? unpack_scalar_unsigned(z32, ZBits) : unpack_scalar_signed(z32, ZBits);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
 	// Assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_u24_unsafe(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_u24_unsafe(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_unsigned(vector_get_x(vector), 8);
-		uint32_t vector_y = pack_scalar_unsigned(vector_get_y(vector), 8);
-		uint32_t vector_z = pack_scalar_unsigned(vector_get_z(vector), 8);
+		uint32_t vector_x = pack_scalar_unsigned(rtm::vector_get_x(vector), 8);
+		uint32_t vector_y = pack_scalar_unsigned(rtm::vector_get_y(vector), 8);
+		uint32_t vector_z = pack_scalar_unsigned(rtm::vector_get_z(vector), 8);
 
 		out_vector_data[0] = safe_static_cast<uint8_t>(vector_x);
 		out_vector_data[1] = safe_static_cast<uint8_t>(vector_y);
@@ -804,11 +805,11 @@ namespace acl
 	}
 
 	// Assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_s24_unsafe(Vector4_32Arg0 vector, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_s24_unsafe(rtm::vector4f_arg0 vector, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_signed(vector_get_x(vector), 8);
-		uint32_t vector_y = pack_scalar_signed(vector_get_y(vector), 8);
-		uint32_t vector_z = pack_scalar_signed(vector_get_z(vector), 8);
+		uint32_t vector_x = pack_scalar_signed(rtm::vector_get_x(vector), 8);
+		uint32_t vector_y = pack_scalar_signed(rtm::vector_get_y(vector), 8);
+		uint32_t vector_z = pack_scalar_signed(rtm::vector_get_z(vector), 8);
 
 		out_vector_data[0] = safe_static_cast<uint8_t>(vector_x);
 		out_vector_data[1] = safe_static_cast<uint8_t>(vector_y);
@@ -816,11 +817,11 @@ namespace acl
 	}
 
 	ACL_DEPRECATED("Use pack_vector3_u24_unsafe and pack_vector3_s24_unsafe instead, to be removed in v2.0")
-	inline void ACL_SIMD_CALL pack_vector3_24(Vector4_32Arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_24(rtm::vector4f_arg0 vector, bool is_unsigned, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), 8) : pack_scalar_signed(vector_get_x(vector), 8);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), 8) : pack_scalar_signed(vector_get_y(vector), 8);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), 8) : pack_scalar_signed(vector_get_z(vector), 8);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), 8) : pack_scalar_signed(rtm::vector_get_x(vector), 8);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), 8) : pack_scalar_signed(rtm::vector_get_y(vector), 8);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), 8) : pack_scalar_signed(rtm::vector_get_z(vector), 8);
 
 		out_vector_data[0] = safe_static_cast<uint8_t>(vector_x);
 		out_vector_data[1] = safe_static_cast<uint8_t>(vector_y);
@@ -828,9 +829,9 @@ namespace acl
 	}
 
 	// Assumes the 'vector_data' is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_u24_unsafe(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_u24_unsafe(const uint8_t* vector_data)
 	{
-#if defined(ACL_SSE2_INTRINSICS) && 0
+#if defined(RTM_SSE2_INTRINSICS) && 0
 		// This implementation leverages fast fixed point coercion, it relies on the
 		// input being positive and normalized as well as fixed point (division by 256, not 255)
 		// TODO: Enable this, it's a bit faster but requires compensating with the clip range to avoid losing precision
@@ -842,14 +843,14 @@ namespace acl
 		__m128i x32y32z32 = _mm_unpacklo_epi16(x16y16z16, zero);
 		__m128i segment_extent_i32 = _mm_or_si128(_mm_slli_epi32(x32y32z32, 23 - 8), exponent);
 		return _mm_sub_ps(_mm_castsi128_ps(segment_extent_i32), _mm_castsi128_ps(exponent));
-#elif defined(ACL_SSE2_INTRINSICS)
+#elif defined(RTM_SSE2_INTRINSICS)
 		__m128i zero = _mm_setzero_si128();
 		__m128i x8y8z8 = _mm_loadu_si128((const __m128i*)vector_data);
 		__m128i x16y16z16 = _mm_unpacklo_epi8(x8y8z8, zero);
 		__m128i x32y32z32 = _mm_unpacklo_epi16(x16y16z16, zero);
 		__m128 value = _mm_cvtepi32_ps(x32y32z32);
 		return _mm_mul_ps(value, _mm_set_ps1(1.0F / 255.0F));
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		uint8x8_t x8y8z8 = vld1_u8(vector_data);
 		uint16x8_t x16y16z16 = vmovl_u8(x8y8z8);
 		uint32x4_t x32y32z32 = vmovl_u16(vget_low_u16(x16y16z16));
@@ -863,19 +864,19 @@ namespace acl
 		float x = unpack_scalar_unsigned(x8, 8);
 		float y = unpack_scalar_unsigned(y8, 8);
 		float z = unpack_scalar_unsigned(z8, 8);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 #endif
 	}
 
 	// Assumes the 'vector_data' is padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_s24_unsafe(const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_s24_unsafe(const uint8_t* vector_data)
 	{
-		const Vector4_32 unsigned_value = unpack_vector3_u24_unsafe(vector_data);
-		return vector_neg_mul_sub(unsigned_value, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f unsigned_value = unpack_vector3_u24_unsafe(vector_data);
+		return rtm::vector_neg_mul_sub(unsigned_value, -2.0F, rtm::vector_set(-1.0F));
 	}
 
 	ACL_DEPRECATED("Use unpack_vector3_u24_unsafe and unpack_vector3_s24_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_24(const uint8_t* vector_data, bool is_unsigned)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_24(const uint8_t* vector_data, bool is_unsigned)
 	{
 		uint8_t x8 = vector_data[0];
 		uint8_t y8 = vector_data[1];
@@ -883,15 +884,15 @@ namespace acl
 		float x = is_unsigned ? unpack_scalar_unsigned(x8, 8) : unpack_scalar_signed(x8, 8);
 		float y = is_unsigned ? unpack_scalar_unsigned(y8, 8) : unpack_scalar_signed(y8, 8);
 		float z = is_unsigned ? unpack_scalar_unsigned(z8, 8) : unpack_scalar_signed(z8, 8);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
 	// Packs data in big-endian order and assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_uXX_unsafe(Vector4_32Arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_uXX_unsafe(rtm::vector4f_arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_unsigned(vector_get_x(vector), num_bits);
-		uint32_t vector_y = pack_scalar_unsigned(vector_get_y(vector), num_bits);
-		uint32_t vector_z = pack_scalar_unsigned(vector_get_z(vector), num_bits);
+		uint32_t vector_x = pack_scalar_unsigned(rtm::vector_get_x(vector), num_bits);
+		uint32_t vector_y = pack_scalar_unsigned(rtm::vector_get_y(vector), num_bits);
+		uint32_t vector_z = pack_scalar_unsigned(rtm::vector_get_z(vector), num_bits);
 
 		uint64_t vector_u64 = static_cast<uint64_t>(vector_x) << (64 - num_bits * 1);
 		vector_u64 |= static_cast<uint64_t>(vector_y) << (64 - num_bits * 2);
@@ -902,11 +903,11 @@ namespace acl
 	}
 
 	// Packs data in big-endian order and assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector3_sXX_unsafe(Vector4_32Arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_sXX_unsafe(rtm::vector4f_arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_signed(vector_get_x(vector), num_bits);
-		uint32_t vector_y = pack_scalar_signed(vector_get_y(vector), num_bits);
-		uint32_t vector_z = pack_scalar_signed(vector_get_z(vector), num_bits);
+		uint32_t vector_x = pack_scalar_signed(rtm::vector_get_x(vector), num_bits);
+		uint32_t vector_y = pack_scalar_signed(rtm::vector_get_y(vector), num_bits);
+		uint32_t vector_z = pack_scalar_signed(rtm::vector_get_z(vector), num_bits);
 
 		uint64_t vector_u64 = static_cast<uint64_t>(vector_x) << (64 - num_bits * 1);
 		vector_u64 |= static_cast<uint64_t>(vector_y) << (64 - num_bits * 2);
@@ -918,46 +919,46 @@ namespace acl
 
 	// Assumes the 'out_vector_data' is padded in order to write up to 8 bytes to it
 	ACL_DEPRECATED("Use pack_vector3_uXX_unsafe and pack_vector3_sXX_unsafe instead, to be removed in v2.0")
-	inline void ACL_SIMD_CALL pack_vector3_n(Vector4_32Arg0 vector, uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector3_n(rtm::vector4f_arg0 vector, uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(vector_get_x(vector), XBits) : pack_scalar_signed(vector_get_x(vector), XBits);
-		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(vector_get_y(vector), YBits) : pack_scalar_signed(vector_get_y(vector), YBits);
-		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(vector_get_z(vector), ZBits) : pack_scalar_signed(vector_get_z(vector), ZBits);
+		uint32_t vector_x = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_x(vector), XBits) : pack_scalar_signed(rtm::vector_get_x(vector), XBits);
+		uint32_t vector_y = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_y(vector), YBits) : pack_scalar_signed(rtm::vector_get_y(vector), YBits);
+		uint32_t vector_z = is_unsigned ? pack_scalar_unsigned(rtm::vector_get_z(vector), ZBits) : pack_scalar_signed(rtm::vector_get_z(vector), ZBits);
 
 		uint64_t vector_u64 = (static_cast<uint64_t>(vector_x) << (YBits + ZBits)) | (static_cast<uint64_t>(vector_y) << ZBits) | static_cast<uint64_t>(vector_z);
 
 		unaligned_write(vector_u64, out_vector_data);
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_uXX(Vector4_32Arg0 input, uint32_t num_bits)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_uXX(rtm::vector4f_arg0 input, uint32_t num_bits)
 	{
-		ACL_ASSERT(vector_all_greater_equal3(input, vector_zero_32()) && vector_all_less_equal3(input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(input), vector_get_y(input), vector_get_z(input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(input, rtm::vector_zero()) && rtm::vector_all_less_equal3(input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(input), rtm::vector_get_y(input), rtm::vector_get_z(input));
 
-		const float max_value = safe_to_float((1 << num_bits) - 1);
+		const float max_value = rtm::scalar_safe_to_float((1 << num_bits) - 1);
 		const float inv_max_value = 1.0F / max_value;
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
 		return decayed;
 	}
 
-	inline Vector4_32 ACL_SIMD_CALL decay_vector3_sXX(Vector4_32Arg0 input, uint32_t num_bits)
+	inline rtm::vector4f RTM_SIMD_CALL decay_vector3_sXX(rtm::vector4f_arg0 input, uint32_t num_bits)
 	{
-		const Vector4_32 half = vector_set(0.5F);
-		const Vector4_32 unsigned_input = vector_mul_add(input, half, half);
+		const rtm::vector4f half = rtm::vector_set(0.5F);
+		const rtm::vector4f unsigned_input = rtm::vector_mul_add(input, half, half);
 
-		ACL_ASSERT(vector_all_greater_equal3(unsigned_input, vector_zero_32()) && vector_all_less_equal3(unsigned_input, vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", vector_get_x(unsigned_input), vector_get_y(unsigned_input), vector_get_z(unsigned_input));
+		ACL_ASSERT(rtm::vector_all_greater_equal3(unsigned_input, rtm::vector_zero()) && rtm::vector_all_less_equal3(unsigned_input, rtm::vector_set(1.0F)), "Expected normalized unsigned input value: %f, %f, %f", rtm::vector_get_x(unsigned_input), rtm::vector_get_y(unsigned_input), rtm::vector_get_z(unsigned_input));
 
-		const float max_value = safe_to_float((1 << num_bits) - 1);
+		const float max_value = rtm::scalar_safe_to_float((1 << num_bits) - 1);
 		const float inv_max_value = 1.0F / max_value;
 
-		const Vector4_32 packed = vector_symmetric_round(vector_mul(unsigned_input, max_value));
-		const Vector4_32 decayed = vector_mul(packed, inv_max_value);
-		return vector_neg_mul_sub(decayed, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f packed = rtm::vector_symmetric_round(rtm::vector_mul(unsigned_input, max_value));
+		const rtm::vector4f decayed = rtm::vector_mul(packed, inv_max_value);
+		return rtm::vector_neg_mul_sub(decayed, -2.0F, rtm::vector_set(-1.0F));
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		ACL_ASSERT(num_bits <= 19, "This function does not support reading more than 19 bits per component");
 
@@ -982,7 +983,7 @@ namespace acl
 			PackedTableEntry(16), PackedTableEntry(17), PackedTableEntry(18), PackedTableEntry(19),
 		};
 
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		const __m128i mask = _mm_castps_si128(_mm_load_ps1((const float*)&k_packed_constants[num_bits].mask));
 		const __m128 inv_max_value = _mm_load_ps1(&k_packed_constants[num_bits].max_value);
@@ -1010,7 +1011,7 @@ namespace acl
 		int_value = _mm_and_si128(int_value, mask);
 		const __m128 value = _mm_cvtepi32_ps(int_value);
 		return _mm_mul_ps(value, inv_max_value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		uint32x4_t mask = vdupq_n_u32(k_packed_constants[num_bits].mask);
 		float inv_max_value = k_packed_constants[num_bits].max_value;
@@ -1064,22 +1065,22 @@ namespace acl
 		vector_u32 = byte_swap(vector_u32);
 		const uint32_t z32 = (vector_u32 >> (bit_shift - (bit_offset % 8))) & mask;
 
-		return vector_mul(vector_set(float(x32), float(y32), float(z32)), inv_max_value);
+		return rtm::vector_mul(rtm::vector_set(float(x32), float(y32), float(z32)), inv_max_value);
 #endif
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_sXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_sXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		ACL_ASSERT(num_bits * 3 <= 64, "Attempting to read too many bits");
 
-		const Vector4_32 unsigned_value = unpack_vector3_uXX_unsafe(num_bits, vector_data, bit_offset);
-		return vector_neg_mul_sub(unsigned_value, -2.0F, vector_set(-1.0F));
+		const rtm::vector4f unsigned_value = unpack_vector3_uXX_unsafe(num_bits, vector_data, bit_offset);
+		return rtm::vector_neg_mul_sub(unsigned_value, -2.0F, rtm::vector_set(-1.0F));
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 8 bytes from it
 	ACL_DEPRECATED("Use unpack_vector3_uXX_unsafe and unpack_vector3_sXX_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_n(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_n(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data)
 	{
 		uint64_t vector_u64 = *safe_ptr_cast<const uint64_t>(vector_data);
 		uint32_t x64 = safe_static_cast<uint32_t>(vector_u64 >> (YBits + ZBits));
@@ -1088,12 +1089,12 @@ namespace acl
 		float x = is_unsigned ? unpack_scalar_unsigned(x64, XBits) : unpack_scalar_signed(x64, XBits);
 		float y = is_unsigned ? unpack_scalar_unsigned(y64, YBits) : unpack_scalar_signed(y64, YBits);
 		float z = is_unsigned ? unpack_scalar_unsigned(z64, ZBits) : unpack_scalar_signed(z64, ZBits);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 12 bytes from it
 	ACL_DEPRECATED("Use unpack_vector3_uXX_unsafe and unpack_vector3_sXX_unsafe instead, to be removed in v2.0")
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector3_n(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector3_n(uint8_t XBits, uint8_t YBits, uint8_t ZBits, bool is_unsigned, const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		uint8_t num_bits_to_read = XBits + YBits + ZBits;
 
@@ -1124,17 +1125,17 @@ namespace acl
 		const float x = is_unsigned ? unpack_scalar_unsigned(x32, XBits) : unpack_scalar_signed(x32, XBits);
 		const float y = is_unsigned ? unpack_scalar_unsigned(y32, YBits) : unpack_scalar_signed(y32, YBits);
 		const float z = is_unsigned ? unpack_scalar_unsigned(z32, ZBits) : unpack_scalar_signed(z32, ZBits);
-		return vector_set(x, y, z);
+		return rtm::vector_set(x, y, z);
 	}
 
 	//////////////////////////////////////////////////////////////////////////
 	// vector2 packing and decay
 
 	// Packs data in big-endian order and assumes the 'out_vector_data' is padded in order to write up to 16 bytes to it
-	inline void ACL_SIMD_CALL pack_vector2_uXX_unsafe(Vector4_32Arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
+	inline void RTM_SIMD_CALL pack_vector2_uXX_unsafe(rtm::vector4f_arg0 vector, uint8_t num_bits, uint8_t* out_vector_data)
 	{
-		uint32_t vector_x = pack_scalar_unsigned(vector_get_x(vector), num_bits);
-		uint32_t vector_y = pack_scalar_unsigned(vector_get_y(vector), num_bits);
+		uint32_t vector_x = pack_scalar_unsigned(rtm::vector_get_x(vector), num_bits);
+		uint32_t vector_y = pack_scalar_unsigned(rtm::vector_get_y(vector), num_bits);
 
 		uint64_t vector_u64 = static_cast<uint64_t>(vector_x) << (64 - num_bits * 1);
 		vector_u64 |= static_cast<uint64_t>(vector_y) << (64 - num_bits * 2);
@@ -1144,7 +1145,7 @@ namespace acl
 	}
 
 	// Assumes the 'vector_data' is in big-endian order and padded in order to load up to 16 bytes from it
-	inline Vector4_32 ACL_SIMD_CALL unpack_vector2_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
+	inline rtm::vector4f RTM_SIMD_CALL unpack_vector2_uXX_unsafe(uint8_t num_bits, const uint8_t* vector_data, uint32_t bit_offset)
 	{
 		ACL_ASSERT(num_bits <= 19, "This function does not support reading more than 19 bits per component");
 
@@ -1169,7 +1170,7 @@ namespace acl
 			PackedTableEntry(16), PackedTableEntry(17), PackedTableEntry(18), PackedTableEntry(19),
 		};
 
-#if defined(ACL_SSE2_INTRINSICS)
+#if defined(RTM_SSE2_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		const __m128i mask = _mm_castps_si128(_mm_load_ps1((const float*)&k_packed_constants[num_bits].mask));
 		const __m128 inv_max_value = _mm_load_ps1(&k_packed_constants[num_bits].max_value);
@@ -1190,7 +1191,7 @@ namespace acl
 		int_value = _mm_and_si128(int_value, mask);
 		const __m128 value = _mm_cvtepi32_ps(int_value);
 		return _mm_mul_ps(value, inv_max_value);
-#elif defined(ACL_NEON_INTRINSICS)
+#elif defined(RTM_NEON_INTRINSICS)
 		const uint32_t bit_shift = 32 - num_bits;
 		uint32x2_t mask = vdup_n_u32(k_packed_constants[num_bits].mask);
 		float inv_max_value = k_packed_constants[num_bits].max_value;
@@ -1229,7 +1230,7 @@ namespace acl
 		vector_u32 = byte_swap(vector_u32);
 		const uint32_t y32 = (vector_u32 >> (bit_shift - (bit_offset % 8))) & mask;
 
-		return vector_mul(vector_set(float(x32), float(y32), 0.0F, 0.0F), inv_max_value);
+		return rtm::vector_mul(rtm::vector_set(float(x32), float(y32), 0.0F, 0.0F), inv_max_value);
 #endif
 	}
 
diff --git a/tools/acl_compressor/main_android/CMakeLists.txt b/tools/acl_compressor/main_android/CMakeLists.txt
--- a/tools/acl_compressor/main_android/CMakeLists.txt
+++ b/tools/acl_compressor/main_android/CMakeLists.txt
@@ -50,7 +50,6 @@ target_compile_options(${PROJECT_NAME} PRIVATE -g)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
diff --git a/tools/acl_compressor/main_ios/CMakeLists.txt b/tools/acl_compressor/main_ios/CMakeLists.txt
--- a/tools/acl_compressor/main_ios/CMakeLists.txt
+++ b/tools/acl_compressor/main_ios/CMakeLists.txt
@@ -40,7 +40,6 @@ add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${ALL_COMMON_SOURCE_FILES} ${ALL_MA
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
diff --git a/tools/acl_compressor/sources/acl_compressor.cpp b/tools/acl_compressor/sources/acl_compressor.cpp
--- a/tools/acl_compressor/sources/acl_compressor.cpp
+++ b/tools/acl_compressor/sources/acl_compressor.cpp
@@ -426,16 +426,16 @@ static void validate_accuracy(IAllocator& allocator, const AnimationClip& clip,
 	const uint32_t additive_num_samples = additive_base_clip != nullptr ? additive_base_clip->get_num_samples() : 0;
 	const float additive_duration = additive_base_clip != nullptr ? additive_base_clip->get_duration() : 0.0F;
 
-	Transform_32* raw_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
-	Transform_32* base_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
-	Transform_32* lossy_pose_transforms = allocate_type_array<Transform_32>(allocator, num_bones);
+	rtm::qvvf* raw_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+	rtm::qvvf* base_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
+	rtm::qvvf* lossy_pose_transforms = allocate_type_array<rtm::qvvf>(allocator, num_bones);
 
 	DefaultOutputWriter pose_writer(lossy_pose_transforms, num_bones);
 
 	// Regression test
 	for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 	{
-		const float sample_time = min(float(sample_index) / sample_rate, clip_duration);
+		const float sample_time = rtm::scalar_min(float(sample_index) / sample_rate, clip_duration);
 
 		// We use the nearest sample to accurately measure the loss that happened, if any
 		clip.sample_pose(sample_time, SampleRoundingPolicy::Nearest, raw_pose_transforms, num_bones);
@@ -455,44 +455,44 @@ static void validate_accuracy(IAllocator& allocator, const AnimationClip& clip,
 		{
 			const float error = error_metric.calculate_object_bone_error(skeleton, raw_pose_transforms, base_pose_transforms, lossy_pose_transforms, bone_index);
 			(void)error;
-			ACL_ASSERT(is_finite(error), "Returned error is not a finite value");
+			ACL_ASSERT(rtm::scalar_is_finite(error), "Returned error is not a finite value");
 			ACL_ASSERT(error < regression_error_threshold, "Error too high for bone %u: %f at time %f", bone_index, error, sample_time);
 		}
 
 		// Validate decompress_bone for rotations only
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
-			Quat_32 rotation;
+			rtm::quatf rotation;
 			context.decompress_bone(bone_index, &rotation, nullptr, nullptr);
-			ACL_ASSERT(quat_near_equal(rotation, lossy_pose_transforms[bone_index].rotation), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::quat_near_equal(rotation, lossy_pose_transforms[bone_index].rotation), "Failed to sample bone index: %u", bone_index);
 		}
 
 		// Validate decompress_bone for translations only
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
-			Vector4_32 translation;
+			rtm::vector4f translation;
 			context.decompress_bone(bone_index, nullptr, &translation, nullptr);
-			ACL_ASSERT(vector_all_near_equal3(translation, lossy_pose_transforms[bone_index].translation), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::vector_all_near_equal3(translation, lossy_pose_transforms[bone_index].translation), "Failed to sample bone index: %u", bone_index);
 		}
 
 		// Validate decompress_bone for scales only
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
-			Vector4_32 scale;
+			rtm::vector4f scale;
 			context.decompress_bone(bone_index, nullptr, nullptr, &scale);
-			ACL_ASSERT(vector_all_near_equal3(scale, lossy_pose_transforms[bone_index].scale), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::vector_all_near_equal3(scale, lossy_pose_transforms[bone_index].scale), "Failed to sample bone index: %u", bone_index);
 		}
 
 		// Validate decompress_bone
 		for (uint16_t bone_index = 0; bone_index < num_bones; ++bone_index)
 		{
-			Quat_32 rotation;
-			Vector4_32 translation;
-			Vector4_32 scale;
+			rtm::quatf rotation;
+			rtm::vector4f translation;
+			rtm::vector4f scale;
 			context.decompress_bone(bone_index, &rotation, &translation, &scale);
-			ACL_ASSERT(quat_near_equal(rotation, lossy_pose_transforms[bone_index].rotation), "Failed to sample bone index: %u", bone_index);
-			ACL_ASSERT(vector_all_near_equal3(translation, lossy_pose_transforms[bone_index].translation), "Failed to sample bone index: %u", bone_index);
-			ACL_ASSERT(vector_all_near_equal3(scale, lossy_pose_transforms[bone_index].scale), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::quat_near_equal(rotation, lossy_pose_transforms[bone_index].rotation), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::vector_all_near_equal3(translation, lossy_pose_transforms[bone_index].translation), "Failed to sample bone index: %u", bone_index);
+			ACL_ASSERT(rtm::vector_all_near_equal3(scale, lossy_pose_transforms[bone_index].scale), "Failed to sample bone index: %u", bone_index);
 		}
 	}
 
@@ -522,7 +522,7 @@ static void validate_accuracy(IAllocator& allocator, const track_array& raw_trac
 	const uint32_t num_samples = tracks.get_num_samples_per_track();
 	const track_type8 track_type = raw_tracks.get_track_type();
 
-	ACL_ASSERT(scalar_near_equal(duration, raw_tracks.get_duration(), 1.0E-7F), "Duration mismatch");
+	ACL_ASSERT(rtm::scalar_near_equal(duration, raw_tracks.get_duration(), 1.0E-7F), "Duration mismatch");
 	ACL_ASSERT(sample_rate == raw_tracks.get_sample_rate(), "Sample rate mismatch");
 	ACL_ASSERT(num_tracks <= raw_tracks.get_num_tracks(), "Num tracks mismatch");
 	ACL_ASSERT(num_samples == raw_tracks.get_num_samples_per_track(), "Num samples mismatch");
@@ -540,7 +540,7 @@ static void validate_accuracy(IAllocator& allocator, const track_array& raw_trac
 	// Regression test
 	for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 	{
-		const float sample_time = min(float(sample_index) / sample_rate, duration);
+		const float sample_time = rtm::scalar_min(float(sample_index) / sample_rate, duration);
 
 		// We use the nearest sample to accurately measure the loss that happened, if any
 		raw_tracks.sample_tracks(sample_time, SampleRoundingPolicy::Nearest, raw_tracks_writer);
@@ -1056,7 +1056,10 @@ static bool read_config(IAllocator& allocator, const Options& options, Algorithm
 		}
 	}
 
-	parser.try_read("constant_rotation_threshold_angle", out_settings.constant_rotation_threshold_angle, default_settings.constant_rotation_threshold_angle);
+	double constant_rotation_threshold_angle;
+	parser.try_read("constant_rotation_threshold_angle", constant_rotation_threshold_angle, default_settings.constant_rotation_threshold_angle.as_radians());
+	out_settings.constant_rotation_threshold_angle = rtm::radians(float(constant_rotation_threshold_angle));
+
 	parser.try_read("constant_translation_threshold", out_settings.constant_translation_threshold, default_settings.constant_translation_threshold);
 	parser.try_read("constant_scale_threshold", out_settings.constant_scale_threshold, default_settings.constant_scale_threshold);
 	parser.try_read("error_threshold", out_settings.error_threshold, default_settings.error_threshold);
@@ -1112,17 +1115,17 @@ static void create_additive_base_clip(const Options& options, AnimationClip& cli
 
 		// Get the bind transform and make sure it has no scale
 		const RigidBone& skel_bone = skeleton.get_bone(bone_index);
-		const Transform_64 bind_transform = transform_set(skel_bone.bind_transform.rotation, skel_bone.bind_transform.translation, vector_set(1.0));
+		const rtm::qvvd bind_transform = rtm::qvv_set(skel_bone.bind_transform.rotation, skel_bone.bind_transform.translation, rtm::vector_set(1.0));
 
 		for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 		{
-			const Quat_64 rotation = quat_normalize(anim_bone.rotation_track.get_sample(sample_index));
-			const Vector4_64 translation = anim_bone.translation_track.get_sample(sample_index);
-			const Vector4_64 scale = anim_bone.scale_track.get_sample(sample_index);
+			const rtm::quatd rotation = rtm::quat_normalize(anim_bone.rotation_track.get_sample(sample_index));
+			const rtm::vector4d translation = anim_bone.translation_track.get_sample(sample_index);
+			const rtm::vector4d scale = anim_bone.scale_track.get_sample(sample_index);
 
-			const Transform_64 bone_transform = transform_set(rotation, translation, scale);
+			const rtm::qvvd bone_transform = rtm::qvv_set(rotation, translation, scale);
 
-			Transform_64 bind_local_transform = bone_transform;
+			rtm::qvvd bind_local_transform = bone_transform;
 			if (options.is_bind_pose_relative)
 				bind_local_transform = convert_to_relative(bind_transform, bone_transform);
 			else if (options.is_bind_pose_additive0)
diff --git a/tools/acl_decompressor/main_android/CMakeLists.txt b/tools/acl_decompressor/main_android/CMakeLists.txt
--- a/tools/acl_decompressor/main_android/CMakeLists.txt
+++ b/tools/acl_decompressor/main_android/CMakeLists.txt
@@ -67,7 +67,6 @@ add_definitions(-DACL_NO_ALLOCATOR_TRACKING)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
diff --git a/tools/acl_decompressor/main_ios/CMakeLists.txt b/tools/acl_decompressor/main_ios/CMakeLists.txt
--- a/tools/acl_decompressor/main_ios/CMakeLists.txt
+++ b/tools/acl_decompressor/main_ios/CMakeLists.txt
@@ -56,7 +56,6 @@ add_definitions(-DACL_NO_ALLOCATOR_TRACKING)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
diff --git a/tools/regression_tester_android/CMakeLists.txt b/tools/regression_tester_android/CMakeLists.txt
--- a/tools/regression_tester_android/CMakeLists.txt
+++ b/tools/regression_tester_android/CMakeLists.txt
@@ -69,7 +69,6 @@ add_definitions(-DSJSON_CPP_ON_ASSERT_THROW)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
diff --git a/tools/regression_tester_ios/CMakeLists.txt b/tools/regression_tester_ios/CMakeLists.txt
--- a/tools/regression_tester_ios/CMakeLists.txt
+++ b/tools/regression_tester_ios/CMakeLists.txt
@@ -61,7 +61,6 @@ add_definitions(-DACL_NO_ALLOCATOR_TRACKING)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
 	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 


Test patch:
diff --git a/tests/main_android/CMakeLists.txt b/tests/main_android/CMakeLists.txt
--- a/tests/main_android/CMakeLists.txt
+++ b/tests/main_android/CMakeLists.txt
@@ -54,7 +54,7 @@ add_definitions(-DRTM_ON_ASSERT_THROW)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
+	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
 # Enable SJSON when needed
diff --git a/tests/main_ios/CMakeLists.txt b/tests/main_ios/CMakeLists.txt
--- a/tests/main_ios/CMakeLists.txt
+++ b/tests/main_ios/CMakeLists.txt
@@ -44,7 +44,7 @@ add_definitions(-DRTM_ON_ASSERT_THROW)
 
 # Disable SIMD if not needed
 if(NOT USE_SIMD_INSTRUCTIONS)
-	add_definitions(-DACL_NO_INTRINSICS)
+	add_definitions(-DRTM_NO_INTRINSICS)
 endif()
 
 # Enable SJSON when needed
diff --git a/tests/sources/core/test_interpolation_utils.cpp b/tests/sources/core/test_interpolation_utils.cpp
--- a/tests/sources/core/test_interpolation_utils.cpp
+++ b/tests/sources/core/test_interpolation_utils.cpp
@@ -25,9 +25,10 @@
 #include <catch.hpp>
 
 #include <acl/core/interpolation_utils.h>
-#include <acl/math/scalar_32.h>
+#include <rtm/scalarf.h>
 
 using namespace acl;
+using namespace rtm;
 
 TEST_CASE("interpolation utils", "[core][utils]")
 {
diff --git a/tests/sources/core/test_utils.cpp b/tests/sources/core/test_utils.cpp
--- a/tests/sources/core/test_utils.cpp
+++ b/tests/sources/core/test_utils.cpp
@@ -25,11 +25,12 @@
 #include <catch.hpp>
 
 #include <acl/core/utils.h>
-#include <acl/math/scalar_32.h>
+#include <rtm/scalarf.h>
 
 #include <limits>
 
 using namespace acl;
+using namespace rtm;
 
 TEST_CASE("misc utils", "[core][utils]")
 {
diff --git a/tests/sources/io/test_reader_writer.cpp b/tests/sources/io/test_reader_writer.cpp
--- a/tests/sources/io/test_reader_writer.cpp
+++ b/tests/sources/io/test_reader_writer.cpp
@@ -36,8 +36,10 @@
 #include <acl/core/ansi_allocator.h>
 #include <acl/io/clip_reader.h>
 #include <acl/io/clip_writer.h>
-#include <acl/math/math.h>
-#include <acl/math/scalar_32.h>
+
+#include <rtm/angled.h>
+#include <rtm/qvvd.h>
+#include <rtm/scalarf.h>
 
 #include <chrono>
 #include <cstdio>
@@ -97,7 +99,7 @@
 
 using namespace acl;
 
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 #ifdef _WIN32
 	constexpr uint32_t k_max_filename_size = MAX_PATH;
 #else
@@ -133,7 +135,7 @@ static void get_temporary_filename(char* filename, uint32_t filename_size, const
 TEST_CASE("sjson_clip_reader_writer", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint16_t num_bones = 3;
@@ -141,17 +143,17 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 	bones[0].name = String(allocator, "root");
 	bones[0].vertex_distance = 4.0F;
 	bones[0].parent_index = k_invalid_bone_index;
-	bones[0].bind_transform = transform_identity_64();
+	bones[0].bind_transform = rtm::qvv_identity();
 
 	bones[1].name = String(allocator, "bone1");
 	bones[1].vertex_distance = 3.0F;
 	bones[1].parent_index = 0;
-	bones[1].bind_transform = transform_set(quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 0.5), vector_set(3.2, 8.2, 5.1), vector_set(1.0));
+	bones[1].bind_transform = rtm::qvv_set(rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 0.5), rtm::vector_set(3.2, 8.2, 5.1), rtm::vector_set(1.0));
 
 	bones[2].name = String(allocator, "bone2");
 	bones[2].vertex_distance = 2.0F;
 	bones[2].parent_index = 1;
-	bones[2].bind_transform = transform_set(quat_from_axis_angle(vector_set(0.0, 0.0, 1.0), k_pi_64 * 0.25), vector_set(6.3, 9.4, 1.5), vector_set(1.0));
+	bones[2].bind_transform = rtm::qvv_set(rtm::quat_from_axis_angle(rtm::vector_set(0.0, 0.0, 1.0), rtm::constants::pi() * 0.25), rtm::vector_set(6.3, 9.4, 1.5), rtm::vector_set(1.0));
 
 	RigidSkeleton skeleton(allocator, bones, num_bones);
 
@@ -160,49 +162,49 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 
 	AnimatedBone* animated_bones = clip.get_bones();
 	animated_bones[0].output_index = 0;
-	animated_bones[0].rotation_track.set_sample(0, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 0.1));
-	animated_bones[0].rotation_track.set_sample(1, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 0.2));
-	animated_bones[0].rotation_track.set_sample(2, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 0.3));
-	animated_bones[0].rotation_track.set_sample(3, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 0.4));
-	animated_bones[0].translation_track.set_sample(0, vector_set(3.2, 1.4, 9.4));
-	animated_bones[0].translation_track.set_sample(1, vector_set(3.3, 1.5, 9.5));
-	animated_bones[0].translation_track.set_sample(2, vector_set(3.4, 1.6, 9.6));
-	animated_bones[0].translation_track.set_sample(3, vector_set(3.5, 1.7, 9.7));
-	animated_bones[0].scale_track.set_sample(0, vector_set(1.0, 1.5, 1.1));
-	animated_bones[0].scale_track.set_sample(1, vector_set(1.1, 1.6, 1.2));
-	animated_bones[0].scale_track.set_sample(2, vector_set(1.2, 1.7, 1.3));
-	animated_bones[0].scale_track.set_sample(3, vector_set(1.3, 1.8, 1.4));
+	animated_bones[0].rotation_track.set_sample(0, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 0.1));
+	animated_bones[0].rotation_track.set_sample(1, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 0.2));
+	animated_bones[0].rotation_track.set_sample(2, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 0.3));
+	animated_bones[0].rotation_track.set_sample(3, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 0.4));
+	animated_bones[0].translation_track.set_sample(0, rtm::vector_set(3.2, 1.4, 9.4));
+	animated_bones[0].translation_track.set_sample(1, rtm::vector_set(3.3, 1.5, 9.5));
+	animated_bones[0].translation_track.set_sample(2, rtm::vector_set(3.4, 1.6, 9.6));
+	animated_bones[0].translation_track.set_sample(3, rtm::vector_set(3.5, 1.7, 9.7));
+	animated_bones[0].scale_track.set_sample(0, rtm::vector_set(1.0, 1.5, 1.1));
+	animated_bones[0].scale_track.set_sample(1, rtm::vector_set(1.1, 1.6, 1.2));
+	animated_bones[0].scale_track.set_sample(2, rtm::vector_set(1.2, 1.7, 1.3));
+	animated_bones[0].scale_track.set_sample(3, rtm::vector_set(1.3, 1.8, 1.4));
 
 	animated_bones[1].output_index = 2;
-	animated_bones[1].rotation_track.set_sample(0, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 1.1));
-	animated_bones[1].rotation_track.set_sample(1, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 1.2));
-	animated_bones[1].rotation_track.set_sample(2, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 1.3));
-	animated_bones[1].rotation_track.set_sample(3, quat_from_axis_angle(vector_set(0.0, 1.0, 0.0), k_pi_64 * 1.4));
-	animated_bones[1].translation_track.set_sample(0, vector_set(5.2, 2.4, 13.4));
-	animated_bones[1].translation_track.set_sample(1, vector_set(5.3, 2.5, 13.5));
-	animated_bones[1].translation_track.set_sample(2, vector_set(5.4, 2.6, 13.6));
-	animated_bones[1].translation_track.set_sample(3, vector_set(5.5, 2.7, 13.7));
-	animated_bones[1].scale_track.set_sample(0, vector_set(2.0, 0.5, 4.1));
-	animated_bones[1].scale_track.set_sample(1, vector_set(2.1, 0.6, 4.2));
-	animated_bones[1].scale_track.set_sample(2, vector_set(2.2, 0.7, 4.3));
-	animated_bones[1].scale_track.set_sample(3, vector_set(2.3, 0.8, 4.4));
+	animated_bones[1].rotation_track.set_sample(0, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 1.1));
+	animated_bones[1].rotation_track.set_sample(1, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 1.2));
+	animated_bones[1].rotation_track.set_sample(2, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 1.3));
+	animated_bones[1].rotation_track.set_sample(3, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 1.0, 0.0), rtm::constants::pi() * 1.4));
+	animated_bones[1].translation_track.set_sample(0, rtm::vector_set(5.2, 2.4, 13.4));
+	animated_bones[1].translation_track.set_sample(1, rtm::vector_set(5.3, 2.5, 13.5));
+	animated_bones[1].translation_track.set_sample(2, rtm::vector_set(5.4, 2.6, 13.6));
+	animated_bones[1].translation_track.set_sample(3, rtm::vector_set(5.5, 2.7, 13.7));
+	animated_bones[1].scale_track.set_sample(0, rtm::vector_set(2.0, 0.5, 4.1));
+	animated_bones[1].scale_track.set_sample(1, rtm::vector_set(2.1, 0.6, 4.2));
+	animated_bones[1].scale_track.set_sample(2, rtm::vector_set(2.2, 0.7, 4.3));
+	animated_bones[1].scale_track.set_sample(3, rtm::vector_set(2.3, 0.8, 4.4));
 
 	animated_bones[2].output_index = 1;
-	animated_bones[2].rotation_track.set_sample(0, quat_from_axis_angle(vector_set(0.0, 0.0, 1.0), k_pi_64 * 0.7));
-	animated_bones[2].rotation_track.set_sample(1, quat_from_axis_angle(vector_set(0.0, 0.0, 1.0), k_pi_64 * 0.8));
-	animated_bones[2].rotation_track.set_sample(2, quat_from_axis_angle(vector_set(0.0, 0.0, 1.0), k_pi_64 * 0.9));
-	animated_bones[2].rotation_track.set_sample(3, quat_from_axis_angle(vector_set(0.0, 0.0, 1.0), k_pi_64 * 0.4));
-	animated_bones[2].translation_track.set_sample(0, vector_set(1.2, 123.4, 11.4));
-	animated_bones[2].translation_track.set_sample(1, vector_set(1.3, 123.5, 11.5));
-	animated_bones[2].translation_track.set_sample(2, vector_set(1.4, 123.6, 11.6));
-	animated_bones[2].translation_track.set_sample(3, vector_set(1.5, 123.7, 11.7));
-	animated_bones[2].scale_track.set_sample(0, vector_set(4.0, 2.5, 3.1));
-	animated_bones[2].scale_track.set_sample(1, vector_set(4.1, 2.6, 3.2));
-	animated_bones[2].scale_track.set_sample(2, vector_set(4.2, 2.7, 3.3));
-	animated_bones[2].scale_track.set_sample(3, vector_set(4.3, 2.8, 3.4));
+	animated_bones[2].rotation_track.set_sample(0, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 0.0, 1.0), rtm::constants::pi() * 0.7));
+	animated_bones[2].rotation_track.set_sample(1, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 0.0, 1.0), rtm::constants::pi() * 0.8));
+	animated_bones[2].rotation_track.set_sample(2, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 0.0, 1.0), rtm::constants::pi() * 0.9));
+	animated_bones[2].rotation_track.set_sample(3, rtm::quat_from_axis_angle(rtm::vector_set(0.0, 0.0, 1.0), rtm::constants::pi() * 0.4));
+	animated_bones[2].translation_track.set_sample(0, rtm::vector_set(1.2, 123.4, 11.4));
+	animated_bones[2].translation_track.set_sample(1, rtm::vector_set(1.3, 123.5, 11.5));
+	animated_bones[2].translation_track.set_sample(2, rtm::vector_set(1.4, 123.6, 11.6));
+	animated_bones[2].translation_track.set_sample(3, rtm::vector_set(1.5, 123.7, 11.7));
+	animated_bones[2].scale_track.set_sample(0, rtm::vector_set(4.0, 2.5, 3.1));
+	animated_bones[2].scale_track.set_sample(1, rtm::vector_set(4.1, 2.6, 3.2));
+	animated_bones[2].scale_track.set_sample(2, rtm::vector_set(4.2, 2.7, 3.3));
+	animated_bones[2].scale_track.set_sample(3, rtm::vector_set(4.3, 2.8, 3.4));
 
 	CompressionSettings settings;
-	settings.constant_rotation_threshold_angle = 32.23F;
+	settings.constant_rotation_threshold_angle = rtm::radians(32.23F);
 	settings.constant_scale_threshold = 1.123F;
 	settings.constant_translation_threshold = 0.124F;
 	settings.error_threshold = 0.23F;
@@ -271,7 +273,7 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 	CHECK(file_clip.skeleton->get_num_bones() == num_bones);
 	CHECK(file_clip.clip->get_num_bones() == num_bones);
 	CHECK(file_clip.clip->get_name() == clip.get_name());
-	CHECK(scalar_near_equal(file_clip.clip->get_duration(), clip.get_duration(), 1.0E-8F));
+	CHECK(rtm::scalar_near_equal(file_clip.clip->get_duration(), clip.get_duration(), 1.0E-8F));
 	CHECK(file_clip.clip->get_num_samples() == clip.get_num_samples());
 	CHECK(file_clip.clip->get_sample_rate() == clip.get_sample_rate());
 
@@ -282,9 +284,9 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 		CHECK(src_bone.name == file_bone.name);
 		CHECK(src_bone.vertex_distance == file_bone.vertex_distance);
 		CHECK(src_bone.parent_index == file_bone.parent_index);
-		CHECK(quat_near_equal(src_bone.bind_transform.rotation, file_bone.bind_transform.rotation, 0.0));
-		CHECK(vector_all_near_equal3(src_bone.bind_transform.translation, file_bone.bind_transform.translation, 0.0));
-		CHECK(vector_all_near_equal3(src_bone.bind_transform.scale, file_bone.bind_transform.scale, 0.0));
+		CHECK(rtm::quat_near_equal(src_bone.bind_transform.rotation, file_bone.bind_transform.rotation, 0.0));
+		CHECK(rtm::vector_all_near_equal3(src_bone.bind_transform.translation, file_bone.bind_transform.translation, 0.0));
+		CHECK(rtm::vector_all_near_equal3(src_bone.bind_transform.scale, file_bone.bind_transform.scale, 0.0));
 
 		const AnimatedBone& src_animated_bone = clip.get_animated_bone(bone_index);
 		const AnimatedBone& file_animated_bone = file_clip.clip->get_animated_bone(bone_index);
@@ -292,9 +294,9 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 
 		for (uint32_t sample_index = 0; sample_index < num_samples; ++sample_index)
 		{
-			CHECK(quat_near_equal(src_animated_bone.rotation_track.get_sample(sample_index), file_animated_bone.rotation_track.get_sample(sample_index), 0.0));
-			CHECK(vector_all_near_equal3(src_animated_bone.translation_track.get_sample(sample_index), file_animated_bone.translation_track.get_sample(sample_index), 0.0));
-			CHECK(vector_all_near_equal3(src_animated_bone.scale_track.get_sample(sample_index), file_animated_bone.scale_track.get_sample(sample_index), 0.0));
+			CHECK(rtm::quat_near_equal(src_animated_bone.rotation_track.get_sample(sample_index), file_animated_bone.rotation_track.get_sample(sample_index), 0.0));
+			CHECK(rtm::vector_all_near_equal3(src_animated_bone.translation_track.get_sample(sample_index), file_animated_bone.translation_track.get_sample(sample_index), 0.0));
+			CHECK(rtm::vector_all_near_equal3(src_animated_bone.scale_track.get_sample(sample_index), file_animated_bone.scale_track.get_sample(sample_index), 0.0));
 		}
 	}
 #endif
@@ -303,7 +305,7 @@ TEST_CASE("sjson_clip_reader_writer", "[io]")
 TEST_CASE("sjson_track_list_reader_writer float1f", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint32_t num_tracks = 3;
@@ -415,7 +417,7 @@ TEST_CASE("sjson_track_list_reader_writer float1f", "[io]")
 TEST_CASE("sjson_track_list_reader_writer float2f", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint32_t num_tracks = 3;
@@ -527,7 +529,7 @@ TEST_CASE("sjson_track_list_reader_writer float2f", "[io]")
 TEST_CASE("sjson_track_list_reader_writer float3f", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint32_t num_tracks = 3;
@@ -639,7 +641,7 @@ TEST_CASE("sjson_track_list_reader_writer float3f", "[io]")
 TEST_CASE("sjson_track_list_reader_writer float4f", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint32_t num_tracks = 3;
@@ -751,7 +753,7 @@ TEST_CASE("sjson_track_list_reader_writer float4f", "[io]")
 TEST_CASE("sjson_track_list_reader_writer vector4f", "[io]")
 {
 	// Only test the reader/writer on non-mobile platforms
-#if defined(ACL_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
+#if defined(RTM_SSE2_INTRINSICS) && defined(ACL_USE_SJSON)
 	ANSIAllocator allocator;
 
 	const uint32_t num_tracks = 3;
diff --git a/tests/sources/math/test_affine_matrix.cpp b/tests/sources/math/test_affine_matrix.cpp
deleted file mode 100644
--- a/tests/sources/math/test_affine_matrix.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <catch.hpp>
-
-#include <acl/math/affine_matrix_32.h>
-#include <acl/math/affine_matrix_64.h>
-#include <acl/math/transform_32.h>
-#include <acl/math/transform_64.h>
-
-using namespace acl;
-
-template<typename MatrixType, typename TransformType, typename FloatType>
-static void test_affine_matrix_impl(const MatrixType& identity, const FloatType threshold)
-{
-	using QuatType = decltype(TransformType::rotation);
-	using Vector4Type = decltype(TransformType::translation);
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0), FloatType(0.0));
-		Vector4Type z_axis = vector_set(FloatType(7.0), FloatType(8.0), FloatType(9.0), FloatType(0.0));
-		Vector4Type w_axis = vector_set(FloatType(10.0), FloatType(11.0), FloatType(12.0), FloatType(1.0));
-		MatrixType mtx = matrix_set(x_axis, y_axis, z_axis, w_axis);
-		REQUIRE(vector_all_near_equal(x_axis, mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(y_axis, mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(z_axis, mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(w_axis, mtx.w_axis, threshold));
-	}
-
-	{
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), identity.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), identity.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), identity.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0)), identity.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type translation = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0));
-		MatrixType mtx = matrix_set(rotation_around_z, translation, vector_set(FloatType(1.0)));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(1.0)), mtx.w_axis, threshold));
-
-		Vector4Type scale = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0));
-		mtx = matrix_set(rotation_around_z, translation, scale);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(4.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(-5.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(6.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(1.0)), mtx.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		MatrixType mtx = matrix_from_quat(rotation_around_z);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0)), mtx.w_axis, threshold));
-	}
-
-	{
-		MatrixType mtx = matrix_from_translation(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0)));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(1.0)), mtx.w_axis, threshold));
-	}
-
-	{
-		MatrixType mtx = matrix_from_scale(vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0)));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(4.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(5.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(6.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0)), mtx.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type translation = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0));
-		Vector4Type scale = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0));
-		TransformType transform = transform_set(rotation_around_z, translation, scale);
-		MatrixType mtx = matrix_from_transform(transform);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(4.0), FloatType(0.0), FloatType(0.0)), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(-5.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(6.0), FloatType(0.0)), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(1.0)), mtx.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type translation = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0));
-		Vector4Type scale = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0));
-		MatrixType mtx = matrix_set(rotation_around_z, translation, scale);
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx, MatrixAxis::X), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx, MatrixAxis::Y), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx, MatrixAxis::Z), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx, MatrixAxis::W), mtx.w_axis, threshold));
-
-		const MatrixType mtx2 = mtx;
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx2, MatrixAxis::X), mtx2.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx2, MatrixAxis::Y), mtx2.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx2, MatrixAxis::Z), mtx2.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx2, MatrixAxis::W), mtx2.w_axis, threshold));
-
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx.x_axis, mtx.y_axis, mtx.z_axis, mtx.w_axis, MatrixAxis::X), mtx.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx.x_axis, mtx.y_axis, mtx.z_axis, mtx.w_axis, MatrixAxis::Y), mtx.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx.x_axis, mtx.y_axis, mtx.z_axis, mtx.w_axis, MatrixAxis::Z), mtx.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(matrix_get_axis(mtx.x_axis, mtx.y_axis, mtx.z_axis, mtx.w_axis, MatrixAxis::W), mtx.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		MatrixType mtx = matrix_from_quat(rotation_around_z);
-		QuatType rotation = quat_from_matrix(mtx);
-		REQUIRE(quat_near_equal(rotation_around_z, rotation, threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		MatrixType mtx_a = matrix_set(rotation_around_z, x_axis, vector_set(FloatType(1.0)));
-		Vector4Type result = matrix_mul_position(mtx_a, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = matrix_mul_position(mtx_a, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0)), threshold));
-
-		QuatType rotation_around_x = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)));
-		MatrixType mtx_b = matrix_set(rotation_around_x, y_axis, vector_set(FloatType(1.0)));
-		result = matrix_mul_position(mtx_b, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = matrix_mul_position(mtx_b, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(-1.0)), threshold));
-
-		MatrixType mtx_ab = matrix_mul(mtx_a, mtx_b);
-		MatrixType mtx_ba = matrix_mul(mtx_b, mtx_a);
-		result = matrix_mul_position(mtx_ab, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(-1.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, matrix_mul_position(mtx_b, matrix_mul_position(mtx_a, x_axis)), threshold));
-		result = matrix_mul_position(mtx_ab, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, matrix_mul_position(mtx_b, matrix_mul_position(mtx_a, y_axis)), threshold));
-		result = matrix_mul_position(mtx_ba, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, matrix_mul_position(mtx_a, matrix_mul_position(mtx_b, x_axis)), threshold));
-		result = matrix_mul_position(mtx_ba, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, matrix_mul_position(mtx_a, matrix_mul_position(mtx_b, y_axis)), threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0), FloatType(0.0));
-		Vector4Type z_axis = vector_set(FloatType(7.0), FloatType(8.0), FloatType(9.0), FloatType(0.0));
-		Vector4Type w_axis = vector_set(FloatType(10.0), FloatType(11.0), FloatType(12.0), FloatType(1.0));
-		MatrixType mtx0 = matrix_set(x_axis, y_axis, z_axis, w_axis);
-		MatrixType mtx1 = math_impl::matrix_transpose(mtx0);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(4.0), FloatType(7.0), FloatType(10.0)), mtx1.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(2.0), FloatType(5.0), FloatType(8.0), FloatType(11.0)), mtx1.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(3.0), FloatType(6.0), FloatType(9.0), FloatType(12.0)), mtx1.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0)), mtx1.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type translation = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0));
-		Vector4Type scale = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0));
-		MatrixType mtx = matrix_set(rotation_around_z, translation, scale);
-		MatrixType inv_mtx = matrix_inverse(mtx);
-		MatrixType result = matrix_mul(mtx, inv_mtx);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), result.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), result.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), result.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0)), result.w_axis, threshold));
-	}
-
-	{
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type translation = vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0));
-		Vector4Type scale = vector_set(FloatType(4.0), FloatType(5.0), FloatType(6.0));
-		MatrixType mtx0 = matrix_set(rotation_around_z, translation, scale);
-		MatrixType mtx0_no_scale = matrix_remove_scale(mtx0);
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0)), mtx0_no_scale.x_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0)), mtx0_no_scale.y_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0)), mtx0_no_scale.z_axis, threshold));
-		REQUIRE(vector_all_near_equal(vector_set(FloatType(1.0), FloatType(2.0), FloatType(3.0), FloatType(1.0)), mtx0_no_scale.w_axis, threshold));
-	}
-}
-
-TEST_CASE("affine matrix 32 math", "[math][affinematrix]")
-{
-	test_affine_matrix_impl<AffineMatrix_32, Transform_32, float>(matrix_identity_32(), 1.0E-4F);
-
-	{
-		Quat_32 rotation_around_z = quat_from_euler(deg2rad(0.0F), deg2rad(90.0F), deg2rad(0.0F));
-		Vector4_32 translation = vector_set(1.0F, 2.0F, 3.0F);
-		Vector4_32 scale = vector_set(4.0F, 5.0F, 6.0F);
-		AffineMatrix_32 src = matrix_set(rotation_around_z, translation, scale);
-		AffineMatrix_64 dst = matrix_cast(src);
-		REQUIRE(vector_all_near_equal(vector_cast(src.x_axis), dst.x_axis, 1.0E-4));
-		REQUIRE(vector_all_near_equal(vector_cast(src.y_axis), dst.y_axis, 1.0E-4));
-		REQUIRE(vector_all_near_equal(vector_cast(src.z_axis), dst.z_axis, 1.0E-4));
-		REQUIRE(vector_all_near_equal(vector_cast(src.w_axis), dst.w_axis, 1.0E-4));
-	}
-}
-
-TEST_CASE("affine matrix 64 math", "[math][affinematrix]")
-{
-	test_affine_matrix_impl<AffineMatrix_64, Transform_64, double>(matrix_identity_64(), 1.0E-4);
-
-	{
-		Quat_64 rotation_around_z = quat_from_euler(deg2rad(0.0), deg2rad(90.0), deg2rad(0.0));
-		Vector4_64 translation = vector_set(1.0, 2.0, 3.0);
-		Vector4_64 scale = vector_set(4.0, 5.0, 6.0);
-		AffineMatrix_64 src = matrix_set(rotation_around_z, translation, scale);
-		AffineMatrix_32 dst = matrix_cast(src);
-		REQUIRE(vector_all_near_equal(vector_cast(src.x_axis), dst.x_axis, 1.0E-4f));
-		REQUIRE(vector_all_near_equal(vector_cast(src.y_axis), dst.y_axis, 1.0E-4f));
-		REQUIRE(vector_all_near_equal(vector_cast(src.z_axis), dst.z_axis, 1.0E-4f));
-		REQUIRE(vector_all_near_equal(vector_cast(src.w_axis), dst.w_axis, 1.0E-4f));
-	}
-}
diff --git a/tests/sources/math/test_quat.cpp b/tests/sources/math/test_quat.cpp
deleted file mode 100644
--- a/tests/sources/math/test_quat.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <catch.hpp>
-
-#include <acl/math/quat_32.h>
-#include <acl/math/quat_64.h>
-#include <acl/math/vector4_32.h>
-#include <acl/math/vector4_64.h>
-
-#include <limits>
-
-using namespace acl;
-
-template<typename QuatType, typename Vector4Type, typename FloatType>
-static Vector4Type quat_rotate_scalar(const QuatType& rotation, const Vector4Type& vector)
-{
-	// (q.W*q.W-qv.qv)v + 2(qv.v)qv + 2 q.W (qv x v)
-	Vector4Type qv = vector_set(quat_get_x(rotation), quat_get_y(rotation), quat_get_z(rotation));
-	Vector4Type vOut = vector_mul(vector_cross3(qv, vector), FloatType(2.0) * quat_get_w(rotation));
-	vOut = vector_add(vOut, vector_mul(vector, (quat_get_w(rotation) * quat_get_w(rotation)) - vector_dot(qv, qv)));
-	vOut = vector_add(vOut, vector_mul(qv, FloatType(2.0) * vector_dot(qv, vector)));
-	return vOut;
-}
-
-template<typename QuatType, typename Vector4Type, typename FloatType>
-static QuatType quat_mul_scalar(const QuatType& lhs, const QuatType& rhs)
-{
-	FloatType lhs_raw[4] = { quat_get_x(lhs), quat_get_y(lhs), quat_get_z(lhs), quat_get_w(lhs) };
-	FloatType rhs_raw[4] = { quat_get_x(rhs), quat_get_y(rhs), quat_get_z(rhs), quat_get_w(rhs) };
-
-	FloatType x = (rhs_raw[3] * lhs_raw[0]) + (rhs_raw[0] * lhs_raw[3]) + (rhs_raw[1] * lhs_raw[2]) - (rhs_raw[2] * lhs_raw[1]);
-	FloatType y = (rhs_raw[3] * lhs_raw[1]) - (rhs_raw[0] * lhs_raw[2]) + (rhs_raw[1] * lhs_raw[3]) + (rhs_raw[2] * lhs_raw[0]);
-	FloatType z = (rhs_raw[3] * lhs_raw[2]) + (rhs_raw[0] * lhs_raw[1]) - (rhs_raw[1] * lhs_raw[0]) + (rhs_raw[2] * lhs_raw[3]);
-	FloatType w = (rhs_raw[3] * lhs_raw[3]) - (rhs_raw[0] * lhs_raw[0]) - (rhs_raw[1] * lhs_raw[1]) - (rhs_raw[2] * lhs_raw[2]);
-
-	return quat_set(x, y, z, w);
-}
-
-template<typename QuatType, typename FloatType>
-static FloatType scalar_dot(const QuatType& lhs, const QuatType& rhs)
-{
-	return (quat_get_x(lhs) * quat_get_x(rhs)) + (quat_get_y(lhs) * quat_get_y(rhs)) + (quat_get_z(lhs) * quat_get_z(rhs)) + (quat_get_w(lhs) * quat_get_w(rhs));
-}
-
-template<typename QuatType, typename FloatType>
-static QuatType scalar_normalize(const QuatType& input)
-{
-	FloatType inv_len = FloatType(1.0) / acl::sqrt(scalar_dot<QuatType, FloatType>(input, input));
-	return quat_set(quat_get_x(input) * inv_len, quat_get_y(input) * inv_len, quat_get_z(input) * inv_len, quat_get_w(input) * inv_len);
-}
-
-template<typename QuatType, typename FloatType>
-static QuatType scalar_lerp(const QuatType& start, const QuatType& end, FloatType alpha)
-{
-	FloatType dot = scalar_dot<QuatType, FloatType>(start, end);
-	FloatType bias = dot >= FloatType(0.0) ? FloatType(1.0) : FloatType(-1.0);
-	FloatType x = quat_get_x(start) + ((quat_get_x(end) * bias) - quat_get_x(start)) * alpha;
-	FloatType y = quat_get_y(start) + ((quat_get_y(end) * bias) - quat_get_y(start)) * alpha;
-	FloatType z = quat_get_z(start) + ((quat_get_z(end) * bias) - quat_get_z(start)) * alpha;
-	FloatType w = quat_get_w(start) + ((quat_get_w(end) * bias) - quat_get_w(start)) * alpha;
-	return quat_normalize(quat_set(x, y, z, w));
-}
-
-template<typename QuatType, typename Vector4Type, typename FloatType>
-static void test_quat_impl(const Vector4Type& zero, const QuatType& identity, const FloatType threshold)
-{
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	REQUIRE(quat_get_x(quat_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(0.0));
-	REQUIRE(quat_get_y(quat_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(2.34));
-	REQUIRE(quat_get_z(quat_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(-3.12));
-	REQUIRE(quat_get_w(quat_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(10000.0));
-
-	REQUIRE(quat_get_x(identity) == FloatType(0.0));
-	REQUIRE(quat_get_y(identity) == FloatType(0.0));
-	REQUIRE(quat_get_z(identity) == FloatType(0.0));
-	REQUIRE(quat_get_w(identity) == FloatType(1.0));
-
-	{
-		struct alignas(16) Tmp
-		{
-			uint8_t padding0[8];	//  8 |  8
-			FloatType values[4];	// 24 | 40
-			uint8_t padding1[8];	// 32 | 48
-		};
-
-		Tmp tmp = { { 0 }, { FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0) }, {} };
-		REQUIRE(quat_get_x(quat_unaligned_load(&tmp.values[0])) == tmp.values[0]);
-		REQUIRE(quat_get_y(quat_unaligned_load(&tmp.values[0])) == tmp.values[1]);
-		REQUIRE(quat_get_z(quat_unaligned_load(&tmp.values[0])) == tmp.values[2]);
-		REQUIRE(quat_get_w(quat_unaligned_load(&tmp.values[0])) == tmp.values[3]);
-	}
-
-	{
-		const Vector4Type vec = vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0));
-		REQUIRE(quat_get_x(vector_to_quat(vec)) == vector_get_x(vec));
-		REQUIRE(quat_get_y(vector_to_quat(vec)) == vector_get_y(vec));
-		REQUIRE(quat_get_z(vector_to_quat(vec)) == vector_get_z(vec));
-		REQUIRE(quat_get_w(vector_to_quat(vec)) == vector_get_w(vec));
-	}
-
-	{
-		struct alignas(16) Tmp
-		{
-			uint8_t padding0[8];	//  8 |  8
-			FloatType values[4];	// 24 | 40
-			uint8_t padding1[8];	// 32 | 48
-		};
-
-		Tmp tmp = { { 0 }, { FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0) }, {} };
-		quat_unaligned_write(quat_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), &tmp.values[0]);
-		REQUIRE(tmp.values[0] == FloatType(0.0));
-		REQUIRE(tmp.values[1] == FloatType(2.34));
-		REQUIRE(tmp.values[2] == FloatType(-3.12));
-		REQUIRE(tmp.values[3] == FloatType(10000.0));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	{
-		QuatType quat = quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0)));
-		QuatType quat_conj = quat_conjugate(quat);
-		REQUIRE(quat_get_x(quat_conj) == -quat_get_x(quat));
-		REQUIRE(quat_get_y(quat_conj) == -quat_get_y(quat));
-		REQUIRE(quat_get_z(quat_conj) == -quat_get_z(quat));
-		REQUIRE(quat_get_w(quat_conj) == quat_get_w(quat));
-	}
-
-	{
-		QuatType quat0 = quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0)));
-		QuatType quat1 = quat_from_euler(deg2rad(FloatType(45.0)), deg2rad(FloatType(60.0)), deg2rad(FloatType(120.0)));
-		QuatType result = quat_mul(quat0, quat1);
-		QuatType result_ref = quat_mul_scalar<QuatType, Vector4Type, FloatType>(quat0, quat1);
-		REQUIRE(quat_near_equal(result, result_ref, threshold));
-
-		quat0 = quat_set(FloatType(0.39564531008956383), FloatType(0.044254239301713752), FloatType(0.22768840967675355), FloatType(0.88863059760894492));
-		quat1 = quat_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0));
-		result = quat_mul(quat0, quat1);
-		result_ref = quat_mul_scalar<QuatType, Vector4Type, FloatType>(quat0, quat1);
-		REQUIRE(quat_near_equal(result, result_ref, threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type result = quat_rotate(rotation_around_z, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = quat_rotate(rotation_around_z, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0)), threshold));
-
-		QuatType rotation_around_x = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)));
-		result = quat_rotate(rotation_around_x, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0)), threshold));
-		result = quat_rotate(rotation_around_x, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0)), threshold));
-
-		QuatType rotation_xz = quat_mul(rotation_around_x, rotation_around_z);
-		QuatType rotation_zx = quat_mul(rotation_around_z, rotation_around_x);
-		result = quat_rotate(rotation_xz, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = quat_rotate(rotation_xz, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0)), threshold));
-		result = quat_rotate(rotation_zx, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0)), threshold));
-		result = quat_rotate(rotation_zx, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0)), threshold));
-	}
-
-	{
-		const QuatType test_rotations[] = {
-			identity,
-			quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0))),
-			quat_from_euler(deg2rad(FloatType(45.0)), deg2rad(FloatType(60.0)), deg2rad(FloatType(120.0))),
-			quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(180.0)), deg2rad(FloatType(45.0))),
-			quat_from_euler(deg2rad(FloatType(-120.0)), deg2rad(FloatType(-90.0)), deg2rad(FloatType(0.0))),
-			quat_from_euler(deg2rad(FloatType(-0.01)), deg2rad(FloatType(0.02)), deg2rad(FloatType(-0.03))),
-		};
-
-		const Vector4Type test_vectors[] = {
-			zero,
-			vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0)),
-			vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)),
-			vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0)),
-			vector_set(FloatType(45.0), FloatType(-60.0), FloatType(120.0)),
-			vector_set(FloatType(-45.0), FloatType(60.0), FloatType(-120.0)),
-			vector_set(FloatType(0.57735026918962576451), FloatType(0.57735026918962576451), FloatType(0.57735026918962576451)),
-			vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0)),
-		};
-
-		for (size_t quat_index = 0; quat_index < get_array_size(test_rotations); ++quat_index)
-		{
-			const QuatType& rotation = test_rotations[quat_index];
-			for (size_t vector_index = 0; vector_index < get_array_size(test_vectors); ++vector_index)
-			{
-				const Vector4Type& vector = test_vectors[vector_index];
-				Vector4Type result = quat_rotate(rotation, vector);
-				Vector4Type result_ref = quat_rotate_scalar<QuatType, Vector4Type, FloatType>(rotation, vector);
-				REQUIRE(vector_all_near_equal3(result, result_ref, threshold));
-			}
-		}
-	}
-
-	{
-		QuatType quat = quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0)));
-		Vector4Type vec = quat_to_vector(quat);
-
-		REQUIRE(scalar_near_equal(quat_length_squared(quat), vector_length_squared(vec), threshold));
-		REQUIRE(scalar_near_equal(quat_length(quat), vector_length(vec), threshold));
-		REQUIRE(scalar_near_equal(quat_length_reciprocal(quat), vector_length_reciprocal(vec), threshold));
-	}
-
-	{
-		QuatType quat = quat_set(FloatType(-0.001138), FloatType(0.91623), FloatType(-1.624598), FloatType(0.715671));
-		const QuatType scalar_normalize_result = scalar_normalize<QuatType, FloatType>(quat);
-		const QuatType quat_normalize_result = quat_normalize(quat);
-		REQUIRE(scalar_near_equal(quat_get_x(quat_normalize_result), quat_get_x(scalar_normalize_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_y(quat_normalize_result), quat_get_y(scalar_normalize_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_z(quat_normalize_result), quat_get_z(scalar_normalize_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_w(quat_normalize_result), quat_get_w(scalar_normalize_result), threshold));
-	}
-
-	{
-		QuatType quat0 = quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0)));
-		QuatType quat1 = quat_from_euler(deg2rad(FloatType(45.0)), deg2rad(FloatType(60.0)), deg2rad(FloatType(120.0)));
-
-		QuatType scalar_result = scalar_lerp<QuatType, FloatType>(quat0, quat1, FloatType(0.33));
-
-		REQUIRE(scalar_near_equal(quat_get_x(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_x(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_y(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_y(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_z(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_z(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_w(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_w(scalar_result), threshold));
-
-		quat1 = quat_neg(quat1);
-		REQUIRE(scalar_near_equal(quat_get_x(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_x(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_y(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_y(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_z(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_z(scalar_result), threshold));
-		REQUIRE(scalar_near_equal(quat_get_w(quat_lerp(quat0, quat1, FloatType(0.33))), quat_get_w(scalar_result), threshold));
-	}
-
-	{
-		QuatType quat0 = quat_from_euler(deg2rad(FloatType(30.0)), deg2rad(FloatType(-45.0)), deg2rad(FloatType(90.0)));
-		QuatType quat1 = quat_neg(quat0);
-
-		REQUIRE(quat_get_x(quat0) == -quat_get_x(quat1));
-		REQUIRE(quat_get_y(quat0) == -quat_get_y(quat1));
-		REQUIRE(quat_get_z(quat0) == -quat_get_z(quat1));
-		REQUIRE(quat_get_w(quat0) == -quat_get_w(quat1));
-	}
-
-	{
-		QuatType quat0 = quat_set(FloatType(0.39564531008956383), FloatType(0.044254239301713752), FloatType(0.22768840967675355), FloatType(-0.88863059760894492));
-		QuatType quat1 = quat_ensure_positive_w(quat0);
-		QuatType quat2 = quat_ensure_positive_w(quat1);
-
-		REQUIRE(quat_get_x(quat0) == -quat_get_x(quat1));
-		REQUIRE(quat_get_y(quat0) == -quat_get_y(quat1));
-		REQUIRE(quat_get_z(quat0) == -quat_get_z(quat1));
-		REQUIRE(quat_get_w(quat0) == -quat_get_w(quat1));
-
-		REQUIRE(quat_get_x(quat2) == quat_get_x(quat1));
-		REQUIRE(quat_get_y(quat2) == quat_get_y(quat1));
-		REQUIRE(quat_get_z(quat2) == quat_get_z(quat1));
-		REQUIRE(quat_get_w(quat2) == quat_get_w(quat1));
-
-		Vector4Type vec1 = quat_to_vector(quat1);
-		QuatType quat3 = quat_from_positive_w(vec1);
-		REQUIRE(quat_get_x(quat1) == quat_get_x(quat3));
-		REQUIRE(quat_get_y(quat1) == quat_get_y(quat3));
-		REQUIRE(quat_get_z(quat1) == quat_get_z(quat3));
-		REQUIRE(scalar_near_equal(quat_get_w(quat1), quat_get_w(quat3), threshold));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Conversion to/from axis/angle/euler
-
-	{
-		QuatType rotation = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type axis;
-		FloatType angle;
-		quat_to_axis_angle(rotation, axis, angle);
-		REQUIRE(vector_all_near_equal3(axis, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0)), threshold));
-		REQUIRE(vector_all_near_equal3(quat_get_axis(rotation), vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0)), threshold));
-		REQUIRE(scalar_near_equal(quat_get_angle(rotation), deg2rad(FloatType(90.0)), threshold));
-	}
-
-	{
-		QuatType rotation = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		Vector4Type axis;
-		FloatType angle;
-		quat_to_axis_angle(rotation, axis, angle);
-		QuatType rotation_new = quat_from_axis_angle(axis, angle);
-		REQUIRE(quat_near_equal(rotation, rotation_new, threshold));
-	}
-
-	{
-		QuatType rotation = quat_set(FloatType(0.39564531008956383), FloatType(0.044254239301713752), FloatType(0.22768840967675355), FloatType(0.88863059760894492));
-		Vector4Type axis_ref = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		axis_ref = quat_rotate(rotation, axis_ref);
-		FloatType angle_ref = deg2rad(FloatType(57.0));
-		QuatType result = quat_from_axis_angle(axis_ref, angle_ref);
-		Vector4Type axis;
-		FloatType angle;
-		quat_to_axis_angle(result, axis, angle);
-		REQUIRE(vector_all_near_equal3(axis, axis_ref, threshold));
-		REQUIRE(scalar_near_equal(angle, angle_ref, threshold));
-	}
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	{
-		const FloatType inf = std::numeric_limits<FloatType>::infinity();
-		const FloatType nan = std::numeric_limits<FloatType>::quiet_NaN();
-		REQUIRE(quat_is_finite(identity) == true);
-		REQUIRE(quat_is_finite(quat_set(inf, inf, inf, inf)) == false);
-		REQUIRE(quat_is_finite(quat_set(inf, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(inf), FloatType(1.0), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(1.0), FloatType(inf), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(inf))) == false);
-		REQUIRE(quat_is_finite(quat_set(nan, nan, nan, nan)) == false);
-		REQUIRE(quat_is_finite(quat_set(nan, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(nan), FloatType(1.0), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(1.0), FloatType(nan), FloatType(1.0))) == false);
-		REQUIRE(quat_is_finite(quat_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(nan))) == false);
-	}
-
-	{
-		QuatType quat0 = quat_set(FloatType(0.39564531008956383), FloatType(0.044254239301713752), FloatType(0.22768840967675355), FloatType(0.88863059760894492));
-		FloatType quat_len = quat_length(quat0);
-		REQUIRE(scalar_near_equal(quat_len, FloatType(1.0), threshold));
-		REQUIRE(quat_is_normalized(quat0) == true);
-
-		QuatType quat1 = vector_to_quat(vector_mul(quat_to_vector(quat0), FloatType(1.1)));
-		REQUIRE(quat_is_normalized(quat1) == false);
-	}
-
-	{
-		REQUIRE(quat_near_equal(identity, identity, threshold) == true);
-		REQUIRE(quat_near_equal(identity, quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(2.0)), FloatType(1.0001)) == true);
-		REQUIRE(quat_near_equal(identity, quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(2.0)), FloatType(1.0)) == true);
-		REQUIRE(quat_near_equal(identity, quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(2.0)), FloatType(0.9999)) == false);
-	}
-
-	{
-		REQUIRE(quat_near_identity(identity, threshold) == true);
-		REQUIRE(quat_near_identity(quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(0.9999999)), FloatType(0.001)) == true);
-		REQUIRE(quat_near_identity(quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(0.98)), FloatType(0.001)) == false);
-	}
-}
-
-TEST_CASE("quat 32 math", "[math][quat]")
-{
-	test_quat_impl<Quat_32, Vector4_32, float>(vector_zero_32(), quat_identity_32(), 1.0E-4F);
-
-	const Quat_32 src = quat_set(0.39564531008956383F, 0.044254239301713752F, 0.22768840967675355F, 0.88863059760894492F);
-	const Quat_64 dst = quat_cast(src);
-	REQUIRE(scalar_near_equal(quat_get_x(dst), 0.39564531008956383, 1.0E-6));
-	REQUIRE(scalar_near_equal(quat_get_y(dst), 0.044254239301713752, 1.0E-6));
-	REQUIRE(scalar_near_equal(quat_get_z(dst), 0.22768840967675355, 1.0E-6));
-	REQUIRE(scalar_near_equal(quat_get_w(dst), 0.88863059760894492, 1.0E-6));
-}
-
-TEST_CASE("quat 64 math", "[math][quat]")
-{
-	test_quat_impl<Quat_64, Vector4_64, double>(vector_zero_64(), quat_identity_64(), 1.0E-6);
-
-	const Quat_64 src = quat_set(0.39564531008956383, 0.044254239301713752, 0.22768840967675355, 0.88863059760894492);
-	const Quat_32 dst = quat_cast(src);
-	REQUIRE(scalar_near_equal(quat_get_x(dst), 0.39564531008956383f, 1.0E-6F));
-	REQUIRE(scalar_near_equal(quat_get_y(dst), 0.044254239301713752f, 1.0E-6F));
-	REQUIRE(scalar_near_equal(quat_get_z(dst), 0.22768840967675355f, 1.0E-6F));
-	REQUIRE(scalar_near_equal(quat_get_w(dst), 0.88863059760894492f, 1.0E-6F));
-}
diff --git a/tests/sources/math/test_quat_packing.cpp b/tests/sources/math/test_quat_packing.cpp
--- a/tests/sources/math/test_quat_packing.cpp
+++ b/tests/sources/math/test_quat_packing.cpp
@@ -27,6 +27,7 @@
 #include <acl/math/quat_packing.h>
 
 using namespace acl;
+using namespace rtm;
 
 TEST_CASE("quat packing math", "[math][quat][packing]")
 {
@@ -38,12 +39,12 @@ TEST_CASE("quat packing math", "[math][quat][packing]")
 	};
 	static_assert((offsetof(UnalignedBuffer, buffer) % 2) == 0, "Minimum packing alignment is 2");
 
-	const Quat_32 quat0 = quat_set(0.39564531008956383F, 0.044254239301713752F, 0.22768840967675355F, 0.88863059760894492F);
+	const quatf quat0 = quat_set(0.39564531008956383F, 0.044254239301713752F, 0.22768840967675355F, 0.88863059760894492F);
 
 	{
 		UnalignedBuffer tmp0;
 		pack_quat_128(quat0, &tmp0.buffer[0]);
-		Quat_32 quat1 = unpack_quat_128(&tmp0.buffer[0]);
+		quatf quat1 = unpack_quat_128(&tmp0.buffer[0]);
 		REQUIRE(quat_get_x(quat0) == quat_get_x(quat1));
 		REQUIRE(quat_get_y(quat0) == quat_get_y(quat1));
 		REQUIRE(quat_get_z(quat0) == quat_get_z(quat1));
@@ -53,7 +54,7 @@ TEST_CASE("quat packing math", "[math][quat][packing]")
 	{
 		UnalignedBuffer tmp0;
 		pack_quat_96(quat0, &tmp0.buffer[0]);
-		Quat_32 quat1 = unpack_quat_96_unsafe(&tmp0.buffer[0]);
+		quatf quat1 = unpack_quat_96_unsafe(&tmp0.buffer[0]);
 		REQUIRE(quat_get_x(quat0) == quat_get_x(quat1));
 		REQUIRE(quat_get_y(quat0) == quat_get_y(quat1));
 		REQUIRE(quat_get_z(quat0) == quat_get_z(quat1));
@@ -63,7 +64,7 @@ TEST_CASE("quat packing math", "[math][quat][packing]")
 	{
 		UnalignedBuffer tmp0;
 		pack_quat_48(quat0, &tmp0.buffer[0]);
-		Quat_32 quat1 = unpack_quat_48(&tmp0.buffer[0]);
+		quatf quat1 = unpack_quat_48(&tmp0.buffer[0]);
 		REQUIRE(scalar_near_equal(quat_get_x(quat0), quat_get_x(quat1), 1.0E-4F));
 		REQUIRE(scalar_near_equal(quat_get_y(quat0), quat_get_y(quat1), 1.0E-4F));
 		REQUIRE(scalar_near_equal(quat_get_z(quat0), quat_get_z(quat1), 1.0E-4F));
@@ -73,7 +74,7 @@ TEST_CASE("quat packing math", "[math][quat][packing]")
 	{
 		UnalignedBuffer tmp0;
 		pack_quat_32(quat0, &tmp0.buffer[0]);
-		Quat_32 quat1 = unpack_quat_32(&tmp0.buffer[0]);
+		quatf quat1 = unpack_quat_32(&tmp0.buffer[0]);
 		REQUIRE(scalar_near_equal(quat_get_x(quat0), quat_get_x(quat1), 1.0E-3F));
 		REQUIRE(scalar_near_equal(quat_get_y(quat0), quat_get_y(quat1), 1.0E-3F));
 		REQUIRE(scalar_near_equal(quat_get_z(quat0), quat_get_z(quat1), 1.0E-3F));
diff --git a/tests/sources/math/test_scalar.cpp b/tests/sources/math/test_scalar.cpp
deleted file mode 100644
--- a/tests/sources/math/test_scalar.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <catch.hpp>
-
-#include <acl/math/scalar_32.h>
-#include <acl/math/scalar_64.h>
-
-#include <limits>
-
-using namespace acl;
-
-template<typename FloatType>
-static void test_scalar_impl(const FloatType pi, const FloatType threshold)
-{
-	const FloatType half_pi = pi * FloatType(0.5);
-	const FloatType two_pi = pi * FloatType(2.0);
-
-	REQUIRE(acl::floor(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(acl::floor(FloatType(0.5)) == FloatType(0.0));
-	REQUIRE(acl::floor(FloatType(2.5)) == FloatType(2.0));
-	REQUIRE(acl::floor(FloatType(3.0)) == FloatType(3.0));
-	REQUIRE(acl::floor(FloatType(-0.5)) == FloatType(-1.0));
-	REQUIRE(acl::floor(FloatType(-2.5)) == FloatType(-3.0));
-	REQUIRE(acl::floor(FloatType(-3.0)) == FloatType(-3.0));
-
-	REQUIRE(acl::ceil(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(acl::ceil(FloatType(0.5)) == FloatType(1.0));
-	REQUIRE(acl::ceil(FloatType(2.5)) == FloatType(3.0));
-	REQUIRE(acl::ceil(FloatType(3.0)) == FloatType(3.0));
-	REQUIRE(acl::ceil(FloatType(-0.5)) == FloatType(0.0));
-	REQUIRE(acl::ceil(FloatType(-2.5)) == FloatType(-2.0));
-	REQUIRE(acl::ceil(FloatType(-3.0)) == FloatType(-3.0));
-
-	REQUIRE(clamp(FloatType(0.5), FloatType(0.0), FloatType(1.0)) == FloatType(0.5));
-	REQUIRE(clamp(FloatType(-0.5), FloatType(0.0), FloatType(1.0)) == FloatType(0.0));
-	REQUIRE(clamp(FloatType(1.5), FloatType(0.0), FloatType(1.0)) == FloatType(1.0));
-
-	REQUIRE(acl::abs(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(acl::abs(FloatType(2.0)) == FloatType(2.0));
-	REQUIRE(acl::abs(FloatType(-2.0)) == FloatType(2.0));
-
-	REQUIRE(scalar_near_equal(FloatType(1.0), FloatType(1.0), FloatType(0.00001)) == true);
-	REQUIRE(scalar_near_equal(FloatType(1.0), FloatType(1.000001), FloatType(0.00001)) == true);
-	REQUIRE(scalar_near_equal(FloatType(1.0), FloatType(0.999999), FloatType(0.00001)) == true);
-	REQUIRE(scalar_near_equal(FloatType(1.0), FloatType(1.001), FloatType(0.00001)) == false);
-	REQUIRE(scalar_near_equal(FloatType(1.0), FloatType(0.999), FloatType(0.00001)) == false);
-
-	REQUIRE(acl::sqrt(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(scalar_near_equal(acl::sqrt(FloatType(0.5)), std::sqrt(FloatType(0.5)), threshold));
-	REQUIRE(scalar_near_equal(acl::sqrt(FloatType(32.5)), std::sqrt(FloatType(32.5)), threshold));
-
-	REQUIRE(scalar_near_equal(acl::sqrt_reciprocal(FloatType(0.5)), FloatType(1.0) / std::sqrt(FloatType(0.5)), threshold));
-	REQUIRE(scalar_near_equal(acl::sqrt_reciprocal(FloatType(32.5)), FloatType(1.0) / std::sqrt(FloatType(32.5)), threshold));
-
-	REQUIRE(scalar_near_equal(acl::reciprocal(FloatType(0.5)), FloatType(1.0 / 0.5), threshold));
-	REQUIRE(scalar_near_equal(acl::reciprocal(FloatType(32.5)), FloatType(1.0 / 32.5), threshold));
-	REQUIRE(scalar_near_equal(acl::reciprocal(FloatType(-0.5)), FloatType(1.0 / -0.5), threshold));
-	REQUIRE(scalar_near_equal(acl::reciprocal(FloatType(-32.5)), FloatType(1.0 / -32.5), threshold));
-
-	const FloatType angles[] = { FloatType(0.0), pi, -pi, half_pi, -half_pi, FloatType(0.5), FloatType(32.5), FloatType(-0.5), FloatType(-32.5) };
-
-	for (const FloatType angle : angles)
-	{
-		REQUIRE(scalar_near_equal(acl::sin(angle), std::sin(angle), threshold));
-		REQUIRE(scalar_near_equal(acl::cos(angle), std::cos(angle), threshold));
-
-		FloatType sin_result;
-		FloatType cos_result;
-		acl::sincos(angle, sin_result, cos_result);
-		REQUIRE(scalar_near_equal(sin_result, std::sin(angle), threshold));
-		REQUIRE(scalar_near_equal(cos_result, std::cos(angle), threshold));
-	}
-
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(-1.0)), std::acos(FloatType(-1.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(-0.75)), std::acos(FloatType(-0.75)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(-0.5)), std::acos(FloatType(-0.5)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(-0.25)), std::acos(-FloatType(0.25)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(0.0)), std::acos(FloatType(0.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(0.25)), std::acos(FloatType(0.25)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(0.5)), std::acos(FloatType(0.5)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(0.75)), std::acos(FloatType(0.75)), threshold));
-	REQUIRE(scalar_near_equal(acl::acos(FloatType(1.0)), std::acos(FloatType(1.0)), threshold));
-
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(-2.0), FloatType(-2.0)), std::atan2(FloatType(-2.0), FloatType(-2.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(-1.0), FloatType(-2.0)), std::atan2(FloatType(-1.0), FloatType(-2.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(-2.0), FloatType(-1.0)), std::atan2(FloatType(-2.0), FloatType(-1.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(2.0), FloatType(2.0)), std::atan2(FloatType(2.0), FloatType(2.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(1.0), FloatType(2.0)), std::atan2(FloatType(1.0), FloatType(2.0)), threshold));
-	REQUIRE(scalar_near_equal(acl::atan2(FloatType(2.0), FloatType(1.0)), std::atan2(FloatType(2.0), FloatType(1.0)), threshold));
-
-	REQUIRE(acl::min(FloatType(-0.5), FloatType(1.0)) == FloatType(-0.5));
-	REQUIRE(acl::min(FloatType(1.0), FloatType(-0.5)) == FloatType(-0.5));
-	REQUIRE(acl::min(FloatType(1.0), FloatType(1.0)) == FloatType(1.0));
-
-	REQUIRE(acl::max(FloatType(-0.5), FloatType(1.0)) == FloatType(1.0));
-	REQUIRE(acl::max(FloatType(1.0), FloatType(-0.5)) == FloatType(1.0));
-	REQUIRE(acl::max(FloatType(1.0), FloatType(1.0)) == FloatType(1.0));
-
-	REQUIRE(deg2rad(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(90.0)), half_pi, threshold));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(-90.0)), -half_pi, threshold));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(180.0)), pi, threshold));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(-180.0)), -pi, threshold));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(360.0)), two_pi, threshold));
-	REQUIRE(scalar_near_equal(deg2rad(FloatType(-360.0)), -two_pi, threshold));
-
-	REQUIRE(acl::is_finite(FloatType(0.0)) == true);
-	REQUIRE(acl::is_finite(FloatType(32.0)) == true);
-	REQUIRE(acl::is_finite(FloatType(-32.0)) == true);
-	REQUIRE(acl::is_finite(std::numeric_limits<FloatType>::infinity()) == false);
-	REQUIRE(acl::is_finite(std::numeric_limits<FloatType>::quiet_NaN()) == false);
-	REQUIRE(acl::is_finite(std::numeric_limits<FloatType>::signaling_NaN()) == false);
-
-	REQUIRE(symmetric_round(FloatType(-1.75)) == FloatType(-2.0));
-	REQUIRE(symmetric_round(FloatType(-1.5)) == FloatType(-2.0));
-	REQUIRE(symmetric_round(FloatType(-1.4999)) == FloatType(-1.0));
-	REQUIRE(symmetric_round(FloatType(-0.5)) == FloatType(-1.0));
-	REQUIRE(symmetric_round(FloatType(-0.4999)) == FloatType(0.0));
-	REQUIRE(symmetric_round(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(symmetric_round(FloatType(0.4999)) == FloatType(0.0));
-	REQUIRE(symmetric_round(FloatType(0.5)) == FloatType(1.0));
-	REQUIRE(symmetric_round(FloatType(1.4999)) == FloatType(1.0));
-	REQUIRE(symmetric_round(FloatType(1.5)) == FloatType(2.0));
-	REQUIRE(symmetric_round(FloatType(1.75)) == FloatType(2.0));
-
-	REQUIRE(fraction(FloatType(0.0)) == FloatType(0.0));
-	REQUIRE(fraction(FloatType(1.0)) == FloatType(0.0));
-	REQUIRE(fraction(FloatType(-1.0)) == FloatType(0.0));
-	REQUIRE(scalar_near_equal(fraction(FloatType(0.25)), FloatType(0.25), threshold));
-	REQUIRE(scalar_near_equal(fraction(FloatType(0.5)), FloatType(0.5), threshold));
-	REQUIRE(scalar_near_equal(fraction(FloatType(0.75)), FloatType(0.75), threshold));
-}
-
-TEST_CASE("scalar 32 math", "[math][scalar]")
-{
-	test_scalar_impl<float>(acl::k_pi_32, 1.0E-6F);
-}
-
-TEST_CASE("scalar 64 math", "[math][scalar]")
-{
-	test_scalar_impl<double>(acl::k_pi_64, 1.0E-9);
-}
diff --git a/tests/sources/math/test_scalar_packing.cpp b/tests/sources/math/test_scalar_packing.cpp
--- a/tests/sources/math/test_scalar_packing.cpp
+++ b/tests/sources/math/test_scalar_packing.cpp
@@ -45,7 +45,7 @@ TEST_CASE("scalar packing math", "[math][scalar][packing]")
 		CHECK(pack_scalar_signed(-1.0F, num_bits) == 0);
 		CHECK(pack_scalar_signed(1.0F, num_bits) == max_value);
 		CHECK(unpack_scalar_signed(0, num_bits) == -1.0F);
-		CHECK(scalar_near_equal(unpack_scalar_signed(max_value, num_bits), 1.0F, threshold));
+		CHECK(rtm::scalar_near_equal(unpack_scalar_signed(max_value, num_bits), 1.0F, threshold));
 
 		uint32_t num_errors = 0;
 		for (uint32_t value = 0; value < max_value; ++value)
diff --git a/tests/sources/math/test_transform.cpp b/tests/sources/math/test_transform.cpp
deleted file mode 100644
--- a/tests/sources/math/test_transform.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <catch.hpp>
-
-#include <acl/math/transform_32.h>
-#include <acl/math/transform_64.h>
-
-using namespace acl;
-
-template<typename TransformType, typename FloatType>
-static void test_transform_impl(const TransformType& identity, const FloatType threshold)
-{
-	using QuatType = decltype(TransformType::rotation);
-	using Vector4Type = decltype(TransformType::translation);
-
-	{
-		Vector4Type zero = vector_set(FloatType(0.0));
-		Vector4Type one = vector_set(FloatType(1.0));
-		QuatType q_identity = quat_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0));
-		TransformType tmp = transform_set(q_identity, zero, one);
-		REQUIRE(quat_near_equal(identity.rotation, tmp.rotation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.translation, tmp.translation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.scale, tmp.scale, threshold));
-		REQUIRE(quat_near_equal(q_identity, tmp.rotation, threshold));
-		REQUIRE(vector_all_near_equal3(zero, tmp.translation, threshold));
-		REQUIRE(vector_all_near_equal3(one, tmp.scale, threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0));
-		Vector4Type test_scale = vector_set(FloatType(1.2));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		TransformType transform_a = transform_set(rotation_around_z, x_axis, test_scale);
-		Vector4Type result = transform_position(transform_a, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.2), FloatType(0.0)), threshold));
-		result = transform_position(transform_a, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-0.2), FloatType(0.0), FloatType(0.0)), threshold));
-
-		QuatType rotation_around_x = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)));
-		TransformType transform_b = transform_set(rotation_around_x, y_axis, test_scale);
-		result = transform_position(transform_b, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.2), FloatType(1.0), FloatType(0.0)), threshold));
-		result = transform_position(transform_b, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(-1.2)), threshold));
-
-		TransformType transform_ab = transform_mul(transform_a, transform_b);
-		TransformType transform_ba = transform_mul(transform_b, transform_a);
-		result = transform_position(transform_ab, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.2), FloatType(1.0), FloatType(-1.44)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position(transform_b, transform_position(transform_a, x_axis)), threshold));
-		result = transform_position(transform_ab, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-0.24), FloatType(1.0), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position(transform_b, transform_position(transform_a, y_axis)), threshold));
-		result = transform_position(transform_ba, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-0.2), FloatType(1.44), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position(transform_a, transform_position(transform_b, x_axis)), threshold));
-		result = transform_position(transform_ba, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(-0.2), FloatType(0.0), FloatType(-1.44)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position(transform_a, transform_position(transform_b, y_axis)), threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		Vector4Type y_axis = vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		TransformType transform_a = transform_set(rotation_around_z, x_axis, vector_set(FloatType(1.0)));
-		Vector4Type result = transform_position_no_scale(transform_a, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = transform_position_no_scale(transform_a, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0)), threshold));
-
-		QuatType rotation_around_x = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)));
-		TransformType transform_b = transform_set(rotation_around_x, y_axis, vector_set(FloatType(1.0)));
-		result = transform_position_no_scale(transform_b, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(0.0)), threshold));
-		result = transform_position_no_scale(transform_b, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(-1.0)), threshold));
-
-		TransformType transform_ab = transform_mul_no_scale(transform_a, transform_b);
-		TransformType transform_ba = transform_mul_no_scale(transform_b, transform_a);
-		result = transform_position_no_scale(transform_ab, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(1.0), FloatType(1.0), FloatType(-1.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position_no_scale(transform_b, transform_position_no_scale(transform_a, x_axis)), threshold));
-		result = transform_position_no_scale(transform_ab, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position_no_scale(transform_b, transform_position_no_scale(transform_a, y_axis)), threshold));
-		result = transform_position_no_scale(transform_ba, x_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position_no_scale(transform_a, transform_position_no_scale(transform_b, x_axis)), threshold));
-		result = transform_position_no_scale(transform_ba, y_axis);
-		REQUIRE(vector_all_near_equal3(result, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0)), threshold));
-		REQUIRE(vector_all_near_equal3(result, transform_position_no_scale(transform_a, transform_position_no_scale(transform_b, y_axis)), threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		Vector4Type test_scale = vector_set(FloatType(1.2));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		TransformType transform_a = transform_set(rotation_around_z, x_axis, test_scale);
-		TransformType transform_b = transform_inverse(transform_a);
-		TransformType transform_ab = transform_mul(transform_a, transform_b);
-		REQUIRE(quat_near_equal(identity.rotation, transform_ab.rotation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.translation, transform_ab.translation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.scale, transform_ab.scale, threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		TransformType transform_a = transform_set(rotation_around_z, x_axis, vector_set(FloatType(1.0)));
-		TransformType transform_b = transform_inverse_no_scale(transform_a);
-		TransformType transform_ab = transform_mul_no_scale(transform_a, transform_b);
-		REQUIRE(quat_near_equal(identity.rotation, transform_ab.rotation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.translation, transform_ab.translation, threshold));
-		REQUIRE(vector_all_near_equal3(identity.scale, transform_ab.scale, threshold));
-	}
-
-	{
-		Vector4Type x_axis = vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0));
-		QuatType rotation_around_z = quat_from_euler(deg2rad(FloatType(0.0)), deg2rad(FloatType(90.0)), deg2rad(FloatType(0.0)));
-		TransformType transform_a = transform_set(rotation_around_z, x_axis, vector_set(FloatType(1.0)));
-		REQUIRE(quat_is_normalized(transform_normalize(transform_a).rotation, threshold));
-
-		QuatType quat = quat_set(FloatType(-0.001138), FloatType(0.91623), FloatType(-1.624598), FloatType(0.715671));
-		TransformType transform_b = transform_set(quat, x_axis, vector_set(FloatType(1.0)));
-		REQUIRE(!quat_is_normalized(transform_b.rotation, threshold));
-		REQUIRE(quat_is_normalized(transform_normalize(transform_b).rotation, threshold));
-	}
-}
-
-TEST_CASE("transform 32 math", "[math][transform]")
-{
-	test_transform_impl<Transform_32, float>(transform_identity_32(), 1.0E-4F);
-
-	const Quat_32 src_rotation = quat_set(0.39564531008956383F, 0.044254239301713752F, 0.22768840967675355F, 0.88863059760894492F);
-	const Vector4_32 src_translation = vector_set(-2.65F, 2.996113F, 0.68123521F);
-	const Vector4_32 src_scale = vector_set(1.2F, 0.8F, 2.1F);
-	const Transform_32 src = transform_set(src_rotation, src_translation, src_scale);
-	const Transform_64 dst = transform_cast(src);
-	REQUIRE(quat_near_equal(src.rotation, quat_cast(dst.rotation), 1.0E-6F));
-	REQUIRE(vector_all_near_equal3(src.translation, vector_cast(dst.translation), 1.0E-6F));
-	REQUIRE(vector_all_near_equal3(src.scale, vector_cast(dst.scale), 1.0E-6F));
-}
-
-TEST_CASE("transform 64 math", "[math][transform]")
-{
-	test_transform_impl<Transform_64, double>(transform_identity_64(), 1.0E-6);
-
-	const Quat_64 src_rotation = quat_set(0.39564531008956383, 0.044254239301713752, 0.22768840967675355, 0.88863059760894492);
-	const Vector4_64 src_translation = vector_set(-2.65, 2.996113, 0.68123521);
-	const Vector4_64 src_scale = vector_set(1.2, 0.8, 2.1);
-	const Transform_64 src = transform_set(src_rotation, src_translation, src_scale);
-	const Transform_32 dst = transform_cast(src);
-	REQUIRE(quat_near_equal(src.rotation, quat_cast(dst.rotation), 1.0E-6));
-	REQUIRE(vector_all_near_equal3(src.translation, vector_cast(dst.translation), 1.0E-6));
-	REQUIRE(vector_all_near_equal3(src.scale, vector_cast(dst.scale), 1.0E-6));
-}
diff --git a/tests/sources/math/test_vector4_32.cpp b/tests/sources/math/test_vector4_32.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 32 math", "[math][vector4]")
-{
-#if defined(ACL_NO_INTRINSICS)
-	const float threshold = 1.0E-4F;
-#else
-	const float threshold = 1.0E-5F;
-#endif
-
-	test_vector4_impl<Vector4_32, Quat_32, float>(vector_zero_32(), quat_identity_32(), threshold);
-
-	const Vector4_32 src = vector_set(-2.65F, 2.996113F, 0.68123521F, -5.9182F);
-	const Vector4_64 dst = vector_cast(src);
-	REQUIRE(scalar_near_equal(vector_get_x(dst), -2.65, 1.0E-6));
-	REQUIRE(scalar_near_equal(vector_get_y(dst), 2.996113, 1.0E-6));
-	REQUIRE(scalar_near_equal(vector_get_z(dst), 0.68123521, 1.0E-6));
-	REQUIRE(scalar_near_equal(vector_get_w(dst), -5.9182, 1.0E-6));
-}
diff --git a/tests/sources/math/test_vector4_32_mix_a.cpp b/tests/sources/math/test_vector4_32_mix_a.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_a.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<A * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::A>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_b.cpp b/tests/sources/math/test_vector4_32_mix_b.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_b.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<B * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::B>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_c.cpp b/tests/sources/math/test_vector4_32_mix_c.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_c.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<C * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::C>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_d.cpp b/tests/sources/math/test_vector4_32_mix_d.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_d.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<D * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::D>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_w.cpp b/tests/sources/math/test_vector4_32_mix_w.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_w.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<W * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::W>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_x.cpp b/tests/sources/math/test_vector4_32_mix_x.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_x.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<X * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::X>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_y.cpp b/tests/sources/math/test_vector4_32_mix_y.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_y.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<Y * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::Y>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_32_mix_z.cpp b/tests/sources/math/test_vector4_32_mix_z.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_32_mix_z.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("Vector4_32 vector_mix<Z * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_32, float, VectorMix::Z>(1.0E-6F);
-}
diff --git a/tests/sources/math/test_vector4_64.cpp b/tests/sources/math/test_vector4_64.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 math", "[math][vector4]")
-{
-	test_vector4_impl<Vector4_64, Quat_64, double>(vector_zero_64(), quat_identity_64(), 1.0E-9);
-
-	const Vector4_64 src = vector_set(-2.65, 2.996113, 0.68123521, -5.9182);
-	const Vector4_32 dst = vector_cast(src);
-	REQUIRE(scalar_near_equal(vector_get_x(dst), -2.65F, 1.0E-6F));
-	REQUIRE(scalar_near_equal(vector_get_y(dst), 2.996113F, 1.0E-6F));
-	REQUIRE(scalar_near_equal(vector_get_z(dst), 0.68123521F, 1.0E-6F));
-	REQUIRE(scalar_near_equal(vector_get_w(dst), -5.9182F, 1.0E-6F));
-}
diff --git a/tests/sources/math/test_vector4_64_mix_a.cpp b/tests/sources/math/test_vector4_64_mix_a.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_a.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<A * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::A>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_b.cpp b/tests/sources/math/test_vector4_64_mix_b.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_b.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<B * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::B>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_c.cpp b/tests/sources/math/test_vector4_64_mix_c.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_c.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<C * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::C>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_d.cpp b/tests/sources/math/test_vector4_64_mix_d.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_d.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<D * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::D>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_w.cpp b/tests/sources/math/test_vector4_64_mix_w.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_w.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<W * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::W>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_x.cpp b/tests/sources/math/test_vector4_64_mix_x.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_x.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<X * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::X>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_y.cpp b/tests/sources/math/test_vector4_64_mix_y.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_y.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<Y * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::Y>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_64_mix_z.cpp b/tests/sources/math/test_vector4_64_mix_z.cpp
deleted file mode 100644
--- a/tests/sources/math/test_vector4_64_mix_z.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include "test_vector4_impl.h"
-
-TEST_CASE("vector4 64 vector_mix<Z * * *>", "[math][vector4]")
-{
-	test_vector4_vector_mix_impl<Vector4_64, double, VectorMix::Z>(1.0E-9);
-}
diff --git a/tests/sources/math/test_vector4_impl.h b/tests/sources/math/test_vector4_impl.h
deleted file mode 100644
--- a/tests/sources/math/test_vector4_impl.h
+++ /dev/null
@@ -1,659 +0,0 @@
-#pragma once
-
-////////////////////////////////////////////////////////////////////////////////
-// The MIT License (MIT)
-//
-// Copyright (c) 2018 Nicholas Frechette & Animation Compression Library contributors
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <catch.hpp>
-
-#include <acl/math/vector4_32.h>
-#include <acl/math/vector4_64.h>
-#include <acl/math/quat_32.h>
-#include <acl/math/quat_64.h>
-
-#include <cstring>
-#include <limits>
-
-using namespace acl;
-
-template<typename Vector4Type>
-inline Vector4Type vector_unaligned_load_raw(const uint8_t* input);
-
-template<>
-inline Vector4_32 vector_unaligned_load_raw<Vector4_32>(const uint8_t* input)
-{
-	return vector_unaligned_load_32(input);
-}
-
-template<>
-inline Vector4_64 vector_unaligned_load_raw<Vector4_64>(const uint8_t* input)
-{
-	return vector_unaligned_load_64(input);
-}
-
-template<typename Vector4Type>
-inline Vector4Type vector_unaligned_load3_raw(const uint8_t* input);
-
-template<>
-inline Vector4_32 vector_unaligned_load3_raw<Vector4_32>(const uint8_t* input)
-{
-	return vector_unaligned_load3_32(input);
-}
-
-template<>
-inline Vector4_64 vector_unaligned_load3_raw<Vector4_64>(const uint8_t* input)
-{
-	return vector_unaligned_load3_64(input);
-}
-
-template<typename Vector4Type, typename FloatType>
-inline const FloatType* vector_as_float_ptr_raw(const Vector4Type& input);
-
-template<>
-inline const float* vector_as_float_ptr_raw<Vector4_32, float>(const Vector4_32& input)
-{
-	return vector_as_float_ptr(input);
-}
-
-template<>
-inline const double* vector_as_float_ptr_raw<Vector4_64, double>(const Vector4_64& input)
-{
-	return vector_as_double_ptr(input);
-}
-
-template<typename Vector4Type>
-inline Vector4Type scalar_cross3(const Vector4Type& lhs, const Vector4Type& rhs)
-{
-	return vector_set(vector_get_y(lhs) * vector_get_z(rhs) - vector_get_z(lhs) * vector_get_y(rhs),
-		vector_get_z(lhs) * vector_get_x(rhs) - vector_get_x(lhs) * vector_get_z(rhs),
-		vector_get_x(lhs) * vector_get_y(rhs) - vector_get_y(lhs) * vector_get_x(rhs));
-}
-
-template<typename Vector4Type, typename FloatType>
-inline FloatType scalar_dot(const Vector4Type& lhs, const Vector4Type& rhs)
-{
-	return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs)) + (vector_get_w(lhs) * vector_get_w(rhs));
-}
-
-template<typename Vector4Type, typename FloatType>
-inline FloatType scalar_dot3(const Vector4Type& lhs, const Vector4Type& rhs)
-{
-	return (vector_get_x(lhs) * vector_get_x(rhs)) + (vector_get_y(lhs) * vector_get_y(rhs)) + (vector_get_z(lhs) * vector_get_z(rhs));
-}
-
-template<typename Vector4Type, typename FloatType>
-inline Vector4Type scalar_normalize3(const Vector4Type& input, FloatType threshold)
-{
-	FloatType len_sq = scalar_dot3<Vector4Type, FloatType>(input, input);
-	if (len_sq >= threshold)
-	{
-		FloatType inv_len = acl::sqrt_reciprocal(len_sq);
-		return vector_set(vector_get_x(input) * inv_len, vector_get_y(input) * inv_len, vector_get_z(input) * inv_len);
-	}
-	else
-		return input;
-}
-
-template<typename Vector4Type, typename QuatType, typename FloatType>
-void test_vector4_impl(const Vector4Type& zero, const QuatType& identity, const FloatType threshold)
-{
-	struct alignas(16) Tmp
-	{
-		uint8_t padding0[8];	//  8 |  8
-		FloatType values[4];	// 24 | 40
-		uint8_t padding1[8];	// 32 | 48
-	};
-
-	Tmp tmp = { { 0 }, { FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0) }, {} };
-	alignas(16) uint8_t buffer[64];
-
-	const FloatType test_value0_flt[4] = { FloatType(2.0), FloatType(9.34), FloatType(-54.12), FloatType(6000.0) };
-	const FloatType test_value1_flt[4] = { FloatType(0.75), FloatType(-4.52), FloatType(44.68), FloatType(-54225.0) };
-	const FloatType test_value2_flt[4] = { FloatType(-2.65), FloatType(2.996113), FloatType(0.68123521), FloatType(-5.9182) };
-	const Vector4Type test_value0 = vector_set(test_value0_flt[0], test_value0_flt[1], test_value0_flt[2], test_value0_flt[3]);
-	const Vector4Type test_value1 = vector_set(test_value1_flt[0], test_value1_flt[1], test_value1_flt[2], test_value1_flt[3]);
-	const Vector4Type test_value2 = vector_set(test_value2_flt[0], test_value2_flt[1], test_value2_flt[2], test_value2_flt[3]);
-
-	//////////////////////////////////////////////////////////////////////////
-	// Setters, getters, and casts
-
-	REQUIRE(vector_get_x(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(0.0));
-	REQUIRE(vector_get_y(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(2.34));
-	REQUIRE(vector_get_z(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(-3.12));
-	REQUIRE(vector_get_w(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(10000.0));
-
-	REQUIRE(vector_get_x(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12))) == FloatType(0.0));
-	REQUIRE(vector_get_y(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12))) == FloatType(2.34));
-	REQUIRE(vector_get_z(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12))) == FloatType(-3.12));
-
-	REQUIRE(vector_get_x(vector_set(FloatType(-3.12))) == FloatType(-3.12));
-	REQUIRE(vector_get_y(vector_set(FloatType(-3.12))) == FloatType(-3.12));
-	REQUIRE(vector_get_z(vector_set(FloatType(-3.12))) == FloatType(-3.12));
-	REQUIRE(vector_get_w(vector_set(FloatType(-3.12))) == FloatType(-3.12));
-
-	REQUIRE(vector_get_x(zero) == FloatType(0.0));
-	REQUIRE(vector_get_y(zero) == FloatType(0.0));
-	REQUIRE(vector_get_z(zero) == FloatType(0.0));
-	REQUIRE(vector_get_w(zero) == FloatType(0.0));
-
-	REQUIRE(vector_get_x(vector_unaligned_load(&tmp.values[0])) == tmp.values[0]);
-	REQUIRE(vector_get_y(vector_unaligned_load(&tmp.values[0])) == tmp.values[1]);
-	REQUIRE(vector_get_z(vector_unaligned_load(&tmp.values[0])) == tmp.values[2]);
-	REQUIRE(vector_get_w(vector_unaligned_load(&tmp.values[0])) == tmp.values[3]);
-
-	REQUIRE(vector_get_x(vector_unaligned_load3(&tmp.values[0])) == tmp.values[0]);
-	REQUIRE(vector_get_y(vector_unaligned_load3(&tmp.values[0])) == tmp.values[1]);
-	REQUIRE(vector_get_z(vector_unaligned_load3(&tmp.values[0])) == tmp.values[2]);
-
-	std::memcpy(&buffer[1], &tmp.values[0], sizeof(tmp.values));
-	REQUIRE(vector_get_x(vector_unaligned_load_raw<Vector4Type>(&buffer[1])) == tmp.values[0]);
-	REQUIRE(vector_get_y(vector_unaligned_load_raw<Vector4Type>(&buffer[1])) == tmp.values[1]);
-	REQUIRE(vector_get_z(vector_unaligned_load_raw<Vector4Type>(&buffer[1])) == tmp.values[2]);
-	REQUIRE(vector_get_w(vector_unaligned_load_raw<Vector4Type>(&buffer[1])) == tmp.values[3]);
-
-	REQUIRE(vector_get_x(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])) == tmp.values[0]);
-	REQUIRE(vector_get_y(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])) == tmp.values[1]);
-	REQUIRE(vector_get_z(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])) == tmp.values[2]);
-
-	REQUIRE(vector_get_x(quat_to_vector(identity)) == quat_get_x(identity));
-	REQUIRE(vector_get_y(quat_to_vector(identity)) == quat_get_y(identity));
-	REQUIRE(vector_get_z(quat_to_vector(identity)) == quat_get_z(identity));
-	REQUIRE(vector_get_w(quat_to_vector(identity)) == quat_get_w(identity));
-
-	REQUIRE(vector_get_component<VectorMix::X>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(0.0));
-	REQUIRE(vector_get_component<VectorMix::Y>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(2.34));
-	REQUIRE(vector_get_component<VectorMix::Z>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(-3.12));
-	REQUIRE(vector_get_component<VectorMix::W>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(10000.0));
-
-	REQUIRE(vector_get_component<VectorMix::A>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(0.0));
-	REQUIRE(vector_get_component<VectorMix::B>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(2.34));
-	REQUIRE(vector_get_component<VectorMix::C>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(-3.12));
-	REQUIRE(vector_get_component<VectorMix::D>(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0))) == FloatType(10000.0));
-
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::X) == FloatType(0.0));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::Y) == FloatType(2.34));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::Z) == FloatType(-3.12));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::W) == FloatType(10000.0));
-
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::A) == FloatType(0.0));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::B) == FloatType(2.34));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::C) == FloatType(-3.12));
-	REQUIRE(vector_get_component(vector_set(FloatType(0.0), FloatType(2.34), FloatType(-3.12), FloatType(10000.0)), VectorMix::D) == FloatType(10000.0));
-
-	REQUIRE((vector_as_float_ptr_raw<Vector4Type, FloatType>(vector_unaligned_load(&tmp.values[0]))[0] == tmp.values[0]));
-	REQUIRE((vector_as_float_ptr_raw<Vector4Type, FloatType>(vector_unaligned_load(&tmp.values[0]))[1] == tmp.values[1]));
-	REQUIRE((vector_as_float_ptr_raw<Vector4Type, FloatType>(vector_unaligned_load(&tmp.values[0]))[2] == tmp.values[2]));
-	REQUIRE((vector_as_float_ptr_raw<Vector4Type, FloatType>(vector_unaligned_load(&tmp.values[0]))[3] == tmp.values[3]));
-
-	vector_unaligned_write(test_value0, &tmp.values[0]);
-	REQUIRE(vector_get_x(test_value0) == tmp.values[0]);
-	REQUIRE(vector_get_y(test_value0) == tmp.values[1]);
-	REQUIRE(vector_get_z(test_value0) == tmp.values[2]);
-	REQUIRE(vector_get_w(test_value0) == tmp.values[3]);
-
-	vector_unaligned_write3(test_value1, &tmp.values[0]);
-	REQUIRE(vector_get_x(test_value1) == tmp.values[0]);
-	REQUIRE(vector_get_y(test_value1) == tmp.values[1]);
-	REQUIRE(vector_get_z(test_value1) == tmp.values[2]);
-	REQUIRE(vector_get_w(test_value0) == tmp.values[3]);
-
-	vector_unaligned_write3(test_value1, &buffer[1]);
-	REQUIRE(vector_get_x(test_value1) == vector_get_x(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])));
-	REQUIRE(vector_get_y(test_value1) == vector_get_y(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])));
-	REQUIRE(vector_get_z(test_value1) == vector_get_z(vector_unaligned_load3_raw<Vector4Type>(&buffer[1])));
-
-	//////////////////////////////////////////////////////////////////////////
-	// Arithmetic
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_add(test_value0, test_value1)), test_value0_flt[0] + test_value1_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_add(test_value0, test_value1)), test_value0_flt[1] + test_value1_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_add(test_value0, test_value1)), test_value0_flt[2] + test_value1_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_add(test_value0, test_value1)), test_value0_flt[3] + test_value1_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_sub(test_value0, test_value1)), test_value0_flt[0] - test_value1_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_sub(test_value0, test_value1)), test_value0_flt[1] - test_value1_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_sub(test_value0, test_value1)), test_value0_flt[2] - test_value1_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_sub(test_value0, test_value1)), test_value0_flt[3] - test_value1_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_mul(test_value0, test_value1)), test_value0_flt[0] * test_value1_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_mul(test_value0, test_value1)), test_value0_flt[1] * test_value1_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_mul(test_value0, test_value1)), test_value0_flt[2] * test_value1_flt[2], threshold));
-	// We have a strange codegen bug with gcc5, use the Catch near equal impl instead
-	REQUIRE(vector_get_w(vector_mul(test_value0, test_value1)) == Approx(test_value0_flt[3] * test_value1_flt[3]).margin(threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_mul(test_value0, FloatType(2.34))), test_value0_flt[0] * FloatType(2.34), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_mul(test_value0, FloatType(2.34))), test_value0_flt[1] * FloatType(2.34), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_mul(test_value0, FloatType(2.34))), test_value0_flt[2] * FloatType(2.34), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_mul(test_value0, FloatType(2.34))), test_value0_flt[3] * FloatType(2.34), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_div(test_value0, test_value1)), test_value0_flt[0] / test_value1_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_div(test_value0, test_value1)), test_value0_flt[1] / test_value1_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_div(test_value0, test_value1)), test_value0_flt[2] / test_value1_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_div(test_value0, test_value1)), test_value0_flt[3] / test_value1_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_max(test_value0, test_value1)), acl::max(test_value0_flt[0], test_value1_flt[0]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_max(test_value0, test_value1)), acl::max(test_value0_flt[1], test_value1_flt[1]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_max(test_value0, test_value1)), acl::max(test_value0_flt[2], test_value1_flt[2]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_max(test_value0, test_value1)), acl::max(test_value0_flt[3], test_value1_flt[3]), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_min(test_value0, test_value1)), acl::min(test_value0_flt[0], test_value1_flt[0]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_min(test_value0, test_value1)), acl::min(test_value0_flt[1], test_value1_flt[1]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_min(test_value0, test_value1)), acl::min(test_value0_flt[2], test_value1_flt[2]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_min(test_value0, test_value1)), acl::min(test_value0_flt[3], test_value1_flt[3]), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_abs(test_value0)), acl::abs(test_value0_flt[0]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_abs(test_value0)), acl::abs(test_value0_flt[1]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_abs(test_value0)), acl::abs(test_value0_flt[2]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_abs(test_value0)), acl::abs(test_value0_flt[3]), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_neg(test_value0)), -test_value0_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_neg(test_value0)), -test_value0_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_neg(test_value0)), -test_value0_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_neg(test_value0)), -test_value0_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_reciprocal(test_value0)), acl::reciprocal(test_value0_flt[0]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_reciprocal(test_value0)), acl::reciprocal(test_value0_flt[1]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_reciprocal(test_value0)), acl::reciprocal(test_value0_flt[2]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_reciprocal(test_value0)), acl::reciprocal(test_value0_flt[3]), threshold));
-
-	const Vector4Type scalar_cross3_result = scalar_cross3<Vector4Type>(test_value0, test_value1);
-	const Vector4Type vector_cross3_result = vector_cross3(test_value0, test_value1);
-	REQUIRE(scalar_near_equal(vector_get_x(vector_cross3_result), vector_get_x(scalar_cross3_result), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_cross3_result), vector_get_y(scalar_cross3_result), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_cross3_result), vector_get_z(scalar_cross3_result), threshold));
-
-	const FloatType test_value10_flt[4] = { FloatType(-0.001138), FloatType(0.91623), FloatType(-1.624598), FloatType(0.715671) };
-	const FloatType test_value11_flt[4] = { FloatType(0.1138), FloatType(-0.623), FloatType(1.4598), FloatType(-0.5671) };
-	const Vector4Type test_value10 = vector_set(test_value10_flt[0], test_value10_flt[1], test_value10_flt[2], test_value10_flt[3]);
-	const Vector4Type test_value11 = vector_set(test_value11_flt[0], test_value11_flt[1], test_value11_flt[2], test_value11_flt[3]);
-	const FloatType scalar_dot_result = scalar_dot<Vector4Type, FloatType>(test_value10, test_value11);
-	const FloatType vector_dot_result = vector_dot(test_value10, test_value11);
-	REQUIRE(scalar_near_equal(vector_dot_result, scalar_dot_result, threshold));
-
-	const FloatType scalar_dot3_result = scalar_dot3<Vector4Type, FloatType>(test_value10, test_value11);
-	const FloatType vector_dot3_result = vector_dot3(test_value10, test_value11);
-	REQUIRE(scalar_near_equal(vector_dot3_result, scalar_dot3_result, threshold));
-
-	const Vector4Type vector_vdot_result = vector_vdot(test_value10, test_value11);
-	REQUIRE(scalar_near_equal(vector_get_x(vector_vdot_result), scalar_dot_result, threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_vdot_result), scalar_dot_result, threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_vdot_result), scalar_dot_result, threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_vdot_result), scalar_dot_result, threshold));
-
-	REQUIRE(scalar_near_equal(scalar_dot<Vector4Type, FloatType>(test_value0, test_value0), vector_length_squared(test_value0), threshold));
-	REQUIRE(scalar_near_equal(scalar_dot3<Vector4Type, FloatType>(test_value0, test_value0), vector_length_squared3(test_value0), threshold));
-
-	REQUIRE(scalar_near_equal(acl::sqrt(scalar_dot<Vector4Type, FloatType>(test_value0, test_value0)), vector_length(test_value0), threshold));
-	REQUIRE(scalar_near_equal(acl::sqrt(scalar_dot3<Vector4Type, FloatType>(test_value0, test_value0)), vector_length3(test_value0), threshold));
-
-	REQUIRE(scalar_near_equal(acl::sqrt_reciprocal(scalar_dot<Vector4Type, FloatType>(test_value0, test_value0)), vector_length_reciprocal(test_value0), threshold));
-	REQUIRE(scalar_near_equal(acl::sqrt_reciprocal(scalar_dot3<Vector4Type, FloatType>(test_value0, test_value0)), vector_length_reciprocal3(test_value0), threshold));
-
-	const Vector4Type test_value_diff = vector_sub(test_value0, test_value1);
-	REQUIRE(scalar_near_equal(acl::sqrt(scalar_dot3<Vector4Type, FloatType>(test_value_diff, test_value_diff)), vector_distance3(test_value0, test_value1), threshold));
-
-	const Vector4Type scalar_normalize3_result = scalar_normalize3<Vector4Type, FloatType>(test_value0, threshold);
-	const Vector4Type vector_normalize3_result = vector_normalize3(test_value0, threshold);
-	REQUIRE(scalar_near_equal(vector_get_x(vector_normalize3_result), vector_get_x(scalar_normalize3_result), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_normalize3_result), vector_get_y(scalar_normalize3_result), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_normalize3_result), vector_get_z(scalar_normalize3_result), threshold));
-
-	const Vector4Type scalar_normalize3_result0 = scalar_normalize3<Vector4Type, FloatType>(zero, threshold);
-	const Vector4Type vector_normalize3_result0 = vector_normalize3(zero, threshold);
-	REQUIRE(scalar_near_equal(vector_get_x(vector_normalize3_result0), vector_get_x(scalar_normalize3_result0), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_normalize3_result0), vector_get_y(scalar_normalize3_result0), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_normalize3_result0), vector_get_z(scalar_normalize3_result0), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_lerp(test_value10, test_value11, FloatType(0.33))), ((test_value11_flt[0] - test_value10_flt[0]) * FloatType(0.33)) + test_value10_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_lerp(test_value10, test_value11, FloatType(0.33))), ((test_value11_flt[1] - test_value10_flt[1]) * FloatType(0.33)) + test_value10_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_lerp(test_value10, test_value11, FloatType(0.33))), ((test_value11_flt[2] - test_value10_flt[2]) * FloatType(0.33)) + test_value10_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_lerp(test_value10, test_value11, FloatType(0.33))), ((test_value11_flt[3] - test_value10_flt[3]) * FloatType(0.33)) + test_value10_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_fraction(test_value0)), acl::fraction(test_value0_flt[0]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_fraction(test_value0)), acl::fraction(test_value0_flt[1]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_fraction(test_value0)), acl::fraction(test_value0_flt[2]), threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_fraction(test_value0)), acl::fraction(test_value0_flt[3]), threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_mul_add(test_value10, test_value11, test_value2)), (test_value10_flt[0] * test_value11_flt[0]) + test_value2_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_mul_add(test_value10, test_value11, test_value2)), (test_value10_flt[1] * test_value11_flt[1]) + test_value2_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_mul_add(test_value10, test_value11, test_value2)), (test_value10_flt[2] * test_value11_flt[2]) + test_value2_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_mul_add(test_value10, test_value11, test_value2)), (test_value10_flt[3] * test_value11_flt[3]) + test_value2_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_mul_add(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[0] * test_value11_flt[0]) + test_value2_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_mul_add(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[1] * test_value11_flt[0]) + test_value2_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_mul_add(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[2] * test_value11_flt[0]) + test_value2_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_mul_add(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[3] * test_value11_flt[0]) + test_value2_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_neg_mul_sub(test_value10, test_value11, test_value2)), (test_value10_flt[0] * -test_value11_flt[0]) + test_value2_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_neg_mul_sub(test_value10, test_value11, test_value2)), (test_value10_flt[1] * -test_value11_flt[1]) + test_value2_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_neg_mul_sub(test_value10, test_value11, test_value2)), (test_value10_flt[2] * -test_value11_flt[2]) + test_value2_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_neg_mul_sub(test_value10, test_value11, test_value2)), (test_value10_flt[3] * -test_value11_flt[3]) + test_value2_flt[3], threshold));
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_neg_mul_sub(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[0] * -test_value11_flt[0]) + test_value2_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_neg_mul_sub(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[1] * -test_value11_flt[0]) + test_value2_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_neg_mul_sub(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[2] * -test_value11_flt[0]) + test_value2_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_neg_mul_sub(test_value10, test_value11_flt[0], test_value2)), (test_value10_flt[3] * -test_value11_flt[0]) + test_value2_flt[3], threshold));
-
-	//////////////////////////////////////////////////////////////////////////
-	// Comparisons and masking
-
-	REQUIRE((vector_get_x(vector_less_than(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[0] < test_value1_flt[0]));
-	REQUIRE((vector_get_y(vector_less_than(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[1] < test_value1_flt[1]));
-	REQUIRE((vector_get_z(vector_less_than(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[2] < test_value1_flt[2]));
-	REQUIRE((vector_get_w(vector_less_than(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[3] < test_value1_flt[3]));
-
-	REQUIRE((vector_get_x(vector_greater_equal(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[0] >= test_value1_flt[0]));
-	REQUIRE((vector_get_y(vector_greater_equal(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[1] >= test_value1_flt[1]));
-	REQUIRE((vector_get_z(vector_greater_equal(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[2] >= test_value1_flt[2]));
-	REQUIRE((vector_get_w(vector_greater_equal(test_value0, test_value1)) != FloatType(0.0)) == (test_value0_flt[3] >= test_value1_flt[3]));
-
-	REQUIRE(vector_all_less_than(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0))) == true);
-	REQUIRE(vector_all_less_than(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0))) == false);
-	REQUIRE(vector_all_less_than(zero, zero) == false);
-
-	REQUIRE(vector_all_less_than3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_than3(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than3(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than3(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_than3(zero, zero) == false);
-
-	REQUIRE(vector_any_less_than(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0))) == true);
-	REQUIRE(vector_any_less_than(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0))) == true);
-	REQUIRE(vector_any_less_than(zero, zero) == false);
-
-	REQUIRE(vector_any_less_than3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than3(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than3(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than3(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_than3(zero, zero) == false);
-
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0))) == true);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(1.0))) == true);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(-1.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(0.0), FloatType(-1.0))) == false);
-	REQUIRE(vector_all_less_equal(zero, zero) == true);
-
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(0.0), FloatType(-1.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal2(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal2(zero, zero) == true);
-
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(0.0), FloatType(1.0), FloatType(0.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(-1.0), FloatType(0.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(0.0), FloatType(-1.0), FloatType(0.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal3(zero, vector_set(FloatType(0.0), FloatType(0.0), FloatType(-1.0), FloatType(0.0))) == false);
-	REQUIRE(vector_all_less_equal3(zero, zero) == true);
-
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0))) == true);
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0))) == true);
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(-1.0))) == true);
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(-1.0))) == true);
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(1.0))) == true);
-	REQUIRE(vector_any_less_equal(zero, vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0))) == false);
-	REQUIRE(vector_any_less_equal(zero, zero) == true);
-
-	REQUIRE(vector_any_less_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_equal3(zero, vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_equal3(zero, vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_equal3(zero, vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(0.0))) == true);
-	REQUIRE(vector_any_less_equal3(zero, vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0))) == false);
-	REQUIRE(vector_any_less_equal3(zero, zero) == true);
-
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), zero) == true);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(0.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(0.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal(zero, zero) == true);
-
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(0.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(0.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_all_greater_equal3(zero, zero) == true);
-
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(0.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(-1.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(0.0), FloatType(-1.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(-1.0)), zero) == false);
-	REQUIRE(vector_any_greater_equal(zero, zero) == true);
-
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(-1.0), FloatType(1.0), FloatType(-1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(0.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(-1.0), FloatType(0.0), FloatType(-1.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(0.0), FloatType(0.0)), zero) == true);
-	REQUIRE(vector_any_greater_equal3(vector_set(FloatType(-1.0), FloatType(-1.0), FloatType(-1.0), FloatType(0.0)), zero) == false);
-	REQUIRE(vector_any_greater_equal3(zero, zero) == true);
-
-	REQUIRE(vector_all_near_equal(zero, zero, threshold) == true);
-	REQUIRE(vector_all_near_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_all_near_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_all_near_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), FloatType(0.9999)) == false);
-
-	REQUIRE(vector_all_near_equal2(zero, zero, threshold) == true);
-	REQUIRE(vector_all_near_equal2(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_all_near_equal2(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_all_near_equal2(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(0.9999)) == false);
-
-	REQUIRE(vector_all_near_equal3(zero, zero, threshold) == true);
-	REQUIRE(vector_all_near_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_all_near_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_all_near_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(0.9999)) == false);
-
-	REQUIRE(vector_any_near_equal(zero, zero, threshold) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(1.0), FloatType(2.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(1.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(2.0), FloatType(1.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(1.0), FloatType(2.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(1.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(2.0), FloatType(1.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(1.0)), FloatType(0.9999)) == false);
-
-	REQUIRE(vector_any_near_equal3(zero, zero, threshold) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(1.0), FloatType(2.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(2.0), FloatType(1.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0001)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(1.0), FloatType(2.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(2.0), FloatType(1.0), FloatType(2.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(2.0), FloatType(2.0), FloatType(1.0), FloatType(2.0)), FloatType(1.0)) == true);
-	REQUIRE(vector_any_near_equal3(zero, vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(2.0)), FloatType(0.9999)) == false);
-
-	const FloatType inf = std::numeric_limits<FloatType>::infinity();
-	const FloatType nan = std::numeric_limits<FloatType>::quiet_NaN();
-	REQUIRE(vector_is_finite(zero) == true);
-	REQUIRE(vector_is_finite(vector_set(inf, inf, inf, inf)) == false);
-	REQUIRE(vector_is_finite(vector_set(inf, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(inf), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(1.0), FloatType(inf), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(inf))) == false);
-	REQUIRE(vector_is_finite(vector_set(nan, nan, nan, nan)) == false);
-	REQUIRE(vector_is_finite(vector_set(nan, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(nan), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(1.0), FloatType(nan), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(nan))) == false);
-
-	REQUIRE(vector_is_finite3(zero) == true);
-	REQUIRE(vector_is_finite3(vector_set(inf, inf, inf, inf)) == false);
-	REQUIRE(vector_is_finite3(vector_set(inf, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(inf), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(inf), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(inf))) == true);
-	REQUIRE(vector_is_finite3(vector_set(nan, nan, nan, nan)) == false);
-	REQUIRE(vector_is_finite3(vector_set(nan, FloatType(1.0), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(nan), FloatType(1.0), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(nan), FloatType(1.0))) == false);
-	REQUIRE(vector_is_finite3(vector_set(FloatType(1.0), FloatType(1.0), FloatType(1.0), FloatType(nan))) == true);
-
-	//////////////////////////////////////////////////////////////////////////
-	// Swizzling, permutations, and mixing
-
-	REQUIRE(scalar_near_equal(vector_get_x(vector_blend(vector_less_than(zero, vector_set(FloatType(1.0))), test_value0, test_value1)), test_value0_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_blend(vector_less_than(zero, vector_set(FloatType(1.0))), test_value0, test_value1)), test_value0_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_blend(vector_less_than(zero, vector_set(FloatType(1.0))), test_value0, test_value1)), test_value0_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_blend(vector_less_than(zero, vector_set(FloatType(1.0))), test_value0, test_value1)), test_value0_flt[3], threshold));
-	REQUIRE(scalar_near_equal(vector_get_x(vector_blend(vector_less_than(vector_set(FloatType(1.0)), zero), test_value0, test_value1)), test_value1_flt[0], threshold));
-	REQUIRE(scalar_near_equal(vector_get_y(vector_blend(vector_less_than(vector_set(FloatType(1.0)), zero), test_value0, test_value1)), test_value1_flt[1], threshold));
-	REQUIRE(scalar_near_equal(vector_get_z(vector_blend(vector_less_than(vector_set(FloatType(1.0)), zero), test_value0, test_value1)), test_value1_flt[2], threshold));
-	REQUIRE(scalar_near_equal(vector_get_w(vector_blend(vector_less_than(vector_set(FloatType(1.0)), zero), test_value0, test_value1)), test_value1_flt[3], threshold));
-
-	//////////////////////////////////////////////////////////////////////////
-	// Misc
-
-	auto scalar_sign = [](FloatType value) { return value >= FloatType(0.0) ? FloatType(1.0) : FloatType(-1.0); };
-	REQUIRE(vector_get_x(vector_sign(test_value0)) == scalar_sign(test_value0_flt[0]));
-	REQUIRE(vector_get_y(vector_sign(test_value0)) == scalar_sign(test_value0_flt[1]));
-	REQUIRE(vector_get_z(vector_sign(test_value0)) == scalar_sign(test_value0_flt[2]));
-	REQUIRE(vector_get_w(vector_sign(test_value0)) == scalar_sign(test_value0_flt[3]));
-
-	{
-		const Vector4Type input0 = vector_set(FloatType(-1.75), FloatType(-1.5), FloatType(-1.4999), FloatType(-0.5));
-		const Vector4Type input1 = vector_set(FloatType(-0.4999), FloatType(0.0), FloatType(0.4999), FloatType(0.5));
-		const Vector4Type input2 = vector_set(FloatType(1.4999), FloatType(1.5), FloatType(1.75), FloatType(0.0));
-
-		const Vector4Type result0 = vector_symmetric_round(input0);
-		const Vector4Type result1 = vector_symmetric_round(input1);
-		const Vector4Type result2 = vector_symmetric_round(input2);
-
-		REQUIRE(vector_get_x(result0) == symmetric_round(vector_get_x(input0)));
-		REQUIRE(vector_get_y(result0) == symmetric_round(vector_get_y(input0)));
-		REQUIRE(vector_get_z(result0) == symmetric_round(vector_get_z(input0)));
-		REQUIRE(vector_get_w(result0) == symmetric_round(vector_get_w(input0)));
-		REQUIRE(vector_get_x(result1) == symmetric_round(vector_get_x(input1)));
-		REQUIRE(vector_get_y(result1) == symmetric_round(vector_get_y(input1)));
-		REQUIRE(vector_get_z(result1) == symmetric_round(vector_get_z(input1)));
-		REQUIRE(vector_get_w(result1) == symmetric_round(vector_get_w(input1)));
-		REQUIRE(vector_get_x(result2) == symmetric_round(vector_get_x(input2)));
-		REQUIRE(vector_get_y(result2) == symmetric_round(vector_get_y(input2)));
-		REQUIRE(vector_get_z(result2) == symmetric_round(vector_get_z(input2)));
-		REQUIRE(vector_get_w(result2) == symmetric_round(vector_get_w(input2)));
-	}
-}
-
-template<typename Vector4Type, typename FloatType, VectorMix XArg>
-void test_vector4_vector_mix_impl(const FloatType threshold)
-{
-	const FloatType test_value0_flt[4] = { FloatType(2.0), FloatType(9.34), FloatType(-54.12), FloatType(6000.0) };
-	const FloatType test_value1_flt[4] = { FloatType(0.75), FloatType(-4.52), FloatType(44.68), FloatType(-54225.0) };
-
-	const Vector4Type test_value0 = vector_set(test_value0_flt[0], test_value0_flt[1], test_value0_flt[2], test_value0_flt[3]);
-	const Vector4Type test_value1 = vector_set(test_value1_flt[0], test_value1_flt[1], test_value1_flt[2], test_value1_flt[3]);
-
-	Vector4Type results[8 * 8 * 8];
-	uint32_t index = 0;
-
-#define ACL_TEST_MIX_XYZ(comp0, comp1, comp2) \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::X>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::Y>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::Z>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::W>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::A>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::B>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::C>(test_value0, test_value1); \
-	results[index++] = vector_mix<comp0, comp1, comp2, VectorMix::D>(test_value0, test_value1)
-
-#define ACL_TEST_MIX_XY(comp0, comp1) \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::X); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::Y); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::Z); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::W); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::A); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::B); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::C); \
-	ACL_TEST_MIX_XYZ(comp0, comp1, VectorMix::D)
-
-#define ACL_TEST_MIX_X(comp0) \
-	ACL_TEST_MIX_XY(comp0, VectorMix::X); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::Y); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::Z); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::W); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::A); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::B); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::C); \
-	ACL_TEST_MIX_XY(comp0, VectorMix::D)
-
-	// This generates 8*8*8 = 512 unit tests... it takes a while to compile and uses a lot of stack space
-	ACL_TEST_MIX_X(XArg);
-
-	auto verify_mix = [&](int comp0, int comp1, int comp2, int comp3, const Vector4Type& actual)
-	{
-		INFO("vector_mix<" << comp0 << ", " << comp1 << ", " << comp2 << ", " << comp3 << ">");
-
-		const Vector4Type expected = vector_set(
-			math_impl::is_vector_mix_arg_xyzw((VectorMix)comp0) ? test_value0_flt[comp0 - (int)VectorMix::X] : test_value1_flt[comp0 - (int)VectorMix::A],
-			math_impl::is_vector_mix_arg_xyzw((VectorMix)comp1) ? test_value0_flt[comp1 - (int)VectorMix::X] : test_value1_flt[comp1 - (int)VectorMix::A],
-			math_impl::is_vector_mix_arg_xyzw((VectorMix)comp2) ? test_value0_flt[comp2 - (int)VectorMix::X] : test_value1_flt[comp2 - (int)VectorMix::A],
-			math_impl::is_vector_mix_arg_xyzw((VectorMix)comp3) ? test_value0_flt[comp3 - (int)VectorMix::X] : test_value1_flt[comp3 - (int)VectorMix::A]);
-
-		REQUIRE(vector_all_near_equal(expected, actual, threshold));
-	};
-
-	index = 0;
-
-	const int comp0 = (int)XArg;
-	for (int comp1 = 0; comp1 < 8; ++comp1)
-		for (int comp2 = 0; comp2 < 8; ++comp2)
-			for (int comp3 = 0; comp3 < 8; ++comp3)
-				verify_mix(comp0, comp1, comp2, comp3, results[index++]);
-
-#undef ACL_TEST_MIX_X
-#undef ACL_TEST_MIX_XY
-#undef ACL_TEST_MIX_XYZ
-}
diff --git a/tests/sources/math/test_vector4_packing.cpp b/tests/sources/math/test_vector4_packing.cpp
--- a/tests/sources/math/test_vector4_packing.cpp
+++ b/tests/sources/math/test_vector4_packing.cpp
@@ -24,12 +24,14 @@
 
 #include <catch.hpp>
 
-#include <acl/math/scalar_32.h>
 #include <acl/math/vector4_packing.h>
 
+#include <rtm/scalarf.h>
+
 #include <cstring>
 
 using namespace acl;
+using namespace rtm;
 
 struct UnalignedBuffer
 {
@@ -43,16 +45,16 @@ TEST_CASE("pack_vector4_128", "[math][vector4][packing]")
 {
 	{
 		UnalignedBuffer tmp;
-		Vector4_32 vec0 = vector_set(6123.123812F, 19237.01293127F, 1891.019231829F, 0.913912387F);
+		vector4f vec0 = vector_set(6123.123812F, 19237.01293127F, 1891.019231829F, 0.913912387F);
 		pack_vector4_128(vec0, &tmp.buffer[0]);
-		Vector4_32 vec1 = unpack_vector4_128(&tmp.buffer[0]);
-		REQUIRE(std::memcmp(&vec0, &vec1, sizeof(Vector4_32)) == 0);
+		vector4f vec1 = unpack_vector4_128(&tmp.buffer[0]);
+		REQUIRE(std::memcmp(&vec0, &vec1, sizeof(vector4f)) == 0);
 	}
 
 	{
 		UnalignedBuffer tmp0;
 		UnalignedBuffer tmp1;
-		Vector4_32 vec0 = vector_set(6123.123812F, 19237.01293127F, 1891.019231829F, 0.913912387F);
+		vector4f vec0 = vector_set(6123.123812F, 19237.01293127F, 1891.019231829F, 0.913912387F);
 		pack_vector4_128(vec0, &tmp0.buffer[0]);
 
 		uint32_t x = unaligned_load<uint32_t>(&tmp0.buffer[0]);
@@ -78,7 +80,7 @@ TEST_CASE("pack_vector4_128", "[math][vector4][packing]")
 			const uint8_t offset = offsets[offset_idx];
 
 			memcpy_bits(&tmp1.buffer[0], offset, &tmp0.buffer[0], 0, 128);
-			Vector4_32 vec1 = unpack_vector4_128_unsafe(&tmp1.buffer[0], offset);
+			vector4f vec1 = unpack_vector4_128_unsafe(&tmp1.buffer[0], offset);
 			if (!vector_all_near_equal(vec0, vec1, 1.0E-6F))
 				num_errors++;
 		}
@@ -96,9 +98,9 @@ TEST_CASE("pack_vector4_64", "[math][vector4][packing]")
 			const float value_signed = unpack_scalar_signed(value, 16);
 			const float value_unsigned = unpack_scalar_unsigned(value, 16);
 
-			Vector4_32 vec0 = vector_set(value_signed);
+			vector4f vec0 = vector_set(value_signed);
 			pack_vector4_64(vec0, false, &tmp.buffer[0]);
-			Vector4_32 vec1 = unpack_vector4_64(&tmp.buffer[0], false);
+			vector4f vec1 = unpack_vector4_64(&tmp.buffer[0], false);
 			if (!vector_all_near_equal(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -119,12 +121,12 @@ TEST_CASE("pack_vector4_32", "[math][vector4][packing]")
 		uint32_t num_errors = 0;
 		for (uint32_t value = 0; value < 256; ++value)
 		{
-			const float value_signed = min(unpack_scalar_signed(value, 8), 1.0F);
-			const float value_unsigned = min(unpack_scalar_unsigned(value, 8), 1.0F);
+			const float value_signed = scalar_min(unpack_scalar_signed(value, 8), 1.0F);
+			const float value_unsigned = scalar_min(unpack_scalar_unsigned(value, 8), 1.0F);
 
-			Vector4_32 vec0 = vector_set(value_signed);
+			vector4f vec0 = vector_set(value_signed);
 			pack_vector4_32(vec0, false, &tmp.buffer[0]);
-			Vector4_32 vec1 = unpack_vector4_32(&tmp.buffer[0], false);
+			vector4f vec1 = unpack_vector4_32(&tmp.buffer[0], false);
 			if (!vector_all_near_equal(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -145,9 +147,9 @@ TEST_CASE("pack_vector4_XX", "[math][vector4][packing]")
 		alignas(16) uint8_t buffer[64];
 
 		uint32_t num_errors = 0;
-		Vector4_32 vec0 = vector_set(unpack_scalar_unsigned(0, 16), unpack_scalar_unsigned(12355, 16), unpack_scalar_unsigned(43222, 16), unpack_scalar_unsigned(54432, 16));
+		vector4f vec0 = vector_set(unpack_scalar_unsigned(0, 16), unpack_scalar_unsigned(12355, 16), unpack_scalar_unsigned(43222, 16), unpack_scalar_unsigned(54432, 16));
 		pack_vector4_uXX_unsafe(vec0, 16, &buffer[0]);
-		Vector4_32 vec1 = unpack_vector4_uXX_unsafe(16, &buffer[0], 0);
+		vector4f vec1 = unpack_vector4_uXX_unsafe(16, &buffer[0], 0);
 		if (!vector_all_near_equal(vec0, vec1, 1.0E-6F))
 			num_errors++;
 
@@ -157,7 +159,7 @@ TEST_CASE("pack_vector4_XX", "[math][vector4][packing]")
 			uint32_t max_value = (1 << num_bits) - 1;
 			for (uint32_t value = 0; value <= max_value; ++value)
 			{
-				const float value_unsigned = clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
+				const float value_unsigned = scalar_clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
 
 				vec0 = vector_set(value_unsigned, value_unsigned, value_unsigned);
 				pack_vector4_uXX_unsafe(vec0, num_bits, &buffer[0]);
@@ -188,9 +190,9 @@ TEST_CASE("pack_vector3_96", "[math][vector4][packing]")
 	{
 		UnalignedBuffer tmp0;
 		UnalignedBuffer tmp1;
-		Vector4_32 vec0 = vector_set(6123.123812F, 19237.01293127F, 0.913912387F);
+		vector4f vec0 = vector_set(6123.123812F, 19237.01293127F, 0.913912387F);
 		pack_vector3_96(vec0, &tmp0.buffer[0]);
-		Vector4_32 vec1 = unpack_vector3_96_unsafe(&tmp0.buffer[0]);
+		vector4f vec1 = unpack_vector3_96_unsafe(&tmp0.buffer[0]);
 		REQUIRE(vector_all_near_equal3(vec0, vec1, 1.0E-6F));
 
 		uint32_t x = unaligned_load<uint32_t>(&tmp0.buffer[0]);
@@ -230,9 +232,9 @@ TEST_CASE("pack_vector3_48", "[math][vector4][packing]")
 			const float value_signed = unpack_scalar_signed(value, 16);
 			const float value_unsigned = unpack_scalar_unsigned(value, 16);
 
-			Vector4_32 vec0 = vector_set(value_signed, value_signed, value_signed);
+			vector4f vec0 = vector_set(value_signed, value_signed, value_signed);
 			pack_vector3_s48_unsafe(vec0, &tmp0.buffer[0]);
-			Vector4_32 vec1 = unpack_vector3_s48_unsafe(&tmp0.buffer[0]);
+			vector4f vec1 = unpack_vector3_s48_unsafe(&tmp0.buffer[0]);
 			if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -255,8 +257,8 @@ TEST_CASE("decay_vector3_48", "[math][vector4][decay]")
 			const float value_signed = unpack_scalar_signed(value, 16);
 			const float value_unsigned = unpack_scalar_unsigned(value, 16);
 
-			Vector4_32 vec0 = vector_set(value_signed, value_signed, value_signed);
-			Vector4_32 vec1 = decay_vector3_s48(vec0);
+			vector4f vec0 = vector_set(value_signed, value_signed, value_signed);
+			vector4f vec1 = decay_vector3_s48(vec0);
 			if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -287,9 +289,9 @@ TEST_CASE("pack_vector3_32", "[math][vector4][packing]")
 			const float value_unsigned_xy = unpack_scalar_unsigned(value_xy, num_bits_xy);
 			const float value_unsigned_z = unpack_scalar_unsigned(value_z, num_bits_z);
 
-			Vector4_32 vec0 = vector_set(value_signed_xy, value_signed_xy, value_signed_z);
+			vector4f vec0 = vector_set(value_signed_xy, value_signed_xy, value_signed_z);
 			pack_vector3_32(vec0, 11, 11, 10, false, &tmp0.buffer[0]);
-			Vector4_32 vec1 = unpack_vector3_32(11, 11, 10, false, &tmp0.buffer[0]);
+			vector4f vec1 = unpack_vector3_32(11, 11, 10, false, &tmp0.buffer[0]);
 			if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -320,8 +322,8 @@ TEST_CASE("decay_vector3_32", "[math][vector4][decay]")
 			const float value_unsigned_xy = unpack_scalar_unsigned(value_xy, num_bits_xy);
 			const float value_unsigned_z = unpack_scalar_unsigned(value_z, num_bits_z);
 
-			Vector4_32 vec0 = vector_set(value_signed_xy, value_signed_xy, value_signed_z);
-			Vector4_32 vec1 = decay_vector3_s32(vec0, num_bits_xy, num_bits_xy, num_bits_z);
+			vector4f vec0 = vector_set(value_signed_xy, value_signed_xy, value_signed_z);
+			vector4f vec1 = decay_vector3_s32(vec0, num_bits_xy, num_bits_xy, num_bits_z);
 			if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -341,12 +343,12 @@ TEST_CASE("pack_vector3_24", "[math][vector4][packing]")
 		uint32_t num_errors = 0;
 		for (uint32_t value = 0; value < 256; ++value)
 		{
-			const float value_signed = min(unpack_scalar_signed(value, 8), 1.0F);
-			const float value_unsigned = min(unpack_scalar_unsigned(value, 8), 1.0F);
+			const float value_signed = scalar_min(unpack_scalar_signed(value, 8), 1.0F);
+			const float value_unsigned = scalar_min(unpack_scalar_unsigned(value, 8), 1.0F);
 
-			Vector4_32 vec0 = vector_set(value_signed, value_signed, value_signed);
+			vector4f vec0 = vector_set(value_signed, value_signed, value_signed);
 			pack_vector3_s24_unsafe(vec0, &tmp0.buffer[0]);
-			Vector4_32 vec1 = unpack_vector3_s24_unsafe(&tmp0.buffer[0]);
+			vector4f vec1 = unpack_vector3_s24_unsafe(&tmp0.buffer[0]);
 			if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 				num_errors++;
 
@@ -367,9 +369,9 @@ TEST_CASE("pack_vector3_XX", "[math][vector4][packing]")
 		alignas(16) uint8_t buffer[64];
 
 		uint32_t num_errors = 0;
-		Vector4_32 vec0 = vector_set(unpack_scalar_signed(0, 16), unpack_scalar_signed(12355, 16), unpack_scalar_signed(43222, 16));
+		vector4f vec0 = vector_set(unpack_scalar_signed(0, 16), unpack_scalar_signed(12355, 16), unpack_scalar_signed(43222, 16));
 		pack_vector3_sXX_unsafe(vec0, 16, &buffer[0]);
-		Vector4_32 vec1 = unpack_vector3_sXX_unsafe(16, &buffer[0], 0);
+		vector4f vec1 = unpack_vector3_sXX_unsafe(16, &buffer[0], 0);
 		if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 			num_errors++;
 
@@ -385,8 +387,8 @@ TEST_CASE("pack_vector3_XX", "[math][vector4][packing]")
 			uint32_t max_value = (1 << num_bits) - 1;
 			for (uint32_t value = 0; value <= max_value; ++value)
 			{
-				const float value_signed = clamp(unpack_scalar_signed(value, num_bits), -1.0F, 1.0F);
-				const float value_unsigned = clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
+				const float value_signed = scalar_clamp(unpack_scalar_signed(value, num_bits), -1.0F, 1.0F);
+				const float value_unsigned = scalar_clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
 
 				vec0 = vector_set(value_unsigned, value_unsigned, value_unsigned);
 				pack_vector3_uXX_unsafe(vec0, num_bits, &buffer[0]);
@@ -436,8 +438,8 @@ TEST_CASE("decay_vector3_XX", "[math][vector4][decay]")
 	{
 		uint32_t num_errors = 0;
 
-		Vector4_32 vec0 = vector_set(unpack_scalar_signed(0, 16), unpack_scalar_signed(12355, 16), unpack_scalar_signed(43222, 16));
-		Vector4_32 vec1 = decay_vector3_sXX(vec0, 16);
+		vector4f vec0 = vector_set(unpack_scalar_signed(0, 16), unpack_scalar_signed(12355, 16), unpack_scalar_signed(43222, 16));
+		vector4f vec1 = decay_vector3_sXX(vec0, 16);
 		if (!vector_all_near_equal3(vec0, vec1, 1.0E-6F))
 			num_errors++;
 
@@ -452,8 +454,8 @@ TEST_CASE("decay_vector3_XX", "[math][vector4][decay]")
 			uint32_t max_value = (1 << num_bits) - 1;
 			for (uint32_t value = 0; value <= max_value; ++value)
 			{
-				const float value_signed = clamp(unpack_scalar_signed(value, num_bits), -1.0F, 1.0F);
-				const float value_unsigned = clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
+				const float value_signed = scalar_clamp(unpack_scalar_signed(value, num_bits), -1.0F, 1.0F);
+				const float value_unsigned = scalar_clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
 
 				vec0 = vector_set(value_signed, value_signed, value_signed);
 				vec1 = decay_vector3_sXX(vec0, num_bits);
@@ -476,7 +478,7 @@ TEST_CASE("pack_vector2_64", "[math][vector4][packing]")
 	{
 		UnalignedBuffer tmp0;
 		UnalignedBuffer tmp1;
-		Vector4_32 vec0 = vector_set(6123.123812F, 19237.01293127F, 0.913912387F, 0.1816253F);
+		vector4f vec0 = vector_set(6123.123812F, 19237.01293127F, 0.913912387F, 0.1816253F);
 		pack_vector4_128(vec0, &tmp0.buffer[0]);
 
 		uint32_t x = unaligned_load<uint32_t>(&tmp0.buffer[0]);
@@ -494,7 +496,7 @@ TEST_CASE("pack_vector2_64", "[math][vector4][packing]")
 			const uint8_t offset = offsets[offset_idx];
 
 			memcpy_bits(&tmp1.buffer[0], offset, &tmp0.buffer[0], 0, 64);
-			Vector4_32 vec1 = unpack_vector2_64_unsafe(&tmp1.buffer[0], offset);
+			vector4f vec1 = unpack_vector2_64_unsafe(&tmp1.buffer[0], offset);
 			if (!vector_all_near_equal2(vec0, vec1, 1.0E-6F))
 				num_errors++;
 		}
@@ -509,9 +511,9 @@ TEST_CASE("pack_vector2_XX", "[math][vector4][packing]")
 		alignas(16) uint8_t buffer[64];
 
 		uint32_t num_errors = 0;
-		Vector4_32 vec0 = vector_set(unpack_scalar_unsigned(0, 16), unpack_scalar_unsigned(12355, 16), unpack_scalar_unsigned(43222, 16), unpack_scalar_unsigned(54432, 16));
+		vector4f vec0 = vector_set(unpack_scalar_unsigned(0, 16), unpack_scalar_unsigned(12355, 16), unpack_scalar_unsigned(43222, 16), unpack_scalar_unsigned(54432, 16));
 		pack_vector2_uXX_unsafe(vec0, 16, &buffer[0]);
-		Vector4_32 vec1 = unpack_vector2_uXX_unsafe(16, &buffer[0], 0);
+		vector4f vec1 = unpack_vector2_uXX_unsafe(16, &buffer[0], 0);
 		if (!vector_all_near_equal2(vec0, vec1, 1.0E-6F))
 			num_errors++;
 
@@ -521,7 +523,7 @@ TEST_CASE("pack_vector2_XX", "[math][vector4][packing]")
 			uint32_t max_value = (1 << num_bits) - 1;
 			for (uint32_t value = 0; value <= max_value; ++value)
 			{
-				const float value_unsigned = clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
+				const float value_unsigned = scalar_clamp(unpack_scalar_unsigned(value, num_bits), 0.0F, 1.0F);
 
 				vec0 = vector_set(value_unsigned, value_unsigned, value_unsigned);
 				pack_vector2_uXX_unsafe(vec0, num_bits, &buffer[0]);