Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion include/game/cLib/c_lib.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
#pragma once
#include <types.h>
#include <game/mLib/m_vec.hpp>
/// @file

/// @brief Provides common utilities.
/// @ingroup clib
namespace cLib {
void memSet(void *dst, int val, ulong size); ///< See memset.

/// @brief Checks if a floating-point value is effectively zero within epsilon tolerance.
/// @param val The float value to evaluate.
/// @return @p true if the absolute value is less than FLT_EPSILON, @p false otherwise.
inline bool isZero(float val) {
return (std::fabs(val) < FLT_EPSILON);
}

/// @brief Calculates the yaw (Y-axis) orientation angle from an origin position to a target position.
/// @param vec1 The origin position vector.
/// @param vec2 The target position vector.
/// @return The calculated yaw value.
s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2);

/// @brief Calculates the pitch (X-axis) orientation angle from an origin position to a target position.
/// @param vec1 The origin position vector.
/// @param vec2 The target position vector.
/// @return The calculated pitch value.
s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2);

/**
* @brief Smoothly moves @p currentPos towards @p targetPos using proportional scaling.
* @details If the applied step overshoots the target, the position is snapped exactly to the target.
* @param currentPos The position to be updated.
* @param targetPos The target position.
* @param ratio The smoothing ratio (between @p 0.0f and @p 1.0f). Higher value means snappier movement.
* @param maxStep The maximum step for a single update.
* @param minStep The minimum step to prevent jittering.
* @return The absolute remaining distance to the target position.
*/
float addCalcPos(mVec3_c *currentPos, const mVec3_c &targetPos, float ratio, float maxStep, float minStep);

/** @brief Moves @p currentPos towards @p targetPos by a fixed @p step amount.
* @details If the applied step overshoots the target, the position is snapped exactly to the target.
* @param currentPos The position to be updated.
* @param targetPos The target position.
* @param step The step value.
* @return @p true if the position reached the target, @p false otherwise.
*/
bool chasePos(mVec3_c *currentPos, const mVec3_c &targetPos, float step);

} // namespace cLib
7 changes: 7 additions & 0 deletions slices/wiimj2d.json
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,13 @@
".sbss": "0x7b0-0x7d0"
}
},
{
"source": "dol/cLib/c_lib.cpp",
"memoryRanges": {
".text": "0x15a490-0x15a8d0",
".sdata2": "0x2b80-0x2b88"
}
},
{
"source": "dol/cLib/c_line.cpp",
"memoryRanges": {
Expand Down
69 changes: 69 additions & 0 deletions source/dol/cLib/c_lib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <game/cLib/c_lib.hpp>
#include <lib/egg/math/eggMath.h>
#include <lib/revolution/MTX/vec.h>
#include <string.h>

inline float calcDistance(const mVec3_c &a, const mVec3_c &b) {
float dx = a.x - b.x;
float dy = a.y - b.y;
float dz = a.z - b.z;
return EGG::Mathf::sqrt(dx * dx + dy * dy + dz * dz);
}

namespace cLib {

void memSet(void *dst, int val, ulong size) {
memset(dst, val, size);
}

float addCalcPos(mVec3_c *currPos, const mVec3_c &targetPos, float ratio, float maxStep, float minStep) {
if (*currPos != targetPos) {
mVec3_c stepVector;
stepVector = *currPos - targetPos;
float distance = PSVECMag(stepVector);
if (distance < minStep) {
*currPos = targetPos;
} else {
stepVector *= ratio;
float step = distance * ratio;
if (!isZero(step)) {
if (step > maxStep) {
stepVector *= maxStep / step;
} else if (step < minStep) {
stepVector *= minStep / step;
}
*currPos -= stepVector;
} else {
*currPos = targetPos;
}
}
}

return calcDistance(*currPos, targetPos);
}

bool chasePos(mVec3_c *currentPos, const mVec3_c &targetPos, float step) {
if (step) {
mVec3_c offset = *currentPos - targetPos;
float distance = PSVECMag(offset);
if (isZero(distance) || distance <= step) {
*currentPos = targetPos;
return true;
}
*currentPos -= (step / distance) * offset;
} else if (*currentPos == targetPos) {
return true;
}
return false;
}

s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2) {
return cM::atan2s(vec2.x - vec1.x, vec2.z - vec1.z);
}

s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2) {
mVec3_c diff = vec2 - vec1;
return cM::atan2s(diff.y, diff.xzLen());
}

} // namespace cLib
9 changes: 3 additions & 6 deletions source/dol/cLib/c_math.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <types.h>
#include <math.h>
#include <nw4r/math.h>
#include <game/cLib/c_lib.hpp>
#include <game/cLib/c_random.hpp>
/// @file

Expand Down Expand Up @@ -96,10 +97,6 @@ inline float getCircleUnit() {
return 65536 / (2 * M_PI);
}

inline bool isZero(float val) {
return (std::fabs(val) < FLT_EPSILON);
}

s16 rad2s(float rad) {
// Clamp the value between -65535 and 65535
int mod = (float)fmod(rad, 2 * M_PI) * getCircleUnit();
Expand All @@ -125,11 +122,11 @@ namespace cM {
inline u32 atan2i(float sin,float cos) {

// 0° or 180°
if (isZero(sin)) {
if (cLib::isZero(sin)) {
return (cos >= 0.0f) ? 0 : 0x8000;

// 90° or 270°
} else if (isZero(cos)) {
} else if (cLib::isZero(cos)) {
return (sin >= 0.0f) ? 0x4000 : 0xC000;

} else if (sin >= 0.0f) {
Expand Down
Loading