Skip to content

perf: redundant sin/cos calls per vertex in rotation logic #1

Description

@ved-in

RotateX and RotateY each call std::sin and std::cos internally on every call. Because these functions are called once per vertex per frame, and cam.rotX / cam.rotY do not change between vertices, the trig is being recomputed N times per frame when it only needs to be computed once.

Where it happens

In renderer.cpp, the rotated lambda:

// cam.rotX and cam.rotY are constant for the entire frame.
// std::sin / std::cos are called here for EVERY vertex.
auto rotated = [&](Vector3 v) -> Vector3 {
    v = RotateY(v, cam.rotY);
    v = RotateX(v, cam.rotX);
    return v;
};

In controls.cpp, the jumpTo lambda (vertex selection in EDIT mode):

// Called for every vertex in the mesh to find the best candidate.
// RotateY and RotateX called fresh for each one.
Vector3 vn = RotateY(mesh.vertices[i], state.camera.rotY);
vn = RotateX(vn, state.camera.rotX);

In controls.cpp, the free-move delta block (arrow key movement):

// Inverted rotations applied to the movement delta.
// Same angles, same redundant trig.
delta = RotateX(delta, -state.camera.rotX);
delta = RotateY(delta, -state.camera.rotY);

All three sites use the same cam.rotX / cam.rotY angles and should use precomputed sin / cos values instead.

Why this matters

For a simple cube (8 vertices) the impact is negligible
For imported OBJ meshes with thousands of vertices the cost compounds linearly with vertex count
4 trig calls are recomputed per vertex when they only need to be computed once per frame

Proposed fix

Precompute sin and cos once before the vertex loop and pass them into the rotation functions. Per-vertex work then becomes only multiplications and additions, no trig.

// Compute once per frame - 4 trig calls total regardless of vertex count
float sy = std::sin(cam.rotY), cy = std::cos(cam.rotY);
float sx = std::sin(cam.rotX), cx = std::cos(cam.rotX);

// Per vertex: pure arithmetic, zero trig
auto rotated = [&](Vector3 v) -> Vector3 {
    v = RotateY(v, cy, sy);
    v = RotateX(v, cx, sx);
    return v;
};

This requires updating the RotateX and RotateY in math.h / math.cpp to accept precomputed cosa / sina

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions