Render bounding box around mesh, centre & scale arcball on bbox

* The arcball lookat position can also be dragged with alt-click or
  middle click.
* Also supports other elements as position not just magically-selected
  "POSITION" element.
This commit is contained in:
baldurk
2015-07-06 19:58:45 +02:00
parent b23db183b6
commit edda31248f
11 changed files with 309 additions and 68 deletions
+43 -15
View File
@@ -91,15 +91,16 @@ namespace renderdocui.Code
virtual public void MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
m_DragStartPos = e.Location;
}
m_DragStartPos = e.Location;
}
virtual public void MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
if (e.Button == MouseButtons.None)
{
m_DragStartPos = new Point(-1, -1);
}
else
{
if (m_DragStartPos.X < 0)
{
@@ -108,10 +109,6 @@ namespace renderdocui.Code
m_DragStartPos = e.Location;
}
else
{
m_DragStartPos = new Point(-1, -1);
}
}
virtual public void KeyUp(object sender, KeyEventArgs e)
@@ -177,20 +174,25 @@ namespace renderdocui.Code
m_Rotation = new Vec3f();
}
public void SetDistance(float dist)
{
m_Distance = Math.Abs(dist);
}
public override void Update()
{
}
public override void Apply()
{
m_Camera.Arcball(m_Distance, Rotation);
m_Camera.Arcball(LookAtPos, m_Distance, Rotation);
}
public override void MouseWheel(object sender, MouseEventArgs e)
{
float mod = (1.0f - (float)e.Delta / 2500.0f);
m_Distance = Math.Max(1.0f, m_Distance * mod);
m_Distance = Math.Max(1e-6f, m_Distance * mod);
((HandledMouseEventArgs)e).Handled = true;
@@ -199,12 +201,35 @@ namespace renderdocui.Code
public override void MouseMove(object sender, MouseEventArgs e)
{
if (DragStartPos.X > 0 && e.Button == MouseButtons.Left)
if (DragStartPos.X > 0)
{
m_Rotation.y += (float)(e.X - DragStartPos.X) / 300.0f;
m_Rotation.x += (float)(e.Y - DragStartPos.Y) / 300.0f;
if (e.Button == MouseButtons.Middle ||
(e.Button == MouseButtons.Left && (Control.ModifierKeys & Keys.Alt) == Keys.Alt)
)
{
float xdelta = (float)(e.X - DragStartPos.X) / 300.0f;
float ydelta = (float)(e.Y - DragStartPos.Y) / 300.0f;
m_Dirty = true;
xdelta *= Math.Max(1.0f, m_Distance);
ydelta *= Math.Max(1.0f, m_Distance);
LookAtPos.x -= m_Camera.Right.x * xdelta;
LookAtPos.y -= m_Camera.Right.y * xdelta;
LookAtPos.z -= m_Camera.Right.z * xdelta;
LookAtPos.x += m_Camera.Up.x * ydelta;
LookAtPos.y += m_Camera.Up.y * ydelta;
LookAtPos.z += m_Camera.Up.z * ydelta;
m_Dirty = true;
}
else if (e.Button == MouseButtons.Left)
{
m_Rotation.y += (float)(e.X - DragStartPos.X) / 300.0f;
m_Rotation.x += (float)(e.Y - DragStartPos.Y) / 300.0f;
m_Dirty = true;
}
}
base.MouseMove(sender, e);
@@ -223,6 +248,9 @@ namespace renderdocui.Code
private float m_Distance = 10.0f;
private Vec3f m_Rotation = new Vec3f();
public Vec3f LookAtPos = new Vec3f();
public override Vec3f Position { get { return m_Camera.Position; } }
public override Vec3f Rotation { get { return m_Rotation; } }
}
+18 -8
View File
@@ -31,40 +31,44 @@ namespace renderdoc
public class Camera
{
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void Maths_CameraArcball(float dist, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right);
private static extern void Maths_CameraArcball(ref FloatVector lookat, float dist, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right, IntPtr up);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void Maths_CameraFPSLook(ref FloatVector lookpos, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right);
private static extern void Maths_CameraFPSLook(ref FloatVector lookpos, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right, IntPtr up);
public void Arcball(float dist, Vec3f rot)
public void Arcball(Vec3f pos, float dist, Vec3f rot)
{
IntPtr p = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr f = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr r = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr u = CustomMarshal.Alloc(typeof(FloatVector));
isarc = true;
parampos.x = dist;
parampos.y = 0.0f;
parampos.z = 0.0f;
paramdist = dist;
parampos = pos;
paramrot = new Vec3f(rot);
var rt = new FloatVector(rot);
var ps = new FloatVector(pos);
Maths_CameraArcball(dist, ref rt, p, f, r);
Maths_CameraArcball(ref ps, dist, ref rt, p, f, r, u);
pos = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(p, typeof(FloatVector), false));
fwd = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(f, typeof(FloatVector), false));
right = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(r, typeof(FloatVector), false));
up = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(u, typeof(FloatVector), false));
CustomMarshal.Free(p);
CustomMarshal.Free(f);
CustomMarshal.Free(r);
CustomMarshal.Free(u);
}
public void fpsLook(Vec3f lookpos, Vec3f lookrot)
{
IntPtr p = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr f = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr r = CustomMarshal.Alloc(typeof(FloatVector));
IntPtr u = CustomMarshal.Alloc(typeof(FloatVector));
isarc = false;
parampos = new Vec3f(lookpos);
@@ -73,31 +77,37 @@ namespace renderdoc
var ps = new FloatVector(lookpos);
var rt = new FloatVector(lookrot);
Maths_CameraFPSLook(ref ps, ref rt, p, f, r);
Maths_CameraFPSLook(ref ps, ref rt, p, f, r, u);
pos = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(p, typeof(FloatVector), false));
fwd = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(f, typeof(FloatVector), false));
right = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(r, typeof(FloatVector), false));
up = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(u, typeof(FloatVector), false));
CustomMarshal.Free(p);
CustomMarshal.Free(f);
CustomMarshal.Free(r);
CustomMarshal.Free(u);
}
private Vec3f pos = new Vec3f(0.0f, 0.0f, 0.0f);
private Vec3f fwd = new Vec3f(0.0f, 0.0f, 1.0f);
private Vec3f right = new Vec3f(1.0f, 0.0f, 0.0f);
private Vec3f up = new Vec3f(0.0f, 1.0f, 0.0f);
public Vec3f Position { get { return pos; } }
public Vec3f Forward { get { return fwd; } }
public Vec3f Right { get { return right; } }
public Vec3f Up { get { return up; } }
private bool isarc = false;
private Vec3f parampos = new Vec3f(0.0f, 0.0f, 0.0f);
private float paramdist = 0.0f;
private Vec3f paramrot = new Vec3f(0.0f, 0.0f, 0.0f);
public bool IsArcball { get { return isarc; } }
public Vec3f PositionParam { get { return parampos; } }
public float DistanceParam { get { return paramdist; } }
public Vec3f RotationParam { get { return paramrot; } }
}
}
+5
View File
@@ -67,6 +67,7 @@ namespace renderdoc
public FloatVector(float X, float Y, float Z, float W) { x = X; y = Y; z = Z; w = W; }
public FloatVector(float X, float Y, float Z) { x = X; y = Y; z = Z; w = 1; }
public FloatVector(Vec3f v) { x = v.x; y = v.y; z = v.z; w = 1; }
public FloatVector(Vec3f v, float W) { x = v.x; y = v.y; z = v.z; w = W; }
public float x, y, z, w;
};
@@ -405,6 +406,10 @@ namespace renderdoc
public FloatVector prevMeshColour = new FloatVector();
public FloatVector currentMeshColour = new FloatVector();
public FloatVector minBounds = new FloatVector();
public FloatVector maxBounds = new FloatVector();
public bool showBBox = false;
public SolidShadeMode solidShadeMode = SolidShadeMode.None;
public bool wireframeDraw = true;
};
+70 -20
View File
@@ -123,8 +123,8 @@ namespace renderdocui.Windows
public Thread m_DataParseThread = null;
private Object m_ThreadLock = new Object();
public Vec3f m_MinBounds = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue);
public Vec3f m_MaxBounds = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue);
public Vec3f[] m_MinBounds = null;
public Vec3f[] m_MaxBounds = null;
public void AbortThread()
{
@@ -1321,8 +1321,8 @@ namespace renderdocui.Windows
state.m_Stream = new Stream[d.Length];
state.m_Reader = new BinaryReader[d.Length];
state.m_MinBounds = new Vec3f(-1.0f, -1.0f, -1.0f);
state.m_MaxBounds = new Vec3f(1.0f, 1.0f, 1.0f);
state.m_MinBounds = null;
state.m_MaxBounds = null;
var bufferFormats = input.BufferFormats;
@@ -1387,8 +1387,14 @@ namespace renderdocui.Windows
var bufferFormats = input.BufferFormats;
var generics = input.GenericValues;
Vec3f minBounds = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue);
Vec3f maxBounds = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue);
Vec3f[] minBounds = new Vec3f[bufferFormats.Length];
Vec3f[] maxBounds = new Vec3f[bufferFormats.Length];
for (int el = 0; el < bufferFormats.Length; el++)
{
minBounds[el] = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue);
maxBounds[el] = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue);
}
while (!finished)
{
@@ -1483,7 +1489,7 @@ namespace renderdocui.Windows
if (bytes.Length != bytesToRead)
continue;
if (elname == "POSITION" || bufferFormats[el].systemValue == SystemAttribute.Position)
// update min/max for this element
{
for (int i = 0; i < fmt.compCount; i++)
{
@@ -1510,18 +1516,18 @@ namespace renderdocui.Windows
if (i == 0)
{
minBounds.x = Math.Min(minBounds.x, val);
maxBounds.x = Math.Max(maxBounds.x, val);
minBounds[el].x = Math.Min(minBounds[el].x, val);
maxBounds[el].x = Math.Max(maxBounds[el].x, val);
}
else if (i == 1)
{
minBounds.y = Math.Min(minBounds.y, val);
maxBounds.y = Math.Max(maxBounds.y, val);
minBounds[el].y = Math.Min(minBounds[el].y, val);
maxBounds[el].y = Math.Max(maxBounds[el].y, val);
}
else if (i == 2)
{
minBounds.z = Math.Min(minBounds.z, val);
maxBounds.z = Math.Max(maxBounds.z, val);
minBounds[el].z = Math.Min(minBounds[el].z, val);
maxBounds[el].z = Math.Max(maxBounds[el].z, val);
}
}
}
@@ -1544,6 +1550,8 @@ namespace renderdocui.Windows
state.m_MinBounds = minBounds;
state.m_MaxBounds = maxBounds;
UI_UpdateBoundingBox();
UI_ShowRows(state, horizScroll);
}));
}));
@@ -1940,6 +1948,8 @@ namespace renderdocui.Windows
m_CurrentCamera = m_Flycam;
}
UI_UpdateBoundingBox();
m_CurrentCamera.Apply();
render.Invalidate();
}
@@ -1953,14 +1963,20 @@ namespace renderdocui.Windows
var state = GetUIState(m_MeshDisplay.type);
Vec3f diag = state.m_MaxBounds.Sub(state.m_MinBounds);
if(diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 0.00001f)
if (state.m_MinBounds == null || state.m_MaxBounds == null)
return;
Vec3f middle = new Vec3f(state.m_MinBounds.x + diag.x / 2.0f,
state.m_MinBounds.y + diag.y / 2.0f,
state.m_MinBounds.z + diag.z / 2.0f);
if (CurPosElement < 0 || CurPosElement >= state.m_MinBounds.Length || CurPosElement >= state.m_MaxBounds.Length)
return;
Vec3f diag = state.m_MaxBounds[CurPosElement].Sub(state.m_MinBounds[CurPosElement]);
if (diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 1e-6f)
return;
Vec3f middle = new Vec3f(state.m_MinBounds[CurPosElement].x + diag.x / 2.0f,
state.m_MinBounds[CurPosElement].y + diag.y / 2.0f,
state.m_MinBounds[CurPosElement].z + diag.z / 2.0f);
Vec3f pos = new Vec3f(middle);
@@ -1970,6 +1986,8 @@ namespace renderdocui.Windows
camSpeed.Value = Helpers.Clamp((decimal)(diag.Length() / 200.0f), camSpeed.Minimum, camSpeed.Maximum);
UI_UpdateBoundingBox();
m_CurrentCamera.Apply();
render.Invalidate();
}
@@ -2060,7 +2078,7 @@ namespace renderdocui.Windows
if (m_Output == null) return;
m_MeshDisplay.arcballCamera = m_Camera.IsArcball;
m_MeshDisplay.cameraPos = new FloatVector(m_Camera.PositionParam);
m_MeshDisplay.cameraPos = new FloatVector(m_Camera.PositionParam, m_Camera.DistanceParam);
m_MeshDisplay.cameraRot = new FloatVector(m_Camera.RotationParam);
m_Output.SetMeshDisplay(m_MeshDisplay);
@@ -2331,6 +2349,36 @@ namespace renderdocui.Windows
}
}
private void UI_UpdateBoundingBox()
{
var ui = GetUIState(m_MeshDisplay.type);
m_MeshDisplay.showBBox = false;
if (ui.m_Stage == MeshDataStage.VSIn &&
CurPosElement >= 0 &&
ui.m_MinBounds != null && CurPosElement < ui.m_MinBounds.Length &&
ui.m_MaxBounds != null && CurPosElement < ui.m_MaxBounds.Length)
{
m_MeshDisplay.showBBox = true;
m_MeshDisplay.minBounds = new FloatVector(ui.m_MinBounds[CurPosElement]);
m_MeshDisplay.maxBounds = new FloatVector(ui.m_MaxBounds[CurPosElement]);
Vec3f diag = ui.m_MaxBounds[CurPosElement].Sub(ui.m_MinBounds[CurPosElement]);
if (diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 1e-6f)
return;
m_Arcball.LookAtPos = new Vec3f(ui.m_MinBounds[CurPosElement].x + diag.x / 2.0f,
ui.m_MinBounds[CurPosElement].y + diag.y / 2.0f,
ui.m_MinBounds[CurPosElement].z + diag.z / 2.0f);
m_Arcball.SetDistance(diag.Length()*0.7f);
m_CurrentCamera.Apply();
render.Invalidate();
}
}
private void UI_UpdateMeshRenderComponents()
{
var ui = GetUIState(m_MeshDisplay.type);
@@ -2434,6 +2482,8 @@ namespace renderdocui.Windows
}
}
UI_UpdateBoundingBox();
if (ui.m_Input == null || ui.m_Input.BufferFormats == null ||
CurSecondElement == -1 || CurSecondElement >= ui.m_Input.BufferFormats.Length)
{