/// <summary> /// Finds the rigging in the model and matches it to the MoCap bone system. /// </summary> /// <param name="bones">bone data from the MoCap system</param> /// private void MatchBones(Bone[] bones) { boneList = new Dictionary <Bone, BoneObject>(); string unmatchedBones = ""; // create copies of the marker template foreach (Bone bone in bones) { BoneNameTranslationEntry entry = null; string boneName = boneNamePrefix + TranslateBoneName(bone.name, ref entry); // find the child in the model with the given bone name Transform boneNode = Utilities.FindInHierarchy(boneName, transform); if (boneNode != null) { boneList[bone] = new BoneObject() { node = boneNode.gameObject, entry = entry }; bone.buffer.EnsureCapacityForModifiers(modifiers); } else { if (unmatchedBones.Length > 0) { unmatchedBones += ", "; } unmatchedBones += bone.name; } } if (unmatchedBones.Length > 0) { Debug.LogWarning("Could not find the following bones in Model '" + this.name + "': " + unmatchedBones); } }
//// <summary> /// Called once per frame. Updates the model based on the bone rotations and positions. /// </summary> /// void Update() { // create bone array if necessary if ((boneList == null) && (actor != null)) { MatchBones(actor.bones); } if (boneList == null) { return; } // update bones Quaternion rot = new Quaternion(); foreach (KeyValuePair <Bone, BoneObject> entry in boneList) { Bone bone = entry.Key; BoneObject obj = entry.Value; MoCapData data = bone.buffer.RunModifiers(modifiers); // update bone game object if (data.tracked) { if ((trackingUsage == TrackingUsage.PositionAndRotation) || (bone.parent == null)) { // change position only when desired, or when a root bone obj.node.transform.localRotation = Quaternion.identity; obj.node.transform.localPosition = data.pos; } rot = Quaternion.identity; string transforms = obj.entry.axisTransformation; foreach (char c in transforms) { switch (c) { case 'X': rot *= Quaternion.Euler(90, 0, 0); break; case 'x': rot *= Quaternion.Euler(-90, 0, 0); break; case 'Y': rot *= Quaternion.Euler(0, 90, 0); break; case 'y': rot *= Quaternion.Euler(0, -90, 0); break; case 'Z': rot *= Quaternion.Euler(0, 0, 90); break; case 'z': rot *= Quaternion.Euler(0, 0, -90); break; } } obj.node.transform.localRotation = data.rot * rot; } } }
/// <summary> /// Creates copies of the bone template for all bones. /// </summary> /// <param name="bones">bone data from the MoCap system</param> /// private void CreateBones(Bone[] bones) { // create node for containing all the marker objects skeletonNode = new GameObject(); skeletonNode.name = "Bones"; skeletonNode.transform.parent = this.transform; skeletonNode.transform.localPosition = Vector3.zero; skeletonNode.transform.localRotation = Quaternion.identity; skeletonNode.transform.localScale = Vector3.one; // create copies of the marker template foreach (Bone bone in bones) { // add empty for position/orientation GameObject boneNode = new GameObject(); boneNode.name = bone.name; GameObject boneRepresentation = null; if (boneTemplate != null) { float scale = bone.length; if (scale <= 0) { scale = 1; } // add subnode for visual that can be scaled boneRepresentation = GameObject.Instantiate(boneTemplate); boneRepresentation.transform.parent = boneNode.transform; boneRepresentation.transform.localScale = scale * Vector3.one; boneRepresentation.transform.localRotation = new Quaternion(); boneRepresentation.name = bone.name + "_visual"; boneRepresentation.SetActive(true); } if (bone.parent != null) { // attach to parent node GameObject parentObject = boneList[bone.parent].node; boneNode.transform.parent = parentObject.transform; } else { // no parent > attach to base skeleton node boneNode.transform.parent = skeletonNode.transform; } boneList[bone] = new BoneObject() { node = boneNode, visual = boneRepresentation }; bone.buffer.EnsureCapacityForModifiers(modifiers); boneTemplate.SetActive(false); } }
//// <summary> /// Called once per frame. /// </summary> /// void Update() { // create marker position array if necessary // but only when tracking is OK, otherwise the bone lengths are undefined if ((skeletonNode == null) && (actor != null) && actor.bones[0].tracked) { CreateBones(actor.bones); } if (skeletonNode == null) { return; } // update bones foreach (KeyValuePair <Bone, BoneObject> entry in boneList) { BoneObject obj = entry.Value; Bone bone = entry.Key; MoCapData data = bone.buffer.RunModifiers(modifiers); // update bone game object if (data.tracked) { obj.node.transform.localPosition = data.pos; obj.node.transform.localRotation = data.rot; // update length of representation GameObject boneRepresentation = obj.visual; if (boneRepresentation != null) { boneRepresentation.transform.localScale = data.length * Vector3.one; } obj.node.SetActive(true); if (bone.parent != null) { Debug.DrawLine( obj.node.transform.parent.position, obj.node.transform.position, Color.red); } } else { // bone not tracked anymore obj.node.SetActive(false); } } }
public override void OnAssetLoad(GameObject gameObject) { base.OnAssetLoad(gameObject); if (gameObject) { var time = param as EntityParamEffectTime; var bone = false; var on = GetAgent(); var entity = on as BattleEntity; if (entity != null) { if (entity.TryGetComponent(out EntityComponentModel model)) { UpdateParticleSystemSpeed(model.animationSpeed); if (time.bone != BonePoint.None && model.gameObject != null) { BoneObject point = BoneObject.GetBone(model.gameObject.transform, time.bone); if (point != null) { if (time.bind) { gameObject.transform.SetParent(point.transform); gameObject.transform.localScale = Vector3.one; gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localRotation = Quaternion.identity; } else { gameObject.transform.localPosition = point.transform.position; gameObject.transform.localRotation = point.transform.rotation; } bone = true; } } } } if (bone == false) { if (on != null) { gameObject.transform.position = on.position; gameObject.transform.rotation = on.rotation; } else { OnEnd(); } } } }
static void SetBonePoint(Transform t) { string name = t.name; if (name.Contains("Root_node")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Root; } else if (name.Contains("Bone_Buff")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Buff; } else if (name.Contains("Bone_Head")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Head; } else if (name.Contains("Bone_Hit")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Hit; } else if (name.Contains("Bip001 Prop1")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Weapon1; } else if (name.Contains("Bip001 Prop2")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Weapon2; } else if (name.Contains("Bip001 Prop3")) { BoneObject bp = t.GetComponent <BoneObject>(); if (bp == null) { bp = t.gameObject.AddComponent <BoneObject>(); } bp.type = BonePoint.Weapon3; } }