private bool ContainsAxis(FSelectedAxes valToCheck, FSelectedAxes majorAxis) { switch (majorAxis) { case FSelectedAxes.X: return(valToCheck == FSelectedAxes.X || valToCheck == FSelectedAxes.XY || valToCheck == FSelectedAxes.XZ || valToCheck == FSelectedAxes.All); case FSelectedAxes.Y: return(valToCheck == FSelectedAxes.Y || valToCheck == FSelectedAxes.XY || valToCheck == FSelectedAxes.YZ || valToCheck == FSelectedAxes.All); case FSelectedAxes.Z: return(valToCheck == FSelectedAxes.Z || valToCheck == FSelectedAxes.XZ || valToCheck == FSelectedAxes.YZ || valToCheck == FSelectedAxes.All); case FSelectedAxes.XY: return(valToCheck == FSelectedAxes.XY || valToCheck == FSelectedAxes.All); case FSelectedAxes.XZ: return(valToCheck == FSelectedAxes.XZ || valToCheck == FSelectedAxes.All); case FSelectedAxes.YZ: return(valToCheck == FSelectedAxes.YZ || valToCheck == FSelectedAxes.All); } return(false); }
public void UpdateForSceneView(WSceneView view) { if (!Enabled) { return; } // Update camera distance to our camera. if ((!m_isTransforming) || (m_mode != FTransformMode.Translation)) { m_cameraDistance = (view.GetCameraPos() - m_position).Length; } WLinearColor[] gizmoColors = new[] { WLinearColor.Red, WLinearColor.Green, WLinearColor.Blue, WLinearColor.Blue, WLinearColor.Red, WLinearColor.Green, WLinearColor.White, }; List <AxisDistanceResult> results = new List <AxisDistanceResult>(); var gizmoBoxes = GetAABBBoundsForMode(m_mode); for (int i = 0; i < gizmoBoxes.Length; i++) { //m_world.DebugDrawBox(gizmoBoxes[i].Min + m_position, gizmoBoxes[i].Max + m_position, gizmoColors[i], 25, 0f); } // Update Highlight Status of Models. int gizmoIndex = (int)m_mode - 1; if (gizmoIndex >= 0) { for (int i = 0; i < m_gizmoMeshes[gizmoIndex].Length; i++) { FSelectedAxes axis = (FSelectedAxes)(m_mode == FTransformMode.Rotation ? i + 1 : i); // Rotation doesn't have a center, thus it needs an index fixup. m_gizmoMeshes[gizmoIndex][i].Highlighted = ContainsAxis(m_selectedAxes, axis); } } //switch (m_mode) //{ // case FTransformMode.Translation: // Console.WriteLine("m_position: {0} m_deltaTranslation: {1} m_totalTranslation: {2}", m_position, m_deltaTranslation, m_totalTranslation); // break; // case FTransformMode.Rotation: // Console.WriteLine("m_rotation: {0} m_localRotation: {1} m_deltaRotation: {2} m_currentRotation: {3} m_totalRotation(UI): {4}", m_rotation, m_localRotation, m_deltaRotation, m_currentRotation, m_totalRotation); // break; // case FTransformMode.Scale: // Console.WriteLine("m_scale: {0} m_deltaScale: {1} m_totalScale: {2}", m_scale, m_deltaScale, m_totalScale); // break; // default: // break; //} }
public AxisDistanceResult(FSelectedAxes axis, float intersectDist) { Axis = axis; Distance = intersectDist; }
public bool CheckSelectedAxes(FRay ray) { // Convert the ray into local space so we can use axis-aligned checks, this solves the checking problem // when the gizmo is rotated due to being in Local mode. FRay localRay = new FRay(); localRay.Direction = Vector3.Transform(ray.Direction, m_rotation.Inverted()); localRay.Origin = Vector3.Transform(ray.Origin - m_position, m_rotation.Inverted()); //m_lineBatcher.DrawLine(localRay.Origin, localRay.Origin + (localRay.Direction * 10000), WLinearColor.White, 25, 5); List <AxisDistanceResult> results = new List <AxisDistanceResult>(); if (m_mode == FTransformMode.Translation) { FAABox[] translationAABB = GetAABBBoundsForMode(FTransformMode.Translation); for (int i = 0; i < translationAABB.Length; i++) { float intersectDist; if (WMath.RayIntersectsAABB(localRay, translationAABB[i].Min, translationAABB[i].Max, out intersectDist)) { results.Add(new AxisDistanceResult((FSelectedAxes)(i + 1), intersectDist)); } } } else if (m_mode == FTransformMode.Rotation) { // We'll use a combination of AABB and Distance checks to give us the quarter-circles we need. FAABox[] rotationAABB = GetAABBBoundsForMode(FTransformMode.Rotation); float screenScale = 0f; for (int i = 0; i < 3; i++) { screenScale += m_scale[i]; } screenScale /= 3f; for (int i = 0; i < rotationAABB.Length; i++) { float intersectDist; if (WMath.RayIntersectsAABB(localRay, rotationAABB[i].Min, rotationAABB[i].Max, out intersectDist)) { Vector3 intersectPoint = localRay.Origin + (localRay.Direction * intersectDist); // Convert this aabb check into a radius check so we clip it by the semi-circles // that the rotation tool actually is. if (intersectPoint.Length > 105f * screenScale) { continue; } results.Add(new AxisDistanceResult((FSelectedAxes)(i + 1), intersectDist)); } } } else if (m_mode == FTransformMode.Scale) { FAABox[] scaleAABB = GetAABBBoundsForMode(FTransformMode.Scale); for (int i = 0; i < scaleAABB.Length; i++) { float intersectDist; if (WMath.RayIntersectsAABB(localRay, scaleAABB[i].Min, scaleAABB[i].Max, out intersectDist)) { // Special-case here to give the center scale point overriding priority. Because we intersected // it, we can just override its distance to zero to make it clickable through the other bounding boxes. if ((FSelectedAxes)i + 1 == FSelectedAxes.All) { intersectDist = 0f; } results.Add(new AxisDistanceResult((FSelectedAxes)(i + 1), intersectDist)); } } } if (results.Count == 0) { m_selectedAxes = FSelectedAxes.None; return(false); } // If we get an intersection, sort them by the closest intersection distance. results.Sort((x, y) => x.Distance.CompareTo(y.Distance)); m_selectedAxes = results[0].Axis; // Store where the mouse hit on the first frame in world space. This means converting the ray back to worldspace. Vector3 localHitPoint = localRay.Origin + (localRay.Direction * results[0].Distance); m_hitPoint = Vector3.Transform(localHitPoint, m_rotation) + m_position; return(true); }
public void EndTransform() { m_isTransforming = false; m_selectedAxes = FSelectedAxes.None; }