public IEnumerator WhileTargeting(HandRole origin, GameObject target) { if (origin == HandRole.RightHand) { GameObject animation = UIManager.instance.PlayAnimation(AnimationType.ArrowPullPush); while (rightIsTargeting && showGuidingArrows) { UIManager.instance.SetArrowPosition(animation, Vector3.Lerp(VivePose.GetPose(HandRole.RightHand).pos, target.transform.position, 0.5f), VivePose.GetPose(HandRole.RightHand).pos); yield return(null); } UIManager.instance.StopAnimation(animation); } else if (origin == HandRole.LeftHand) { GameObject animation = UIManager.instance.PlayAnimation(AnimationType.ArrowPullPush); while (leftIsTargeting && showGuidingArrows) { UIManager.instance.SetArrowPosition(animation, Vector3.Lerp(VivePose.GetPose(HandRole.LeftHand).pos, target.transform.position, 0.5f), VivePose.GetPose(HandRole.LeftHand).pos); yield return(null); } UIManager.instance.StopAnimation(animation); } }
private void Update() { if (connectedDeviceChanged) { connectedDeviceChanged = false; OnConnectedDeviceChanged.Invoke(); } if (previousScannedDevice != currentScannedDevice) { OnScanning.Invoke(0f); } else if (ViveRole.IsValidIndex(currentScannedDevice) && sentDevice != currentScannedDevice) { var scannedDuration = Time.time - lastScannedChangedTime; if (scannedDuration > scanDuration) { if (!ViveRole.IsValidIndex(sentDevice) && scannedReticle != null) { scannedReticle.gameObject.SetActive(true); scannedReticle.position = VivePose.GetPose(currentScannedDevice, VROrigin).pos; } OnDeviceScanned.Invoke(sentDevice = currentScannedDevice); OnScanning.Invoke(0f); } else { OnScanning.Invoke(scannedDuration / scanDuration); } } }
// Update is called once per frame void Update() { trackerPose = VivePose.GetPose(HandRole.RightHand); // Engine move if (WristBandInput.bBeginMove) { OnMoveBegin(); } if (WristBandInput.bEndMove) { OnMoveEnd(); } if (WristBandInput.bIsMoving && stayingColliders.Count == 0) { Engine.position += trackerPose.pos - oriTransOfTracker; oriTransOfTracker = trackerPose.pos; } // Call ToolBox if (WristBandInput.bToolBox) { ani.clip = toolboxClip; ani.Play(); } // DisAssemble if (WristBandInput.bDisAssemble) { ani.clip = disassembleClip; ani.Play(); } }
IEnumerator CheckPose() { if (hasTexts) { StartCoroutine(UIManager.instance.ShowText(texts[0])); } GameObject rightArrow = UIManager.instance.PlayAnimation(AnimationType.ArrowUp); GameObject leftArrow = UIManager.instance.PlayAnimation(AnimationType.ArrowUp); float counter = 0; float interval = 0.1f; while (!embodied) { float threshold = VivePose.GetPose(DeviceRole.Hmd).pos.y *embodyThreshold; float rightHandProgress = Mathf.Clamp(VivePose.GetPose(HandRole.RightHand).pos.y / VivePose.GetPose(DeviceRole.Hmd).pos.y, 0, 1); float leftHandProgress = Mathf.Clamp(VivePose.GetPose(HandRole.LeftHand).pos.y / VivePose.GetPose(DeviceRole.Hmd).pos.y, 0, 1); UIManager.instance.SetArrowUpPosition(rightArrow, HandRole.RightHand); UIManager.instance.SetArrowUpPosition(leftArrow, HandRole.LeftHand); if (leftHandProgress > threshold && rightHandProgress > threshold) { counter += Time.deltaTime; if (counter >= interval + 0.02f) { ViveInput.TriggerHapticVibration(HandRole.RightHand, interval, 85 * rightHandProgress, 0.25f * rightHandProgress); ViveInput.TriggerHapticVibration(HandRole.LeftHand, interval, 85 * leftHandProgress, 0.25f * leftHandProgress); counter = 0; } if (VivePose.GetPose(HandRole.RightHand).pos.y > VivePose.GetPose(DeviceRole.Hmd).pos.y&& VivePose.GetPose(HandRole.LeftHand).pos.y > VivePose.GetPose(DeviceRole.Hmd).pos.y) { UIManager.instance.StopAnimation(rightArrow); UIManager.instance.StopAnimation(leftArrow); embodied = true; yield return(null); DataRecorder.instance.SetEvent("Embodied"); ViveInput.TriggerHapticVibration(HandRole.RightHand, interval, 200, 0.9f); ViveInput.TriggerHapticVibration(HandRole.LeftHand, interval, 200, 0.9f); LocalSceneManager.instance.stage0done = true; PrepStage1(); break; } } yield return(null); } }
private void OnEnable() { if (IsInstance) { m_viveRole.onDeviceIndexChanged += OnDeviceIndexChanged; VivePose.AddNewPosesListener(this); OnDeviceIndexChanged(m_viveRole.GetDeviceIndex()); } }
private void OnDisable() { if (IsInstance) { m_viveRole.onDeviceIndexChanged -= OnDeviceIndexChanged; VivePose.RemoveNewPosesListener(this); UpdateActivity(); } }
public void Move(bool MoveMe) { Vector3 movementVector = Vector3.forward * 0; if (MoveMe) { movementVector = Vector3.ProjectOnPlane(VivePose.GetPose(viveRole).forward, Vector3.up) * MovementMultiplier; } player.SimpleMove(movementVector); // always call simple move or you get stuck falling }
void Update() { if (false && VRModule.TryGetConnectedDeviceIndex(trackerSerialNumber, out uint deviceIndex)) { transform.position = VivePose.GetPose(deviceIndex).pos; transform.rotation = VivePose.GetPose(deviceIndex).rot; } else { transform.position = transformSource.position; transform.rotation = transformSource.rotation; } }
public virtual void OnNewPoses() { UpdateRenderModel(); if (isActiveAndEnabled && m_applyTracking) { var deviceIndex = GetCurrentDeviceIndex(); if (VivePose.IsValid(deviceIndex)) { TrackPose(VivePose.GetPose(deviceIndex), m_origin); } } }
public virtual void OnNewPoses() { var valid = VivePose.IsValidEx(viveRole.roleType, viveRole.roleValue); if (valid) { TrackPose(VivePose.GetPoseEx(viveRole.roleType, viveRole.roleValue), m_origin); } if (ChangeProp.Set(ref m_isValid, valid)) { SetValid(m_isValid); } }
public virtual void OnNewPoses() { var deviceIndex = m_viveRole.GetDeviceIndex(); if (VRModule.IsValidDeviceIndex(deviceIndex)) { m_staticExCamPose = VivePose.GetPose(deviceIndex); } if (isQuadViewActive) { RigidPose.SetPose(transform, m_staticExCamPose, m_origin); } }
IEnumerator RotateBacteria(HandRole hand) { Vector3 initialControllerPosition = VivePose.GetPose(hand).pos; Vector3 controllerOffset; while (ControllerManager.instance.GetIsPressed(hand)) { controllerOffset = VivePose.GetPose(hand).pos - initialControllerPosition; Rotate(controllerOffset); yield return(null); } }
public virtual void OnNewPoses() { var deviceIndex = m_viveRole.GetDeviceIndex(); var deviceValid = VRModule.IsValidDeviceIndex(deviceIndex); if (deviceValid) { m_staticExCamPose = VivePose.GetPose(deviceIndex); } if (deviceValid || m_staticExCamEnabled) { Pose.SetPose(transform, m_staticExCamPose, m_origin); } }
private void startZoom() { //Zoom mode Debug.Log("Zoom start"); isGrabbing = true; mode = "zoom"; initialPosR = VivePose.GetPoseEx(HandRole.RightHand, origin).pos; initialPosL = VivePose.GetPoseEx(HandRole.LeftHand, origin).pos; initialZoom = transform.localScale.x; //Take PUN ownership if necessary if (!this.photonView.IsMine) { this.GetComponent <PhotonView>().TransferOwnership(PhotonNetwork.LocalPlayer); } }
private void Update() { if (ViveInput.GetPressDownEx <HandRole>(HandRole.RightHand, ControllerButton.Trigger)) { if (Time.time - lastFireTime < coolTime) { return; } Pose pose = VivePose.GetPose(HandRole.RightHand); Vector3 position = pose.pos; Vector3 forward = pose.rot * Vector3.forward; Spawn(position, forward, 0); lastFireTime = Time.time; } }
private void startRotate() { //Rotate mode Debug.Log("Rotate start"); isGrabbing = true; mode = "rotate"; initialPosR = VivePose.GetPoseEx(HandRole.RightHand, origin).pos; initialPosL = VivePose.GetPoseEx(HandRole.LeftHand, origin).pos; initialRotR = VivePose.GetPoseEx(HandRole.RightHand, origin).rot; initialRot = transform.rotation; //Take PUN ownership if necessary if (!this.photonView.IsMine) { this.GetComponent <PhotonView>().TransferOwnership(PhotonNetwork.LocalPlayer); } }
public Vector3 GetRotation(int index) { Quaternion rotation; switch (index) { case 1: rotation = VivePose.GetPoseEx(DeviceRole.Hmd).rot; break; case 2: rotation = VivePose.GetPoseEx(HandRole.LeftHand).rot; break; case 3: rotation = VivePose.GetPoseEx(HandRole.RightHand).rot; break; case 4: rotation = VivePose.GetPoseEx(TrackerRole.Tracker1).rot; break; case 5: rotation = VivePose.GetPoseEx(TrackerRole.Tracker2).rot; break; case 6: rotation = VivePose.GetPoseEx(TrackerRole.Tracker3).rot; break; default: rotation = new Quaternion(0, 0, 0, 0); break; } Vector3 normal = rotation.eulerAngles; normal.x -= 180; normal.x = Mathf.Abs(normal.x); normal.y -= 180; normal.y = Mathf.Abs(normal.y); normal.z -= 180; normal.z = Mathf.Abs(normal.z); return(normal); }
/*private IEnumerator PullPush(Vector3 target, HandRole hand, Action<Direction> action) * { * yield return null; * * float threshold = 20; * Debug.Log("Registering Pull and Push"); * * Vector3 playerForward = target - Camera.main.transform.position; * if (hand == HandRole.RightHand) * { * while (GetIsPressed(hand)) * { * if (VivePose.GetAngularVelocity(hand).sqrMagnitude > 30) * { * if (Vector3.Cross(playerForward, VivePose.GetAngularVelocity(hand)).x < threshold * -1 && Mathf.Abs(Vector3.Dot(playerForward, VivePose.GetAngularVelocity(hand))) < 30) * { * Debug.Log("Push"); * action(Direction.Backward); * break; * } * else if (Vector3.Cross(playerForward, VivePose.GetAngularVelocity(hand)).x > threshold && Mathf.Abs(Vector3.Dot(playerForward, VivePose.GetAngularVelocity(hand))) < 30) * { * Debug.Log("Pull"); * action(Direction.Forward); * break; * } * } * yield return null; * } * } * else if (hand == HandRole.LeftHand) * { * while (GetIsPressed(hand)) * { * if (VivePose.GetAngularVelocity(hand).sqrMagnitude > 30) * { * if (Vector3.Cross(playerForward, VivePose.GetAngularVelocity(hand)).x < threshold * -1 && Mathf.Abs(Vector3.Dot(playerForward, VivePose.GetAngularVelocity(hand))) < 30) * { * Debug.Log("Pull"); * action(Direction.Forward); * break; * } * else if (Vector3.Cross(playerForward, VivePose.GetAngularVelocity(hand)).x > threshold && Mathf.Abs(Vector3.Dot(playerForward, VivePose.GetAngularVelocity(hand))) < 30) * { * Debug.Log("Push"); * action(Direction.Backward); * break; * } * } * yield return null; * } * } * }*/ private IEnumerator PullPush(HandRole hand, Action <Direction> action) { yield return(null); Vector3 velocity; Transform camera = Camera.main.transform; while (GetIsPressed(hand)) { velocity = VivePose.GetVelocity(hand); if (velocity.sqrMagnitude > 2) { if (velocity.y > -1 && velocity.y < 1) { float dot = Vector3.Dot(Vector3.forward, camera.InverseTransformVector(velocity) - camera.InverseTransformVector(VivePose.GetPose(hand).pos)); float angle = Vector3.Angle(Vector3.forward, camera.InverseTransformVector(velocity) - camera.InverseTransformVector(VivePose.GetPose(hand).pos)); if (angle < 60 || angle > 120) { showGuidingArrows = false; yield return(null); if (Mathf.Sign(dot) == 1) { DataRecorder.instance.SetEvent("Push"); action(Direction.Backward); break; } else if (Mathf.Sign(dot) == -1) { DataRecorder.instance.SetEvent("Pull"); action(Direction.Forward); break; } } } } yield return(null); } }
public void UpdateState() { if (alreadySelected) { return; } List <SelectWall> wallCandidates = ReconstructManager.Instance.GetWallCandidate(); HTC.UnityPlugin.Utility.RigidPose rightHandPose = VivePose.GetPose(HandRole.RightHand); Matrix4x4 matRot = Matrix4x4.Rotate(rightHandPose.rot); Vector3 rightArmPos = rightHandPose.pos; Vector3 rightHandDir = matRot.GetColumn(2); RaycastHit hit; int hitLayer = (1 << ARRender.UnityRenderOnTopNoShadowLayer); if (Physics.Raycast(rightArmPos, rightHandDir, out hit, 99999, hitLayer)) { foreach (SelectWall wall in wallCandidates) { int hashL = wall.selectWall.GetHashCode(); int hashH = hit.collider.gameObject.GetHashCode(); if (hashL == hashH) { wall.SetSelectColor(); bool triggerpress = ViveInput.GetPress(HandRole.RightHand, ControllerButton.Trigger); if (triggerpress) { GameObject finalWall = ReconstructManager.SetPivotInMeshCenter( wall.origWall.transform, wall.origWall.GetComponent <MeshCollider>().sharedMesh, ReconstructManager.Instance.selectedWallRoot.transform, ReconstructManager.Instance.selectWallMaterial, wall.origWall.name + "_convexWall : " + wall.area, wall.normal, wall.center); finalWall.layer = AdvanceRender.ScanLiveMeshLayer; break; } } } } alreadySelected = CheckSelectDone(wallCandidates); }
/// <summary> /// Throws an error of <see cref="currentPoseTransform"/> is not assigned. /// </summary> private void SetAdjustmentReferencePoses() { calibrationControllerReferencePose = VivePose.GetPose(calibrationController, null); for (int i = 0; i < poseTransforms.Length; i++) { pointCloudReferencePoses[i].position = poseTransforms[i].transform.position; pointCloudReferencePoses[i].rotation = poseTransforms[i].transform.rotation; } if (skyboxControl) { skyboxReferenceRotation = skyboxControl.SkyboxMaterial.GetFloat(SkyboxControl._Rotation); } if (RenderSettings.skybox) { skyboxReferenceRotation = RenderSettings.skybox.GetFloat(SkyboxControl._Rotation); } }
// Update is called once per frame private void Update() { curLeftPos = VivePose.GetPose(leftHandRole).pos; curRightPos = VivePose.GetPose(rightHandRole).pos; leftPunchDirection = (curLeftPos - lastLeftPos); rightPunchDirection = (curRightPos - lastRightPos); leftMomentum = leftPunchDirection.magnitude / Time.deltaTime; rightMomentum = rightPunchDirection.magnitude / Time.deltaTime; CheckPunch(); //CheckJump(); CheckRun(); lastLeftPos = curLeftPos; lastRightPos = curRightPos; }
private void AdjustSkybox() { Pose controllerPose = VivePose.GetPose(calibrationController); // The delta rotation of the hand controller Quaternion rotationOffset = controllerPose.rotation * Quaternion.Inverse(calibrationControllerReferencePose.rotation); print("rotationOffset: w=" + rotationOffset.w + " x=" + rotationOffset.x + " y=" + rotationOffset.y + " z=" + rotationOffset.z); // Force unity to use "small" angles (below 180 degrees) if (rotationOffset.w < 0f) { rotationOffset.w = -rotationOffset.w; rotationOffset.x = -rotationOffset.x; rotationOffset.y = -rotationOffset.y; rotationOffset.z = -rotationOffset.z; } rotationOffset.ToAngleAxis(out float deltaRotationAngle, out Vector3 deltaRotationAxis); // Force Unity to not switch the axis after 180 degrees rotation. We simply set current rotation as reference if (deltaRotationAngle > 150) { print("Resetting offset angle."); SetAdjustmentReferencePoses(); return; } print("rotationOffset angle: " + deltaRotationAngle + "\t axis: " + deltaRotationAxis); Quaternion scaledRotationOffset = Quaternion.Slerp(Quaternion.identity, rotationOffset, adjustmentRatio); Vector3 scaledRotationOffsetEuler = scaledRotationOffset.eulerAngles; print("skyboxReferenceRotation: " + skyboxReferenceRotation); float newRotation = skyboxReferenceRotation + scaledRotationOffsetEuler.y; newRotation %= 360; if (RenderSettings.skybox) { RenderSettings.skybox.SetFloat(SkyboxControl._Rotation, newRotation); } else { SkyboxControl.SkyboxRotation_Event.Invoke(this, newRotation); } }
void OnGUI() { if (enableMotion && ShowDebug) { string rightFootDisplay = ""; string leftFootDisplay = ""; if (rightFoot != null) { rightFootDisplay = string.Format("Right Foot - Connected:\nangular\nx [{0}]\ny [{1}]\nz [{2}]\nvel\nx [{3}]\ny [{4}]\nz [{5}]\n", VivePose.GetAngularVelocity(rightFoot).x, VivePose.GetAngularVelocity(rightFoot).y, VivePose.GetAngularVelocity(rightFoot).z, VivePose.GetVelocity(rightFoot).x, VivePose.GetVelocity(rightFoot).y, VivePose.GetVelocity(rightFoot).z ); } else { rightFootDisplay = string.Format("Right Foot - Disconnected"); } if (leftFoot != null) { leftFootDisplay = string.Format("Left Foot - Connected:\nangular\nx [{0}]\ny [{1}]\nz [{2}]\nvel\nx [{3}]\ny [{4}]\nz [{5}]\n", VivePose.GetAngularVelocity(leftFoot).x, VivePose.GetAngularVelocity(leftFoot).y, VivePose.GetAngularVelocity(leftFoot).z, VivePose.GetVelocity(leftFoot).x, VivePose.GetVelocity(leftFoot).y, VivePose.GetVelocity(leftFoot).z ); } else { rightFootDisplay = string.Format("Left Foot - Disconnected"); } GUI.Label(new Rect(10, 10, 500, 300), rightFootDisplay); GUI.Label(new Rect(10, 350, 500, 300), leftFootDisplay); } }
public void UpdateStatus() { if (!VivePose.IsConnected(m_deviceIndex)) { m_deviceIndex = ViveRole.INVALID_DEVICE_INDEX; textDeviceIndex.text = string.Empty; textDeviceClass.text = string.Empty; textSerialNum.text = string.Empty; textModelNum.text = string.Empty; } else { textDeviceIndex.text = m_deviceIndex.ToString(); textDeviceClass.text = ViveRole.GetDeviceClass(m_deviceIndex).ToString(); textSerialNum.text = ViveRole.GetSerialNumber(m_deviceIndex); textModelNum.text = ViveRole.GetModelNumber(m_deviceIndex); } }
// Update is called once per frame void Update() { RigidPose pose = VivePose.GetPoseEx(HandRole.RightHand); //RigidPose pose2 = VivePose.GetPoseEx(TrackerRole.Tracker1); //print(pose1.pos.x + " " + pose1.pos.y + " " + pose1.pos.z); //set transform to the mid point between them //if (VivePose.IsValidEx(HandRole.RightHand) && VivePose.IsValidEx(TrackerRole.Tracker1)) //{ // transform.localPosition = Vector3.Lerp(pose1.pos, pose2.pos, 0.5f); // transform.localRotation = Quaternion.Lerp(pose1.rot, pose2.rot, 0.5f); //} if (ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger)) { v = pose.pos - v0; } //print(v); }
// Update is called once per frame void Update() { last = VivePose.GetPose(rightHandRole).pos; uiHandRot = VivePose.GetPose(rightHandRole).rot; //transform.LookAt(Camera.main.transform); Vector3 euler = righthand.eulerAngles; float eulery = Mathf.Abs(euler.y - 360.0f); if (eulery >= 35.0f && eulery < 200.0f && last.y >= 1.6f) { handui.gameObject.SetActive(true); } else if (last.y <= 1.5) { handui.gameObject.SetActive(false); } }
public void UpdateStatus() { if (!VivePose.IsConnected(m_deviceIndex)) { m_deviceIndex = VRModule.INVALID_DEVICE_INDEX; textDeviceIndex.text = string.Empty; textDeviceClass.text = string.Empty; textSerialNum.text = string.Empty; textModelNum.text = string.Empty; } else { var deviceState = VRModule.GetCurrentDeviceState(m_deviceIndex); textDeviceIndex.text = m_deviceIndex.ToString(); textDeviceClass.text = deviceState.deviceClass.ToString();; textSerialNum.text = deviceState.serialNumber; textModelNum.text = deviceState.modelNumber; } }
private void InternalSetQuadViewActive(bool value) { if (value && m_externalCamera == null && !string.IsNullOrEmpty(m_configPath) && File.Exists(m_configPath)) { // don't know why SteamVR_ExternalCamera must be instantiated from the prefab // when create SteamVR_ExternalCamera using AddComponent, errors came out when disabling var prefab = Resources.Load <GameObject>("SteamVR_ExternalCamera"); if (prefab == null) { Debug.LogError("SteamVR_ExternalCamera prefab not found!"); } else { var ctrlMgr = Instantiate(prefab); var extCam = ctrlMgr.transform.GetChild(0); extCam.gameObject.name = "SteamVR External Camera"; extCam.SetParent(transform, false); DestroyImmediate(extCam.GetComponent <SteamVR_TrackedObject>()); DestroyImmediate(ctrlMgr); m_externalCamera = extCam.GetComponent <SteamVR_ExternalCamera>(); SteamVR_Render.instance.externalCamera = m_externalCamera; m_externalCamera.configPath = m_configPath; m_externalCamera.ReadConfig(); } } if (m_externalCamera != null) { m_externalCamera.gameObject.SetActive(value); if (value) { VivePose.AddNewPosesListener(this); } else { VivePose.RemoveNewPosesListener(this); } } }
private uint GetCurrentDeviceIndex() { uint result; switch (m_mode) { case Mode.ViveRole: result = m_viveRole.GetDeviceIndex(); break; case Mode.DeivceIndex: result = (uint)m_deviceIndex; break; case Mode.Disable: default: return(ViveRole.INVALID_DEVICE_INDEX); } return(VivePose.IsValid(result) ? result : ViveRole.INVALID_DEVICE_INDEX); }
private void AdjustPointcloud(TrackerTransform targetTransform, Pose refPose) { Pose controllerPose = VivePose.GetPose(calibrationController); // The delta rotation of the hand controller Quaternion rotationOffset = controllerPose.rotation * Quaternion.Inverse(calibrationControllerReferencePose.rotation); print("rotationOffset: w=" + rotationOffset.w + " x=" + rotationOffset.x + " y=" + rotationOffset.y + " z=" + rotationOffset.z); // Force Unity to use "small" angles (below 180 degrees) if (rotationOffset.w < 0f) { rotationOffset.w = -rotationOffset.w; rotationOffset.x = -rotationOffset.x; rotationOffset.y = -rotationOffset.y; rotationOffset.z = -rotationOffset.z; } rotationOffset.ToAngleAxis(out float deltaRotationAngle, out Vector3 deltaRotationAxis); // Force Unity to not switch the axis after 180 degrees rotation. We simply set current rotation as reference if (deltaRotationAngle > 150) { SetAdjustmentReferencePoses(); return; } print("rotationOffset angle: " + deltaRotationAngle + "\t axis: " + deltaRotationAxis); Vector3 positionOffset = controllerPose.position - calibrationControllerReferencePose.position; // Always rotate and position from the reference targetTransform.transform.rotation = refPose.rotation; targetTransform.transform.position = refPose.position; Quaternion scaledRotationOffset = Quaternion.Slerp(Quaternion.identity, rotationOffset, adjustmentRatio); print("scaledRotationOffset: " + scaledRotationOffset); scaledRotationOffset.ToAngleAxis(out float scaledDeltaRotationAngle, out Vector3 scaledDeltaRotationAxis); print("scaledRotationOffset angle: " + scaledDeltaRotationAngle + "\t axis: " + scaledDeltaRotationAxis); targetTransform.transform.RotateAround(calibrationControllerReferencePose.position, scaledDeltaRotationAxis, scaledDeltaRotationAngle); targetTransform.transform.position += (positionOffset * adjustmentRatio); }