public static Avatar LoadHumanoidAvatar(Transform root, Dictionary <Transform, VrmLib.HumanoidBones> boneMap) { var description = new HumanDescription { skeleton = root.Traverse() .Select(x => x.ToSkeletonBone()).ToArray(), human = boneMap .Select(x => new HumanBone { boneName = x.Key.name, humanName = s_humanTranitBoneNameMap[x.Value], limit = new HumanLimit { useDefaultValues = true, } }).ToArray(), armStretch = 0.05f, legStretch = 0.05f, upperArmTwist = 0.5f, lowerArmTwist = 0.5f, upperLegTwist = 0.5f, lowerLegTwist = 0.5f, feetSpacing = 0, hasTranslationDoF = false, }; return(AvatarBuilder.BuildHumanAvatar(root.gameObject, description)); }
public static void CreateAvatar() { GameObject go = Selection.activeGameObject; if (go != null && go.GetComponent("Animator") != null) { HumanDescription hd = new HumanDescription(); Dictionary <string, string> boneName = new System.Collections.Generic.Dictionary <string, string>(); boneName["Chest"] = "spine"; boneName["Head"] = "head"; boneName["Hips"] = "hip"; boneName["LeftFoot"] = "footL"; boneName["LeftHand"] = "handL"; boneName["LeftLowerArm"] = "elbowL"; boneName["LeftLowerLeg"] = "kneeL"; boneName["LeftShoulder"] = "clavL"; boneName["LeftUpperArm"] = "armL"; boneName["LeftUpperLeg"] = "legL"; boneName["RightFoot"] = "footR"; boneName["RightHand"] = "handR"; boneName["RightLowerArm"] = "elbowR"; boneName["RightLowerLeg"] = "kneeR"; boneName["RightShoulder"] = "clavR"; boneName["RightUpperArm"] = "armR"; boneName["RightUpperLeg"] = "legR"; boneName["Spine"] = "spine2"; string[] humanName = HumanTrait.BoneName; HumanBone[] humanBones = new HumanBone[boneName.Count]; int j = 0; int i = 0; while (i < humanName.Length) { if (boneName.ContainsKey(humanName[i])) { HumanBone humanBone = new HumanBone(); humanBone.humanName = humanName[i]; humanBone.boneName = boneName[humanName[i]]; humanBone.limit.useDefaultValues = true; humanBones[j++] = humanBone; } i++; } hd.human = humanBones; //hd.skeleton = new SkeletonBone[18]; //hd.skeleton[0].name = ("Hips") ; Avatar avatar = AvatarBuilder.BuildHumanAvatar(go, hd); avatar.name = (go.name + "_Avatar"); Debug.Log(avatar.isHuman ? "is human" : "is generic"); Animator animator = go.GetComponent("Animator") as Animator; animator.avatar = avatar; string path = AssetDatabase.GenerateUniqueAssetPath(Puppet2D_Editor._puppet2DPath + "/Animation/" + avatar.name + ".asset"); AssetDatabase.CreateAsset(avatar, path); } }
public override object WriteTo(object obj) { if (obj is Avatar) { obj = base.WriteTo(obj); if (obj == null) { return(null); } return(obj); } Animator animator = (Animator)obj; if (isHuman) { HumanDescription desc = (HumanDescription)humanDescription.WriteTo(new HumanDescription()); desc.skeleton[0].name = animator.gameObject.name; animator.avatar = AvatarBuilder.BuildHumanAvatar(animator.gameObject, desc); base.WriteTo(animator.avatar); } else { animator.avatar = AvatarBuilder.BuildGenericAvatar(animator.gameObject, ""); } return(obj); }
//#if UNITY_EDITOR /// <summary> /// * https://answers.unity.com/questions/612177/how-can-i-access-human-avatar-bone-and-muscle-valu.html /// </summary> /// <param name="target"></param> /// <param name="des"></param> /// <returns></returns> public static bool GetHumanDescription(UnityEngine.Object target, ref HumanDescription des) { if (target != null) { var ava = target as Avatar; des = ava.humanDescription; return(true); /*var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(target)); * if (importer != null) * { * Debug.Log("AssetImporter Type: " + importer.GetType()); * ModelImporter modelImporter = importer as ModelImporter; * if (modelImporter != null) * { * des = modelImporter.humanDescription; * Debug.Log("## Cool stuff data by ModelImporter ##"); * return true; * } * else * { * Debug.LogWarning("## Please Select Imported Model in Project View not prefab or other things ##"); * } * }*/ } return(false); }
public static Avatar CreateAvatar(GameObject root, UMA.UmaTPose umaTPose) { HumanDescription description = CreateHumanDescription(root, umaTPose); Avatar res = AvatarBuilder.BuildHumanAvatar(root, description); return(res); }
public static void DebugLogHumanAvatar(GameObject root, HumanDescription description) { Debug.Log("***", root); Dictionary <String, String> bones = new Dictionary <String, String>(); foreach (var sb in description.skeleton) { Debug.Log(sb.name); bones[sb.name] = sb.name; } Debug.Log("----"); foreach (var hb in description.human) { string boneName; if (bones.TryGetValue(hb.boneName, out boneName)) { Debug.Log(hb.humanName + " -> " + boneName); } else { Debug.LogWarning(hb.humanName + " !-> " + hb.boneName); } } Debug.Log("++++"); }
/// <summary> /// Avatarを生成する /// </summary> public static Avatar GenerateAvatar(Transform root, HumanDescription humanDescription, ICollection <SkeletonInfo> HumanSkeletonInfos) { List <SkeletonBone> skeletonList = new List <SkeletonBone>(); HumanSkeletonInfos.ToList().ForEach(_ => skeletonList.Add(_.GetSkeletonBone())); var skleton = skeletonList.ToArray(); humanDescription.skeleton = skleton; // AvatarBuilder生成時はanimatorがあるコンポーネントは「parent = null」にする必要がある Transform tmp_pare = root.parent; // tmp保存 root.parent = null; // 親なしにする var ret = AvatarBuilder.BuildHumanAvatar(root.gameObject, humanDescription); root.parent = tmp_pare; // 親を元に戻す // 要らないのでは? //humanDescription.skeleton = skleton; /* * // unity2017から仕様が変わったのか、avatar更新後に初期値を設定する必要があるようになった * // ⇒ 修正。HumanPoseHandlerで設定したほうが直接的に修正できる * foreach (var info in HumanSkeletonInfos) * { * info.transform.localPosition = info.Position; * info.transform.localRotation = info.Rotation; * }*/ return(ret); }
private Avatar CreateAvatar(GameObject go) { HumanDescription desc = CreateHumanDescription(go); Transform parent = go.transform.parent; Vector3 position = go.transform.position; Quaternion rotation = go.transform.rotation; go.transform.parent = null; go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; Avatar avatar = AvatarBuilder.BuildHumanAvatar(go, desc); go.transform.parent = parent; go.transform.position = position; go.transform.rotation = rotation; if (avatar == null) { Debug.LogError("Something went wrong building the avatar."); return(null); } if (!avatar.isValid) { Debug.LogError("Avatar is invalid."); return(null); } avatar.name = "avatar"; return(avatar); }
static int _CreateHumanDescription(IntPtr L) { LuaScriptMgr.CheckArgsCount(L, 0); HumanDescription obj = new HumanDescription(); LuaScriptMgr.PushValue(L, obj); return(1); }
/// <summary> /// Builds the object avatar, based on pre-defined templates (Mixamo, Biped), or based on the <see cref="TriLib.AvatarLoader.CustomBoneNames"></see>, if it's not null or empty. /// </summary> /// <returns><c>true</c> if avatar was built, <c>false</c> otherwise.</returns> private bool BuildAvatar() { var animator = CurrentAvatar.GetComponent <Animator>(); if (animator == null) { #if ASSIMP_OUTPUT_MESSAGES Debug.LogError("No Animator Component found on current Avatar."); #endif return(false); } var skeletonBones = new List <SkeletonBone>(); var humanBones = new List <HumanBone>(); var boneTransforms = FindOutBoneTransforms(CurrentAvatar); if (boneTransforms.Count == 0) { #if ASSIMP_OUTPUT_MESSAGES Debug.LogError("No suitable bones format found"); #endif return(false); } foreach (var boneTransform in boneTransforms) { humanBones.Add(CreateHumanBone(boneTransform.Key, boneTransform.Value.name)); } var transforms = CurrentAvatar.GetComponentsInChildren <Transform>(); var rootTransform = transforms[1]; skeletonBones.Add(CreateSkeletonBone(rootTransform)); rootTransform.localEulerAngles = Vector3.zero; for (var i = 0; i < transforms.Length; i++) { var childTransform = transforms[i]; var meshRenderers = childTransform.GetComponentsInChildren <MeshRenderer>(); if (meshRenderers.Length > 0) { continue; } var skinnedMeshRenderers = childTransform.GetComponentsInChildren <SkinnedMeshRenderer>(); if (skinnedMeshRenderers.Length > 0) { continue; } skeletonBones.Add(CreateSkeletonBone(childTransform)); } var humanDescription = new HumanDescription(); humanDescription.armStretch = ArmStretch; humanDescription.feetSpacing = FeetSpacing; humanDescription.hasTranslationDoF = HasTranslationDof; humanDescription.legStretch = LegStretch; humanDescription.lowerArmTwist = LowerArmTwist; humanDescription.lowerLegTwist = LowerLegTwist; humanDescription.upperArmTwist = UpperArmTwist; humanDescription.upperLegTwist = UpperLegTwist; humanDescription.skeleton = skeletonBones.ToArray(); humanDescription.human = humanBones.ToArray(); animator.avatar = AvatarBuilder.BuildHumanAvatar(CurrentAvatar, humanDescription); return(true); }
/// <summary> /// Creates a human (biped) avatar for a UMA character. /// </summary> /// <returns>The human avatar.</returns> /// <param name="umaData">UMA data.</param> /// <param name="umaTPose">UMA TPose.</param> public static Avatar CreateAvatar(UMAData umaData, UmaTPose umaTPose) { umaTPose.DeSerialize(); HumanDescription description = CreateHumanDescription(umaData, umaTPose); //DebugLogHumanAvatar(umaData.gameObject, description); Avatar res = AvatarBuilder.BuildHumanAvatar(umaData.gameObject, description); return(res); }
public void Awake() { _Animator = GetComponent <Animator>(); HumanDescription description = AvatarUtils.CreateHumanDescription(gameObject); Avatar avatar = AvatarBuilder.BuildHumanAvatar(gameObject, description); avatar.name = gameObject.name; _Animator.avatar = avatar; }
static int BuildHumanAvatar(IntPtr L) { LuaScriptMgr.CheckArgsCount(L, 2); GameObject arg0 = LuaScriptMgr.GetNetObject <GameObject>(L, 1); HumanDescription arg1 = LuaScriptMgr.GetNetObject <HumanDescription>(L, 2); Avatar o = AvatarBuilder.BuildHumanAvatar(arg0, arg1); LuaScriptMgr.Push(L, o); return(1); }
private async Task <bool> BuildAvatar() { // HumanBoneのためのリストを取得する List <HumanBone> humanBones = new List <HumanBone>(); string[] boneNames = HumanTrait.BoneName; await Task.Run(() => { foreach (string humanBoneName in boneNames) { if (!MMDModel.Unity_MMDBoneNameDictionary.ContainsKey(humanBoneName)) { continue; } if (MMDModel.Unity_MMDBoneNameDictionary[humanBoneName] == null) { continue; } HumanBone humanBone = new HumanBone(); humanBone.humanName = humanBoneName; humanBone.boneName = MMDModel.Unity_MMDBoneNameDictionary[humanBoneName]; humanBone.limit.useDefaultValues = true; humanBones.Add(humanBone); } }); // HumanDescription(関節の曲がり方などを定義した構造体) HumanDescription humanDesc = new HumanDescription(); humanDesc.human = humanBones.ToArray(); humanDesc.skeleton = GetTransforms(transform).ToArray(); humanDesc.upperArmTwist = 0.5f; humanDesc.lowerArmTwist = 0.5f; humanDesc.upperLegTwist = 0.5f; humanDesc.lowerLegTwist = 0.5f; humanDesc.armStretch = 0.05f; humanDesc.legStretch = 0.05f; humanDesc.feetSpacing = 0.05f; // アバターオブジェクトをビルド Avatar avatar = AvatarBuilder.BuildHumanAvatar(gameObject, humanDesc); avatar.name = gameObject.name + AvatarNameTail; if (!avatar.isValid || !avatar.isHuman) { UnityEngine.Debug.Log("Error when building avatar"); return(false); } animator = gameObject.AddComponent <Animator>(); animator.avatar = avatar; animator.applyRootMotion = true; animator.runtimeAnimatorController = RuntimeAnimatorController; return(true); }
private static HumanDescription ReadHumanDescription() { HumanDescription humanDescription = new HumanDescription(); List <HumanBone> humanBones = new List <HumanBone>(); HumanTemplate template = Resources.Load(humanTemplateFile) as HumanTemplate; string[] boneNames = HumanTrait.BoneName; //List<string> mapping = new List<string>(); foreach (string boneName in boneNames) { HumanBone newBone = new HumanBone(); newBone.humanName = boneName; newBone.boneName = template.Find(boneName); if (newBone.boneName != "") { HumanLimit limit = new HumanLimit(); limit.useDefaultValues = true; newBone.limit = limit; humanBones.Add(newBone); } } humanDescription.human = humanBones.ToArray(); humanDescription.upperArmTwist = 0.5f; humanDescription.lowerArmTwist = 0.5f; humanDescription.upperLegTwist = 0.5f; humanDescription.lowerLegTwist = 0.5f; humanDescription.armStretch = 0.05f; humanDescription.legStretch = 0.05f; humanDescription.feetSpacing = 0.0f; humanDescription.hasTranslationDoF = true; //if (secondPass && _isAnimation) { //skeletonDescription = modelImporter.humanDescription.skeleton; List <SkeletonBone> skeletonBones = new List <SkeletonBone>(); for (int i = 0; i < skeletonDescription.Length; i++) { SkeletonBone newSkeletonBone = new SkeletonBone(); newSkeletonBone.name = skeletonDescription[i].name; newSkeletonBone.position = skeletonDescription[i].position; newSkeletonBone.rotation = skeletonDescription[i].rotation; newSkeletonBone.scale = skeletonDescription[i].scale; //newSkeletonBone.transformModified = skeletonDescription[i].transformModified; skeletonBones.Add(newSkeletonBone); } humanDescription.skeleton = skeletonBones.ToArray(); } return(humanDescription); }
/// <summary> </summary> public HumanDescription GetHumanDescription() { HumanDescription hd = new HumanDescription(); hd.human = new HumanBone[humanBoneDatas.Length]; for (int i = 0; i < hd.human.Length; i++) { hd.human[i] = humanBoneDatas[i].Get(); } return(hd); }
protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container) { YAMLMappingNode node = base.ExportYAMLRoot(container); node.Add(AvatarSizeName, AvatarSize); node.Add(AvatarName, AvatarConstant.ExportYAML(container)); node.Add(TOSName, TOS.ExportYAML()); if (IsReadHumanDescription(container.Version)) { node.Add(HumanDescriptionName, HumanDescription.ExportYAML(container)); } return(node); }
private static void LoadHumanoidObsolete(VRMImporterContext context) { var parsed = context.Json.ParseAsJson()["extensions"]["VRM"]; var skeleton = context.Root.transform.Traverse().Select(x => ToSkeletonBone(x)).ToArray(); var description = new HumanDescription { human = parsed[HUMANOID_KEY]["bones"] .ObjectItems .Select(x => new { x.Key, Index = x.Value.GetInt32() }) .Where(x => x.Index != -1) .Select(x => { var humanBone = EnumUtil.TryParseOrDefault <HumanBodyBones>(x.Key); var hb = new HumanBone { boneName = context.Nodes[x.Index].name, humanName = ToHumanBoneName(humanBone) }; hb.limit.useDefaultValues = true; return(hb); }).ToArray(), skeleton = skeleton, lowerArmTwist = 0.5f, upperArmTwist = 0.5f, upperLegTwist = 0.5f, lowerLegTwist = 0.5f, armStretch = 0.05f, legStretch = 0.05f, feetSpacing = 0.0f, }; context.HumanoidAvatar = AvatarBuilder.BuildHumanAvatar(context.Root, description); context.HumanoidAvatar.name = Path.GetFileNameWithoutExtension(context.Path); context.AvatarDescription = UniHumanoid.AvatarDescription.CreateFrom(description); context.AvatarDescription.name = "AvatarDescription"; var humanoid = context.Root.AddComponent <VRMHumanoidDescription>(); humanoid.Avatar = context.HumanoidAvatar; humanoid.Description = context.AvatarDescription; var animator = context.Root.GetComponent <Animator>(); if (animator == null) { animator = context.Root.AddComponent <Animator>(); } animator.avatar = context.HumanoidAvatar; }
public override void Read(AssetReader reader) { base.Read(reader); m_TOS.Clear(); AvatarSize = reader.ReadUInt32(); AvatarConstant.Read(reader); m_TOS.Read(reader); if (IsReadHumanDescription(reader.Version)) { HumanDescription.Read(reader); } }
// Start is called before the first frame update void Start() { mainController = GameObject.Find("MainController").GetComponent <MainController>(); animator = this.GetComponent <Animator>(); numHBones = Enum.GetNames(typeof(HumanBodyBones)).Length - 1; animationState = new Quaternion[numHBones]; animationInitState = new Quaternion[numHBones]; HumanDescription humanDescription = this.GetComponent <Animator>().avatar.humanDescription; for (int i = 1; i < Math.Min(numHBones, humanDescription.skeleton.Length); i++) { animationInitState[i] = humanDescription.skeleton[i].rotation; } }
public Avatar Create() { // check if it's a valid mecanim avatar var boneName = HumanTrait.BoneName; for (var x = 0; x < boneName.Length; x++) { if (!HumanTrait.RequiredBone(x)) { continue; } var requiredBoneType = Naming.MecanimNameToBoneType(boneName[x]); if (!_boneMapping.ContainsKey(requiredBoneType)) { return(AvatarBuilder.BuildGenericAvatar(_root, "")); } } var humanBones = new HumanBone[_boneMapping.Count]; var skeletonBones = GetSkeletonBones(); for (var x = 0; x < _boneMapping.Count; x++) { var item = _boneMapping.ElementAt(x); var boneType = item.Key; var go = item.Value; var mecanimBoneName = Naming.BoneTypeToMecanimName(boneType); if (mecanimBoneName == "default") { mecanimBoneName = go.name; } var humanBone = new HumanBone { humanName = mecanimBoneName, boneName = go.name, limit = { useDefaultValues = true } }; humanBones[x] = humanBone; } var humanDescription = new HumanDescription() { skeleton = skeletonBones, human = humanBones }; return(AvatarBuilder.BuildHumanAvatar(_root, humanDescription)); }
/// <summary> /// animatorのAvatarを更新する /// </summary> public static void UpdateAnimatorAvatar(Animator animator, HumanDescription humanDescription, ICollection <SkeletonInfo> HumanSkeletonInfos, string avatarName = "customAvater") { Avatar avater = GenerateAvatar(animator.transform, humanDescription, HumanSkeletonInfos); avater.name = avatarName; animator.avatar = avater; // 一度ポーズを更新しないとおかしなポーズになる。 // たぶん更新前のavatarにおいての位置・回転情報が残ったままなので変になる? var PoseHandler = new HumanPoseHandler(animator.avatar, animator.transform); var pose = new HumanPose(); PoseHandler.GetHumanPose(ref pose); PoseHandler.SetHumanPose(ref pose); }
public static AvatarDescription CreateFrom(HumanDescription description) { var avatarDescription = ScriptableObject.CreateInstance <AvatarDescription>(); avatarDescription.name = "AvatarDescription"; avatarDescription.armStretch = description.armStretch; avatarDescription.legStretch = description.legStretch; avatarDescription.feetSpacing = description.feetSpacing; avatarDescription.hasTranslationDoF = description.hasTranslationDoF; avatarDescription.lowerArmTwist = description.lowerArmTwist; avatarDescription.lowerLegTwist = description.lowerLegTwist; avatarDescription.upperArmTwist = description.upperArmTwist; avatarDescription.upperLegTwist = description.upperLegTwist; avatarDescription.human = description.human.Select(BoneLimit.From).ToArray(); return(avatarDescription); }
protected override void ReadFromImpl(object obj) { base.ReadFromImpl(obj); HumanDescription uo = (HumanDescription)obj; human = Assign(uo.human, v_ => (PersistentHumanBone <TID>)v_); skeleton = Assign(uo.skeleton, v_ => (PersistentSkeletonBone <TID>)v_); upperArmTwist = uo.upperArmTwist; lowerArmTwist = uo.lowerArmTwist; upperLegTwist = uo.upperLegTwist; lowerLegTwist = uo.lowerLegTwist; armStretch = uo.armStretch; legStretch = uo.legStretch; feetSpacing = uo.feetSpacing; hasTranslationDoF = uo.hasTranslationDoF; }
/// <summary> /// Creates a Mecanim human description for a UMA character. /// </summary> /// <returns>The human description.</returns> /// <param name="umaData">UMA data.</param> /// <param name="umaTPose">UMA TPose.</param> public static HumanDescription CreateHumanDescription(UMAData umaData, UmaTPose umaTPose) { var res = new HumanDescription(); res.armStretch = umaTPose.armStretch == 0.0f ? 0.05f : umaTPose.armStretch; // this is for compatiblity with the existing tpose. res.legStretch = umaTPose.legStretch == 0.0f ? 0.05f : umaTPose.legStretch; res.feetSpacing = umaTPose.feetSpacing; res.lowerArmTwist = umaTPose.lowerArmTwist == 0.0f ? 0.5f : umaTPose.lowerArmTwist; res.lowerLegTwist = umaTPose.lowerLegTwist == 0.0f ? 0.5f : umaTPose.lowerLegTwist; res.upperArmTwist = umaTPose.upperArmTwist == 0.0f ? 0.5f : umaTPose.upperArmTwist; res.upperLegTwist = umaTPose.upperLegTwist == 0.0f ? 0.5f : umaTPose.upperLegTwist; res.skeleton = umaTPose.boneInfo; res.human = umaTPose.humanInfo; SkeletonModifier(umaData, ref res.skeleton, res.human); return(res); }
public static Avatar LoadHumanoidAvatar(Transform root, Dictionary <Transform, VrmLib.HumanoidBones> boneMap) { var description = new HumanDescription { skeleton = root.Traverse() .Select(x => x.ToSkeletonBone()).ToArray(), human = root.Traverse() .Where(x => boneMap.ContainsKey(x)) .Select(x => new HumanBone { boneName = x.name, humanName = s_humanTranitBoneNameMap[boneMap[x]], }).ToArray(), }; return(AvatarBuilder.BuildHumanAvatar(root.gameObject, description)); }
/// <summary> /// Creates a Mecanim human description for a UMA character. /// </summary> /// <returns>The human description.</returns> /// <param name="umaData">UMA data.</param> /// <param name="umaTPose">UMA TPose.</param> public static HumanDescription CreateHumanDescription(UMAData umaData, UmaTPose umaTPose) { var res = new HumanDescription(); res.armStretch = 0; res.feetSpacing = 0; res.legStretch = 0; res.lowerArmTwist = 0.2f; res.lowerLegTwist = 1f; res.upperArmTwist = 0.5f; res.upperLegTwist = 0.1f; res.skeleton = umaTPose.boneInfo; res.human = umaTPose.humanInfo; SkeletonModifier(umaData, ref res.skeleton, res.human); return(res); }
public static int constructor(IntPtr l) { int result; try { HumanDescription humanDescription = default(HumanDescription); LuaObject.pushValue(l, true); LuaObject.pushValue(l, humanDescription); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
/// <summary> /// Reads from Mecanim human description. /// </summary> /// <param name="description">Human description.</param> public void ReadFromHumanDescription(HumanDescription description) { humanInfo = description.human; boneInfo = description.skeleton; armStretch = description.armStretch; feetSpacing = description.feetSpacing; legStretch = description.legStretch; lowerArmTwist = description.lowerArmTwist; lowerLegTwist = description.lowerLegTwist; upperArmTwist = description.upperArmTwist; upperLegTwist = description.upperLegTwist; extendedInfo = true; Serialize(); boneInfo = null; humanInfo = null; }
public HumanDescription GetHumanDescription() { HumanDescription humanDesc = new HumanDescription(); humanDesc.human = GetHumanBones().ToArray(); humanDesc.skeleton = GetSkeletonBones().ToArray(); humanDesc.armStretch = 0.05f; humanDesc.legStretch = 0.05f; humanDesc.upperArmTwist = 0.5f; humanDesc.lowerArmTwist = 0.5f; humanDesc.upperLegTwist = 0.5f; humanDesc.lowerLegTwist = 0.5f; humanDesc.feetSpacing = 0.0f; humanDesc.hasTranslationDoF = false; return(humanDesc); }