Improved 1D transfer function editor. Use smoothstep instead of LERP for TF control points.

This commit is contained in:
Matias Lavik 2022-01-01 20:52:21 +01:00
Родитель 711cd51609
Коммит 208a10fd78
2 изменённых файлов: 107 добавлений и 46 удалений

Просмотреть файл

@ -93,8 +93,73 @@ namespace UnityVolumeRendering
tfPaletteGUIMat.SetTexture("_TFTex", tf.GetTexture());
Graphics.DrawTexture(new Rect(bgRect.x, bgRect.y + bgRect.height + 20, bgRect.width, 20.0f), tfTexture, tfPaletteGUIMat);
// Release selected colour/alpha points if mouse leaves window
if (movingAlphaPointIndex != -1 && !bgRect.Contains(currentEvent.mousePosition))
movingAlphaPointIndex = -1;
if (movingColPointIndex != -1 && !(currentEvent.mousePosition.x >= bgRect.x && currentEvent.mousePosition.x <= bgRect.x + bgRect.width))
movingColPointIndex = -1;
// Colour control points
// Mouse down => Move or remove selected colour control point
if (currentEvent.type == EventType.MouseDown)
{
float mousePos = (currentEvent.mousePosition.x - bgRect.x) / bgRect.width;
int pointIndex = PickColourControlPoint(mousePos);
if (pointIndex != -1)
{
if(currentEvent.button == 0)
{
movingColPointIndex = selectedColPointIndex = pointIndex;
}
else if(currentEvent.button == 1 && currentEvent.control)
{
tf.colourControlPoints.RemoveAt(pointIndex);
currentEvent.type = EventType.Ignore;
movingColPointIndex = selectedColPointIndex = -1;
}
}
}
else if (currentEvent.type == EventType.MouseUp)
movingColPointIndex = -1;
// Mouse down => Move or remove selected alpha control point
if (currentEvent.type == EventType.MouseDown)
{
Vector2 mousePos = new Vector2((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 1.0f - (currentEvent.mousePosition.y - bgRect.y) / bgRect.height);
int pointIndex = PickAlphaControlPoint(mousePos);
if (pointIndex != -1)
{
if(currentEvent.button == 0)
{
movingAlphaPointIndex = pointIndex;
}
else if(currentEvent.button == 1 && currentEvent.control)
{
tf.alphaControlPoints.RemoveAt(pointIndex);
currentEvent.type = EventType.Ignore;
selectedColPointIndex = -1;
}
}
}
// Move selected alpha control point
if (movingAlphaPointIndex != -1)
{
TFAlphaControlPoint alphaPoint = tf.alphaControlPoints[movingAlphaPointIndex];
alphaPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f);
alphaPoint.alphaValue = Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f);
tf.alphaControlPoints[movingAlphaPointIndex] = alphaPoint;
}
// Move selected colour control point
if (movingColPointIndex != -1)
{
TFColourControlPoint colPoint = tf.colourControlPoints[movingColPointIndex];
colPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f);
tf.colourControlPoints[movingColPointIndex] = colPoint;
}
// Draw colour control points
for (int iCol = 0; iCol < tf.colourControlPoints.Count; iCol++)
{
TFColourControlPoint colPoint = tf.colourControlPoints[iCol];
@ -102,31 +167,9 @@ namespace UnityVolumeRendering
GUI.color = Color.red;
GUI.skin.box.fontSize = 6;
GUI.Box(ctrlBox, "*");
if (currentEvent.type == EventType.MouseDown && ctrlBox.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y)))
{
// Move colour control point
if(currentEvent.button == 0)
{
movingColPointIndex = iCol;
selectedColPointIndex = iCol;
}
// Remove it (if ctrl + right click)
else if(currentEvent.button == 1 && currentEvent.control)
{
tf.colourControlPoints.RemoveAt(iCol);
currentEvent.type = EventType.Ignore;
selectedColPointIndex = -1;
continue;
}
}
else if (movingColPointIndex == iCol)
{
colPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f);
}
tf.colourControlPoints[iCol] = colPoint;
}
// Alpha control points
// Draw alpha control points
for (int iAlpha = 0; iAlpha < tf.alphaControlPoints.Count; iAlpha++)
{
TFAlphaControlPoint alphaPoint = tf.alphaControlPoints[iAlpha];
@ -134,28 +177,6 @@ namespace UnityVolumeRendering
GUI.color = oldColour;
GUI.skin.box.fontSize = 6;
GUI.Box(ctrlBox, "*");
if (currentEvent.type == EventType.MouseDown && ctrlBox.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y)))
{
// Move alpha point
if(currentEvent.button == 0)
{
movingAlphaPointIndex = iAlpha;
}
// Remove alpha point
else if(currentEvent.button == 1 && currentEvent.control)
{
tf.alphaControlPoints.RemoveAt(iAlpha);
currentEvent.type = EventType.Ignore;
selectedColPointIndex = -1;
continue;
}
}
else if (movingAlphaPointIndex == iAlpha)
{
alphaPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f);
alphaPoint.alphaValue = Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f);
}
tf.alphaControlPoints[iAlpha] = alphaPoint;
}
if (currentEvent.type == EventType.MouseUp)
@ -204,6 +225,43 @@ namespace UnityVolumeRendering
GUI.color = oldColour;
}
private int PickColourControlPoint(float position)
{
const float MIN_DIST_THRESHOLD = 0.03f;
int nearestPointIndex = -1;
float nearestDist = 1000.0f;
for (int i = 0; i < tf.colourControlPoints.Count; i++)
{
TFColourControlPoint ctrlPoint = tf.colourControlPoints[i];
float dist = Mathf.Abs(ctrlPoint.dataValue - position);
if (dist < MIN_DIST_THRESHOLD && dist < nearestDist)
{
nearestPointIndex = i;
nearestDist = dist;
}
}
return nearestPointIndex;
}
private int PickAlphaControlPoint(Vector2 position)
{
const float MIN_DIST_THRESHOLD = 0.05f;
int nearestPointIndex = -1;
float nearestDist = 1000.0f;
for (int i = 0; i < tf.alphaControlPoints.Count; i++)
{
TFAlphaControlPoint ctrlPoint = tf.alphaControlPoints[i];
Vector2 ctrlPos = new Vector2(ctrlPoint.dataValue, ctrlPoint.alphaValue);
float dist = (ctrlPos - position).magnitude;
if (dist < MIN_DIST_THRESHOLD && dist < nearestDist)
{
nearestPointIndex = i;
nearestDist = dist;
}
}
return nearestPointIndex;
}
private void OnSelectionChange()
{
VolumeRenderedObject newVolRendObj = Selection.activeGameObject?.GetComponent<VolumeRenderedObject>();

Просмотреть файл

@ -81,6 +81,9 @@ namespace UnityVolumeRendering
float tCol = (Mathf.Clamp(t, leftCol.dataValue, rightCol.dataValue) - leftCol.dataValue) / (rightCol.dataValue - leftCol.dataValue);
float tAlpha = (Mathf.Clamp(t, leftAlpha.dataValue, rightAlpha.dataValue) - leftAlpha.dataValue) / (rightAlpha.dataValue - leftAlpha.dataValue);
tCol = Mathf.SmoothStep(0.0f, 1.0f, tCol);
tAlpha = Mathf.SmoothStep(0.0f, 1.0f, tAlpha);
Color pixCol = rightCol.colourValue * tCol + leftCol.colourValue * (1.0f - tCol);
pixCol.a = rightAlpha.alphaValue * tAlpha + leftAlpha.alphaValue * (1.0f - tAlpha);