Page MenuHomeFeedback Tracker

Angle Clamping Commands
New, NormalPublic

Description

I would like to request some new script commands that deal with angles. Namely clamping them. My use case is clamping rotations between a certain angle. Creating a sqf function is possible and I have done it, but repeatedly call that function every frame is not fun.

// Name, Description, return type, unary arg
"clampAngle", "clamp angles a,b,c", SCALAR, ARRAY
"clampAxis", "clamp an axis between 0..360", SCALAR, SCALAR;
"normalizeAxis", "normalize an axis between -180..180", SCALAR, SCALAR;
"clampVector", "clamps all components of a vec3 between 0 and 360", ARRAY, ARRAY

clampAngle [35, 20, 25]; //args are angle value, min angle, max angle returns 25
clampAngle [-20, 20, 25]; // returns 20
clampAxis 400; //returns 40 
clampAxis -10; //returns 350
normalizeAxis 562; //returns -158
normalizeAxis -280; // returns 80
clampVector [400, 600, 800];  // returns [40, 240, 80]
clampVector[762, 562, 9772];  // returns [42, 202, 52]

In addition information I have provide c++ code for implementation of all the commands that I have requested.

Details

Severity
Feature
Resolution
Open
Reproducibility
N/A
Operating System
Windows 10 x64
Category
Scripting
Additional Information
/*
 * @brief returns a value between 0 and 360 degrees
 * @author Killerswin2
 * @param angle float angle in degrees to be AxisClamped
 * @return float clampedAxis
 * @see Rotator::clampAxis for sqf cmd
 */
float clampAxisInternal(float angle)
{
    angle = std::fmod(angle, 360);

    if (angle < 0)
    {
        angle = angle + 360.0f;
    }

    return angle;
}

/*
 * @brief returns a value between -180 and 180 degrees
 * @author Killerswin2
 * @param angle float angle in degrees to be normalized
 * @return float normalized angle
 * @see Rotator::normalizeAxis for sqf cmd
 */
float normalizeAxisInternal(float angle)
{
    // make sure angle is with in (0,360)
    angle = clampAxisInternal(angle);

    if (angle > 180.0f)
    {
        angle = angle - 360.0f;     // in the range of -180,180 normalized
    }

    return angle;
}


/*
 * @brief clamps an angle in degrees between min angle and max angle.
 * @author Killerswin2
 * @param angle float current angle measurement
 * @param minAngle float min allowed angle to clamp to
 * @param maxAngle float max allowed angle to clamp to
 * @return float normalized angle
 * @see Rotator::clampAngle for sqf cmd
 * @warning coterminal angles are handled, 400 -> 40
 */
float clampAngleInternal(float angle, float minAngle, float maxAngle)
{
    float deltaAngle = clampAxisInternal(maxAngle - minAngle) * 0.5f;
    float centerAngle = clampAxisInternal(minAngle + deltaAngle);
    float centerDisplacement = normalizeAxisInternal(angle - centerAngle);

    // clamp values here
    if (centerDisplacement > deltaAngle)
    {
        return normalizeAxisInternal(centerAngle + deltaAngle);
    }
    else if (centerDisplacement < -deltaAngle)
    {
        return normalizeAxisInternal(centerAngle - deltaAngle);
    }

    return normalizeAxisInternal(angle);
}


/*
* @brief clamps all components of a vec3 between 0 and 360
* @author Killerswin2
* @param x float x component
* @param y float y component
* @param z float z component
* @return vec3 clamped vec3
* @see Rotator::clamp for sqf cmd
*/
vector3 clampInternal(float x, float y, float z)
{
    return vector3{clampAxisInternal(x), clampAxisInternal(y), clampAxisInternal(z)};
}

Event Timeline

SaMatra added a subscriber: SaMatra.Mar 5 2023, 6:27 AM
killerswin2 updated the task description. (Show Details)Mar 5 2023, 6:57 AM
killerswin2 edited Additional Information. (Show Details)Mar 5 2023, 7:27 PM
killerswin2 added a comment.EditedMar 5 2023, 7:40 PM

float clampAngleInternal(float angle, float minAngle, float maxAngle)
was incorrect for negative angles.

float deltaAngle = clampAxisInternal(maxAngle - minAngle) * 0.5f;

is the correct statement