cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Grip Pose question

lordraider
Honored Guest
Hello,

I managed to create a custom grip pose and saved it as a prefab in unity.
In my main project i set the custom grip pose to the LeftHandCustomPose variable of the OvrAvatar when let's say the trigger is being pressed. But it instantly changes the pose to the new pose.
Is there default support to smoothly transition the default pose to the "gripping" trigger pose base on the trigger value?
Or do I need to traverse the 2 poses (from pose and to pose)  myself and apply a lineair lerp for the joint transform positions and quaternions according the trigger value?

Don't know if the sdk support this.. you can only set one custom pose at a time and also can't set what's the "type" of the pose (trigger , index , normal and so on) so I suppose you need to manage this yourself?

Thanks in advance
6 REPLIES 6

fget487
Honored Guest
Good question i would really know too....

lordraider
Honored Guest
I managed to do it yesterday, just loop through all the joint transforms and lerp just the rotations, not the locations, because the rotation automatically moves your joint in a realistic manner, moving the location from a to b in a straight line makes your finger parts "cringe" 🙂

Chadobado
Explorer
@lordraider where/how did you lerp the joint rotations?  I spent a few hours on this and haven't been successful.  Ended up modifying the UpdateTransforms function to try and return a Quaternion.Lerp/Slerp'd rotation that OvrAvatar would pass to CAPI.ovrAvatar_Set*HandCustomGesture(..) but I've had zero luck. 

masterchop
Protege


I managed to do it yesterday, just loop through all the joint transforms and lerp just the rotations, not the locations, because the rotation automatically moves your joint in a realistic manner, moving the location from a to b in a straight line makes your finger parts "cringe" 🙂


Do you have a quick sample of this? i think i can make the changes but how to make it real.

Chadobado
Explorer
Also, just to clarify - are you lerping the rotations of the joints and sending that custom pose back to the SDK, or are you simply updating the hand mesh's bones in Unity only?

Does anyone know why the UpdatePose function in OvrAvatarHand is empty?  Am I correct in thinking we should subclass this and override this method to extend the system/add custom behaviors?

RussG
Explorer
I am only moving one finger so I don't have to traverse the entire hand skeleton but here's my quick-and-dirty solution.  It's a little gross, and only handles one bone, but again, quick-and-dirty.

I created two prefabs in the pose editor and saved them, and then lerp the index finger from one to the other based on the position of the trigger.

RootName in my case is the name of the root bone of the index finger
LerpFromPose and LerpToPose are the prefabs saved from the pose editor
The script is attached to LocalAvatar and is called from my loop where I handle the state of the flashlight.

using UnityEngine;
using UnityExtensions;

public class LerpAnimation : MonoBehaviour
{

public string RootName;
public GameObject LerpFromPose;
public GameObject LerpToPose;

Transform m_lerpTarget;
Transform m_fromRoot;
Transform m_toRoot;

// Use this for initialization
void Start ()
{
if (null == RootName ||
null == LerpFromPose ||
null == LerpToPose)
{
this.enabled = false;
}
}


public void LerpUpdate(float lerp)
{
if (!this.enabled)
return;

// these skeletons should match up one-for-one, although I don't verify that anywhere
if (null == m_lerpTarget)
{
m_lerpTarget = transform.FindChildAnywhere(RootName);
if (null == m_lerpTarget)
return;
}

if (null == m_fromRoot)
{
m_fromRoot = LerpFromPose.transform.FindChildAnywhere(RootName);
if (null == m_fromRoot)
return;
}

if (null == m_toRoot)
{
m_toRoot = LerpToPose.transform.FindChildAnywhere(RootName);
if (null == m_toRoot)
return;
}

lerp = Mathf.Clamp01(lerp);

Transform cur = m_lerpTarget;
Transform from = m_fromRoot;
Transform to = m_toRoot;

while (true)
{
cur.localRotation = Quaternion.Lerp(from.localRotation, to.localRotation, lerp);

if (0 == cur.childCount)
break;

cur = cur.GetChild(0);
from = from.GetChild(0);
to = to.GetChild(0);
}
}
}