1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //
6 //  This software is distributed WITHOUT ANY WARRANTY; without even
7 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 //  PURPOSE.  See the above copyright notice for more information.
9 //============================================================================
10 
11 #include <vtkm/rendering/TextAnnotationBillboard.h>
12 
13 #include <vtkm/Matrix.h>
14 
15 namespace vtkm
16 {
17 namespace rendering
18 {
19 
TextAnnotationBillboard(const std::string & text,const vtkm::rendering::Color & color,vtkm::Float32 scalar,const vtkm::Vec3f_32 & position,vtkm::Float32 angleDegrees)20 TextAnnotationBillboard::TextAnnotationBillboard(const std::string& text,
21                                                  const vtkm::rendering::Color& color,
22                                                  vtkm::Float32 scalar,
23                                                  const vtkm::Vec3f_32& position,
24                                                  vtkm::Float32 angleDegrees)
25   : TextAnnotation(text, color, scalar)
26   , Position(position)
27   , Angle(angleDegrees)
28 {
29 }
30 
~TextAnnotationBillboard()31 TextAnnotationBillboard::~TextAnnotationBillboard() {}
32 
SetPosition(const vtkm::Vec3f_32 & position)33 void TextAnnotationBillboard::SetPosition(const vtkm::Vec3f_32& position)
34 {
35   this->Position = position;
36 }
37 
SetPosition(vtkm::Float32 xpos,vtkm::Float32 ypos,vtkm::Float32 zpos)38 void TextAnnotationBillboard::SetPosition(vtkm::Float32 xpos,
39                                           vtkm::Float32 ypos,
40                                           vtkm::Float32 zpos)
41 {
42   this->SetPosition(vtkm::make_Vec(xpos, ypos, zpos));
43 }
44 
Render(const vtkm::rendering::Camera & camera,const vtkm::rendering::WorldAnnotator & worldAnnotator,vtkm::rendering::Canvas & canvas) const45 void TextAnnotationBillboard::Render(const vtkm::rendering::Camera& camera,
46                                      const vtkm::rendering::WorldAnnotator& worldAnnotator,
47                                      vtkm::rendering::Canvas& canvas) const
48 {
49   using MatrixType = vtkm::Matrix<vtkm::Float32, 4, 4>;
50   using VectorType = vtkm::Vec3f_32;
51 
52   MatrixType viewMatrix = camera.CreateViewMatrix();
53   MatrixType projectionMatrix =
54     camera.CreateProjectionMatrix(canvas.GetWidth(), canvas.GetHeight());
55 
56   VectorType screenPos = vtkm::Transform3DPointPerspective(
57     vtkm::MatrixMultiply(projectionMatrix, viewMatrix), this->Position);
58 
59   canvas.SetViewToScreenSpace(camera, true);
60   MatrixType translateMatrix =
61     vtkm::Transform3DTranslate(screenPos[0], screenPos[1], -screenPos[2]);
62 
63   vtkm::Float32 windowAspect = vtkm::Float32(canvas.GetWidth()) / vtkm::Float32(canvas.GetHeight());
64 
65   MatrixType scaleMatrix = vtkm::Transform3DScale(1.f / windowAspect, 1.f, 1.f);
66 
67   MatrixType viewportMatrix;
68   vtkm::MatrixIdentity(viewportMatrix);
69   //if view type == 2D?
70   {
71     vtkm::Float32 vl, vr, vb, vt;
72     camera.GetRealViewport(canvas.GetWidth(), canvas.GetHeight(), vl, vr, vb, vt);
73     vtkm::Float32 xs = (vr - vl);
74     vtkm::Float32 ys = (vt - vb);
75     viewportMatrix = vtkm::Transform3DScale(2.f / xs, 2.f / ys, 1.f);
76   }
77 
78   MatrixType rotateMatrix = vtkm::Transform3DRotateZ(this->Angle * vtkm::Pi_180f());
79 
80   vtkm::Matrix<vtkm::Float32, 4, 4> fullTransformMatrix = vtkm::MatrixMultiply(
81     translateMatrix,
82     vtkm::MatrixMultiply(scaleMatrix, vtkm::MatrixMultiply(viewportMatrix, rotateMatrix)));
83 
84   VectorType origin = vtkm::Transform3DPointPerspective(fullTransformMatrix, VectorType(0, 0, 0));
85   VectorType right = vtkm::Transform3DVector(fullTransformMatrix, VectorType(1, 0, 0));
86   VectorType up = vtkm::Transform3DVector(fullTransformMatrix, VectorType(0, 1, 0));
87 
88   // scale depth from (1, -1) to (0, 1);
89   vtkm::Float32 depth = screenPos[2] * .5f + .5f;
90   worldAnnotator.AddText(
91     origin, right, up, this->Scale, this->Anchor, this->TextColor, this->Text, depth);
92 
93   canvas.SetViewToWorldSpace(camera, true);
94 }
95 }
96 } // vtkm::rendering
97