コード例 #1
0
    private void InitializeCapsules(OVRPlugin.Skeleton skeleton)
    {
        if (_enablePhysicsCapsules)
        {
            _capsules = new List <OVRBoneCapsule>(new OVRBoneCapsule[skeleton.NumBoneCapsules]);
            Capsules  = _capsules.AsReadOnly();

            if (!_capsulesGO)
            {
                _capsulesGO = new GameObject("Capsules");
                _capsulesGO.transform.SetParent(transform, false);
                _capsulesGO.transform.localPosition = Vector3.zero;
                _capsulesGO.transform.localRotation = Quaternion.identity;
            }

            _capsules = new List <OVRBoneCapsule>(new OVRBoneCapsule[skeleton.NumBoneCapsules]);
            Capsules  = _capsules.AsReadOnly();

            for (int i = 0; i < skeleton.NumBoneCapsules; ++i)
            {
                var       capsule = skeleton.BoneCapsules[i];
                Transform bone    = Bones[capsule.BoneIndex].Transform;

                var capsuleRigidBodyGO = new GameObject((_bones[capsule.BoneIndex].Id).ToString() + "_CapsuleRigidBody");
                capsuleRigidBodyGO.transform.SetParent(_capsulesGO.transform, false);
                capsuleRigidBodyGO.transform.position = bone.position;
                capsuleRigidBodyGO.transform.rotation = bone.rotation;

                var capsuleRigidBody = capsuleRigidBodyGO.AddComponent <Rigidbody>();
                capsuleRigidBody.mass        = 1.0f;
                capsuleRigidBody.isKinematic = true;
                capsuleRigidBody.useGravity  = false;
#if UNITY_2018_3_OR_NEWER
                capsuleRigidBody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
#else
                capsuleRigidBody.collisionDetectionMode = CollisionDetectionMode.Continuous;
#endif

                var capsuleColliderGO = new GameObject((_bones[capsule.BoneIndex].Id).ToString() + "_CapsuleCollider");
                capsuleColliderGO.transform.SetParent(capsuleRigidBodyGO.transform, false);
                var capsuleCollider = capsuleColliderGO.AddComponent <CapsuleCollider>();
                var p0    = capsule.Points[0].FromFlippedXVector3f();
                var p1    = capsule.Points[1].FromFlippedXVector3f();
                var delta = p1 - p0;
                var mag   = delta.magnitude;
                var rot   = Quaternion.FromToRotation(Vector3.right, delta);
                capsuleCollider.radius    = capsule.Radius;
                capsuleCollider.height    = mag + capsule.Radius * 2.0f;
                capsuleCollider.isTrigger = false;                 //Edit
                capsuleCollider.direction = 0;
                capsuleColliderGO.transform.localPosition = p0;
                capsuleColliderGO.transform.localRotation = rot;
                capsuleCollider.center = Vector3.right * mag * 0.5f;



                _capsules[i] = new OVRBoneCapsule(capsule.BoneIndex, capsuleRigidBody, capsuleCollider);
            }
        }
    }
コード例 #2
0
        public bool InitializeSkeleton(ref OVRPlugin.Skeleton skeleton)
        {
            _bones         = new List <Transform>(new Transform[(int)OVRPlugin.BoneId.Max]);
            _readOnlyBones = _bones.AsReadOnly();

            for (int i = 0; i < skeleton.NumBones && i < skeleton.NumBones; ++i)
            {
                var boneGO = new GameObject((skeleton.Bones[i].Id).ToString());
                if (((OVRPlugin.BoneId)skeleton.Bones[i].ParentBoneIndex) == OVRPlugin.BoneId.Invalid)
                {
                    boneGO.transform.SetParent(_skeleton.transform);
                }
                else if (_bones.Count > skeleton.Bones[i].ParentBoneIndex &&
                         _bones[skeleton.Bones[i].ParentBoneIndex])
                {
                    boneGO.transform.SetParent(_bones[skeleton.Bones[i].ParentBoneIndex].transform);
                }
                else
                {
                    Debug.LogError("Cannot find bone parent");
                }
                boneGO.transform.localPosition = skeleton.Bones[i].Pose.Position.FromFlippedZVector3f();
                boneGO.transform.localRotation = skeleton.Bones[i].Pose.Orientation.FromFlippedZQuatf();

                _bones[i] = boneGO.transform;
            }
            return(true);
        }
コード例 #3
0
    private void Initialize()
    {
        var skeleton = new OVRPlugin.Skeleton();

        if (OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)_skeletonType, out skeleton))
        {
            InitializeBones(skeleton);
            InitializeBindPose(skeleton);
            InitializeCapsules(skeleton);

            IsInitialized = true;
        }
    }
コード例 #4
0
    protected override void InitializeBones(OVRPlugin.Skeleton skeleton)
    {
        _bones = new List <OVRBone>(new OVRBone[skeleton.NumBones]);
        Bones  = _bones.AsReadOnly();

        for (int i = 0; i < skeleton.NumBones; ++i)
        {
            BoneId    id        = (BoneId)skeleton.Bones[i].Id;
            short     parentIdx = skeleton.Bones[i].ParentBoneIndex;
            Transform t         = _customBones[(int)id];
            _bones[i] = new OVRBone(id, parentIdx, t);
        }
    }
コード例 #5
0
        public bool InitializePhysics(ref OVRPlugin.Skeleton skeleton)
        {
            if (!_handSkeleton.IsInitialized)
            {
                return(false);
            }
            _capsulesParent.name = _hand.HandType + "Physics";
            // Each capsule is associated to a bone. there can be more than on capsule per bone.
            for (var ci = 0; ci < skeleton.NumBoneCapsules; ++ci)
            {
                var       capsule = skeleton.BoneCapsules[ci];
                Transform bone    = _handSkeleton.Bones[capsule.BoneIndex];
                // put the capsule in a separate flat hierarchy, because we can't have nested rigid bodies
                var capsuleObj = new GameObject(((
                                                     OVRPlugin.BoneId)capsule.BoneIndex).ToString() + "_Capsule");
                var t = capsuleObj.transform;

                // create the capsule collider
                var capsuleCollider = capsuleObj.AddComponent <CapsuleCollider>();
                var p0       = capsule.Points[0].FromFlippedZVector3f();
                var p1       = capsule.Points[1].FromFlippedZVector3f();
                var heading  = p1 - p0;
                var distance = heading.magnitude;
                capsuleCollider.radius    = capsule.Radius;
                capsuleCollider.height    = distance + capsule.Radius * 2.0f;
                capsuleCollider.isTrigger = false;

                capsuleCollider.direction = 0;
                t.position             = bone.position;
                t.rotation             = bone.rotation;
                capsuleCollider.center = Vector3.Lerp(p0, p1, 0.5f);
                t.SetParent(_capsulesParent, true);

                // set up rigidBody
                var rigidBody = capsuleObj.AddComponent <Rigidbody>();
                rigidBody.mass        = 1.0f;
                rigidBody.isKinematic = true;
                rigidBody.useGravity  = false;
#if UNITY_2018_3_OR_NEWER
                rigidBody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
#else
                rigidBody.collisionDetectionMode = CollisionDetectionMode.Continuous;
#endif
                var capsuleInfo = capsuleObj.AddComponent <CapsuleInfo>();
                capsuleInfo.Init(_hand, (OVRPlugin.BoneId)capsule.BoneIndex, rigidBody, capsuleCollider);
                _capsules[ci] = capsuleInfo;
            }
            return(true);
        }
コード例 #6
0
        private IEnumerator InitializeSkeleton()
        {
            bool success = false;

            while (!success)
            {
                var skeleton = new OVRPlugin.Skeleton();
                if (OVRPlugin.GetSkeleton(HandSkeleton.GetSkeletonTypeFromHandType(_hand.HandType), out skeleton))
                {
                    success = InitializePhysics(ref skeleton);
                }
                yield return(null);
            }
            IsInitialized = true;
        }
コード例 #7
0
    private void Initialize()
    {
        var skeleton = new OVRPlugin.Skeleton();

        FreezeIndex  = false;
        FreezeMiddle = false;
        FreezePinky  = false;
        FreezeRing   = false;
        FreezeThumb  = false;
        if (OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)_skeletonType, out skeleton))
        {
            InitializeBones(skeleton);
            InitializeBindPose(skeleton);
            InitializeCapsules(skeleton);

            IsInitialized = true;
        }
    }
コード例 #8
0
    private void InitializeBindPose(OVRPlugin.Skeleton skeleton)
    {
        _bindPoses = new List <OVRBone>(new OVRBone[skeleton.NumBones]);
        BindPoses  = _bindPoses.AsReadOnly();

        if (!_bindPosesGO)
        {
            _bindPosesGO = new GameObject("BindPoses");
            _bindPosesGO.transform.SetParent(transform, false);
            _bindPosesGO.transform.localPosition = Vector3.zero;
            _bindPosesGO.transform.localRotation = Quaternion.identity;
        }

        for (int i = 0; i < skeleton.NumBones; ++i)
        {
            BoneId  id         = (OVRSkeleton.BoneId)skeleton.Bones[i].Id;
            short   parentIdx  = skeleton.Bones[i].ParentBoneIndex;
            var     bindPoseGO = new GameObject(id.ToString());
            OVRBone bone       = _bones[i];

            if (bone.Transform != null)
            {
                bindPoseGO.transform.localPosition = bone.Transform.localPosition;
                bindPoseGO.transform.localRotation = bone.Transform.localRotation;
            }

            _bindPoses[i] = new OVRBone(id, parentIdx, bindPoseGO.transform);
        }

        for (int i = 0; i < skeleton.NumBones; ++i)
        {
            if (((OVRPlugin.BoneId)skeleton.Bones[i].ParentBoneIndex) == OVRPlugin.BoneId.Invalid)
            {
                _bindPoses[i].Transform.SetParent(_bindPosesGO.transform, false);
            }
            else
            {
                _bindPoses[i].Transform.SetParent(_bindPoses[_bones[i].ParentBoneIndex].Transform, false);
            }
        }
    }
コード例 #9
0
    virtual protected void InitializeBones(OVRPlugin.Skeleton skeleton)
    {
        _bones = new List <OVRBone>(new OVRBone[skeleton.NumBones]);
        Bones  = _bones.AsReadOnly();

        if (!_bonesGO)
        {
            _bonesGO = new GameObject("Bones");
            _bonesGO.transform.SetParent(transform, false);
            _bonesGO.transform.localPosition = Vector3.zero;
            _bonesGO.transform.localRotation = Quaternion.identity;
        }

        // pre-populate bones list before attempting to apply bone hierarchy
        for (int i = 0; i < skeleton.NumBones; ++i)
        {
            BoneId     id        = (OVRSkeleton.BoneId)skeleton.Bones[i].Id;
            short      parentIdx = skeleton.Bones[i].ParentBoneIndex;
            Vector3    pos       = skeleton.Bones[i].Pose.Position.FromFlippedXVector3f();
            Quaternion rot       = skeleton.Bones[i].Pose.Orientation.FromFlippedXQuatf();

            var boneGO = new GameObject(id.ToString());
            boneGO.transform.localPosition = pos;
            boneGO.transform.localRotation = rot;
            _bones[i] = new OVRBone(id, parentIdx, boneGO.transform);
        }

        for (int i = 0; i < skeleton.NumBones; ++i)
        {
            if (((OVRPlugin.BoneId)skeleton.Bones[i].ParentBoneIndex) == OVRPlugin.BoneId.Invalid)
            {
                _bones[i].Transform.SetParent(_bonesGO.transform, false);
            }
            else
            {
                _bones[i].Transform.SetParent(_bones[_bones[i].ParentBoneIndex].Transform, false);
            }
        }
    }
コード例 #10
0
        private IEnumerator InitializeSkeleton()
        {
            bool success = false;

            while (!success)
            {
                var skeleton = new OVRPlugin.Skeleton();
                if (OVRPlugin.GetSkeleton(GetSkeletonTypeFromHandType(_hand.HandType), out skeleton))
                {
                    success = InitializeSkeleton(ref skeleton);
                }
                yield return(null);
            }
            if (GetComponent <HandMesh>() != null)
            {
                while (!AttacheBonesToMesh())
                {
                    yield return(null);
                }
            }
            IsInitialized = true;
        }
コード例 #11
0
        /// <summary>
        /// Bonesを生成
        /// </summary>
        /// <param name="skeleton">あらかじめ用意されたボーンの情報</param>
        /// <param name="hand">左右どちらかの手</param>
        /// <param name="isInitialize">初期化完了フラグ</param>
        private void InitializeBones(OVRPlugin.Skeleton skeleton, GameObject hand, out bool isInitialize)
        {
            _bones = new List <OVRBone>(new OVRBone[skeleton.NumBones]);

            var bonesGO = new GameObject("Bones");

            bonesGO.transform.SetParent(hand.transform, false);
            bonesGO.transform.localPosition = Vector3.zero;
            bonesGO.transform.localRotation = Quaternion.identity;

            for (var i = 0; i < skeleton.NumBones; ++i)
            {
                var id        = (OVRSkeleton.BoneId)skeleton.Bones[i].Id;
                var parentIdx = skeleton.Bones[i].ParentBoneIndex;
                var pos       = skeleton.Bones[i].Pose.Position.FromFlippedXVector3f();
                var rot       = skeleton.Bones[i].Pose.Orientation.FromFlippedXQuatf();

                var boneGO = new GameObject(id.ToString());
                boneGO.transform.localPosition = pos;
                boneGO.transform.localRotation = rot;
                _bones[i] = new OVRBone(id, parentIdx, boneGO.transform);
            }

            for (var i = 0; i < skeleton.NumBones; ++i)
            {
                if (((OVRPlugin.BoneId)skeleton.Bones[i].ParentBoneIndex) == OVRPlugin.BoneId.Invalid)
                {
                    _bones[i].Transform.SetParent(bonesGO.transform, false);
                }
                else
                {
                    _bones[i].Transform.SetParent(_bones[_bones[i].ParentBoneIndex].Transform, false);
                }
            }

            isInitialize = true;
        }
コード例 #12
0
        private async void Start()
        {
            _skinMeshRendererL = _leftHandVisual.GetComponent <SkinnedMeshRenderer>();
            _skinMeshRendererR = _rightHandVisual.GetComponent <SkinnedMeshRenderer>();

            //部屋に入るまで待つ
            await UniTask.WaitUntil(() => PhotonNetwork.InRoom);

            //タグで検索
            var ovrSkeletonL = GameObject.FindGameObjectWithTag("HandL").GetComponent <OVRSkeleton>();
            var ovrSkeletonR = GameObject.FindGameObjectWithTag("HandR").GetComponent <OVRSkeleton>();

            //ボーン情報のデータプロバイダー
            var dataProviderL = ovrSkeletonL.GetComponent <OVRSkeleton.IOVRSkeletonDataProvider>();
            var dataProviderR = ovrSkeletonR.GetComponent <OVRSkeleton.IOVRSkeletonDataProvider>();

            //手の認識を待つ
            await UniTask.WaitUntil(() => OVRInput.IsControllerConnected(OVRInput.Controller.Hands));

            //あらかじめ決まっているボーンの情報を所持できるクラス
            var skeleton = new OVRPlugin.Skeleton();

            //あらかじめ決まっているボーンの情報を取得し、実際にボーンを生成
            OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)dataProviderL.GetSkeletonType(), out skeleton);
            InitializeBones(skeleton, _leftHandVisual, out _isInitializedBoneL);

            OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)dataProviderR.GetSkeletonType(), out skeleton);
            InitializeBones(skeleton, _rightHandVisual, out _isInitializedBoneR);

            //正しい順序で生成したボーンのリストを作成
            ReadyHand(_leftHandVisual, _bonesL, out _isInitializedHandL);
            ReadyHand(_rightHandVisual, _bonesR, out _isInitializedHandR);

            Quaternion wristFixupRotation = new Quaternion(0.0f, 1.0f, 0.0f, 0.0f);

            _skinMeshRendererL.enabled = true;
            _skinMeshRendererR.enabled = true;

            this.UpdateAsObservable()
            .Subscribe(_ =>
            {
                if (_isInitializedBoneL == false)
                {
                    OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)dataProviderL.GetSkeletonType(), out skeleton);
                    InitializeBones(skeleton, _leftHandVisual, out _isInitializedBoneL);
                }

                if (_isInitializedBoneR == false)
                {
                    OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)dataProviderR.GetSkeletonType(), out skeleton);
                    InitializeBones(skeleton, _leftHandVisual, out _isInitializedBoneR);
                }

                if (_isInitializedHandL == false)
                {
                    ReadyHand(_leftHandVisual, _bonesL, out _isInitializedHandL);
                }

                if (_isInitializedHandR == false)
                {
                    ReadyHand(_rightHandVisual, _bonesR, out _isInitializedHandR);
                }

                if (photonView.IsMine)
                {
                    //頭
                    var cameraTransform = Camera.main.transform;

                    _headVisual.transform.localPosition = cameraTransform.localPosition;
                    _headVisual.transform.localRotation = cameraTransform.localRotation;

                    //ボーンの情報取得
                    _dataL = dataProviderL.GetSkeletonPoseData();
                    _dataR = dataProviderR.GetSkeletonPoseData();

                    //認識してないときは自分の手のみ非表示にする
                    var shouldRendererL        = _dataL.IsDataValid && _dataL.IsDataHighConfidence;
                    var shouldRendererR        = _dataR.IsDataValid && _dataR.IsDataHighConfidence;
                    _skinMeshRendererL.enabled = shouldRendererL;
                    _skinMeshRendererR.enabled = shouldRendererR;

                    //左手
                    if (_dataL.IsDataValid && _dataL.IsDataHighConfidence)
                    {
                        //ルートのローカルポジションを適用
                        _leftHandVisual.transform.localPosition = _dataL.RootPose.Position.FromFlippedZVector3f();
                        _leftHandVisual.transform.localRotation = _dataL.RootPose.Orientation.FromFlippedZQuatf();
                        _leftHandVisual.transform.localScale    = new Vector3(_dataL.RootScale, _dataL.RootScale, _dataL.RootScale);

                        //ボーンのリストに受け取った値を反映
                        for (var i = 0; i < _bonesL.Count; ++i)
                        {
                            _bonesL[i].transform.localRotation = _dataL.BoneRotations[i].FromFlippedXQuatf();

                            if (_bonesL[i].name == OVRSkeleton.BoneId.Hand_WristRoot.ToString())
                            {
                                _bonesL[i].transform.localRotation *= wristFixupRotation;
                            }
                        }
                    }

                    //右手
                    if (_dataR.IsDataValid && _dataR.IsDataHighConfidence)
                    {
                        //ルートのローカルポジションを適用
                        _rightHandVisual.transform.localPosition = _dataR.RootPose.Position.FromFlippedZVector3f();
                        _rightHandVisual.transform.localRotation = _dataR.RootPose.Orientation.FromFlippedZQuatf();
                        _rightHandVisual.transform.localScale    = new Vector3(_dataR.RootScale, _dataR.RootScale, _dataR.RootScale);


                        //ボーンのリストに受け取った値を反映
                        for (var i = 0; i < _bonesR.Count; ++i)
                        {
                            _bonesR[i].transform.localRotation = _dataR.BoneRotations[i].FromFlippedXQuatf();

                            if (_bonesR[i].name == OVRSkeleton.BoneId.Hand_WristRoot.ToString())
                            {
                                _bonesR[i].transform.localRotation *= wristFixupRotation;
                            }
                        }
                    }
                }
            })
            .AddTo(this);
        }
コード例 #13
0
 public SkeletonData(OVRPlugin.Skeleton skeleton, OVRPlugin.SkeletonType skeletonType)
 {
     Skeleton     = skeleton;
     SkeletonType = skeletonType;
 }
コード例 #14
0
    private void Initialize()
    {
        var skeleton = new OVRPlugin.Skeleton();

        if (OVRPlugin.GetSkeleton((OVRPlugin.SkeletonType)_skeletonType, out skeleton))
        {
            if (!_bonesGO)
            {
                _bonesGO = new GameObject("Bones");
                _bonesGO.transform.SetParent(transform, false);
                _bonesGO.transform.localPosition = Vector3.zero;
                _bonesGO.transform.localRotation = Quaternion.identity;
            }

            if (!_bindPosesGO)
            {
                _bindPosesGO = new GameObject("BindPoses");
                _bindPosesGO.transform.SetParent(transform, false);
                _bindPosesGO.transform.localPosition = Vector3.zero;
                _bindPosesGO.transform.localRotation = Quaternion.identity;
            }

            if (_enablePhysicsCapsules)
            {
                if (!_capsulesGO)
                {
                    _capsulesGO = new GameObject("Capsules");
                    _capsulesGO.transform.SetParent(transform, false);
                    _capsulesGO.transform.localPosition = Vector3.zero;
                    _capsulesGO.transform.localRotation = Quaternion.identity;
                }
            }

            _bones = new List <OVRBone>(new OVRBone[skeleton.NumBones]);
            Bones  = _bones.AsReadOnly();

            _bindPoses = new List <OVRBone>(new OVRBone[skeleton.NumBones]);
            BindPoses  = _bindPoses.AsReadOnly();

            // pre-populate bones list before attempting to apply bone hierarchy
            for (int i = 0; i < skeleton.NumBones; ++i)
            {
                BoneId     id        = (OVRSkeleton.BoneId)skeleton.Bones[i].Id;
                short      parentIdx = skeleton.Bones[i].ParentBoneIndex;
                Vector3    pos       = skeleton.Bones[i].Pose.Position.FromFlippedZVector3f();
                Quaternion rot       = skeleton.Bones[i].Pose.Orientation.FromFlippedZQuatf();

                var boneGO = new GameObject(id.ToString());
                boneGO.transform.localPosition = pos;
                boneGO.transform.localRotation = rot;
                _bones[i] = new OVRBone(id, parentIdx, boneGO.transform);

                var bindPoseGO = new GameObject(id.ToString());
                bindPoseGO.transform.localPosition = pos;
                bindPoseGO.transform.localRotation = rot;
                _bindPoses[i] = new OVRBone(id, parentIdx, bindPoseGO.transform);
            }

            for (int i = 0; i < skeleton.NumBones; ++i)
            {
                if (((OVRPlugin.BoneId)skeleton.Bones[i].ParentBoneIndex) == OVRPlugin.BoneId.Invalid)
                {
                    _bones[i].Transform.SetParent(_bonesGO.transform, false);
                    _bindPoses[i].Transform.SetParent(_bindPosesGO.transform, false);
                }
                else
                {
                    _bones[i].Transform.SetParent(_bones[_bones[i].ParentBoneIndex].Transform, false);
                    _bindPoses[i].Transform.SetParent(_bindPoses[_bones[i].ParentBoneIndex].Transform, false);
                }
            }

            if (_enablePhysicsCapsules)
            {
                _capsules = new List <OVRBoneCapsule>(new OVRBoneCapsule[skeleton.NumBoneCapsules]);
                Capsules  = _capsules.AsReadOnly();

                for (int i = 0; i < skeleton.NumBoneCapsules; ++i)
                {
                    var       capsule = skeleton.BoneCapsules[i];
                    Transform bone    = Bones[capsule.BoneIndex].Transform;

                    var capsuleRigidBodyGO = new GameObject((_bones[capsule.BoneIndex].Id).ToString() + "_CapsuleRigidBody");
                    capsuleRigidBodyGO.transform.SetParent(_capsulesGO.transform, false);
                    capsuleRigidBodyGO.transform.localPosition = bone.position;
                    capsuleRigidBodyGO.transform.localRotation = bone.rotation;

                    var capsuleRigidBody = capsuleRigidBodyGO.AddComponent <Rigidbody>();
                    capsuleRigidBody.mass        = 1.0f;
                    capsuleRigidBody.isKinematic = true;
                    capsuleRigidBody.useGravity  = false;
#if UNITY_2018_3_OR_NEWER
                    capsuleRigidBody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
#else
                    capsuleRigidBody.collisionDetectionMode = CollisionDetectionMode.Continuous;
#endif

                    var capsuleColliderGO = new GameObject((_bones[capsule.BoneIndex].Id).ToString() + "_CapsuleCollider");
                    capsuleColliderGO.transform.SetParent(capsuleRigidBodyGO.transform, false);
                    var capsuleCollider = capsuleColliderGO.AddComponent <CapsuleCollider>();
                    var p0    = capsule.Points[0].FromFlippedZVector3f();
                    var p1    = capsule.Points[1].FromFlippedZVector3f();
                    var delta = p1 - p0;
                    var mag   = delta.magnitude;
                    var rot   = Quaternion.FromToRotation(capsuleRigidBodyGO.transform.localRotation * Vector3.right, delta);
                    capsuleCollider.radius    = capsule.Radius;
                    capsuleCollider.height    = mag + capsule.Radius * 2.0f;
                    capsuleCollider.isTrigger = false;
                    capsuleCollider.direction = 0;
                    capsuleColliderGO.transform.localPosition = p0;
                    capsuleColliderGO.transform.localRotation = rot;
                    capsuleCollider.center = Vector3.right * mag * 0.5f;

                    _capsules[i] = new OVRBoneCapsule(capsule.BoneIndex, capsuleRigidBody, capsuleCollider);
                }
            }

            _isInitialized = true;
        }
    }