Allolib  1.0
C++ Components For Interactive Multimedia
al_Pickable.hpp
1 #ifndef __PICKABLE_HPP__
2 #define __PICKABLE_HPP__
3 
4 #include <vector>
5 
6 #include "al/graphics/al_Graphics.hpp"
7 #include "al/math/al_Ray.hpp"
8 #include "al/ui/al_BoundingBox.hpp"
9 #include "al/ui/al_Parameter.hpp"
10 #include "al/ui/al_ParameterBundle.hpp"
11 
12 namespace al {
13 
14 enum PickEventType {
15  Point,
16  Pick,
17  PickPose,
18  Unpick,
19  Drag,
20  TranslateRay,
21  RotateRay,
22  RotateRayTrackball,
23  RotateTurntable,
24  RotatePose,
25  Scale
26 };
27 
28 struct PickEvent {
29  PickEventType type;
30  Rayd ray;
31  Pose pose;
32  Vec3f vec;
33  float amount;
34 
35  PickEvent(PickEventType t, Rayd r) : type(t), ray(r) {}
36  PickEvent(PickEventType t, Rayd r, Pose p) : type(t), ray(r), pose(p) {}
37  PickEvent(PickEventType t, Rayd r, Vec3f v) : type(t), ray(r), vec(v) {}
38  PickEvent(PickEventType t, Rayd r, Pose p, Vec3f v) : type(t), ray(r), pose(p), vec(v) {}
39  PickEvent(PickEventType t, Rayd r, float v) : type(t), ray(r), amount(v) {}
40  PickEvent(PickEventType t, Pose p) : type(t), pose(p) {}
41  PickEvent(PickEventType t, float v) : type(t), amount(v) {}
42 };
43 
44 struct Pickable;
45 
46 struct Hit {
47  bool hit;
48  Rayd ray;
49  double t;
50  Pickable *p;
51 
52  Hit() : hit(false) {}
53  Hit(bool h, Rayd r, double tt, Pickable *pp) : hit(h), ray(r), t(tt), p(pp) {}
54  Vec3d operator()() { return hit ? ray(t) : Vec3d(); }
55 };
56 
59 struct Pickable {
60  std::string name;
61 
62  ParameterBool hover{"hover", name}, selected{"selected", name};
63  ParameterPose pose{"pose", name};
64  ParameterVec3 scaleVec{"scaleVec", name};
65  Parameter scale{"scale", name, 1.0f, "", 0.0f, 10.0f};
66  ParameterBundle bundle{"pickable"};
67 
68  Pickable *parent = nullptr;
69  std::vector<Pickable *> children;
70  bool testChildren = true;
71  bool containChildren = false;
72  bool containedChild = false;
73  int depth = 0;
74 
75  // initial values, and previous values
76  Pose pose0, prevPose;
77  Vec3f scale0, prevScale;
78 
79  Pickable();
80 
81  virtual ~Pickable() {}
82 
84  virtual Hit intersect(Rayd r) = 0;
85  virtual Hit intersect(Vec3d v) { return intersect(Rayd(v, Vec3d())); }
86 
88  virtual bool onEvent(PickEvent e, Hit hit) { return false; }
89 
91  virtual bool event(PickEvent e);
92 
93  void clearSelection();
94 
95  bool intersects(Rayd &r) { return intersect(r).hit; }
96  bool intersectsChild(Rayd &r);
97 
98  Hit intersectChildren(Rayd &r);
99 
100  void addChild(Pickable &pickable);
101  void addChild(Pickable *p) { addChild(*p); }
102 
104  inline void pushMatrix(Graphics &g) {
105  g.pushMatrix();
106  g.translate(pose.get().pos());
107  g.rotate(pose.get().quat());
108  g.scale(scaleVec.get());
109  }
111  inline void popMatrix(Graphics &g) { g.popMatrix(); }
112 
113  void draw(Graphics &g,
114  std::function<void(Pickable &p)> f = [](Pickable &p) {});
115 
116  void foreach (std::function<void(Pickable &p)> pre,
117  std::function<void(Pickable &p)> post = [](Pickable & /*p*/) {
118  }) {
119  pre(*this);
120  for (auto *c : children) c->foreach (pre, post);
121  post(*this);
122  }
123 
127  Vec3f transformVecWorld(const Vec3f &v, float w = 1);
129  Vec3f transformVecLocal(const Vec3f &v, float w = 1);
130 };
131 
135  Mesh *mesh{nullptr}; // pointer to mesh that is wrapped
136  BoundingBox bb; // original bounding box
137  BoundingBox aabb; // axis aligned bounding box (after pose/scale transforms)
138 
139  // used for moving pickable naturally
140  Vec3f selectPos;
141  Vec3f selectOffset;
142  Quatf selectQuat;
143  float selectDist;
144 
145  PickableBB(std::string name_ = "") {
146  Pickable::name = name_;
147  bundle.name(name_);
148  }
149  PickableBB(Mesh &m) { set(m); }
150 
152  void set(Mesh &m);
153 
156  // bool contains(Vec3d v){ auto p = transformVecLocal(v); return
157  // bb.contains(p); }
158 
159  bool onEvent(PickEvent e, Hit h);
160 
161  void drawMesh(Graphics &g);
162 
163  void drawBB(Graphics &g);
164 
166  void setCenter(Vec3f &pos);
167 
169  void setQuat(Quatf &q);
170 
172  double intersectBB(Rayd localRay);
173 
175  double intersectAABB(Rayd ray);
176 
179 
182  void updateAABB();
183 };
184 
185 } // namespace al
186 
187 #endif
Interface for loading fonts and rendering text.
Definition: al_Graphics.hpp:63
Stores buffers related to rendering graphical objects.
Definition: al_Mesh.hpp:62
std::string name() const
get the name for this bundle
The Parameter class.
virtual ParameterType get()
get the parameter's value
A local coordinate frame.
Definition: al_Pose.hpp:63
Vec3d & pos()
Get "position" vector.
Definition: al_Pose.hpp:100
Quatd & quat()
Get quaternion component (represents orientation)
Definition: al_Pose.hpp:108
void rotate(float angle, float x=0., float y=0., float z=1.)
void scale(float x, float y, float z=1.)
Scale current matrix along each dimension.
void translate(float x, float y, float z=0.)
Translate current matrix.
void popMatrix()
Pop current matrix stack.
void pushMatrix()
Push current matrix stack.
Definition: al_App.hpp:23
Vec< 3, double > Vec3d
double 3-vector
Definition: al_Vec.hpp:60
void setCenter(Vec3f &pos)
set the pickable's center position
void setQuat(Quatf &q)
set pickable's orientation maintaining same center position
float intersectBoundingSphere(Rayd ray)
intersect ray with bounding sphere
Hit intersect(Rayd r)
override base methods
double intersectAABB(Rayd ray)
intersect ray with pickable AxisAlignedBoundingBox
void set(Mesh &m)
initialize bounding box;
bool onEvent(PickEvent e, Hit h)
override callback
double intersectBB(Rayd localRay)
intersect ray with pickable BoundingBox
void popMatrix(Graphics &g)
pop matrix.
void pushMatrix(Graphics &g)
apply pickable pose transforms
virtual Hit intersect(Rayd r)=0
intersection test must be implemented
Vec3f transformVecLocal(const Vec3f &v, float w=1)
transfrom a vector in world space to local space
Rayd transformRayLocal(const Rayd &ray)
transform a ray in world space to local space
Vec3f transformVecWorld(const Vec3f &v, float w=1)
transfrom a vector in local space to world space
virtual bool onEvent(PickEvent e, Hit hit)
override callback
Definition: al_Pickable.hpp:88
virtual bool event(PickEvent e)
do interaction on self and children, call onEvent callbacks