private void UpdateSelection() { // Get right controller buttons states bool primaryButtonState = VRInput.GetValue(VRInput.primaryController, CommonUsages.primaryButton); bool triggerState = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton); GameObject hoveredObject = Selection.HoveredObject; VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.grip, () => { Selection.HoveredObject = hoveredObject; }, () => { Selection.AuxiliarySelection = null; }); // Multi-selection using the trigger button if (triggerState && !GlobalState.Instance.selectionGripped && null != hoveredObject && !selector.Deforming) { if (!primaryButtonState) { foreach (GameObject obj in collidedObjects) { selector.AddSiblingsToSelection(obj); } } } }
protected override void DoUpdate() { VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.triggerButton, () => { group = new CommandGroup("Gun"); }, () => { group.Submit(); group = null; } ); bool triggered = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton); if (triggered && prefabs.Count > 0) { if (Time.time - prevTime > 1f / fireRate) { int prefabIndex = UnityEngine.Random.Range(0, prefabs.Count); GameObject spawned = Instantiate(prefabs[prefabIndex]); ThrowedObject throwed = spawned.AddComponent <ThrowedObject>(); throwed.AddForce(transform.forward * power); throwed.SetScale(objectScale); new CommandAddGameObject(spawned).Submit(); Matrix4x4 matrix = SceneManager.RightHanded.worldToLocalMatrix * mouthpiece.localToWorldMatrix; Maths.DecomposeMatrix(matrix, out Vector3 t, out _, out _); Vector3 scale = Vector3.one; SceneManager.SetObjectMatrix(spawned, Matrix4x4.TRS(t, Quaternion.identity, scale)); prevTime = Time.time; } } }
private void Update() { // Trigger action forwarded to Colorize script bool triggerState = VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton); if (triggerState && collidedObjects.Count > 0) { // Process then remove objects from the list of collided objects in order to prevent // processing the same objects each frame (until trigger exit) colorizer.ProcessObjects(collidedObjects.ToList()); collidedObjects.Clear(); } // Scaling of collider if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK)) { Vector2 val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); if (val != Vector2.zero) { float scale = gameObject.transform.localScale.x; if (val.y > 0.3f) { scale += 0.001f; } if (val.y < -0.3f) { scale -= 0.001f; } scale = Mathf.Clamp(scale, 0.001f, 0.5f); gameObject.transform.localScale = new Vector3(scale, scale, scale); } } }
private void UpdateEraser() { GameObject hoveredObject = Selection.HoveredObject; if (null == hoveredObject && Selection.SelectedObjects.Count == 0) { return; } // If we have a hovered object, only destroy it if (null != hoveredObject) { // Don't delete UI handles if (hoveredObject.GetComponent <UIHandle>()) { return; } if (VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton)) { CommandGroup group = new CommandGroup("Erase Hovered Object"); try { RemoveCollidedObject(hoveredObject); selector.RemoveSiblingsFromSelection(hoveredObject, false); new CommandRemoveGameObject(hoveredObject).Submit(); } finally { group.Submit(); } } } // If we don't have any hovered object but we collided with a selection, delete the whole selection else if (collidedObjects.Count > 0 && Selection.IsSelected(collidedObjects[0])) { if (VRInput.GetValue(VRInput.primaryController, CommonUsages.triggerButton)) { CommandGroup group = new CommandGroup("Erase Selected Objects"); try { foreach (GameObject gobject in Selection.SelectedObjects) { RemoveCollidedObject(gobject); selector.RemoveSiblingsFromSelection(gobject, false); new CommandRemoveGameObject(gobject).Submit(); } } finally { group.Submit(); } } } }
// Update is called once per frame void Update() { if (!device.isValid) { CaptureController(); CaptureInitialTransforms(); } // GRIP if (null != gripTransform) { float gripAmount = VRInput.GetValue(device, CommonUsages.grip); gripTransform.localRotation = initGripRotation * Quaternion.Euler(0, gripAmount * gripRotationAmplitude * gripDirection, 0); gripTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", gripAmount > 0.01f ? UIOptions.SelectedColor : Color.black); } // TRIGGER if (null != triggerTransform) { float triggerAmount = VRInput.GetValue(device, CommonUsages.trigger); triggerTransform.localRotation = initTriggerRotation * Quaternion.Euler(triggerAmount * triggerRotationAmplitude, 0, 0); triggerTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", triggerAmount > 0.01f ? UIOptions.SelectedColor : Color.black); } // JOYSTICK if (null != joystickTransform) { Vector2 joystick = VRInput.GetValue(device, CommonUsages.primary2DAxis); joystickTransform.localRotation = initJoystickRotation * Quaternion.Euler(joystick.y * joystickRotationAmplitude, 0, joystick.x * -joystickRotationAmplitude); joystickTransform.gameObject.GetComponent <MeshRenderer>().materials[1].SetColor("_BaseColor", joystick.magnitude > 0.05f ? UIOptions.SelectedColor : Color.black); } // PRIMARY if (null != primaryTransform) { bool primaryState = VRInput.GetValue(device, CommonUsages.primaryButton); primaryTransform.localPosition = initPrimaryTranslation; primaryTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", primaryState ? UIOptions.SelectedColor : Color.black); if (primaryState) { primaryTransform.localPosition += new Vector3(0, 0, primaryTranslationAmplitude); // TODO: quick anim? CoRoutine. } } // SECONDARY if (null != secondaryTransform) { bool secondaryState = VRInput.GetValue(device, CommonUsages.secondaryButton); secondaryTransform.localPosition = initSecondaryTranslation; secondaryTransform.gameObject.GetComponent <MeshRenderer>().material.SetColor("_BaseColor", secondaryState ? UIOptions.SelectedColor : Color.black); if (secondaryState) { secondaryTransform.localPosition += new Vector3(0, 0, secondaryTranslationAmplitude); // TODO: quick anim? CoRoutine. } } }
private void HandlePalette() { if (null == ToolsUIManager.Instance) { return; } if (VRInput.GetValue(VRInput.secondaryController, CommonUsages.trigger) > deadZone) { ToolsUIManager.Instance.PopUpPalette(true); } else { ToolsUIManager.Instance.PopUpPalette(false); } }
private void SelectObjects(List <GameObject> gobjects) { bool primaryState = VRInput.GetValue(VRInput.primaryController, CommonUsages.primaryButton); ICommand command; if (!primaryState) { command = new CommandAddToSelection(gobjects); } else { command = new CommandRemoveFromSelection(gobjects); } command.Redo(); command.Submit(); selectionHasChanged = true; }
// Update is called once per frame void Update() { if (!device.isValid) { CaptureController(); CaptureInitialTransforms(); } // GRIP if (null != gripTransform) { float gripAmount = VRInput.GetValue(device, CommonUsages.grip); AnimateGrip(gripAmount); } // TRIGGER if (null != triggerTransform) { float triggerAmout = VRInput.GetValue(device, CommonUsages.trigger); AnimateTrigger(triggerAmout); } // JOYSTICK if (null != joystickTransform) { Vector2 joystick = VRInput.GetValue(device, CommonUsages.primary2DAxis); AnimateJoystick(joystick); } // PRIMARY if (null != primaryTransform) { bool primaryState = VRInput.GetValue(device, CommonUsages.primaryButton); AnimatePrimaryButton(primaryState); } // SECONDARY if (null != secondaryTransform) { bool secondaryState = VRInput.GetValue(device, CommonUsages.secondaryButton); AnimateSecondaryButton(secondaryState); } }
private Vector4 GetJoysticksValue() { Vector2 leftJoyValue = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis); Vector2 rightJoyValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); Vector4 currentValue = new Vector4(leftJoyValue.x, leftJoyValue.y, rightJoyValue.x, rightJoyValue.y); float damping = options.fpsDamping * 5f; int elemCount = (int)damping; int currentSize = prevJoysticksStates.Count; if (currentSize > elemCount) { prevJoysticksStates.RemoveRange(0, currentSize - elemCount); deltaTimes.RemoveRange(0, currentSize - elemCount); } prevJoysticksStates.Add(currentValue); deltaTimes.Add(Time.deltaTime); Vector4 average = Vector4.zero; float invCount = 1f / (float)prevJoysticksStates.Count; float dtSum = 0; foreach (float dt in deltaTimes) { dtSum += dt; } float invDtSum = 1f / dtSum; for (int i = 0; i < prevJoysticksStates.Count; i++) { average += prevJoysticksStates[i] * deltaTimes[i] * invDtSum; } return(average); }
protected override void DoUpdate() { // Update feedback position and scale if (GlobalState.Settings.cameraFeedbackVisible) { bool trigger = false; if (feedbackPositioning && VRInput.GetValue(VRInput.primaryController, CommonUsages.gripButton)) { GlobalState.Settings.cameraFeedbackDirection = rig.InverseTransformDirection(transform.forward); // direction local to rig trigger = true; } if (trigger) { // Cam feedback scale Vector2 joystickAxis = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); float value = GlobalState.Settings.cameraFeedbackScaleValue; if (joystickAxis.y > deadZone) { value *= cameraFeedbackScaleFactor; } if (joystickAxis.y < -deadZone) { value /= cameraFeedbackScaleFactor; } GlobalState.Settings.cameraFeedbackScaleValue = Mathf.Clamp(value, GlobalState.Settings.cameraFeedbackMinScaleValue, GlobalState.Settings.cameraFeedbackMaxScaleValue); GlobalState.Instance.cameraFeedback.GetComponent <CameraFeedback>().UpdateTransform(); } } // called to update focal slider value UpdateUI(); if (!GlobalState.Settings.cameraFeedbackVisible || !feedbackPositioning) { base.DoUpdate(); } }
protected override void DoUpdateGui() { bool gripped = false; VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.gripButton, async() => { await OnGrabUIObject(); // Since OnGrabUIObject may take some time, check we are still gripped gripped = VRInput.GetValue(VRInput.primaryController, CommonUsages.gripButton); if (gripped) { OnStartGrip(); } }, () => { // Only end grip if we were effectively gripped if (gripped) { OnEndGrip(); } }); }
protected override void DoUpdate() { if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK)) { Vector2 AxisValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); if (AxisValue != Vector2.zero) { float scaleFactor = 1f + GlobalState.Settings.scaleSpeed / 1000f; if (null == curveManip) { float selectorRadius = mouthpiece.localScale.x; if (AxisValue.y > deadzone) { selectorRadius *= scaleFactor; } if (AxisValue.y < deadzone) { selectorRadius /= scaleFactor; } selectorRadius = Mathf.Clamp(selectorRadius, 0.001f, 0.5f); mouthpiece.localScale = Vector3.one * selectorRadius; } else { if (AxisValue.y > deadzone) { scaleIndice *= scaleFactor; } if (AxisValue.y < deadzone) { scaleIndice /= scaleFactor; } scaleIndice = Mathf.Clamp(scaleIndice, 0.001f, 100f); } } } }
public override void Update() { if (ray == null) { return; } // // RAY - collision with scene objects. // if (!isLocked) { RaycastHit hit; Vector3 worldStart = paletteController.TransformPoint(0.01f, 0.0f, 0.05f); Vector3 worldEnd = paletteController.TransformPoint(0, 0, 3); Vector3 worldDirection = worldEnd - worldStart; Ray r = new Ray(worldStart, worldDirection); int layersMask = LayerMask.GetMask(new string[] { "Default", "Selection", "Hover" }); if (Physics.Raycast(r, out hit, 100.0f, layersMask)) { target = hit.collider.transform; targetPosition = hit.collider.bounds.center; minDistance = hit.collider.bounds.extents.magnitude; ray.SetStartPosition(worldStart); ray.SetEndPosition(hit.point); ray.SetActiveColor(); if (target) { Selection.HoveredObject = target.gameObject; } } else { if (target) { Selection.HoveredObject = null; } target = null; targetPosition = Vector3.zero; minDistance = 0.0f; ray.SetStartPosition(worldStart); ray.SetEndPosition(worldEnd); ray.SetDefaultColor(); } } else { Vector3 up = Vector3.up; //rig.up; Vector3 forward = Vector3.Normalize(camera.position - targetPosition); Vector3 right = Vector3.Cross(up, forward); float distance = Vector3.Distance(camera.position, targetPosition); // // Left Joystick -- left/right = rotate left/right. // up/down = rotate up/down. Vector2 val = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis); if (val != Vector2.zero) { // Horizontal rotation if (Mathf.Abs(val.x) > deadZone) { float value = Mathf.Sign(val.x) * (Mathf.Abs(val.x) - deadZone) / (1.0f - deadZone); // remap float rotate_amount_h = value * options.orbitRotationalSpeed; //rotationalSpeed; rig.RotateAround(targetPosition, up, -rotate_amount_h); } // Vertical rotation if (Mathf.Abs(val.y) > deadZone) { float value = Mathf.Sign(val.y) * (Mathf.Abs(val.y) - deadZone) / (1.0f - deadZone); // remap float dot = Vector3.Dot(up, forward); bool in_safe_zone = (Mathf.Abs(dot) < 0.8f); bool above_but_going_down = (dot > 0.8f) && (value < 0.0f); bool below_but_going_up = (dot < -0.8f) && (value > 0.0f); if (!limitVertical || in_safe_zone || above_but_going_down || below_but_going_up) // only within limits { float rotate_amount_v = value * options.orbitRotationalSpeed; //rotationalSpeed; rig.RotateAround(targetPosition, right, -rotate_amount_v); } } } // // Right Joystick -- left/right = move closer/farther // up/down = scale world val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); if (val != Vector2.zero) { float remainingDistance = distance - minDistance; bool in_safe_zone = (remainingDistance > 0.0f); // Move the world closer/farther if (Mathf.Abs(val.x) > deadZone) { float value = Mathf.Sign(val.x) * (Mathf.Abs(val.x) - deadZone) / (1.0f - deadZone); // remap bool too_close_but_going_back = (remainingDistance <= 0.0f) && (value < 0.0f); if (in_safe_zone || too_close_but_going_back) { Vector3 offset = forward * value * (minMoveDistance + options.orbitMoveSpeed * Mathf.Abs(remainingDistance)); //moveSpeed rig.position -= offset; } } /* * // Scale the world * if (Mathf.Abs(val.y) > deadZone) * { * float value = Mathf.Sign(val.y) * (Mathf.Abs(val.y) - deadZone) / (1.0f - deadZone); // remap * bool too_close_but_scaling_down = (remainingDistance <= 0.0f) && (value < 0.0f); * if (in_safe_zone || too_close_but_scaling_down) * { * float scale = 1.0f + (value * options.orbitScaleSpeed); // scaleSpeed * * Vector3 scalePivot = targetPosition; * Vector3 pivot_to_world = world.position - scalePivot; * pivot_to_world.Scale(new Vector3(scale, scale, scale)); * world.position = scalePivot + pivot_to_world; * targetPosition = world.position - pivot_to_world; * minDistance *= scale; * * float finalScale = scale * world.localScale.x; * float clampedScale = Mathf.Clamp(finalScale, 1.0f / maxPlayerScale, minPlayerScale); * * // should touch rig, not world * world.localScale = new Vector3(clampedScale, clampedScale, clampedScale); * * GlobalState.WorldScale = world.localScale.x; * * UpdateCameraClipPlanes(); * } * } */ } // Position the ray AFTER the rotation of the camera, to avoid a one frame shift. ray.SetStartPosition(paletteController.TransformPoint(0.01f, 0.0f, 0.05f)); ray.SetEndPosition(targetPosition); } // // LEFT GRIP (click) - lock on targetted object/point. // VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton, () => { if (target != null) { isLocked = true; ray.gameObject.SetActive(false); // hide ray on grip } GlobalState.IsGrippingWorld = true; }, () => { isLocked = false; ray.gameObject.SetActive(true); GlobalState.IsGrippingWorld = false; }); }
public override void Update() { // // LEFT GRIP WORLD // VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton, () => { // left AFTER right => reset all // NOTE: isRightGripped && Selection.selection.Count > 0 means that the selectionTool will/has gripped objects, // and is no longer able to be used for two-hands interaction. if (isRightGripped) // && Selection.selection.Count == 0) { ResetInitControllerMatrices(ResetType.LEFT_AND_RIGHT); ResetInitWorldMatrix(); ResetDistance(); // after reset world, use scale SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); lineUI.Show(true, StretchUI.LineMode.DOUBLE); GlobalState.IsGrippingWorld = true; ToolsManager.ActivateCurrentTool(false); } isLeftGripped = true; }, () => { SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); lineUI.Show(false); ToolsManager.ActivateCurrentTool(true); GlobalState.IsGrippingWorld = false; isLeftGripped = false; }); // // RIGHT GRIP WORLD // // NOTE: On ne peut predire dans quel ordre les Update vont s'executer. Le Selector/SelectorTrigger peuvent // recuperer le LeftGrip avant nous, et commencer a grip un objet avant qu'on ait pu set la property // GlobalState.IsGrippingWorld. Cela pose-t-il encore un probleme? VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.gripButton, () => { //if (Selection.selection.Count == 0) { // right AFTER left and no selection, reset all if (isLeftGripped) { ResetInitControllerMatrices(ResetType.LEFT_AND_RIGHT); ResetInitWorldMatrix(); ResetDistance(); // NOTE: called after "reset world", because it uses the scale. SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); lineUI.Show(true, StretchUI.LineMode.DOUBLE); GlobalState.IsGrippingWorld = true; ToolsManager.ActivateCurrentTool(false); } // even if no left gripped, just flag the right as gripped for the next update isRightGripped = true; } }, () => { // si on relache le right et que le left est tjs grip, reset left if (isLeftGripped) { ResetInitControllerMatrices(ResetType.LEFT_ONLY); ResetInitWorldMatrix(); SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); } //lineUI.Show(true, StretchUI.LineMode.SINGLE); ToolsManager.ActivateCurrentTool(true); GlobalState.IsGrippingWorld = false; isRightGripped = false; }); // NOTE: we test isLeftGrip because we can be ungripped but still over the deadzone, strangely. if (isLeftGripped && VRInput.GetValue(VRInput.secondaryController, CommonUsages.grip) > deadZone) { if (isRightGripped) { float prevScale = scale; VRInput.GetControllerTransform(VRInput.secondaryController, out Vector3 currentLeftControllerPosition_L, out Quaternion currentLeftControllerRotation_L); VRInput.GetControllerTransform(VRInput.primaryController, out Vector3 currentRightControllerPosition_L, out Quaternion currentRightControllerRotation_L); Matrix4x4 currentLeftControllerMatrix_L_Scaled = Matrix4x4.TRS(currentLeftControllerPosition_L, currentLeftControllerRotation_L, new Vector3(scale, scale, scale)); Matrix4x4 currentLeftControllerMatrix_W = initPivotMatrix * currentLeftControllerMatrix_L_Scaled; Vector3 currentLeftControllerPosition_W = currentLeftControllerMatrix_W.MultiplyPoint(Vector3.zero); // update right joystick Matrix4x4 currentRightControllerMatrix_L_Scaled = Matrix4x4.TRS(currentRightControllerPosition_L, currentRightControllerRotation_L, new Vector3(scale, scale, scale)); Vector3 currentRightControllerPosition_W = (initPivotMatrix * currentRightControllerMatrix_L_Scaled).MultiplyPoint(Vector3.zero); // scale handling (before computing the "transformed" matrix with the new scale) float newDistance = Vector3.Distance(currentLeftControllerPosition_W, currentRightControllerPosition_W); float factor = newDistance / prevDistance; float oldScale = scale; scale *= factor; prevDistance = newDistance; Vector3 middlePosition_L = (currentLeftControllerPosition_L + currentRightControllerPosition_L) * 0.5f; Vector3 middleXVector = (currentRightControllerPosition_L - currentLeftControllerPosition_L).normalized; Vector3 middleForwardVector = -Vector3.Cross(middleXVector, pivot.up).normalized; Quaternion middleRotation_L = Quaternion.LookRotation(middleForwardVector, pivot.up); Matrix4x4 middleMatrix_L_Scaled = Matrix4x4.TRS(middlePosition_L, middleRotation_L, Vector3.one) * Matrix4x4.Scale(Vector3.one * scale); Matrix4x4 middleMatrix_W_Delta = initPivotMatrix * middleMatrix_L_Scaled * initMiddleMatrix_WtoL; Matrix4x4 transformed = middleMatrix_W_Delta * initWorldMatrix_W; transformed = transformed.inverse; float s = 1.0f; float clampedScale = Mathf.Clamp(transformed.lossyScale.x, 1.0f / maxPlayerScale, minPlayerScale); if (transformed.lossyScale.x == clampedScale) { // translate/rotate/scale using the new scale rig.localPosition = new Vector3(transformed.GetColumn(3).x, transformed.GetColumn(3).y, transformed.GetColumn(3).z); rig.localRotation = transformed.rotation; rig.localScale = new Vector3(clampedScale, clampedScale, clampedScale); s = oldScale; } // Get head position VRInput.GetControllerTransform(VRInput.head, out Vector3 HeadPosition, out Quaternion headRotation); Matrix4x4 invHeadMatrix = Matrix4x4.TRS(HeadPosition, headRotation, Vector3.one).inverse; // Project left & right controller into head matrix to determine which one is on the left Vector3 leftControllerInHeadMatrix = invHeadMatrix.MultiplyPoint(currentLeftControllerPosition_L); Vector3 rightControllerInHeadMatrix = invHeadMatrix.MultiplyPoint(currentRightControllerPosition_L); // reverse text if right and left hands are crossed if (leftControllerInHeadMatrix.x > rightControllerInHeadMatrix.x) { middleXVector = -middleXVector; } // Rotation for the line text Vector3 middleForward180 = Vector3.Cross(middleXVector, pivot.up).normalized; Vector3 rolledUp = Vector3.Cross(-middleXVector, middleForward180).normalized; Quaternion middleRotationWithRoll_L = Quaternion.LookRotation(middleForward180, rolledUp); Matrix4x4 middleMatrixWithRoll_L_Scaled = Matrix4x4.TRS(middlePosition_L, middleRotationWithRoll_L, new Vector3(s, s, s)); Quaternion middleRotationWithRoll_W = (pivot.localToWorldMatrix * middleMatrixWithRoll_L_Scaled).rotation; lineUI.UpdateLineUI(pivot.TransformPoint(currentLeftControllerPosition_L), pivot.TransformPoint(currentRightControllerPosition_L), middleRotationWithRoll_W, 1f / GlobalState.WorldScale); } GlobalState.WorldScale = 1f / rig.localScale.x; UpdateCameraClipPlanes(); } }
public override void Update() { if (teleport == null) { return; } // Teleport Vector2 leftJoyValue = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis); float joyMag = leftJoyValue.magnitude; float yVal = leftJoyValue.y; float xVal = leftJoyValue.x; if (teleporting) { if (joyMag > deadZone) { Vector3 rayStartPosition = GlobalState.Instance.VRControllers.GetFrontAnchor().position; Vector3 rayStartDirection = GlobalState.Instance.VRControllers.GetFrontAnchor().up; List <Vector3> points; RaycastHit hitInfo; bool hit = ComputeTrajectory(rayStartPosition, rayStartDirection, trajectoryParams, out points, out hitInfo); if (hit) { isValidLocationHit = true; teleportTarget = hitInfo.point; teleport.SetActiveColor(); teleportTargetObject.gameObject.SetActive(true); } else { teleport.SetImpossibleColor(); teleportTargetObject.gameObject.SetActive(false); } float cameraYAngle = Camera.main.transform.rotation.eulerAngles.y; float joyAngle = 90.0f - Mathf.Rad2Deg * Mathf.Atan2(leftJoyValue.y, leftJoyValue.x); teleportRay.positionCount = points.Count; teleportRay.SetPositions(points.ToArray()); teleportTargetObject.position = teleportTarget + new Vector3(0f, 0.01f, 0f); teleportTargetObject.rotation = Quaternion.Euler(0.0f, cameraYAngle + joyAngle, 0.0f); teleportRay.startWidth = rayWidth / GlobalState.WorldScale; teleportRay.endWidth = rayWidth / GlobalState.WorldScale; } else // GO OUT of teleport mode, and TELEPORT { teleporting = false; if (isValidLocationHit) { float cameraHeight = camera.position.y; Vector3 cameraToRig = rig.position; cameraToRig = camera.InverseTransformPoint(cameraToRig); Vector3 cameraForwardProj = new Vector3(camera.forward.x, 0.0f, camera.forward.z).normalized; float YAngleDelta = Vector3.SignedAngle(cameraForwardProj, teleportTargetObject.forward, Vector3.up); Quaternion deltaRotation = Quaternion.Euler(0.0f, YAngleDelta, 0.0f); rig.rotation = rig.rotation * deltaRotation; /* place camera above target * Vector3 camera_to_rig = rig.transform.position - camera.transform.position; * Vector3 new_camera_to_target = new Vector3(0.0f, teleportTarget.y - camera.transform.position.y, 0.0f); * Vector3 deltaPosition = camera_to_rig - new_camera_to_target; */ rig.position = teleportTarget; rig.localScale = Vector3.one; if (options.lockHeight) { rig.position = new Vector3(rig.position.x, cameraHeight + cameraToRig.y, rig.position.z); } GlobalState.WorldScale = 1f; UpdateCameraClipPlanes(); isValidLocationHit = false; } teleport.gameObject.SetActive(false); } } else { // GO IN teleport mode if (yVal > deadZone) { teleporting = true; teleport.gameObject.SetActive(true); teleportTargetObject.gameObject.layer = 2; // Ignore Raycast - TODO: put in prefab. } else { // ROTATE +/- 45 degrees using Left/Right impulses. if (Mathf.Abs(xVal) > 0.8f && !rotating) { rig.RotateAround(camera.position, Vector3.up, Mathf.Sign(xVal) * 45f); rotating = true; } if (Mathf.Abs(xVal) <= 0.8f && rotating) { rotating = false; } } } }
public override void Update() { // TODO: on garde le rotate 45 degres ou on le reserve au mode teleport (et on fait du continu vomitif pour le mode fly)? // // Joystick -- go forward/backward, and rotate 45 degrees. // Vector2 val = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis); if (val != Vector2.zero) { float d = Vector3.Distance(world.transform.TransformPoint(Vector3.one), world.transform.TransformPoint(Vector3.zero)); Vector3 velocity = Camera.main.transform.forward * val.y * d; rig.position += velocity * flySpeed; if (Mathf.Abs(val.x) > 0.95f && !rotating) { rig.rotation *= Quaternion.Euler(0f, Mathf.Sign(val.x) * 45f, 0f); rotating = true; } if (Mathf.Abs(val.x) <= 0.95f && rotating) { rotating = false; } } // // LEFT GRIP WORLD (on click) // VRInput.ButtonEvent(VRInput.secondaryController, CommonUsages.gripButton, () => { ResetInitControllerMatrices(); ResetInitWorldMatrix(); SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); isLeftGripped = true; GlobalState.IsGrippingWorld = true; }, () => { SetLeftControllerVisibility(ControllerVisibility.SHOW_NORMAL); isLeftGripped = false; GlobalState.IsGrippingWorld = false; }); // NOTE: we test isLeftGrip because we can be ungripped but still over the deadzone, strangely. if (isLeftGripped && VRInput.GetValue(VRInput.secondaryController, CommonUsages.grip) > deadZone) { float prevScale = scale; // Scale using left joystick. Vector2 joystickAxis = VRInput.GetValue(VRInput.secondaryController, CommonUsages.primary2DAxis); if (joystickAxis.y > deadZone) { scale *= fixedScaleFactor; } if (joystickAxis.y < -deadZone) { scale /= fixedScaleFactor; } // update left joystick Vector3 currentLeftControllerPosition_L; Quaternion currentLeftControllerRotation_L; VRInput.GetControllerTransform(VRInput.secondaryController, out currentLeftControllerPosition_L, out currentLeftControllerRotation_L); Matrix4x4 currentLeftControllerMatrix_L_Scaled = Matrix4x4.TRS(currentLeftControllerPosition_L, currentLeftControllerRotation_L, new Vector3(scale, scale, scale)); Matrix4x4 currentLeftControllerMatrix_W_Delta = initPivotMatrix * currentLeftControllerMatrix_L_Scaled * initLeftControllerMatrix_WtoL; Matrix4x4 transformed = currentLeftControllerMatrix_W_Delta * initRigMatrix_W; transformed = transformed.inverse; rig.localPosition = new Vector3(transformed.GetColumn(3).x, transformed.GetColumn(3).y, transformed.GetColumn(3).z); rig.localRotation = transformed.rotation; float clampedScale = Mathf.Clamp(transformed.lossyScale.x, 1.0f / maxPlayerScale, minPlayerScale); rig.localScale = new Vector3(clampedScale, clampedScale, clampedScale); if (transformed.lossyScale.x != clampedScale) { scale = prevScale; } GlobalState.WorldScale = 1f / rig.localScale.x; UpdateCameraClipPlanes(); } }
private void UpdateToolPaint(Vector3 position, Quaternion _) { // ON TRIGGER VRInput.ButtonEvent(VRInput.primaryController, CommonUsages.trigger, () => { BeginPaint(); paintPrevPosition = Vector3.zero; undoGroup = new CommandGroup("Paint"); }, () => { try { EndCurrentPaint(); } finally { if (null != undoGroup) { undoGroup.Submit(); undoGroup = null; } } }); float triggerValue = VRInput.GetValue(VRInput.primaryController, CommonUsages.trigger); // Change brush size if (navigation.CanUseControls(NavigationMode.UsedControls.RIGHT_JOYSTICK)) { Vector2 val = VRInput.GetValue(VRInput.primaryController, CommonUsages.primary2DAxis); if (val != Vector2.zero) { if (val.y > 0.3f) { brushSize += 0.001f; } if (val.y < -0.3f) { brushSize -= 0.001f; } brushSize = Mathf.Clamp(brushSize, 0.001f, 0.5f); mouthpiece.localScale = new Vector3(brushSize, brushSize, brushSize); } } paintLineRenderer.enabled = false; Vector3 penPosition = mouthpiece.position; if (paintOnSurface) { Vector3 direction = transform.forward; // (paintItem.position - centerEye.position).normalized; Vector3 startRay = penPosition + mouthpiece.lossyScale.x * direction; Vector3 endRay = startRay + 1000f * direction; paintLineRenderer.enabled = true; paintLineRenderer.positionCount = 2; paintLineRenderer.SetPosition(0, startRay); paintLineRenderer.SetPosition(1, endRay); paintLineRenderer.startWidth = 0.005f / GlobalState.WorldScale; paintLineRenderer.endWidth = paintLineRenderer.startWidth; bool hit = Physics.Raycast(startRay, direction, out RaycastHit hitInfo, Mathf.Infinity); if (!hit) { return; } penPosition = hitInfo.point - 0.001f * direction; paintLineRenderer.SetPosition(1, penPosition); } else if (paintTool == PaintTools.Volume) { if (currentVolume) { VolumeController controller = currentVolume.GetComponent <VolumeController>(); if (null != controller) { paintLineRenderer.enabled = true; Vector3 C = controller.bounds.center; Vector3 E = controller.bounds.extents; Vector3 tlf = controller.transform.TransformPoint(C + new Vector3(-E.x, E.y, -E.z)); Vector3 trf = controller.transform.TransformPoint(C + new Vector3(E.x, E.y, -E.z)); Vector3 blf = controller.transform.TransformPoint(C + new Vector3(-E.x, -E.y, -E.z)); Vector3 brf = controller.transform.TransformPoint(C + new Vector3(E.x, -E.y, -E.z)); Vector3 tlb = controller.transform.TransformPoint(C + new Vector3(-E.x, E.y, E.z)); Vector3 trb = controller.transform.TransformPoint(C + new Vector3(E.x, E.y, E.z)); Vector3 blb = controller.transform.TransformPoint(C + new Vector3(-E.x, -E.y, E.z)); Vector3 brb = controller.transform.TransformPoint(C + new Vector3(E.x, -E.y, E.z)); paintLineRenderer.positionCount = 16; paintLineRenderer.SetPositions(new Vector3[] { blf, tlf, brf, trf, brb, trb, blb, blf, brf, brb, blb, tlb, tlf, trf, trb, tlb }); paintLineRenderer.startWidth = 0.001f / GlobalState.WorldScale; paintLineRenderer.endWidth = 0.001f / GlobalState.WorldScale; } } } // Draw float deadZone = VRInput.deadZoneIn; if (triggerValue >= deadZone && ( (position != paintPrevPosition && currentPaint != null) || currentVolume != null) ) { // Add a point (the current world position) to the line renderer float pressure = (triggerValue - deadZone) / (1f - deadZone); float value = brushSize / GlobalState.WorldScale * pressure; switch (paintTool) { case PaintTools.Pencil: freeDraw.AddControlPoint(penPosition, 0.5f * value); break; case PaintTools.FlatPencil: freeDraw.AddFlatLineControlPoint(penPosition, -transform.forward, 0.5f * value); break; case PaintTools.ConvexHull: freeDraw.AddConvexHullPoint(penPosition); break; case PaintTools.Volume: volumeGenerator.AddPoint(penPosition, 2.0f * value * strength); break; } switch (paintTool) { case PaintTools.Pencil: case PaintTools.FlatPencil: case PaintTools.ConvexHull: { // set mesh components MeshFilter meshFilter = currentPaint.GetComponent <MeshFilter>(); Mesh mesh = meshFilter.mesh; mesh.Clear(); mesh.vertices = freeDraw.vertices; mesh.normals = freeDraw.normals; mesh.triangles = freeDraw.triangles; break; } case PaintTools.Volume: if (null != currentVolume) { MeshFilter meshFilter = currentVolume.GetComponent <MeshFilter>(); Mesh mesh = meshFilter.mesh; mesh.Clear(); mesh.vertices = volumeGenerator.vertices; mesh.triangles = volumeGenerator.triangles; mesh.RecalculateNormals(); // Recompute collider MeshCollider meshCollider = currentVolume.GetComponent <MeshCollider>(); meshCollider.sharedMesh = mesh; // force update meshCollider.enabled = false; meshCollider.enabled = true; VolumeController controller = currentVolume.GetComponent <VolumeController>(); controller.origin = volumeGenerator.origin; controller.bounds = volumeGenerator.bounds; // TODO: dont duplicate data? use volumeparameters in volumegenerator? controller.field = volumeGenerator.field; controller.resolution = volumeGenerator.resolution; controller.stepSize = volumeGenerator.stepSize; //controller.UpdateBoundsRenderer(); } break; } } paintPrevPosition = position; }