protected override void Manipulate() { if (_axis == Axis.Y) { float angle = YAngle(); float deltaAngle = angle - _priorAngle; TargetTransform.Rotate(new Vector3(0, deltaAngle, 0), Space.World); _priorAngle = angle; } else if (_axis == Axis.X) { float angle = XAngle(); float deltaAngle = angle - _priorAngle; if (_rotateAxis == RotateAxis.LocalX) { TargetTransform.Rotate(new Vector3(deltaAngle, 0, 0), Space.Self); } else if (_rotateAxis == RotateAxis.LocalZ) { TargetTransform.Rotate(new Vector3(0, 0, deltaAngle), Space.Self); } else if (_rotateAxis == RotateAxis.Screen) { Vector3 cameraDirection = _eventCamera.EventCameraRef.transform.position - TargetTransform.position; Vector3 crossDirection = Vector3.Cross(cameraDirection, Vector3.up); TargetTransform.RotateAround(TargetTransform.position, crossDirection, deltaAngle); } _priorAngle = angle; } }
/// <summary> /// Executes the next step in the refinement process. /// </summary> private void NextStep() { // If we're already on the last step, just finish up if (currentStep == RayRefinementStep.Refinement) { FinishRefinement(); return; } // Increment the step currentStep++; // Execute switch (currentStep) { case RayRefinementStep.ModelOrigin: // Create the target CreateTarget(originPrefab, ref modelOrigin, currentStep.ToString()); // Parent the target modelOrigin.transform.SetParent(TargetTransform, worldPositionStays: true); break; case RayRefinementStep.ModelDirection: // Create the target CreateTarget(directionPrefab, ref modelDirection, currentStep.ToString()); // Parent the target modelDirection.transform.SetParent(TargetTransform, worldPositionStays: true); // Add line renderer modelLine = AddLine(modelDirection); break; case RayRefinementStep.PlacementOrigin: // Hide meshes? if (autoHideMeshes) { modelLine.enabled = false; this.gameObject.SetMeshesEnabled(enabled: false, inChildren: true); } // Create the target CreateTarget(originPrefab, ref placementOrigin, currentStep.ToString()); break; case RayRefinementStep.PlacementDirection: // Create the target CreateTarget(directionPrefab, ref placementDirection, currentStep.ToString()); // Add line renderer placementLine = AddLine(placementDirection); break; case RayRefinementStep.Refinement: // Re-show meshes? if (autoHideMeshes) { modelLine.enabled = true; this.gameObject.SetMeshesEnabled(enabled: true, inChildren: true); } // Get transform positions Vector3 modelOriginWorld = modelOrigin.transform.position; Vector3 modelDirectionWorld = modelDirection.transform.position; Vector3 placementOriginWorld = placementOrigin.transform.position; Vector3 placementDirectionWorld = placementDirection.transform.position; // Calculate the model angle float modelAngle = Mathf.Atan2(modelDirectionWorld.x - modelOriginWorld.x, modelDirectionWorld.z - modelOriginWorld.z) * Mathf.Rad2Deg; // Calculate the placement angle float placementAngle = Mathf.Atan2(placementDirectionWorld.x - placementOriginWorld.x, placementDirectionWorld.z - placementOriginWorld.z) * Mathf.Rad2Deg; // Calculate the model -> placement position offset Vector3 offset = placementOriginWorld - modelOriginWorld; // Calculate the model -> placement rotation offset float rotation = (placementAngle - modelAngle); // Update parent position to align origins TargetTransform.position += offset; // Update parent rotation, but around placement origin TargetTransform.RotateAround(placementOriginWorld, Vector3.up, rotation); // Finish refinement FinishRefinement(); break; default: Debug.LogError($"Unknown {nameof(RayRefinementStep)}: {currentStep}"); break; } }