diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index ac1f5c5..7b96a9d 100644 --- a/src/sc_sacd.cpp +++ b/src/sc_sacd.cpp @@ -684,6 +684,14 @@ SC_SACD_Vec3 SC_SACD_Vec3_Div(SC_SACD_Vec3 vec, float scalar) { return vec / scalar; } +SC_SACD_Vec3 SC_SACD_Vec3_Negate(SC_SACD_Vec3 vec) { + return SC_SACD_Vec3{-vec.x, -vec.y, -vec.z}; +} + +SC_SACD_Vec3 SC_SACD_Vec3_Normalize(SC_SACD_Vec3 vec) { + return vec / SC_SACD_Vec3_Length(vec); +} + SC_SACD_Vec3 SC_SACD_Vec3_Project(SC_SACD_Vec3 vec, SC_SACD_Vec3 target) { float upper_dot_product = SC_SACD_Dot_Product(vec, target); float lower_dot_product = SC_SACD_Dot_Product(target, target); diff --git a/src/sc_sacd.h b/src/sc_sacd.h index 8b400a9..ae05156 100644 --- a/src/sc_sacd.h +++ b/src/sc_sacd.h @@ -142,6 +142,11 @@ SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Difference(SC_SACD_Vec3 a, SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Mult(SC_SACD_Vec3 vec, float scalar); SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Div(SC_SACD_Vec3 vec, float scalar); +SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Negate(SC_SACD_Vec3 vec); + +/// Turns vec into a unit vector and returns the unit vector. +SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Normalize(SC_SACD_Vec3 vec); + /// Projects "vec" onto "target". SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Project(SC_SACD_Vec3 vec, SC_SACD_Vec3 target); diff --git a/src/test.cpp b/src/test.cpp index ea8e03c..1fe322c 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -840,6 +840,68 @@ int main() { CHECK_FLOAT(result.z, 3.0F); } + // Test negate. + { + SC_SACD_Vec3 vec{1.0F, 2.0F, 3.0F}; + vec = SC_SACD_Vec3_Negate(vec); + CHECK_FLOAT(vec.x, -1.0F); + CHECK_FLOAT(vec.y, -2.0F); + CHECK_FLOAT(vec.z, -3.0F); + } + + // Test normalize. + { + SC_SACD_Vec3 vec{1.0F, 0.0F, 0.0F}; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, 1.0F); + CHECK_FLOAT(vec.y, 0.0F); + CHECK_FLOAT(vec.z, 0.0F); + + vec.x = 0.0F; + vec.y = -1.0F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, 0.0F); + CHECK_FLOAT(vec.y, -1.0F); + CHECK_FLOAT(vec.z, 0.0F); + + vec.y = 0.0F; + vec.z = 0.7F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, 0.0F); + CHECK_FLOAT(vec.y, 0.0F); + CHECK_FLOAT(vec.z, 1.0F); + + vec.x = 1.0F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, std::sqrt(0.5F)); + CHECK_FLOAT(vec.y, 0.0F); + CHECK_FLOAT(vec.z, std::sqrt(0.5F)); + + vec.x = 1.0F; + vec.y = 1.0F; + vec.z = 1.0F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, std::sqrt(1.0F / 3.0F)); + CHECK_FLOAT(vec.y, std::sqrt(1.0F / 3.0F)); + CHECK_FLOAT(vec.z, std::sqrt(1.0F / 3.0F)); + + vec.x = 1.0F; + vec.y = -1.0F; + vec.z = -1.0F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, std::sqrt(1.0F / 3.0F)); + CHECK_FLOAT(vec.y, -std::sqrt(1.0F / 3.0F)); + CHECK_FLOAT(vec.z, -std::sqrt(1.0F / 3.0F)); + + vec.x = 1.0F; + vec.y = 2.0F; + vec.z = 3.0F; + vec = SC_SACD_Vec3_Normalize(vec); + CHECK_FLOAT(vec.x, std::sqrt(1.0F / 14.0F)); + CHECK_FLOAT(vec.y, std::sqrt(4.0F / 14.0F)); + CHECK_FLOAT(vec.z, std::sqrt(9.0F / 14.0F)); + } + std::cout << "Checks checked: " << checks_checked << '\n' << "Checks passed: " << checks_passed << '\n';