Free Electron
Tree.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 __vegetation_Tree_h__
8 #define __vegetation_Tree_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
15 typedef DenseVector<F64> VectorN;
16 typedef SparseMatrix<F64> MatrixN;
17 
18 /**************************************************************************//**
19  @brief Vegetation model for a Dynamic Tree
20 
21  @ingroup vegetation
22 *//***************************************************************************/
23 class FE_DL_EXPORT Tree: virtual public PlantModelI, public Initialize<Tree>
24 {
25  public:
26  Tree(void) {}
27 virtual ~Tree(void);
28 
29  void initialize(void);
30 virtual void reset(void);
31  void start(void);
32  void stop(void);
33 
34  //* as PlantModelI
35 virtual void generate(const Record seed);
36 virtual void addBranch(U32 a_fromIndex,U32 a_toIndex,
37  U32 a_level,Real a_radius1,Real a_radius2,
38  const SpatialVector& a_span,
39  Real a_rigidity);
40 virtual void prepare(void);
41 virtual void update(const Real deltaT);
42 
43 virtual U32 numSticks(void) const
44  { FEASSERT(m_sticks==m_stickArray.size());
45  return m_sticks; }
46 virtual PlantModelI::Stick* stick(U32 index)
47  { FEASSERT(index<m_stickMap.size());
48  I32 compactIndex=m_stickMap[index];
49  return compactIndex<0? NULL:
50  m_stickArray[compactIndex]; }
51 
52 virtual U32 numLeaves(void) const
53  { return m_leafArray.size(); }
54 virtual PlantModelI::Leaf* leaf(U32 index)
55  { FEASSERT(index<numLeaves());
56  return m_leafArray[index]; }
57 virtual
58 const SpatialVector* leafPoints(void) const { return m_pLeafPoints; }
59 virtual
60 const SpatialVector* leafNormals(void) const { return m_pLeafNormals; }
61 
62 virtual U32 stickBundles(void) const
63  { FEASSERT(m_bundles==m_bundleSize.size());
64  return m_bundles; }
65 virtual U32 stickBundleSize(U32 bundle) const
66  { FEASSERT(bundle<stickBundles());
67  return m_bundleSize[bundle]; }
68 virtual
69 const SpatialTransform* stickTransforms(U32 bundle) const
70  { FEASSERT(bundle<stickBundles());
71  return m_stickTransformBundles[bundle]; }
72 virtual
73 const SpatialVector* stickScale(U32 bundle) const
74  { FEASSERT(bundle<stickBundles());
75  return m_stickScaleBundles[bundle]; }
76 virtual
77 const Real* stickBaseScale(U32 bundle) const
78  { FEASSERT(bundle<stickBundles());
79  return m_stickBaseScaleBundles[bundle]; }
80 virtual
81 const U32* stickSlices(U32 bundle) const
82  { FEASSERT(bundle<stickBundles());
83  return m_stickSliceBundles[bundle]; }
84 
85 virtual void setLocation(const SpatialVector& location)
86  { m_location=location; }
87 virtual void setOffset(const SpatialVector& offset)
88  { m_offset=offset; }
89 
90 virtual sp<SurfaceI> collider(void) { return m_spCollider; }
91 virtual void setCollider(sp<SurfaceI> a_spCollider)
92  { m_spCollider=a_spCollider; }
93 
94 virtual SpatialTransform& colliderTransform(void)
95  { return m_colliderTransform; }
96 virtual void setColliderTransform(
97  const SpatialTransform& a_rColliderTransform)
98  { m_colliderTransform=a_rColliderTransform; }
99 
100 virtual SpatialVector& effectorForce(void)
101  { return m_effectorForce; }
102 
103 virtual void setGravity(const SpatialVector& a_gravity)
104  { m_gravity=a_gravity; }
105 virtual void setUniformVelocity(const SpatialVector& a_velocity)
106  { m_uniformVelocity=a_velocity; }
107 virtual void setUniformRigidity(const Real a_rigidity)
108  { m_uniformRigidity=a_rigidity; }
109 virtual void setDamping(const Real a_damping)
110  { m_damping=a_damping; }
111 virtual void setReactivity(const Real a_reactivity)
112  { m_reactivity=a_reactivity; }
113 virtual void setThreshold(const Real a_threshold)
114  { m_threshold=a_threshold; }
115 virtual void setCollisionMethod(const String a_collisionMethod)
116  { m_collisionMethod=a_collisionMethod; }
117 virtual void setCollideEnd(const BWORD a_collideEnd)
118  { m_collideEnd=a_collideEnd; }
119 virtual void setRepulsion(const Real a_repulsion)
120  { m_repulsion=a_repulsion; }
121 virtual void setRepulsionFalloff(const Real a_repulsionFalloff)
122  { m_repulsionFalloff=a_repulsionFalloff; }
123 virtual void setDepletion(const Real a_depletion)
124  { m_depletion=a_depletion; }
125 virtual void setDepletionFalloff(const Real a_depletionFalloff)
126  { m_depletionFalloff=a_depletionFalloff; }
127 virtual void setWindHampering(const Real a_windHampering)
128  { m_windHampering=a_windHampering; }
129 virtual void setWindFalloff(const Real a_windFalloff)
130  { m_windFalloff=a_windFalloff; }
131 virtual void setPlasticity(const Real a_plasticity)
132  { m_plasticity=a_plasticity; }
133 virtual void setCompensation(const BWORD a_compensation)
134  { m_compensation=a_compensation; }
135 virtual void setCorrection(const BWORD a_correction)
136  { m_correction=a_correction; }
137 
138  /// @brief Leaf on a Tree
139  class Leaf:
140  virtual public PlantModelI::Leaf,
141  public CastableAs<Leaf>
142  {
143  public:
144  Leaf(void)
145  {
146  set(m_center);
147  set(m_normal);
148  }
149  virtual ~Leaf(void) {}
150  virtual const SpatialVector& center(void) const { return m_center; }
151  virtual const SpatialVector& normal(void) const { return m_normal; }
152 
153  SpatialVector m_center;
154  SpatialVector m_normal;
155  };
156 
157  /// @brief Segment of a branch
158  class Stick:
159  virtual public PlantModelI::Stick,
160  public CastableAs<Stick>
161  {
162  public:
163  Stick(void)
164  {
165  m_children.setAutoDestruct(TRUE);
166  reset();
167  }
168  virtual ~Stick(void) {}
169 
170  void reset(void)
171  {
172  m_pParent=NULL;
173  m_index=0;
174  m_level=0;
175  m_targeted=0;
176  m_mass=1.0f;
177  m_length=0.0f;
178  m_spring=0.0f;
179  m_drag=0.0f;
180  m_radius1=1.0f;
181  m_radius2=1.0f;
182  m_resolution=0;
183  m_freedom=1.0;
184 
185  set(m_base);
186  set(m_span);
187  set(m_windVelocity);
188  set(m_target);
189  set(m_rest);
190  set(m_position);
191  set(m_velocity);
192  set(m_lastAddPosition);
193  set(m_lastAddDelta);
194  set(m_contact);
195  set(m_intensity);
196 
197  m_children.deleteAll();
198  m_leafIndexArray.clear();
199  }
200 
201  //* as PlantModelI::Stick
202  virtual const SpatialVector& base(void) const { return m_base; }
203  virtual const SpatialVector& span(void) const { return m_span; }
204  virtual const SpatialQuaternion& rotation(void) const
205  { return m_rotation; }
206  virtual Real radius1(void) const
207  { return m_radius1; }
208  virtual Real radius2(void) const
209  { return m_radius2; }
210  virtual I32 resolution(void) const
211  { return m_resolution; }
212  virtual String stateString(void) const
213  {
214  String result;
215  result.sPrintf(
216  " %d %.2f %.2f",
217  m_index,
218  m_rest[0]+m_position[0],
219  m_rest[1]+m_position[1]);
220  return result;
221  }
222  virtual void setWindVelocity(
223  const SpatialVector& a_windVelocity)
224  { m_windVelocity=a_windVelocity; }
225  virtual void setTarget(
226  const SpatialVector& a_target)
227  { m_target=a_target; }
228  virtual void setTargeted(
229  const I32 a_targeted)
230  { m_targeted=a_targeted; }
231 
232  void attach(Stick* pChild)
233  {
234  m_children.append(pChild);
235  pChild->m_pParent=this;
236  }
237  void attachLeaf(U32 leafIndex)
238  {
239  const U32 size=m_leafIndexArray.size();
240  m_leafIndexArray.resize(size+1);
241  m_leafIndexArray[size]=leafIndex;
242  }
243 
244  void grow(sp<Tree>& rspTree,U32& stick,
245  const U32 segment,const U32 level,
246  const F32 a_fullLength,const F32 along,
247  const F32 baseRotate,const F32 rotate);
248  void populate_static(sp<Tree>& rspTree,
249  MatrixN* dfdx,MatrixN* dfdv,
250  VectorN& invMass);
251  Real effectOfEffector(sp<Tree>& rspTree,
252  const SpatialVector& a_effector,
253  SpatialVector& a_effect);
254  void populate_dynamic(sp<Tree>& rspTree,
255  VectorN* force,
256  VectorN* velocity,
257  VectorN* addPosition,
258  VectorN* addVelocity,
259  bool rekine);
260  void forward_kine(U32 thread,
261  sp<Tree>& rspTree,const F32 deltaT,
262  const VectorN* deltaV,
263  const VectorN* addPosition,
264  const VectorN* addVelocity,
265  SpatialVector& rEffectorForce,
266  BWORD rebundle);
267  void forward_kine_recursive(U32 thread,
268  sp<Tree>& rspTree,
269  const F32 deltaT,
270  const VectorN* deltaV,
271  const VectorN* addPosition,
272  const VectorN* addVelocity,
273  SpatialVector& rEffectorForce,
274  BWORD only_zero);
275 
276  Stick* m_pParent;
277  List<Stick*> m_children;
278  Array<U32> m_leafIndexArray;
279  U32 m_index;
280  U32 m_level;
281 
282  SpatialVector m_base;
283  SpatialVector m_span;
284  SpatialVector m_dir[2]; //* world dir of an angle change
285  SpatialVector m_windVelocity;
286  SpatialVector m_target;
287  I32 m_targeted;
288  F32 m_mass;
289  F32 m_length;
290  F32 m_spring; //* angular spring
291  F32 m_drag; //* bending, not viscosity
292  F32 m_radius1;
293  F32 m_radius2;
294  I32 m_resolution;
295  Vector2 m_absRest; //* for addBranch
296  SpatialVector m_dirRest; //* for addBranch
297  Vector2 m_rest;
298  Vector2 m_position;
299  Vector2 m_velocity;
300  SpatialQuaternion m_rotation;
301  SpatialQuaternion m_correction;
302  SpatialTransform m_transform;
303  Vector2 m_intensity;
304  Real m_freedom;
305 
306  //* TODO list of
307 
308  //* decay adjustment after release
309  Vector2 m_lastAddPosition;
310  Vector2 m_lastAddDelta;
311 
312  //* debug
313  SpatialVector m_contact;
314  SpatialVector m_contact2;
315  };
316 
317  void addKine(Tree::Stick* pStick)
318  {
319  U32 index=m_kineArray.size();
320  m_kineArray.resize(index+1,NULL);
321  m_kineArray[index]=pStick;
322  }
323  void setStick(U32 index,Tree::Stick* pStick)
324  {
325  if(index>=m_stickArray.size())
326  {
327  m_stickArray.resize(index+1,NULL);
328  }
329  m_stickArray[index]=pStick;
330  }
331 
332  U32 newLeaf(void)
333  {
334  const U32 size=m_leafArray.size();
335  m_leafArray.resize(size+1);
336  m_leafArray[size]=new Leaf();
337  return size;
338  }
339 
340  void forward_kine_thread(U32 thread,I32 index);
341 
342  private:
343 static F32 shapeFunction(const F32 along,
344  const F32 valleybase,
345  const F32 valleytip,
346  const F32 peakAlong,
347  const F32 powerbase,
348  const F32 powertip);
349  void bindLevel(const U32 level);
350 
351  TreeSeed m_seedRV;
352  StickLevel m_levelRV;
353  I32 m_boundLevel;
354 
355  F32 m_lastDeltaT;
356  U32 m_sticks;
357  Stick m_root;
358  Array<Tree::Stick*> m_kineArray; //* TODO not pointers
359  Array<Tree::Stick*> m_stickArray; //* TODO not pointers
360  Array<I32> m_stickMap; //* before compacting
361  Array<Tree::Leaf*> m_leafArray;
362  SpatialVector* m_pLeafPoints;
363  SpatialVector* m_pLeafNormals;
364 
365  Array<SpatialTransform*> m_stickTransformBundles;
366  Array<SpatialVector*> m_stickScaleBundles;
367  Array<Real*> m_stickBaseScaleBundles;
368  Array<U32*> m_stickSliceBundles;
369  Array<U32> m_bundleSize;
370  U32 m_bundles;
371 
372  SpatialVector m_location;
373  SpatialVector m_offset;
374  SpatialQuaternion m_rotation;
375 
376  sp<SurfaceI> m_spCollider;
377  SpatialTransform m_colliderTransform;
378  SpatialVector m_effectorForce; //* TODO list of
379  Array<SpatialVector> m_effectorForceArray;
380 
381  SpatialVector m_gravity;
382  SpatialVector m_uniformVelocity;
383  Real m_uniformRigidity;
384  Real m_damping;
385  Real m_reactivity;
386  Real m_threshold;
387  String m_collisionMethod;
388  BWORD m_collideEnd;
389  BWORD m_compensation;
390  BWORD m_correction;
391  I32 m_useCorrection; //* 0=no 1=store 2=apply
392  Real m_repulsion;
393  Real m_repulsionFalloff;
394  Real m_depletion;
395  Real m_depletionFalloff;
396  Real m_windHampering;
397  Real m_windFalloff;
398  Real m_plasticity;
399 
400  sp<Profiler> m_spProfiler;
401  sp<Profiler::Profile> m_spProfileReset;
402  sp<Profiler::Profile> m_spProfilePopulate;
403  sp<Profiler::Profile> m_spProfileSolve;
404  sp<Profiler::Profile> m_spProfileSolveWait;
405  sp<Profiler::Profile> m_spProfileThreadWait;
406  sp<Profiler::Profile> m_spProfileSetup[2];
407  sp<Profiler::Profile> m_spProfileSolver[2];
408  sp<Profiler::Profile> m_spProfileKine;
409  sp<Profiler::Profile> m_spProfileKineWait;
410 
411  Array< sp<Profiler::Profile> > m_spProfileKineLimbArray;
412 
413  VectorN m_force[2];
414  VectorN m_velocity[2];
415  VectorN m_addPosition[2];
416  VectorN m_addVelocity[2];
417  VectorN m_tempVector1[2];
418  VectorN m_tempVector2[2];
419  VectorN m_deltaV[2];
420  VectorN m_b[2];
421 
422  // diagonal matrices represented as vectors
423  VectorN m_mass;
424  VectorN m_im;
425  VectorN m_him;
426  VectorN m_invSqrtA[2];
427 
428  MatrixN m_A[2];
429 // MatrixN m_A2[2];
430  MatrixN m_tempMatrix[2];
431  MatrixN m_dfdx[2];
432 // MatrixN m_dfdx2[2];
433 // MatrixN m_hdfdx[2];
434  MatrixN m_imdfdx[2];
435  MatrixN m_imdfdv[2];
436  MatrixN m_identity;
437 
439 
440  void solve(U32 m);
441  void runSolvers(void);
442  void runKine(void);
443 
444  class SolverWorker: public Thread::Functor
445  {
446  public:
447  SolverWorker(sp< JobQueue<I32> > a_spJobQueue,
448  U32 a_id,String a_stage):
449  m_id(a_id),
450  m_hpJobQueue(a_spJobQueue) {}
451 
452  virtual void operate(void);
453 
454  void setObject(sp<Counted> spTree)
455  { m_hpTree=sp<Component>(spTree); }
456 
457  private:
458  U32 m_id;
459  hp< JobQueue<I32> > m_hpJobQueue;
460  hp<Tree> m_hpTree;
461  };
462 
463  sp< JobQueue<I32> > m_spJobQueue;
464  sp< Gang<SolverWorker,I32> > m_spGang;
465 };
466 
467 } /* namespace ext */
468 } /* namespace fe */
469 
470 #endif /* __vegetation_Tree_h__ */
Stem Segment in a PlantModelI.
Definition: PlantModelI.h:28
Fully Bidirectional Doubly-Linked List.
Definition: List.h:496
kernel
Definition: namespace.dox:3
TreeSeed RecordView.
Definition: TreeSeed.h:26
Organ of photosynthesis and transpiration.
Definition: PlantModelI.h:47
Per-class participation in the Initialized <> mechanism.
Definition: Initialized.h:117
Segment of a branch.
Definition: Tree.h:158
Dense vector - size fixed by template.
Definition: Vector.h:19
Vegetation model for a Dynamic Tree.
Definition: Tree.h:23
Leaf on a Tree.
Definition: Tree.h:139
Safe handle for shared pointer.
Definition: Handled.h:61
String & sPrintf(const char *fmt,...)
Populate the string in the manner of sprintf().
Definition: String.cc:529
Automatically reference-counted string container.
Definition: String.h:128
Reference to an instance of a Layout.
Definition: RecordSB.h:35
StickLevel RecordView.
Definition: StickLevel.h:35
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
U32 size(const Vector< N, T > &lhs)
Return the number of elements.
Definition: Vector.h:635
solve Ax=b for x
Definition: ConjugateGradient.h:38
Vegetation subsystem.
Definition: PlantModelI.h:20
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192