Skip to content

Commit

Permalink
Hips following option
Browse files Browse the repository at this point in the history
`Moving` parameter
  • Loading branch information
SDraw committed Nov 3, 2022
1 parent 8ef2566 commit a3b4f46
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Merged set of MelonLoader mods for ChilloutVR.
| Full name | Short name | Latest version | Available in [CVRMA](https://github.com/knah/CVRMelonAssistant) | Current Status | Notes |
|-----------|------------|----------------|-----------------------------------------------------------------|----------------|-------|
| Avatar Change Info | ml_aci | 1.0.3 | Yes | Working |
| Avatar Motion Tweaker | ml_amt | 1.1.7 | Yes | Working |
| Avatar Motion Tweaker | ml_amt | 1.1.8 | Yes, pending update | Working |
| Desktop Head Tracking | ml_dht | 1.0.7 | Yes | Working |
| Desktop Reticle Switch | ml_drs | 1.0.0 | Yes | Working |
| Four Point Tracking | ml_fpt | 1.0.9 | Yes | Working |
Expand Down
1 change: 1 addition & 0 deletions ml_amt/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ System.Collections.IEnumerator WaitForLocalPlayer()
m_localTweaker.SetIKOverrideFly(Settings.IKOverrideFly);
m_localTweaker.SetIKOverrideJump(Settings.IKOverrideJump);
m_localTweaker.SetDetectEmotes(Settings.DetectEmotes);
m_localTweaker.SetFollowHips(Settings.FollowHips);
}

public override void OnDeinitializeMelon()
Expand Down
53 changes: 52 additions & 1 deletion ml_amt/MotionTweaker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class MotionTweaker : MonoBehaviour
enum ParameterType
{
Upright,
GroundedRaw
GroundedRaw,
Moving
}

enum ParameterSyncType
Expand Down Expand Up @@ -49,13 +50,15 @@ enum PoseState
float m_ikWeight = 1f; // Original weight
float m_locomotionWeight = 1f; // Original weight
float m_avatarScale = 1f; // Instantiated scale
Transform m_avatarHips = null;

bool m_avatarReady = false;
bool m_compatibleAvatar = false;
float m_upright = 1f;
PoseState m_poseState = PoseState.Standing;
bool m_grounded = false;
bool m_groundedRaw = false;
bool m_moving = false;

bool m_ikOverrideCrouch = true;
float m_crouchLimit = 0.65f;
Expand All @@ -76,6 +79,9 @@ enum PoseState
bool m_detectEmotes = true;
bool m_emoteActive = false;

bool m_followHips = true;
Vector3 m_hipsToPlayer = Vector3.zero;

readonly List<AdditionalParameterInfo> m_parameters = null;

public MotionTweaker()
Expand All @@ -94,6 +100,7 @@ void Start()
Settings.IKOverrideFlyChange += this.SetIKOverrideFly;
Settings.IKOverrideJumpChange += this.SetIKOverrideJump;
Settings.DetectEmotesChange += this.SetDetectEmotes;
Settings.FollowHipsChange += this.SetFollowHips;
}

void OnDestroy()
Expand All @@ -107,6 +114,7 @@ void OnDestroy()
Settings.IKOverrideFlyChange -= this.SetIKOverrideFly;
Settings.IKOverrideJumpChange -= this.SetIKOverrideJump;
Settings.DetectEmotesChange -= this.SetDetectEmotes;
Settings.FollowHipsChange -= this.SetFollowHips;
}

void Update()
Expand All @@ -115,6 +123,7 @@ void Update()
{
m_grounded = (bool)ms_grounded.GetValue(MovementSystem.Instance);
m_groundedRaw = (bool)ms_groundedRaw.GetValue(MovementSystem.Instance);
m_moving = !Mathf.Approximately(MovementSystem.Instance.movementVector.magnitude, 0f);

// Update upright
Matrix4x4 l_hmdMatrix = PlayerSetup.Instance.transform.GetMatrix().inverse * (PlayerSetup.Instance._inVr ? PlayerSetup.Instance.vrHeadTracker.transform.GetMatrix() : PlayerSetup.Instance.desktopCameraRig.transform.GetMatrix());
Expand All @@ -124,6 +133,12 @@ void Update()
m_upright = Mathf.Clamp(((l_avatarViewHeight > 0f) ? (l_currentHeight / l_avatarViewHeight) : 0f), 0f, 1f);
PoseState l_poseState = (m_upright <= m_proneLimit) ? PoseState.Proning : ((m_upright <= m_crouchLimit) ? PoseState.Crouching : PoseState.Standing);

if(m_followHips && (m_avatarHips != null))
{
Vector4 l_hipsToPlayer = (PlayerSetup.Instance.transform.GetMatrix().inverse * m_avatarHips.GetMatrix()) * ms_pointVector;
m_hipsToPlayer.Set(l_hipsToPlayer.x, 0f, l_hipsToPlayer.z);
}

if(PlayerSetup.Instance._inVr && (m_vrIk != null) && m_vrIk.enabled)
{
if(m_poseState != l_poseState)
Expand Down Expand Up @@ -196,6 +211,20 @@ void Update()
}
}
break;

case ParameterType.Moving:
{
switch(l_param.m_sync)
{
case ParameterSyncType.Local:
PlayerSetup.Instance._animator.SetBool(l_param.m_hash, m_moving);
break;
case ParameterSyncType.Synced:
PlayerSetup.Instance.animatorManager.SetAnimatorParameterBool(l_param.m_name, m_moving);
break;
}
}
break;
}
}
}
Expand All @@ -217,13 +246,17 @@ public void OnAvatarClear()
m_locomotionOffset = Vector3.zero;
m_avatarScale = 1f;
m_emoteActive = false;
m_moving = false;
m_hipsToPlayer = Vector3.zero;
m_avatarHips = null;
m_parameters.Clear();
}

public void OnSetupAvatar()
{
m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
m_locomotionLayer = PlayerSetup.Instance._animator.GetLayerIndex("Locomotion/Emotes");
m_avatarHips = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Hips);

// Parse animator parameters
AnimatorControllerParameter[] l_params = PlayerSetup.Instance._animator.parameters;
Expand Down Expand Up @@ -280,6 +313,8 @@ public void OnSetupAvatar()

void OnIKPreUpdate()
{
bool l_overrided = false;

m_ikWeight = m_vrIk.solver.IKPositionWeight;
m_locomotionWeight = m_vrIk.solver.locomotion.weight;

Expand All @@ -290,14 +325,26 @@ void OnIKPreUpdate()
if(PlayerSetup.Instance._inVr)
{
if((m_ikOverrideCrouch && (m_poseState != PoseState.Standing)) || (m_ikOverrideProne && (m_poseState == PoseState.Proning)))
{
m_vrIk.solver.locomotion.weight = 0f;
l_overrided = true;
}
if(m_ikOverrideFly && MovementSystem.Instance.flying)
{
m_vrIk.solver.locomotion.weight = 0f;
l_overrided = true;
}
}

// But not this
if(m_ikOverrideJump && !m_grounded && !MovementSystem.Instance.flying)
{
m_vrIk.solver.locomotion.weight = 0f;
l_overrided = true;
}

if(l_overrided && m_followHips && !m_moving)
PlayerSetup.Instance._avatar.transform.localPosition = m_hipsToPlayer;
}

void OnIKPostUpdate()
Expand Down Expand Up @@ -356,5 +403,9 @@ public void SetDetectEmotes(bool p_state)
{
m_detectEmotes = p_state;
}
public void SetFollowHips(bool p_state)
{
m_followHips = p_state;
}
}
}
6 changes: 3 additions & 3 deletions ml_amt/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System.Reflection;

[assembly: AssemblyTitle("AvatarMotionTweaker")]
[assembly: AssemblyVersion("1.1.7")]
[assembly: AssemblyFileVersion("1.1.7")]
[assembly: AssemblyVersion("1.1.8")]
[assembly: AssemblyFileVersion("1.1.8")]

[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.1.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.1.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
3 changes: 3 additions & 0 deletions ml_amt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Available mod's settings in `Settings - Implementation - Avatar Motion Tweaker`:
* Note: Can be overrided by avatar. For this avatar has to have child gameobject with name `ProneLimit`, its Y-axis location will be used as limit, should be in range [0.0, 1.0].
* **IK override while flying:** disables legs locomotion/autostep in fly mode; default value - `true`.
* **IK override while jumping:** disables legs locomotion/autostep in jump; default value - `true`.
* **Follow hips on IK override:** adjust avatar position to overcome animation snapping on IK override; default value - `true`.
* **Pose transitions:** allows regular avatars animator to transit in crouch/prone states; default value - `true`.
* Note: Avatar is considered as regular if its AAS animator doesn't have `Upright` parameter.
* **Adjusted pose movement speed:** scales movement speed upon crouching/proning; default value - `true`.
Expand All @@ -31,6 +32,8 @@ Available additional parameters for AAS animator:
* Note: Can't be used for transitions between poses in desktop mode. In desktop mode its value is driven by avatar animations. Use `CVR Parameter Stream` for detecting desktop/VR modes and change AAS animator transitions accordingly.
* **`GroundedRaw`:** defines instant grounding state of player instead of delayed default parameter `Grounded`.
* Note: Can be set as local-only (not synced) if starts with `#` character.
* **`Moving`:** defines movement state of player
* Note: Can be set as local-only (not synced) if starts with `#` character.

Additional avatars tweaks:
* If avatar has child object with name `LocomotionOffset` its local position will be used for offsetting VRIK locomotion mass center.
18 changes: 17 additions & 1 deletion ml_amt/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum ModSetting
AdjustedMovement,
IKOverrideFly,
IKOverrideJump,
DetectEmotes
DetectEmotes,
FollowHips
};

static bool ms_ikOverrideCrouch = true;
Expand All @@ -29,6 +30,7 @@ enum ModSetting
static bool ms_ikOverrideFly = true;
static bool ms_ikOverrideJump = true;
static bool ms_detectEmotes = true;
static bool ms_followHips = true;

static MelonLoader.MelonPreferences_Category ms_category = null;
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
Expand All @@ -42,6 +44,7 @@ enum ModSetting
static public event Action<bool> IKOverrideFlyChange;
static public event Action<bool> IKOverrideJumpChange;
static public event Action<bool> DetectEmotesChange;
static public event Action<bool> FollowHipsChange;

public static void Init()
{
Expand All @@ -57,6 +60,7 @@ public static void Init()
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideFly.ToString(), true));
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideJump.ToString(), true));
ms_entries.Add(ms_category.CreateEntry(ModSetting.DetectEmotes.ToString(), true));
ms_entries.Add(ms_category.CreateEntry(ModSetting.FollowHips.ToString(), true));

Load();

Expand Down Expand Up @@ -96,6 +100,7 @@ static void Load()
ms_ikOverrideFly = (bool)ms_entries[(int)ModSetting.IKOverrideFly].BoxedValue;
ms_ikOverrideJump = (bool)ms_entries[(int)ModSetting.IKOverrideJump].BoxedValue;
ms_detectEmotes = (bool)ms_entries[(int)ModSetting.DetectEmotes].BoxedValue;
ms_followHips = (bool)ms_entries[(int)ModSetting.FollowHips].BoxedValue;
}

static void OnSliderUpdate(string p_name, string p_value)
Expand Down Expand Up @@ -177,6 +182,13 @@ static void OnToggleUpdate(string p_name, string p_value)
DetectEmotesChange?.Invoke(ms_detectEmotes);
}
break;

case ModSetting.FollowHips:
{
ms_followHips = bool.Parse(p_value);
FollowHipsChange?.Invoke(ms_followHips);
}
break;
}

ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
Expand Down Expand Up @@ -219,5 +231,9 @@ public static bool DetectEmotes
{
get => ms_detectEmotes;
}
public static bool FollowHips
{
get => ms_followHips;
}
}
}
7 changes: 7 additions & 0 deletions ml_amt/resources/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ function inp_toggle_mod_amt(_obj, _callbackName) {
<div id="IKOverrideJump" class ="inp_toggle no-scroll" data-current="true"></div>
</div>
</div>
<div class ="row-wrapper">
<div class ="option-caption">Follow hips on IK override: </div>
<div class ="option-input">
<div id="FollowHips" class ="inp_toggle no-scroll" data-current="true"></div>
</div>
</div>
<div class ="row-wrapper">
<div class ="option-caption">Pose transitions: </div>
Expand Down

0 comments on commit a3b4f46

Please sign in to comment.