Unity_HeadboxVive_0308
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========using System.Collections.Generic;
using UnityEngine;
namespace ViveSR
{
namespace anipal
{
namespace Lip
{
public class SRanipal_AvatarLipSample_v2 : MonoBehaviour
{
[SerializeField] private List<LipShapeTable_v2> LipShapeTables;
//[SerializeField] private List<LipMapping> lipMappers;#region Headbox_LipMapping_blendshapes
//*public const string BLENDSHAPE_PREFIX = "blendShape1.";
public static List<LipMapping> LipMappings = new List<LipMapping> // See SRanipal_Lip_v2 Script (namespace Lip)
{
new LipMapping{viveName = LipShape_v2.Cheek_Puff_Left, avatarName = $"{BLENDSHAPE_PREFIX}SR_06_L_Cheek_Puff", headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Cheek_Puff_Right, avatarName = $"{BLENDSHAPE_PREFIX}SR_06_R_Cheek_Puff",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Cheek_Suck, avatarName = $"{BLENDSHAPE_PREFIX}SR_07_Cheek_Suck",headboxWeight = 1.0f},//SR_14_Cheek_Suck (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Ape_Shape, avatarName = $"{BLENDSHAPE_PREFIX}SR_08_Mouth_Ape_Shape",headboxWeight = 1.0f},//SR_01_Mouth_Ape_Shape (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Lower_DownLeft, avatarName = $"{BLENDSHAPE_PREFIX}SR_16_L_Mouth_Lower_Down" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Lower_DownRight, avatarName = $"{BLENDSHAPE_PREFIX}SR_16_R_Mouth_Lower_Down" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Lower_Inside, avatarName = $"{BLENDSHAPE_PREFIX}SR_18_Mouth_Lower_Inside",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Lower_Left, avatarName = $"{BLENDSHAPE_PREFIX}SR_10_L_Mouth_Lower",headboxWeight = 1.0f },
new LipMapping{viveName = LipShape_v2.Mouth_Lower_Overlay, avatarName = $"{BLENDSHAPE_PREFIX}SR_19_Mouth_Lower_Overlay",headboxWeight = 1.0f },
new LipMapping{viveName = LipShape_v2.Mouth_Lower_Overturn, avatarName = $"{BLENDSHAPE_PREFIX}SR_12_Mouth_Lower_Overturn",headboxWeight = 1.0f},//SR_03_Mouth_Lower_Overturn (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Lower_Right, avatarName = $"{BLENDSHAPE_PREFIX}SR_10_R_Mouth_Lower" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Sad_Left, avatarName = $"{BLENDSHAPE_PREFIX}SR_13_L_Mouth_Sad" ,headboxWeight = 1.0f},//SR_05_L_Mouth_Sad (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Sad_Right, avatarName = $"{BLENDSHAPE_PREFIX}SR_13_R_Mouth_Sad",headboxWeight = 1.0f},//SR_05_R_Mouth_Sad (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Upper_Inside, avatarName = $"{BLENDSHAPE_PREFIX}SR_17_Mouth_Upper_Inside",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Upper_Left, avatarName = $"{BLENDSHAPE_PREFIX}SR_09_L_Mouth_Upper" ,headboxWeight = 1.0f},//SR_02_L_Mouth_Upper (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Upper_Overturn, avatarName = $"{BLENDSHAPE_PREFIX}SR_11_Mouth_Upper_Overturn",headboxWeight = 1.0f },//SR_04_Mouth_Upper_Overturn (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Upper_Right, avatarName = $"{BLENDSHAPE_PREFIX}SR_09_R_Mouth_Upper",headboxWeight = 1.0f},//SR_02_R_Mouth_Upper (Two similar blendshape)new LipMapping{viveName = LipShape_v2.Mouth_Upper_UpLeft, avatarName = $"{BLENDSHAPE_PREFIX}SR_15_L_Mouth_Upper_Up" ,headboxWeight = 0.2f},
new LipMapping{viveName = LipShape_v2.Mouth_Upper_UpRight, avatarName = $"{BLENDSHAPE_PREFIX}SR_15_R_Mouth_Upper_Up",headboxWeight = 0.2f},
#region Vive lip blendshape but no mapping blendshape in Headbox
new LipMapping{viveName = LipShape_v2.Jaw_Forward, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Jaw_Left, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Jaw_Open, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Jaw_Right, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Pout, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Smile_Left, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Mouth_Smile_Right, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
#endregionnew LipMapping{viveName = LipShape_v2.Tongue_Down, avatarName = $"{BLENDSHAPE_PREFIX}SR_Tongue_Down" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_LongStep1, avatarName = $"{BLENDSHAPE_PREFIX}SR_Tongue_LongStep1" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_LongStep2, avatarName = $"{BLENDSHAPE_PREFIX}SR_Tongue_LongStep2",headboxWeight = 1.0f},
#region Vive tongue blendshape but no mapping blendshape in Headbox
new LipMapping{viveName = LipShape_v2.Tongue_DownLeft_Morph, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_DownRight_Morph, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_Left, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_Right, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_Roll, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_Up, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_UpLeft_Morph, avatarName = $"{BLENDSHAPE_PREFIX}",headboxWeight = 1.0f},
new LipMapping{viveName = LipShape_v2.Tongue_UpRight_Morph, avatarName = $"{BLENDSHAPE_PREFIX}" ,headboxWeight = 1.0f},
#endregion
};
//*/public List<HeadboxMapped> headboxMapped = new List<HeadboxMapped>();
private List<int> headboxIndex = new List<int>();
#endregionpublic bool NeededToGetData = true;
private Dictionary<LipShape_v2, float> LipWeightings;
private void Start()
{
if (!SRanipal_Lip_Framework.Instance.EnableLip)
{
enabled = false;
return;
}
SetLipShapeTables(LipShapeTables);
SetHeadboxMapped();
}
private void Update()
{
if (SRanipal_Lip_Framework.Status != SRanipal_Lip_Framework.FrameworkStatus.WORKING) return;
if (NeededToGetData)
{
SRanipal_Lip_v2.GetLipWeightings(out LipWeightings);
UpdateLipShapes(LipWeightings);
}
}
public void SetLipShapeTables(List<LipShapeTable_v2> lipShapeTables)
{
bool valid = true;
if (lipShapeTables == null)
{
valid = false;
}
else
{
for (int table = 0; table < lipShapeTables.Count; ++table)
{
// Debug.Log("lipShapeTables.Count: " + lipShapeTables.Count);if (lipShapeTables[table].skinnedMeshRenderer == null)
{
valid = false;
break;
}
for (int shape = 0; shape < lipShapeTables[table].lipShapes.Length; ++shape) // The headbox skinned lipshapes table length is 111 (0-110).
{
//Debug.Log("lipShapeTables[table].lipShapes.Length: " + lipShapeTables[table].lipShapes.Length);
LipShape_v2 lipShape = lipShapeTables[table].lipShapes[shape];
if (lipShape > LipShape_v2.Max || lipShape < 0)
{
valid = false;
break;
}
}
}
}
if (valid)
{
LipShapeTables = lipShapeTables;
}
}
private void SetHeadboxMapped()
{
foreach (var table in LipShapeTables)
{
HeadboxLipMapped(table);
}
}
public void UpdateLipShapes(Dictionary<LipShape_v2, float> lipWeightings)
{
foreach (var table in LipShapeTables)
{
RenderModelLipShape(table, lipWeightings);
Debug.Log("table 109: " + table.lipShapes[109]);
}
}
private void RenderModelLipShape(LipShapeTable_v2 lipShapeTable, Dictionary<LipShape_v2, float> weighting)
{
for (int i = 0; i < lipShapeTable.lipShapes.Length; i++) // The headbox skinned lipshapes table length is 111 (0-110).
{
//Debug.Log("Blendshape table length: " + lipShapeTable.lipShapes.Length);int targetIndex = (int)lipShapeTable.lipShapes[i];
if (targetIndex > (int)LipShape_v2.Max || targetIndex < 0) continue;
if (headboxIndex.Contains(i))
{
for (int j = 0; j < headboxMapped.Count; j++)
{
if (headboxMapped[j].headboxMappedIndex == i)
{
lipShapeTable.skinnedMeshRenderer.SetBlendShapeWeight(i, weighting[(LipShape_v2)targetIndex] * 100 * headboxMapped[j].headboxWeight);
}
}
}
else
{
lipShapeTable.skinnedMeshRenderer.SetBlendShapeWeight(i, weighting[(LipShape_v2)targetIndex] * 100);
}
//Debug.Log("Blendshape Index: " + i + " , " + "Blendshape Weighting: " + weighting[(LipShape_v2)targetIndex] * 100);
}
}
private void HeadboxLipMapped(LipShapeTable_v2 lipShapeTable)
{
for (int skinnedIndex = 0; skinnedIndex < lipShapeTable.skinnedMeshRenderer.sharedMesh.blendShapeCount; ++skinnedIndex)
{
string elementName = lipShapeTable.skinnedMeshRenderer.sharedMesh.GetBlendShapeName(skinnedIndex);
foreach (LipMapping lipmapping in LipMappings)
{
if (elementName == lipmapping.avatarName)
{
HeadboxMapped hb = new HeadboxMapped(skinnedIndex,elementName,lipmapping.headboxWeight);
if (!Contains(headboxMapped, hb)) // There should be a simpler way to do this here, so if you have time change it
{
headboxMapped.Add(hb);
headboxIndex.Add(hb.headboxMappedIndex);
}
//Debug.Log("run: " + elementName + skinnedIndex);
}
}
}
}
bool Contains(List<HeadboxMapped> list, HeadboxMapped headboxMapped)
{
foreach (HeadboxMapped n in list)
{
if (n.headboxMappedIndex == headboxMapped.headboxMappedIndex && n.headboxMappedName == headboxMapped.headboxMappedName && n.headboxWeight == headboxMapped.headboxWeight)
{ return true; }
}
return false;
}
}
}
}
}
Comments