Skip to content

Fix uninitialized member state in IKSolverVR causing erratic elbow/arm IK#8

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-iksolvervr-initialization
Draft

Fix uninitialized member state in IKSolverVR causing erratic elbow/arm IK#8
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-iksolvervr-initialization

Conversation

Copy link
Copy Markdown

Copilot AI commented May 4, 2026

Several IKSolverVR members were declared without default values, leading to nondeterministic solver initialization and potential junk-pointer dereferences that manifested as unstable elbow/arm positioning.

Changes — include/customTypes/FinalIK/IKSolverVR.hpp

  • bool initiated= false: gates FixTransforms(), Update(), and Read(); garbage value allows solver to run before init
  • bool firstInitiation= true: Update() uses this to trigger Initiate(root) on first call; must start true
  • UnityEngine::Transform* root= nullptr: passed into Initiate() on first update; uninitialized = crash risk
  • VirtualBone* rootBone= nullptr: Read() branches on rootBone == nullptr to construct vs. update the bone; a garbage non-null pointer would invoke Read() on invalid memory, corrupting the entire arm chain
  • int supportLegIndex= -1 (was 0): code explicitly resets to -1 at the start of each solve cycle before recomputing; starting at 0 falsely marks leg 0 as the support leg on the first frame, biasing root/shoulder space
// Before — undefined behavior waiting to happen
bool initiated;
bool firstInitiation;
UnityEngine::Transform* root;
VirtualBone* rootBone;
int supportLegIndex = 0;

// After
bool initiated = false;
bool firstInitiation = true;
UnityEngine::Transform* root = nullptr;
VirtualBone* rootBone = nullptr;
int supportLegIndex = -1;
Original prompt

Create a PR for repo BSQ-VRM/VRM-Qavatars (base: main) to address buggy elbow/arm IK behavior likely caused by uninitialized member state in IKSolverVR.

Context:

  • In include/customTypes/FinalIK/IKSolverVR.hpp, several members are declared without default initialization:
    • bool initiated;
    • bool firstInitiation;
    • UnityEngine::Transform* root;
    • VirtualBone* rootBone;
    • (optionally) int supportLegIndex currently defaults to 0.
  • These are used in src/customTypes/FinalIK/IKSolverVR.cpp for initialization gating (FixTransforms/Update/Read) and pointer checks (rootBone == nullptr). If uninitialized, they can cause nondeterministic solver init and potentially junk-pointer dereference.

Required changes:

  1. In include/customTypes/FinalIK/IKSolverVR.hpp, add safe default initializers:
    • initiated = false
    • firstInitiation = true (or false if consistent with existing flow; choose the value that ensures Initiate() happens on first Update when root is set)
    • root = nullptr
    • rootBone = nullptr
  2. Consider changing supportLegIndex default from 0 to -1 to avoid an invalid bias prior to first computation; ensure locomotion->Solve() handles -1 or adjust code accordingly.
  3. Ensure compilation passes and no behavior regressions.

Notes:

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: There's an issue with the elbow positioning being buggy, i'm thinking uninitialized float. any ideas?

Assistant: Most likely, yes: you have uninitialized state, but it’s not a float—it's multiple member variables/pointers in IKSolverVR that are never initialized (and can directly manifest as “random elbow” / arm-solver instability).

1) initiated and firstInitiation are never initialized

In IKSolverVR.hpp these are declared but have no default values:

bool initiated;
bool firstInitiation;

Yet they gate important behavior:

  • FixTransforms() early-outs on !initiated
  • Update() calls Initiate(root) if firstInitiation is true
  • Read() has special one-time init logic under if (!initiated)

If either bool starts as garbage, you can get:

  • solver running before proper init (bad readPositions/readRotations, offsets, etc.)
  • init happening repeatedly or not at all
  • default locals not stored before use

That kind of “sometimes the elbow explodes / jitters” is classic.

Fix: default-initialize them in the header:

bool initiated = false;
bool firstInitiation = true;   // or false, depending on your intended flow
UnityEngine::Transform* root = nullptr;
VirtualBone* rootBone = nullptr;

2) rootBone is also never initialized

In the header:

VirtualBone* rootBone;

In Read() you do:

if (rootBone == nullptr) { rootBone = new VirtualBone(...); } else { rootBone->Read(...); }

But if rootBone is uninitialized garbage, it may be non-null and you’ll call rootBone->Read(...) on a junk pointer. That can corrupt anything, including arm chain data used for elbows.

So rootBone = nullptr; is critical.

3) supportLegIndex default is suspicious

You set:

int supportLegIndex = 0;

But later in Solve() you pass it into locomotion:

locomotion->Solve(..., supportLegIndex, ...);

And only after a full solve do you recompute it, and you also sometimes set it to -1:

supportLegIndex = -1;
...
supportLegIndex = m;

If locomotion expects -1 initially (or validates it), starting at 0 might bias locomotion/root offsets for the first frame(s). That can indirectly disturb arm/shoulder space and show up as elbow weirdness. Not as strong as the uninitialized pointers/bools, but worth fixing.

What I’d do first (minimal changes, high impact)

  1. Initialize these in IKSolverVR.hpp:
    • initiated = false
    • firstInitiation = true (if you rely on it to auto-init)
    • root = nullptr
    • rootBone = nullptr
  2. Consider supportLegIndex = -1 as the safer default.

Quick verification

If you can add logging for one run, print at solver construction / first Update():

  • initiated, firstInitiation, rootBone, root
    If any look non-deterministic between runs, that confirms it.

If you want, paste VR/Arm.* (especially where elbow bend plane / pole vector is derived) and I can point to the next most likely culprit after initialization (often a zero-length axis or invalid shoulder/chest reference feeding the elbow plane).

User: can you make a pr with those changes?

Assistant: I’ve queued up the pull request creation with the member-initialization fixes, and I’m currently waiting for your approval in the confirmation dialo...

This pull request was created from Copilot chat.

Agent-Logs-Url: https://github.com/BSQ-VRM/VRM-Qavatars/sessions/70de94b6-d9a8-45b2-9a06-3e59663c427c

Co-authored-by: Futuremappermydud <54294576+Futuremappermydud@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix uninitialized member state in IKSolverVR Fix uninitialized member state in IKSolverVR causing erratic elbow/arm IK May 4, 2026
Copilot AI requested a review from Futuremappermydud May 4, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants