Free Electron
SurfaceCylinder.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __surface_SurfaceCylinder_h__
8 #define __surface_SurfaceCylinder_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
15 /**************************************************************************//**
16  @brief Cylindrical Surface
17 
18  @ingroup surface
19 *//***************************************************************************/
20 class FE_DL_EXPORT SurfaceCylinder:
21  public SurfaceDisk,
22  public CastableAs<SurfaceCylinder>
23 {
24  protected:
25  class Impact:
26  public SurfaceDisk::Impact,
27  public CastableAs<Impact>
28  {
29  public:
30  Impact(void)
31  {
32 #if FE_COUNTED_STORE_TRACKER
33  setName("SurfaceCylinder::Impact");
34 #endif
35  }
36  virtual ~Impact(void) {}
37 
38  virtual SpatialVector normal(void)
39  {
40  if(!m_resolved)
41  {
42  resolve();
43  }
44  return m_normal;
45  }
46 
47  virtual SpatialVector axis(void)
48  { return m_axis; }
49  void setAxis(SpatialVector a_axis)
50  { m_axis=a_axis; }
51 
52  virtual Real along(void)
53  { return m_along; }
54  void setAlong(Real a_along)
55  { m_along=a_along; }
56 
57  protected:
58  SpatialVector m_axis;
59  Real m_along;
60 
61  };
62  public:
63  SurfaceCylinder(void);
64 virtual ~SurfaceCylinder(void) {}
65 
66  //* As Protectable
67 virtual Protectable* clone(Protectable* pInstance=NULL);
68 
69  using SurfaceDisk::sample;
70 
71  //* As SurfaceI
72 virtual SpatialTransform sample(Vector2 a_uv) const;
73 
74  using SurfaceDisk::nearestPoint;
75 
76 virtual sp<ImpactI> nearestPoint(const SpatialVector& a_origin,
77  Real a_maxDistance) const
78  {
79  SpatialVector direction;
80  SpatialVector intersection;
81  Real along(Real(0));
82  Real distance=
84  m_location,m_span,m_endRadius,
85  a_origin,direction,along,
86  intersection);
87  if(a_maxDistance>0.0 && distance>a_maxDistance)
88  {
89  return sp<Impact>(NULL);
90  }
91 
92  sp<Impact> spImpact=
93  m_cylinderImpactPool.get();
94  spImpact->setSurface(this);
95  spImpact->setLocationLocal(m_location);
96  spImpact->setAxis(m_span);
97  spImpact->setRadius(m_endRadius);
98  spImpact->setOrigin(a_origin);
99  spImpact->setDirection(direction);
100  spImpact->setDistance(distance);
101  spImpact->setIntersectionLocal(intersection);
102  spImpact->setAlong(along);
103  return spImpact;
104  }
105 
106  using SurfaceDisk::rayImpact;
107 
108 virtual sp<ImpactI> rayImpact(const SpatialVector& a_origin,
109  const SpatialVector& a_direction,
110  Real a_maxDistance,BWORD a_anyHit) const
111  {
112  SpatialVector intersection;
113  Real along(Real(0));
114  Real distance=
116  m_location,m_span,m_endRadius,
117  a_origin,a_direction,along,
118  intersection);
119  if(a_maxDistance>0.0 && distance>a_maxDistance)
120  {
121  return sp<Impact>(NULL);
122  }
123 
124  sp<Impact> spImpact=
125  m_cylinderImpactPool.get();
126  spImpact->setSurface(this);
127  spImpact->setLocationLocal(m_location);
128  spImpact->setAxis(m_span);
129  spImpact->setRadius(m_endRadius);
130  spImpact->setOrigin(a_origin);
131  spImpact->setDirection(a_direction);
132  spImpact->setDistance(distance);
133  spImpact->setIntersectionLocal(intersection);
134  spImpact->setAlong(along);
135  return spImpact;
136  }
137 
138  using SurfaceDisk::draw;
139 
140 virtual void draw(const SpatialTransform& a_transform,
141  sp<DrawI> a_spDrawI,
142  const fe::Color* a_color,
143  sp<DrawBufferI> a_spDrawBuffer,
144  sp<PartitionI> a_spPartition) const;
145 
146  void setLocation(const SpatialVector& a_rLocation)
147  { m_location=a_rLocation;
148  updateSphere(); }
149  SpatialVector location(void)
150  { checkCache();
151  return m_location; }
152  SpatialVector location(void) const
153  { return m_location; }
154 
155  void setBaseRadius(Real a_baseRadius)
156  { m_baseRadius=a_baseRadius;
157  updateSphere(); }
158  Real baseRadius(void)
159  { checkCache();
160  return m_baseRadius; }
161  Real baseRadius(void) const
162  { return m_baseRadius; }
163 
164  void setEndRadius(Real a_endRadius)
165  { m_endRadius=a_endRadius;
166  updateSphere(); }
167  Real endRadius(void)
168  { checkCache();
169  return m_endRadius; }
170  Real endRadius(void) const
171  { return m_endRadius; }
172 
173  protected:
174 
175 virtual void updateSphere(void);
176 virtual void cache(void);
177 virtual void resolveImpact(sp<ImpactI> a_spImpactI) const
178  {
179  // TODO m_baseRadius and m_endRadius scaling
180 
181  sp<Impact> spImpact(a_spImpactI);
182 
183  // TEMP no nearest
184  if(!spImpact.isValid())
185  {
186  return;
187  }
188 
189  SpatialVector normal;
191  spImpact->locationLocal(),
192  spImpact->axis(),
193  spImpact->radius(),
194  spImpact->origin(),
195  spImpact->direction(),
196  spImpact->distance(),
197  spImpact->along(),
198  spImpact->intersectionLocal(),
199  normal);
200  spImpact->setNormalLocal(normal);
201  }
202 
203  SpatialVector m_location;
204  Real m_baseRadius;
205  Real m_endRadius;
206 
207  private:
208 mutable CountedPool<Impact> m_cylinderImpactPool;
209 };
210 
211 } /* namespace ext */
212 } /* namespace fe */
213 
214 #endif /* __surface_SurfaceCylinder_h__ */
215 
Flat Circular Surface.
Definition: SurfaceDisk.h:20
Base class providing protection counting for cp<>
Definition: Protectable.h:28
kernel
Definition: namespace.dox:3
Find intersection between ray and cylinder.
Definition: RayCylinderIntersect.h:26
Special vector for color (RGBA)
Definition: Color.h:21
Cylindrical Surface.
Definition: SurfaceCylinder.h:20
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
Find point nearest to a cylindrical solid.
Definition: PointCylinderNearest.h:21
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192