jittery movement of held item (tracking hand position/rotation) when item meshes are offset

I’m writing my own library to handle grabbing objects in VR.

I am using the method that changes the velocity and angular velocity of the held object every FixedUpdate based on the difference between the held object’s position and rotation to the controller’s position and rotation respectively.

The item that can be held has the following hierarchy
6958529--819359--upload_2021-3-21_15-30-6.png

Part 1 and Part 2 are simple meshes, that each have a box collider. hold position 1 and hold position 2 are empty game objects that mark locations the player can grab the object at. When the player grabs the item I calculated which hold position is closest to the hand then reposition the ‘item components’ GameObject according to the local position of the appropriate hold position (‘item component’ strictly exists to be repositioned within ‘item’). ‘item’ has the only rigidbody component… This all works fine. The item can be picked up and it can be held at two locations.

However the movement of the item is jittery if it is held at a hold position that is not located at the origin of the ‘item’ GameObject.

I have ‘hold position 1’ located near the origin, and the movement of the object is smooth when the item is held at this location (e.g. the ‘item components’ object has a local position of 0,0,0).

I have ‘hold position 2’ located about half a meter below the origin of the the ‘item’ GameObject and the item’s movement is jittery (e.g. in this case the ‘item components’ object has a local position of about 0,0.5,0, which places the meshes and colliders of the item further up in relation to the hand).

I thought this may be tied to center of mass and inertia tensor. So I called ResetCenterOfMass and ResetInertiaTensor on the rigid body after I moved the 'item component’s position and rotation. But I saw no different in the resulting behavior.

The parent gameobject of the item has code with the following FixedUpdate

void FixedUpdate()
       if (isHeld)
        {
            rigidb.velocity = (temp.GetPalm().transform.position - transform.position) * speed / Time.fixedDeltaTime;

            rigidb.maxAngularVelocity = maxAngularVelocity;
            Quaternion deltaRot = temp.GetPalm().transform.rotation * Quaternion.Inverse(transform.rotation);// transform.rotation);
            Vector3 eulerRotShortestDistance = new Vector3(Mathf.DeltaAngle(0, deltaRot.eulerAngles.x), Mathf.DeltaAngle(0, deltaRot.eulerAngles.y), Mathf.DeltaAngle(0, deltaRot.eulerAngles.z));
            eulerRotShortestDistance *= Mathf.Deg2Rad;
            rigidb.angularVelocity = eulerRotShortestDistance * rotSpeed / Time.fixedDeltaTime;
        }
    }

When I pick up the object I run a function that repositions the children objects (that are the 3D models that make up the object)

    public void BeginHold(HandController hand)
    {
        //orient children gameobjects so hand hold location is at parent gameobject's origin
        if(GetHoldForGivenHand(hand, out Transform tform))
        {
            objectComponents.transform.localPosition = -tform.localPosition;
            objectComponents.transform.localRotation = tform.localRotation;
            //rigidb.ResetCenterOfMass();
            //rigidb.ResetInertiaTensor();
        }
        else
        {
            Debug.LogError("could not find current hand hold");
        }

        isHeld = true;
    }

For anyone who may run into my post here. I found the answer myself. This requires the center of mass of the rigid body to be located at 0,0,0 in relation to the origin of the GameObject where the RigidBody is located. Otherwise Unity calculates the center of mass based on the colliders of all the children, which causes the rotation of the item to be incorrect unless it is held at or near the center of mass.