//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using bs;
namespace bs.Editor
{
/** @addtogroup Handles
* @{
*/
///
/// Handle that allows an object to be scaled along the three primary axes, as well as a free axis currently
/// facing the camera.
///
public sealed class ScaleHandle : DefaultHandle
{
private const float SMALL_CUBE_SIZE = 0.175f;
private const float CENTER_CUBE_SIZE = 0.33f;
private Vector3 delta;
private HandleSliderLine xAxis;
private HandleSliderLine yAxis;
private HandleSliderLine zAxis;
private HandleSliderPlane freeAxis;
///
/// Returns the amount of scaling applied since the last frame. Only valid while the handle is being dragged.
///
public Vector3 Delta
{
get { return delta; }
}
///
internal override bool IsDragged()
{
return xAxis.State == HandleSlider.StateType.Active ||
yAxis.State == HandleSlider.StateType.Active ||
zAxis.State == HandleSlider.StateType.Active ||
freeAxis.State == HandleSlider.StateType.Active;
}
///
/// Creates a new scale handle.
///
public ScaleHandle()
{
xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f);
yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f);
zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f);
freeAxis = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f);
}
///
protected internal override void PreInput()
{
xAxis.Position = position;
yAxis.Position = position;
zAxis.Position = position;
xAxis.Rotation = rotation;
yAxis.Rotation = rotation;
zAxis.Rotation = rotation;
float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
Vector3 freeAxisOffset = (Vector3.XAxis * -0.2f + Vector3.YAxis * -0.2f) * handleSize;
freeAxis.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
freeAxis.Position = position + freeAxis.Rotation.Rotate(freeAxisOffset);
}
///
protected internal override void PostInput()
{
delta = Vector3.Zero;
delta += xAxis.Delta * GetXDir() * 0.1f;
delta += yAxis.Delta * GetYDir() * 0.1f;
delta += zAxis.Delta * GetZDir() * 0.1f;
delta += (freeAxis.Delta.x + freeAxis.Delta.y) * Vector3.One * 0.1f;
}
///
protected internal override void Draw()
{
HandleDrawing.Layer = 1;
HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
// Draw 1D sliders
Vector3 smallCubeExtents = new Vector3(SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f);
if (xAxis.State == HandleSlider.StateType.Active)
HandleDrawing.Color = Color.White;
else if (xAxis.State == HandleSlider.StateType.Hover)
HandleDrawing.Color = Color.BansheeOrange;
else
HandleDrawing.Color = Color.Red;
Vector3 xCubeOffset = Vector3.XAxis * SMALL_CUBE_SIZE * 0.5f;
Vector3 xCubeStart = Vector3.XAxis - xCubeOffset;
HandleDrawing.DrawLine(Vector3.Zero, xCubeStart, handleSize);
HandleDrawing.DrawCube(xCubeStart + xCubeOffset, smallCubeExtents, handleSize);
if (yAxis.State == HandleSlider.StateType.Active)
HandleDrawing.Color = Color.White;
else if (yAxis.State == HandleSlider.StateType.Hover)
HandleDrawing.Color = Color.BansheeOrange;
else
HandleDrawing.Color = Color.Green;
Vector3 yCubeOffset = Vector3.YAxis * SMALL_CUBE_SIZE * 0.5f;
Vector3 yCubeStart = Vector3.YAxis - yCubeOffset;
HandleDrawing.DrawLine(Vector3.Zero, yCubeStart, handleSize);
HandleDrawing.DrawCube(yCubeStart + yCubeOffset, smallCubeExtents, handleSize);
if (zAxis.State == HandleSlider.StateType.Active)
HandleDrawing.Color = Color.White;
else if (zAxis.State == HandleSlider.StateType.Hover)
HandleDrawing.Color = Color.BansheeOrange;
else
HandleDrawing.Color = Color.Blue;
Vector3 zCubeOffset = Vector3.ZAxis * SMALL_CUBE_SIZE * 0.5f;
Vector3 zCubeStart = Vector3.ZAxis - zCubeOffset;
HandleDrawing.DrawLine(Vector3.Zero, zCubeStart, handleSize);
HandleDrawing.DrawCube(zCubeStart + zCubeOffset, smallCubeExtents, handleSize);
// Draw free scale handle
if (freeAxis.State == HandleSlider.StateType.Active)
HandleDrawing.Color = Color.White;
else if (freeAxis.State == HandleSlider.StateType.Hover)
HandleDrawing.Color = Color.BansheeOrange;
else
HandleDrawing.Color = Color.White;
//// Rotate it so it always faces the camera, and move it forward a bit to always render in front
Vector3 bottomLeft = -Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;
Vector3 topLeft = -Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
Vector3 topRight = Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
Vector3 bottomRight = Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;
Vector3 offset = Vector3.ZAxis*0.1f;
Quaternion cameraRot = EditorApplication.SceneViewCamera.SceneObject.Rotation;
bottomLeft = cameraRot.Rotate(bottomLeft + offset);
topLeft = cameraRot.Rotate(topLeft + offset);
topRight = cameraRot.Rotate(topRight + offset);
bottomRight = cameraRot.Rotate(bottomRight + offset);
HandleDrawing.DrawLine(bottomLeft, bottomRight, handleSize);
HandleDrawing.DrawLine(bottomLeft, topLeft, handleSize);
HandleDrawing.DrawLine(topLeft, topRight, handleSize);
HandleDrawing.DrawLine(bottomRight, topRight, handleSize);
}
///
/// Returns the direction of the handle's x axis in world space.
///
/// Direction of the handle's x axis in world space
private Vector3 GetXDir()
{
return rotation.Rotate(Vector3.XAxis);
}
///
/// Returns the direction of the handle's y axis in world space.
///
/// Direction of the handle's y axis in world space
private Vector3 GetYDir()
{
return rotation.Rotate(Vector3.YAxis);
}
///
/// Returns the direction of the handle's z axis in world space.
///
/// Direction of the handle's z axis in world space
private Vector3 GetZDir()
{
return rotation.Rotate(Vector3.ZAxis);
}
}
/** @} */
}