adding billboard text support and cleaning up.

This commit is contained in:
Jeremy Meredith 2016-05-23 13:52:47 -04:00
parent dddc74904b
commit dbdd670ba8
8 changed files with 666 additions and 302 deletions

@ -27,6 +27,7 @@
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <vtkm/rendering/AxisAnnotation.h>
#include <vtkm/rendering/TextAnnotation.h>
namespace vtkm {
namespace rendering {
@ -38,20 +39,22 @@ protected:
vtkm::Float64 maj_size, maj_toff;
vtkm::Float64 min_size, min_toff;
int axis;
vtkm::Float64 invertx, inverty, invertz;
vtkm::Float32 invertx, inverty, invertz;
vtkm::Float64 x0, y0, z0, x1, y1, z1;
vtkm::Float64 lower, upper;
vtkm::Float64 fontscale;
vtkm::Float32 fontoffset;
vtkm::Float32 linewidth;
vtkm::rendering::Color color;
//vector<BillboardTextAnnotation*> labels; ///<\todo: add text back in
std::vector<BillboardTextAnnotation*> labels;
int moreOrLessTickAdjustment;
public:
AxisAnnotation3D() : AxisAnnotation()
{
axis = 0;
color = Color(1,1,1);
fontscale = 0.05;
fontoffset = 0.1f; // world space offset from axis
fontscale = 0.05; // screen space font size
linewidth = 1.0;
color = Color(1,1,1);
moreOrLessTickAdjustment = 0;
@ -104,21 +107,24 @@ public:
void SetLabelFontScale(vtkm::Float64 s)
{
fontscale = s;
#if 0
for (unsigned int i=0; i<labels.size(); i++)
labels[i]->SetScale(s);
#endif
labels[i]->SetScale(vtkm::Float32(s));
}
void SetLabelFontOffset(vtkm::Float32 off)
{
fontoffset = off;
}
void SetRange(vtkm::Float64 l, vtkm::Float64 u)
{
lower = l;
upper = u;
}
virtual void Render(View &,
WorldAnnotator &worldannotator)
virtual void Render(View &view,
WorldAnnotator &worldAnnotator,
RenderSurface &renderSurface)
{
bool infront = true;
worldannotator.AddLine(x0,y0,z0,
worldAnnotator.AddLine(x0,y0,z0,
x1,y1,z1,
linewidth, color, infront);
@ -127,15 +133,15 @@ public:
// major ticks
CalculateTicks(lower, upper, false, positions, proportions, moreOrLessTickAdjustment);
unsigned int nmajor = (unsigned int)proportions.size();
#if 0
while ((int)labels.size() < nmajor)
while (labels.size() < nmajor)
{
labels.push_back(new BillboardTextAnnotation(win,"test",
color,
fontscale,
0,0,0, false, 0));
labels.push_back(new BillboardTextAnnotation("test",
color,
vtkm::Float32(fontscale),
0,0,0,
0));
}
#endif
for (unsigned int i=0; i<nmajor; ++i)
{
vtkm::Float64 xc = x0 + (x1-x0) * proportions[i];
@ -160,33 +166,33 @@ public:
vtkm::Float64 zs = zc - tz*maj_toff;
vtkm::Float64 ze = zc + tz*(1. - maj_toff);
worldannotator.AddLine(xs,ys,zs,
xe,ye,ze,
linewidth, color, infront);
worldAnnotator.AddLine(xs,ys,zs,
xe,ye,ze,
linewidth, color, infront);
}
vtkm::Float64 tx=0, ty=0, tz=0;
const vtkm::Float64 s = 0.4;
vtkm::Float32 tx=0, ty=0, tz=0;
const vtkm::Float32 s = 0.4f;
switch (axis)
{
case 0: ty=s*fontscale; tz=s*fontscale; break;
case 1: tx=s*fontscale; tz=s*fontscale; break;
case 2: tx=s*fontscale; ty=s*fontscale; break;
case 0: ty=s*fontoffset; tz=s*fontoffset; break;
case 1: tx=s*fontoffset; tz=s*fontoffset; break;
case 2: tx=s*fontoffset; ty=s*fontoffset; break;
}
tx *= invertx;
ty *= inverty;
tz *= invertz;
#if 0
char val[256];
snprintf(val, 256, "%g", positions[i]);
labels[i]->SetText(val);
//if (fabs(positions[i]) < 1e-10)
// labels[i]->SetText("0");
labels[i]->SetPosition(xc - tx, yc - ty, zc - tz);
labels[i]->SetPosition(vtkm::Float32(xc - tx),
vtkm::Float32(yc - ty),
vtkm::Float32(zc - tz));
labels[i]->SetAlignment(TextAnnotation::HCenter,
TextAnnotation::VCenter);
#endif
}
// minor ticks
@ -216,18 +222,16 @@ public:
vtkm::Float64 zs = zc - tz*min_toff;
vtkm::Float64 ze = zc + tz*(1. - min_toff);
worldannotator.AddLine(xs,ys,zs,
worldAnnotator.AddLine(xs,ys,zs,
xe,ye,ze,
linewidth, color, infront);
}
}
#if 0
for (unsigned int i=0; i<nmajor; ++i)
{
labels[i]->Render(view);
labels[i]->Render(view, worldAnnotator, renderSurface);
}
#endif
}
};

@ -0,0 +1,290 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_MatrixHelpers_h
#define vtk_m_rendering_MatrixHelpers_h
#include <vtkm/Matrix.h>
namespace vtkm {
namespace rendering {
struct MatrixHelpers
{
static VTKM_CONT_EXPORT
void CreateOGLMatrix(const vtkm::Matrix<vtkm::Float32,4,4> &mtx,
vtkm::Float32 *oglM)
{
oglM[ 0] = mtx[0][0];
oglM[ 1] = mtx[1][0];
oglM[ 2] = mtx[2][0];
oglM[ 3] = mtx[3][0];
oglM[ 4] = mtx[0][1];
oglM[ 5] = mtx[1][1];
oglM[ 6] = mtx[2][1];
oglM[ 7] = mtx[3][1];
oglM[ 8] = mtx[0][2];
oglM[ 9] = mtx[1][2];
oglM[10] = mtx[2][2];
oglM[11] = mtx[3][2];
oglM[12] = mtx[0][3];
oglM[13] = mtx[1][3];
oglM[14] = mtx[2][3];
oglM[15] = mtx[3][3];
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ViewMatrix(const vtkm::Vec<vtkm::Float32,3> &position,
const vtkm::Vec<vtkm::Float32,3> &lookAt,
const vtkm::Vec<vtkm::Float32,3> &up)
{
vtkm::Vec<vtkm::Float32,3> viewDir = position-lookAt;
vtkm::Vec<vtkm::Float32,3> right = vtkm::Cross(up,viewDir);
vtkm::Vec<vtkm::Float32,3> ru = vtkm::Cross(viewDir,right);
vtkm::Normalize(viewDir);
vtkm::Normalize(right);
vtkm::Normalize(ru);
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
matrix(0,0) = right[0];
matrix(0,1) = right[1];
matrix(0,2) = right[2];
matrix(1,0) = ru[0];
matrix(1,1) = ru[1];
matrix(1,2) = ru[2];
matrix(2,0) = viewDir[0];
matrix(2,1) = viewDir[1];
matrix(2,2) = viewDir[2];
matrix(0,3) = -vtkm::dot(right,position);
matrix(1,3) = -vtkm::dot(ru,position);
matrix(2,3) = -vtkm::dot(viewDir,position);
return matrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> WorldMatrix(const vtkm::Vec<vtkm::Float32,3> &neworigin,
const vtkm::Vec<vtkm::Float32,3> &newx,
const vtkm::Vec<vtkm::Float32,3> &newy,
const vtkm::Vec<vtkm::Float32,3> &newz)
{
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
matrix(0,0) = newx[0];
matrix(0,1) = newy[0];
matrix(0,2) = newz[0];
matrix(1,0) = newx[1];
matrix(1,1) = newy[1];
matrix(1,2) = newz[1];
matrix(2,0) = newx[2];
matrix(2,1) = newy[2];
matrix(2,2) = newz[2];
matrix(0,3) = neworigin[0];
matrix(1,3) = neworigin[1];
matrix(2,3) = neworigin[2];
return matrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Vec<vtkm::Float32,3> &v)
{
return ScaleMatrix(v[0], v[1], v[2]);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Float32 &s)
{
return ScaleMatrix(s,s,s);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Float32 &x,
const vtkm::Float32 &y,
const vtkm::Float32 &z)
{
vtkm::Matrix<vtkm::Float32,4,4> scaleMatrix(0.0f);
scaleMatrix(0,0) = x;
scaleMatrix(1,1) = y;
scaleMatrix(2,2) = z;
scaleMatrix(3,3) = 1.0f;
return scaleMatrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> TranslateMatrix(const vtkm::Vec<vtkm::Float32,3> &v)
{
return TranslateMatrix(v[0], v[1], v[2]);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> TranslateMatrix(const vtkm::Float32 &x,
const vtkm::Float32 &y,
const vtkm::Float32 &z)
{
vtkm::Matrix<vtkm::Float32,4,4> translateMatrix;
vtkm::MatrixIdentity(translateMatrix);
translateMatrix(0,3) = x;
translateMatrix(1,3) = y;
translateMatrix(2,3) = z;
return translateMatrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> RotateXMatrix(vtkm::Float32 angleRadians)
{
vtkm::Matrix<vtkm::Float32,4,4> M;
M(0,0) = 1.f;
M(0,1) = 0.f;
M(0,2) = 0.f;
M(0,3) = 0.f;
M(1,0) = 0.f;
M(1,1) = cosf(angleRadians);
M(1,2) = - sinf(angleRadians);
M(1,3) = 0.f;
M(2,0) = 0.f;
M(2,1) = sinf(angleRadians);
M(2,2) = cosf(angleRadians);
M(2,3) = 0.f;
M(3,0) = 0.f;
M(3,1) = 0.f;
M(3,2) = 0.f;
M(3,3) = 1.f;
return M;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> RotateYMatrix(vtkm::Float32 angleRadians)
{
vtkm::Matrix<vtkm::Float32,4,4> M;
M(0,0) = cosf(angleRadians);
M(0,1) = 0.f;
M(0,2) = sinf(angleRadians);
M(0,3) = 0.f;
M(1,0) = 0.f;
M(1,1) = 1.f;
M(1,2) = 0.f;
M(1,3) = 0.f;
M(2,0) = - sinf(angleRadians);
M(2,1) = 0.f;
M(2,2) = cosf(angleRadians);
M(2,3) = 0.f;
M(3,0) = 0.f;
M(3,1) = 0.f;
M(3,2) = 0.f;
M(3,3) = 1.f;
return M;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> RotateZMatrix(vtkm::Float32 angleRadians)
{
vtkm::Matrix<vtkm::Float32,4,4> M;
M(0,0) = cosf(angleRadians);
M(0,1) = - sinf(angleRadians);
M(0,2) = 0.f;
M(0,3) = 0.f;
M(1,0) = sinf(angleRadians);
M(1,1) = cosf(angleRadians);
M(1,2) = 0.f;
M(1,3) = 0.f;
M(2,0) = 0.f;
M(2,1) = 0.f;
M(2,2) = 1.f;
M(2,3) = 0.f;
M(3,0) = 0.f;
M(3,1) = 0.f;
M(3,2) = 0.f;
M(3,3) = 1.f;
return M;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> TrackballMatrix(vtkm::Float32 p1x,
vtkm::Float32 p1y,
vtkm::Float32 p2x,
vtkm::Float32 p2y)
{
const vtkm::Float32 RADIUS = 0.80f; //z value lookAt x = y = 0.0
const vtkm::Float32 COMPRESSION = 3.5f; // multipliers for x and y.
const vtkm::Float32 AR3 = RADIUS*RADIUS*RADIUS;
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
if (p1x==p2x && p1y==p2y) { return matrix; }
vtkm::Vec<vtkm::Float32, 3> p1(p1x,p1y, AR3/((p1x*p1x+p1y*p1y)*COMPRESSION+AR3));
vtkm::Vec<vtkm::Float32, 3> p2(p2x,p2y, AR3/((p2x*p2x+p2y*p2y)*COMPRESSION+AR3));
vtkm::Vec<vtkm::Float32, 3> axis = vtkm::Normal(vtkm::Cross(p2,p1));
//std::cout<<"Axis: "<<axis[0]<<" "<<axis[1]<<" "<<axis[2]<<std::endl;
vtkm::Vec<vtkm::Float32, 3> p2_p1(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]);
vtkm::Float32 t = vtkm::Magnitude(p2_p1);
t = vtkm::Min(vtkm::Max(t, -1.0f), 1.0f);
vtkm::Float32 phi = static_cast<vtkm::Float32>(-2.0f*asin(t/(2.0f*RADIUS)));
vtkm::Float32 val = static_cast<vtkm::Float32>(sin(phi/2.0f));
axis[0] *= val;
axis[1] *= val;
axis[2] *= val;
//quaternion
vtkm::Float32 q[4] = {axis[0], axis[1], axis[2], static_cast<vtkm::Float32>(cos(phi/2.0f))};
// normalize quaternion to unit magnitude
t = 1.0f / static_cast<vtkm::Float32>(sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]));
q[0] *= t;
q[1] *= t;
q[2] *= t;
q[3] *= t;
/*
std::cout<<"P1: "<<p1[0]<<" "<<p1[1]<<" "<<p1[2]<<std::endl;
std::cout<<"P2: "<<p2[0]<<" "<<p2[1]<<" "<<p2[2]<<std::endl;
std::cout<<"T= "<<t<<std::endl;
std::cout<<"PHI= "<<phi<<std::endl;
std::cout<<"QUAT: "<<q[0]<<" "<<q[1]<<" "<<q[2]<<" "<<q[3]<<std::endl;
*/
matrix(0,0) = 1 - 2 * (q[1]*q[1] + q[2]*q[2]);
matrix(0,1) = 2 * (q[0]*q[1] + q[2]*q[3]);
matrix(0,2) = (2 * (q[2]*q[0] - q[1]*q[3]) );
matrix(1,0) = 2 * (q[0]*q[1] - q[2]*q[3]);
matrix(1,1) = 1 - 2 * (q[2]*q[2] + q[0]*q[0]);
matrix(1,2) = (2 * (q[1]*q[2] + q[0]*q[3]) );
matrix(2,0) = (2 * (q[2]*q[0] + q[1]*q[3]) );
matrix(2,1) = (2 * (q[1]*q[2] - q[0]*q[3]) );
matrix(2,2) = (1 - 2 * (q[1]*q[1] + q[0]*q[0]) );
return matrix;
}
};
}} //namespace vtkm::rendering
#endif // vtk_m_rendering_MatrixHelpers_h

@ -27,6 +27,7 @@
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/TextureGL.h>
#include <vtkm/rendering/MatrixHelpers.h>
#include <GL/gl.h>
#include <iostream>
@ -65,10 +66,10 @@ public:
{
vtkm::Float32 oglP[16], oglM[16];
CreateOGLMatrix(v.CreateProjectionMatrix(), oglP);
MatrixHelpers::CreateOGLMatrix(v.CreateProjectionMatrix(), oglP);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(oglP);
CreateOGLMatrix(v.CreateViewMatrix(), oglM);
MatrixHelpers::CreateOGLMatrix(v.CreateViewMatrix(), oglM);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(oglM);
@ -121,28 +122,6 @@ public:
}
}
VTKM_CONT_EXPORT
void CreateOGLMatrix(const vtkm::Matrix<vtkm::Float32,4,4> &mtx,
vtkm::Float32 *oglM)
{
oglM[ 0] = mtx[0][0];
oglM[ 1] = mtx[1][0];
oglM[ 2] = mtx[2][0];
oglM[ 3] = mtx[3][0];
oglM[ 4] = mtx[0][1];
oglM[ 5] = mtx[1][1];
oglM[ 6] = mtx[2][1];
oglM[ 7] = mtx[3][1];
oglM[ 8] = mtx[0][2];
oglM[ 9] = mtx[1][2];
oglM[10] = mtx[2][2];
oglM[11] = mtx[3][2];
oglM[12] = mtx[0][3];
oglM[13] = mtx[1][3];
oglM[14] = mtx[2][3];
oglM[15] = mtx[3][3];
}
VTKM_CONT_EXPORT
virtual void SaveAs(const std::string &fileName)
{
@ -250,7 +229,9 @@ private:
BitmapFont font;
TextureGL fontTexture;
void RenderText(float scale, float anchorx, float anchory, std::string text)
void RenderText(vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
std::string text)
{
if (fontTexture.id == 0)
{

@ -29,114 +29,219 @@ namespace rendering {
class TextAnnotation
{
public:
enum HorizontalAlignment
public:
enum HorizontalAlignment
{
Left,
HCenter,
Right
Left,
HCenter,
Right
};
enum VerticalAlignment
enum VerticalAlignment
{
Bottom,
VCenter,
Top
Bottom,
VCenter,
Top
};
protected:
std::string text;
Color color;
vtkm::Float32 scale;
vtkm::Float32 anchorx, anchory;
protected:
std::string text;
Color color;
vtkm::Float32 scale;
vtkm::Float32 anchorx, anchory;
public:
TextAnnotation(const std::string &txt, Color c, vtkm::Float32 s)
: text(txt), color(c), scale(s)
public:
TextAnnotation(const std::string &txt, Color c, vtkm::Float32 s)
: text(txt), color(c), scale(s)
{
// default anchor: bottom-left
anchorx = -1;
anchory = -1;
}
virtual ~TextAnnotation()
{
}
void SetText(const std::string &txt)
{
text = txt;
}
void SetRawAnchor(vtkm::Float32 h, vtkm::Float32 v)
{
anchorx = h;
anchory = v;
}
void SetAlignment(HorizontalAlignment h, VerticalAlignment v)
{
switch (h)
{
// default anchor: bottom-left
anchorx = -1;
anchory = -1;
case Left: anchorx = -1.0f; break;
case HCenter: anchorx = 0.0f; break;
case Right: anchorx = +1.0f; break;
}
virtual ~TextAnnotation()
{
}
void SetText(const std::string &txt)
{
text = txt;
}
void SetRawAnchor(vtkm::Float32 h, vtkm::Float32 v)
{
anchorx = h;
anchory = v;
}
void SetAlignment(HorizontalAlignment h, VerticalAlignment v)
{
switch (h)
{
case Left: anchorx = -1.0f; break;
case HCenter: anchorx = 0.0f; break;
case Right: anchorx = +1.0f; break;
}
// For vertical alignment, "center" is generally the center
// of only the above-baseline contents of the font, so we
// use a value slightly off of zero for VCenter.
// (We don't use an offset value instead of -1.0 for the
// bottom value, because generally we want a true minimum
// extent, e.g. to have text sitting at the bottom of a
// window, and in that case, we need to keep all the text,
// including parts that descend below the baseline, above
// the bottom of the window.
switch (v)
{
case Bottom: anchory = -1.0f; break;
case VCenter: anchory = -0.06f; break;
case Top: anchory = +1.0f; break;
}
}
void SetScale(vtkm::Float32 s)
// For vertical alignment, "center" is generally the center
// of only the above-baseline contents of the font, so we
// use a value slightly off of zero for VCenter.
// (We don't use an offset value instead of -1.0 for the
// bottom value, because generally we want a true minimum
// extent, e.g. to have text sitting at the bottom of a
// window, and in that case, we need to keep all the text,
// including parts that descend below the baseline, above
// the bottom of the window.
switch (v)
{
scale = s;
case Bottom: anchory = -1.0f; break;
case VCenter: anchory = -0.06f; break;
case Top: anchory = +1.0f; break;
}
virtual void Render(View &view,
WorldAnnotator &worldAnnotator,
RenderSurface &renderSurface) = 0;
}
void SetScale(vtkm::Float32 s)
{
scale = s;
}
virtual void Render(View &view,
WorldAnnotator &worldAnnotator,
RenderSurface &renderSurface) = 0;
};
class ScreenTextAnnotation : public TextAnnotation
{
protected:
vtkm::Float32 x,y;
vtkm::Float32 angle;
public:
ScreenTextAnnotation(const std::string &txt, Color c, vtkm::Float32 s,
vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 angleDeg = 0.)
: TextAnnotation(txt,c,s)
{
x = ox;
y = oy;
angle = angleDeg;
}
void SetPosition(vtkm::Float32 ox, vtkm::Float32 oy)
{
x = ox;
y = oy;
}
virtual void Render(View &view,
WorldAnnotator &,
RenderSurface &renderSurface)
{
vtkm::Float32 WindowAspect = vtkm::Float32(view.Width) /
vtkm::Float32(view.Height);
protected:
vtkm::Float32 x,y;
vtkm::Float32 angle;
public:
ScreenTextAnnotation(const std::string &txt, Color c, vtkm::Float32 s,
vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 angleDeg = 0.)
: TextAnnotation(txt,c,s)
{
x = ox;
y = oy;
angle = angleDeg;
}
void SetPosition(vtkm::Float32 ox, vtkm::Float32 oy)
{
x = ox;
y = oy;
}
virtual void Render(View &view,
WorldAnnotator &,
RenderSurface &renderSurface)
{
vtkm::Float32 WindowAspect = vtkm::Float32(view.Width) /
vtkm::Float32(view.Height);
//win->SetupForScreenSpace();
renderSurface.AddText(x,y,
scale,
angle,
WindowAspect,
anchorx, anchory,
color, text);
//win->SetupForScreenSpace();
renderSurface.AddText(x,y,
scale,
angle,
WindowAspect,
anchorx, anchory,
color, text);
}
};
class BillboardTextAnnotation : public TextAnnotation
{
protected:
vtkm::Float32 x,y,z;
vtkm::Float32 angle;
public:
BillboardTextAnnotation(const std::string &txt, Color c, vtkm::Float32 s,
vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz,
vtkm::Float32 angleDeg = 0.)
: TextAnnotation(txt,c,s)
{
x = ox;
y = oy;
z = oz;
angle = angleDeg;
}
void SetPosition(vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz)
{
x = ox;
y = oy;
z = oz;
}
virtual void Render(View &view,
WorldAnnotator &worldAnnotator,
RenderSurface &renderSurface)
{
vtkm::Matrix<vtkm::Float32, 4, 4> V, P;
V = view.CreateViewMatrix();
P = view.CreateProjectionMatrix();
vtkm::Vec<vtkm::Float32,4> p4w(x,y,z,1);
vtkm::Vec<vtkm::Float32,4> p4s =
vtkm::MatrixMultiply(vtkm::MatrixMultiply(P,V), p4w);
renderSurface.SetViewToScreenSpace(view,true);
vtkm::Float32 psx = p4s[0] / p4s[3];
vtkm::Float32 psy = p4s[1] / p4s[3];
vtkm::Float32 psz = p4s[2] / p4s[3];
vtkm::Matrix<vtkm::Float32, 4, 4> T;
T = MatrixHelpers::TranslateMatrix(psx,psy,-psz);
vtkm::Float32 WindowAspect =
vtkm::Float32(view.Width) / vtkm::Float32(view.Height);
vtkm::Matrix<vtkm::Float32, 4, 4> SW;
SW = MatrixHelpers::ScaleMatrix(1.f/WindowAspect, 1, 1);
vtkm::Matrix<vtkm::Float32, 4, 4> SV;
vtkm::MatrixIdentity(SV);
//if view type == 2D?
{
vtkm::Float32 vl, vr, vb, vt;
view.GetRealViewport(vl,vr,vb,vt);
vtkm::Float32 xs = (vr-vl);
vtkm::Float32 ys = (vt-vb);
SV = MatrixHelpers::ScaleMatrix(2.f/xs, 2.f/ys, 1);
}
vtkm::Matrix<vtkm::Float32, 4, 4> R;
R = MatrixHelpers::RotateZMatrix(angle * 3.14159265f / 180.f);
vtkm::Vec<vtkm::Float32,4> origin4(0,0,0,1);
vtkm::Vec<vtkm::Float32,4> right4(1,0,0,0);
vtkm::Vec<vtkm::Float32,4> up4(0,1,0,0);
vtkm::Matrix<vtkm::Float32, 4, 4> M =
vtkm::MatrixMultiply(T,
vtkm::MatrixMultiply(SW,
vtkm::MatrixMultiply(SV,
R)));
vtkm::Vec<vtkm::Float32,4> new_origin4 =
vtkm::MatrixMultiply(M, origin4);
vtkm::Vec<vtkm::Float32,4> new_right4 =
vtkm::MatrixMultiply(M, right4);
vtkm::Vec<vtkm::Float32,4> new_up4 =
vtkm::MatrixMultiply(M, up4);
vtkm::Float32 px = new_origin4[0] / new_origin4[3];
vtkm::Float32 py = new_origin4[1] / new_origin4[3];
vtkm::Float32 pz = new_origin4[2] / new_origin4[3];
vtkm::Float32 rx = new_right4[0];
vtkm::Float32 ry = new_right4[1];
vtkm::Float32 rz = new_right4[2];
vtkm::Float32 ux = new_up4[0];
vtkm::Float32 uy = new_up4[1];
vtkm::Float32 uz = new_up4[2];
worldAnnotator.AddText(px,py,pz,
rx,ry,rz,
ux,uy,uz,
scale,
anchorx, anchory,
color, text);
renderSurface.SetViewToWorldSpace(view,true);
}
};

@ -22,6 +22,7 @@
#include <vtkm/Math.h>
#include <vtkm/Matrix.h>
#include <vtkm/VectorAnalysis.h>
#include <vtkm/rendering/MatrixHelpers.h>
namespace vtkm {
namespace rendering {
@ -38,7 +39,7 @@ class View
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> CreateViewMatrix()
{
return View::ViewMatrix(this->Position, this->LookAt, this->Up);
return MatrixHelpers::ViewMatrix(this->Position, this->LookAt, this->Up);
}
VTKM_CONT_EXPORT
@ -69,8 +70,8 @@ class View
matrix(3,3) = 0.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = View::TranslateMatrix(this->XPan, this->YPan, 0);
Z = View::ScaleMatrix(this->Zoom, this->Zoom, 1);
T = MatrixHelpers::TranslateMatrix(this->XPan, this->YPan, 0);
Z = MatrixHelpers::ScaleMatrix(this->Zoom, this->Zoom, 1);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
@ -101,7 +102,7 @@ class View
vtkm::Vec<vtkm::Float32,3> position = lookAt;
position[2] = 1.f;
vtkm::Vec<vtkm::Float32,3> up(0,1,0);
return View::ViewMatrix(position, lookAt, up);
return MatrixHelpers::ViewMatrix(position, lookAt, up);
}
VTKM_CONT_EXPORT
@ -133,144 +134,6 @@ class View
vtkm::Float32 XScale;
};
private:
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ViewMatrix(const vtkm::Vec<vtkm::Float32,3> &position,
const vtkm::Vec<vtkm::Float32,3> &lookAt,
const vtkm::Vec<vtkm::Float32,3> &up)
{
vtkm::Vec<vtkm::Float32,3> viewDir = position-lookAt;
vtkm::Vec<vtkm::Float32,3> right = vtkm::Cross(up,viewDir);
vtkm::Vec<vtkm::Float32,3> ru = vtkm::Cross(viewDir,right);
vtkm::Normalize(viewDir);
vtkm::Normalize(right);
vtkm::Normalize(ru);
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
matrix(0,0) = right[0];
matrix(0,1) = right[1];
matrix(0,2) = right[2];
matrix(1,0) = ru[0];
matrix(1,1) = ru[1];
matrix(1,2) = ru[2];
matrix(2,0) = viewDir[0];
matrix(2,1) = viewDir[1];
matrix(2,2) = viewDir[2];
matrix(0,3) = -vtkm::dot(right,position);
matrix(1,3) = -vtkm::dot(ru,position);
matrix(2,3) = -vtkm::dot(viewDir,position);
return matrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Vec<vtkm::Float32,3> &v)
{
return ScaleMatrix(v[0], v[1], v[2]);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Float32 &s)
{
return ScaleMatrix(s,s,s);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> ScaleMatrix(const vtkm::Float32 &x,
const vtkm::Float32 &y,
const vtkm::Float32 &z)
{
vtkm::Matrix<vtkm::Float32,4,4> scaleMatrix(0.0f);
scaleMatrix(0,0) = x;
scaleMatrix(1,1) = y;
scaleMatrix(2,2) = z;
scaleMatrix(3,3) = 1.0f;
return scaleMatrix;
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> TranslateMatrix(const vtkm::Vec<vtkm::Float32,3> &v)
{
return TranslateMatrix(v[0], v[1], v[2]);
}
static VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4> TranslateMatrix(const vtkm::Float32 &x,
const vtkm::Float32 &y,
const vtkm::Float32 &z)
{
vtkm::Matrix<vtkm::Float32,4,4> translateMatrix;
vtkm::MatrixIdentity(translateMatrix);
translateMatrix(0,3) = x;
translateMatrix(1,3) = y;
translateMatrix(2,3) = z;
return translateMatrix;
}
VTKM_CONT_EXPORT
vtkm::Matrix<vtkm::Float32,4,4>
CreateTrackball(vtkm::Float32 p1x, vtkm::Float32 p1y, vtkm::Float32 p2x, vtkm::Float32 p2y)
{
const vtkm::Float32 RADIUS = 0.80f; //z value lookAt x = y = 0.0
const vtkm::Float32 COMPRESSION = 3.5f; // multipliers for x and y.
const vtkm::Float32 AR3 = RADIUS*RADIUS*RADIUS;
vtkm::Matrix<vtkm::Float32,4,4> matrix;
vtkm::MatrixIdentity(matrix);
if (p1x==p2x && p1y==p2y) { return matrix; }
vtkm::Vec<vtkm::Float32, 3> p1(p1x,p1y, AR3/((p1x*p1x+p1y*p1y)*COMPRESSION+AR3));
vtkm::Vec<vtkm::Float32, 3> p2(p2x,p2y, AR3/((p2x*p2x+p2y*p2y)*COMPRESSION+AR3));
vtkm::Vec<vtkm::Float32, 3> axis = vtkm::Normal(vtkm::Cross(p2,p1));
//std::cout<<"Axis: "<<axis[0]<<" "<<axis[1]<<" "<<axis[2]<<std::endl;
vtkm::Vec<vtkm::Float32, 3> p2_p1(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]);
vtkm::Float32 t = vtkm::Magnitude(p2_p1);
t = vtkm::Min(vtkm::Max(t, -1.0f), 1.0f);
vtkm::Float32 phi = static_cast<vtkm::Float32>(-2.0f*asin(t/(2.0f*RADIUS)));
vtkm::Float32 val = static_cast<vtkm::Float32>(sin(phi/2.0f));
axis[0] *= val;
axis[1] *= val;
axis[2] *= val;
//quaternion
vtkm::Float32 q[4] = {axis[0], axis[1], axis[2], static_cast<vtkm::Float32>(cos(phi/2.0f))};
// normalize quaternion to unit magnitude
t = 1.0f / static_cast<vtkm::Float32>(sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]));
q[0] *= t;
q[1] *= t;
q[2] *= t;
q[3] *= t;
/*
std::cout<<"P1: "<<p1[0]<<" "<<p1[1]<<" "<<p1[2]<<std::endl;
std::cout<<"P2: "<<p2[0]<<" "<<p2[1]<<" "<<p2[2]<<std::endl;
std::cout<<"T= "<<t<<std::endl;
std::cout<<"PHI= "<<phi<<std::endl;
std::cout<<"QUAT: "<<q[0]<<" "<<q[1]<<" "<<q[2]<<" "<<q[3]<<std::endl;
*/
matrix(0,0) = 1 - 2 * (q[1]*q[1] + q[2]*q[2]);
matrix(0,1) = 2 * (q[0]*q[1] + q[2]*q[3]);
matrix(0,2) = (2 * (q[2]*q[0] - q[1]*q[3]) );
matrix(1,0) = 2 * (q[0]*q[1] - q[2]*q[3]);
matrix(1,1) = 1 - 2 * (q[2]*q[2] + q[0]*q[0]);
matrix(1,2) = (2 * (q[1]*q[2] + q[0]*q[3]) );
matrix(2,0) = (2 * (q[2]*q[0] + q[1]*q[3]) );
matrix(2,1) = (2 * (q[1]*q[2] - q[0]*q[3]) );
matrix(2,2) = (1 - 2 * (q[1]*q[1] + q[0]*q[0]) );
return matrix;
}
public:
enum ViewTypeEnum { VIEW_2D, VIEW_3D };
ViewTypeEnum ViewType;
@ -432,17 +295,17 @@ public:
printVec("up", view3d.up);
std::cout<<"*****************************************************************"<<std::endl;
*/
vtkm::Matrix<vtkm::Float32,4,4> R1 = CreateTrackball(x1,y1, x2,y2);
vtkm::Matrix<vtkm::Float32,4,4> R1 = MatrixHelpers::TrackballMatrix(x1,y1, x2,y2);
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> T1 = View::TranslateMatrix(-this->View3d.LookAt);
vtkm::Matrix<vtkm::Float32,4,4> T1 = MatrixHelpers::TranslateMatrix(-this->View3d.LookAt);
//vtkm::MatrixIdentity(T1);
//T1(0,3) = -view3d.lookAt[0];
//T1(1,3) = -view3d.lookAt[1];
//T1(2,3) = -view3d.lookAt[2];
//Translate matrix
vtkm::Matrix<vtkm::Float32,4,4> T2 = View::TranslateMatrix(this->View3d.LookAt);
vtkm::Matrix<vtkm::Float32,4,4> T2 = MatrixHelpers::TranslateMatrix(this->View3d.LookAt);
//T2(0,3) = view3d.lookAt[0];
//T2(1,3) = view3d.lookAt[1];
//T2(2,3) = view3d.lookAt[2];

@ -151,8 +151,16 @@ public:
bbox.SetExtents(scene.GetSpatialBounds());
bbox.Render(this->view, this->worldAnnotator);
///\todo: set x/y/ztest based on view
bool xtest=true, ytest=false, ztest=false;
bool xtest = this->view.View3d.LookAt[0] > this->view.View3d.Position[0];
bool ytest = this->view.View3d.LookAt[1] > this->view.View3d.Position[1];
bool ztest = this->view.View3d.LookAt[2] > this->view.View3d.Position[2];
const bool outsideedges = true; // if false, do closesttriad
if (outsideedges)
{
xtest = !xtest;
//ytest = !ytest;
}
vtkm::Float64 xrel = vtkm::Abs(dx) / size;
vtkm::Float64 yrel = vtkm::Abs(dy) / size;
@ -170,11 +178,11 @@ public:
xaxis.SetRange(xmin, xmax);
xaxis.SetMajorTickSize(size / 40.f, 0);
xaxis.SetMinorTickSize(size / 80.f, 0);
xaxis.SetLabelFontScale(size / 30.);
xaxis.SetLabelFontOffset(vtkm::Float32(size / 15.f));
xaxis.SetMoreOrLessTickAdjustment(xrel < .3 ? -1 : 0);
xaxis.Render(this->view, this->worldAnnotator);
xaxis.Render(this->view, this->worldAnnotator, this->surface);
yaxis.SetAxis(0);
yaxis.SetAxis(1);
yaxis.SetColor(Color(1,1,1));
yaxis.SetTickInvert(xtest,ytest,ztest);
yaxis.SetWorldPosition(xtest ? xmin : xmax,
@ -186,11 +194,11 @@ public:
yaxis.SetRange(ymin, ymax);
yaxis.SetMajorTickSize(size / 40.f, 0);
yaxis.SetMinorTickSize(size / 80.f, 0);
yaxis.SetLabelFontScale(size / 30.);
yaxis.SetLabelFontOffset(vtkm::Float32(size / 15.f));
yaxis.SetMoreOrLessTickAdjustment(yrel < .3 ? -1 : 0);
yaxis.Render(this->view, this->worldAnnotator);
yaxis.Render(this->view, this->worldAnnotator, this->surface);
zaxis.SetAxis(0);
zaxis.SetAxis(2);
zaxis.SetColor(Color(1,1,1));
zaxis.SetTickInvert(xtest,ytest,ztest);
zaxis.SetWorldPosition(xtest ? xmin : xmax,
@ -202,9 +210,9 @@ public:
zaxis.SetRange(zmin, zmax);
zaxis.SetMajorTickSize(size / 40.f, 0);
zaxis.SetMinorTickSize(size / 80.f, 0);
zaxis.SetLabelFontScale(size / 30.);
zaxis.SetLabelFontOffset(vtkm::Float32(size / 15.f));
zaxis.SetMoreOrLessTickAdjustment(zrel < .3 ? -1 : 0);
zaxis.Render(this->view, this->worldAnnotator);
zaxis.Render(this->view, this->worldAnnotator, this->surface);
}
};

@ -37,6 +37,13 @@ public:
vtkm::Float32,
const vtkm::rendering::Color &,
bool=false) {}
virtual void AddText(vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32, vtkm::Float32, vtkm::Float32,
vtkm::Float32,
vtkm::Float32, vtkm::Float32,
Color,
std::string) {}
};
}} //namespace vtkm::rendering

@ -20,12 +20,17 @@
#ifndef vtk_m_rendering_WorldAnnotatorGL_h
#define vtk_m_rendering_WorldAnnotatorGL_h
#include <vtkm/Matrix.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/SceneRenderer.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/View.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>
#include <vtkm/rendering/BitmapFont.h>
#include <vtkm/rendering/BitmapFontFactory.h>
#include <vtkm/rendering/TextureGL.h>
#include <vtkm/rendering/MatrixHelpers.h>
namespace vtkm {
namespace rendering {
@ -58,6 +63,107 @@ public:
glDepthRange(0,1);
}
virtual void AddText(vtkm::Float32 ox, vtkm::Float32 oy, vtkm::Float32 oz,
vtkm::Float32 rx, vtkm::Float32 ry, vtkm::Float32 rz,
vtkm::Float32 ux, vtkm::Float32 uy, vtkm::Float32 uz,
vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
Color color,
std::string text)
{
vtkm::Vec<vtkm::Float32,3> o(ox,oy,oz);
vtkm::Vec<vtkm::Float32,3> r(rx,ry,rz);
vtkm::Vec<vtkm::Float32,3> u(ux,uy,uz);
vtkm::Vec<vtkm::Float32,3> n = vtkm::Cross(r,u);
vtkm::Normalize(n);
vtkm::Matrix<vtkm::Float32,4,4> m;
m = MatrixHelpers::WorldMatrix(o, r, u, n);
vtkm::Float32 ogl[16];
MatrixHelpers::CreateOGLMatrix(m, ogl);
glPushMatrix();
glMultMatrixf(ogl);
glColor3fv(color.Components);
RenderText(scale, anchorx, anchory, text);
glPopMatrix();
}
private:
BitmapFont font;
TextureGL fontTexture;
void RenderText(vtkm::Float32 scale,
vtkm::Float32 anchorx, vtkm::Float32 anchory,
std::string text)
{
if (fontTexture.id == 0)
{
font = BitmapFontFactory::CreateLiberation2Sans();
std::vector<unsigned char> &rawpngdata = font.GetRawImageData();
std::vector<unsigned char> rgba;
unsigned long width, height;
int error = decodePNG(rgba, width, height,
&rawpngdata[0], rawpngdata.size());
if (error != 0)
{
return;
}
fontTexture.CreateAlphaFromRGBA(int(width),int(height),rgba);
}
fontTexture.Enable();
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_LIGHTING);
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -.5);
glBegin(GL_QUADS);
vtkm::Float32 textwidth = font.GetTextWidth(text);
vtkm::Float32 fx = -(.5f + .5f*anchorx) * textwidth;
vtkm::Float32 fy = -(.5f + .5f*anchory);
vtkm::Float32 fz = 0;
for (unsigned int i=0; i<text.length(); ++i)
{
char c = text[i];
char nextchar = (i < text.length()-1) ? text[i+1] : 0;
vtkm::Float32 vl,vr,vt,vb;
vtkm::Float32 tl,tr,tt,tb;
font.GetCharPolygon(c, fx, fy,
vl, vr, vt, vb,
tl, tr, tt, tb, nextchar);
glTexCoord2f(tl, 1.f-tt);
glVertex3f(scale*vl, scale*vt, fz);
glTexCoord2f(tl, 1.f-tb);
glVertex3f(scale*vl, scale*vb, fz);
glTexCoord2f(tr, 1.f-tb);
glVertex3f(scale*vr, scale*vb, fz);
glTexCoord2f(tr, 1.f-tt);
glVertex3f(scale*vr, scale*vt, fz);
}
glEnd();
fontTexture.Disable();
//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0);
glDepthMask(GL_TRUE);
glDisable(GL_ALPHA_TEST);
}
};
}} //namespace vtkm::rendering