Atoms Crowd  7.0.0
AnimationStateOperator.h
1 #pragma once
2 // ===========================================================================
3 // Copyright (c) 2015 Toolchefs Ltd. All rights reserved.
4 //
5 // Use of this software is subject to the terms of the Toolchefs license
6 // agreement provided at the time of installation or download, or which
7 // otherwise accompanies this software in either electronic or hard copy form.
8 // ===========================================================================
9 
10 
11 #include <AtomsGraph/Ports.h>
12 #include <Atoms/Globals.h>
13 #include <Atoms/Graph/Operator.h>
14 #include <Atoms/AnimationClip.h>
15 #include <Atoms/AnimationState.h>
16 #include <Atoms/StateMachine.h>
17 #include <Atoms/Graph/AgentBehaviourNetwork.h>
18 #include <unordered_map>
19 #include <list>
20 #include <Atoms/Graph/Operators/StateMachineBaseNodeOperator.h>
21 #include <mutex>
22 
23 namespace Atoms
24 {
25 
27  {
28  public:
29 
30  class MotionType
31  {
32  public:
33  MotionType() :
34  currentRandomClip(0),
35  allRandom(false)
36  {}
37 
38  std::vector<unsigned int> clips;
39  int currentRandomClip;
40  bool allRandom;
41  };
42 
43  class SubState
44  {
45  public:
46  SubState() : offset(0.0), hash(-1), isTurning(false), transitionStarted(false), bypass(false) {}
47  std::vector<unsigned> ids;
48  double offset;
49  int hash;
50  bool isTurning;
51  bool transitionStarted;
52  bool bypass;
53  };
54 
56  {
57  public:
59  clipPtr(nullptr),
60  start(0.0),
61  end(0.0),
62  frame(0.0),
63  fps(30.0),
64  hasLoop(false),
65  timePort1(nullptr),
66  timePort2(nullptr)
67  {}
68 
69  AnimationClipPtr clipPtr;
70  double start;
71  double end;
72  //double blend;
73  double frame;
74  double fps;
75  bool hasLoop;
76 
77  AtomsGraph::DoublePort* timePort1;
78  AtomsGraph::DoublePort* timePort2;
79  AtomsGraph::LongPort* frameOffsetPort1;
80  AtomsGraph::LongPort* frameOffsetPort2;
81  };
82 
83  class ClipData
84  {
85  public:
86  ClipData() :
87  clipPtr(nullptr),
88  tag(""),
89  start(0.0),
90  end(0.0),
91  //blend(0.0),
92  frame(0.0),
93  weight(0.0),
94  fps(30.0),
95  framesBlendInOffset(0),
96  resetTime(0.0),
97  mergeType(0),
98  motionType(0),
99  angle(0.0),
100  blendAngle(0.0),
101  maxTurnAngle(0.0),
102  previousAngle(0.0),
103  randomWeight(1.0),
104  numBlendFrames(1),
105  hasLoop(false),
106  synced(false),
107  useClipDirection(false),
108  timePort(nullptr),
109  weightPort(nullptr),
110  activePort(nullptr),
111  frameOffsetPort(nullptr)
112  {}
113 
114  AnimationClipPtr clipPtr;
115  std::string tag;
116  double start;
117  double end;
118  //double blend;
119  double frame;
120  double weight;
121  double fps;
122  double framesBlendInOffset;
123  double resetTime;
124  unsigned int mergeType;
125  unsigned int motionType;
126  double angle;
127  double blendAngle;
128  double maxTurnAngle;
129  double previousAngle;
130  double randomWeight;
131  unsigned int numBlendFrames;
132  bool hasLoop;
133  bool synced;
134  bool useClipDirection;
135 
136  AtomsGraph::DoublePort* timePort;
137  AtomsGraph::DoublePort* weightPort;
138  AtomsGraph::BooleanPort* activePort;
139  AtomsGraph::LongPort* frameOffsetPort;
140  };
141 
142  NODE_STANDARD_MEMBERS
143 
145 
146  virtual ~AnimationStateOperator();
147 
148  bool compute(const AtomsGraph::ComputeData* computeData);
149 
150  void reset();
151 
152  void updateTurningData(
153  AtomsCore::Vector3& direction,
154  AtomsCore::Vector3& upDirVec,
155  AtomsCore::Vector3& projDir,
156  AtomsCore::Vector3& agentTurnAngle,
157  bool behave3d,
158  bool isFirst);
159 
160  void initializeFirstFrame(
161  AtomsCore::Vector3& direction,
162  AtomsCore::Vector3& upDirVec,
163  AtomsCore::Vector3& projDir);
164 
165  void advanceSingleClip(double timeStep, double frameStep, bool randomClip = false);
166 
167  int pickNewRandomClipId(AnimationStateOperator::MotionType& motionType);
168 
169  double getMergeWeight(const AnimationStateOperator::ClipData& clipData);
170 
171  double updateTurnWeights(MotionType& motionType, double turnAngled, double& straight_weight, double maxWeight);
172 
173  void computeTurnWeights(double maxWeight);
174 
175  std::pair<int, int> getUnsyncedClipId();
176 
177  int getUnsyncedClip(MotionType& motionData, double turnAngled);
178 
179  void buildNetwork(const AtomsPtr<Atoms::StateMachine>& stateMachine, const Atoms::AnimationState &state, std::map<std::string, std::string>& clipToAgentTypeNames, std::mutex& mutex, const double starFrame, AtomsCore::Rand32* idRandom);
180 
181  bool isReadyToTransition(double frameRate = 1.0, bool checkTransitionFrames = true, bool checkForceTransition = true);
182  double computeBlendInOffset(double frameRate, bool checkTransitionFrames = true);
183  void computeBlendInOffsetInPlace(double frameRate, bool checkTransitionFrames = true);
184  double getBlendInOffset();
185  double getBlendInOffset(int clipId);
186  void prepareForBlendIn(double offset, double timeStep);
187  void prepareClipForBlendIn(int clipId, double offset);
188  int getActiveClipId();
189  bool isBlendInStage(double offset, unsigned int blend);
190  bool isBlendInStage(int clipId, double offset, unsigned int blend);
191  bool isBlendOutStage(double& frameDifference, unsigned int blend);
192  double computeBlendInWeight(double offset, unsigned int blend);
193  double computeBlendInWeight(int clipId, double offset, unsigned int blend);
194  double computeBlendOutWeight(unsigned int blend);
195  double computeBlendOutWeight(int clipId, unsigned int blend);
196  void setUpBlendOutFrame(double offset, double timeStep);
197  bool isBlendOutFinished(unsigned int blend);
198  void setClipFrameAndWeights();
199  void initSubState(double frame);
200 
201  bool hasClips() { return m_clips.size() > 0; };
202 
203  protected:
204 
205  std::vector<double> m_frames;
206 
207  std::vector<MotionType> m_motionInfo;
208 
209  std::vector<ClipData> m_clips;
210 
211  std::vector<AdditiveClipData> m_additiveClips;
212 
213  std::vector<std::string> m_clipNames;
214 
215  std::list<SubState> m_subStateQueue;
216 
217  AtomsCore::Rand32* m_idRandom;
218 
219  AtomsCore::Vector3 m_previousDirection;
220  AtomsCore::Vector3 m_cacheUpVector;
221  AtomsCore::Vector3 m_cacheDirectionVector;
222 
223  AtomsCore::Vector3 m_turnAngle;
224  AtomsCore::Vector3 m_prevTurnAngle;
225  AtomsCore::Vector3 m_maxTurnAngle;
226 
227  double m_previousTime;
228 
229  int m_currentState;
230 
231  unsigned int m_postRandClipId;
232 
233 
234  bool m_transitionStarted;
235  bool m_skipCycle;
236  bool m_randomLoop;
237  bool m_needLockDirectionForTurning;
238 
239  };
240 }
Animation State.
Definition: AnimationState.h:25
Definition: AnimationStateOperator.h:56
Definition: AnimationStateOperator.h:84
Definition: AnimationStateOperator.h:31
Definition: AnimationStateOperator.h:44
Definition: AnimationStateOperator.h:27
bool compute(const AtomsGraph::ComputeData *computeData)
Compute function.
void reset()
Operator reset function.
Definition: StateMachineBaseNodeOperator.h:27
Definition: Node.h:21
Generic node port class.
Definition: PortTemplate.h:24
AtomsMath::Vector3 Vector3
Vector3 class.
Definition: AtomsMath.h:57
Atoms namespace.
Definition: Agent.h:29
AtomsPtr< AnimationClip > AnimationClipPtr
animation clip pointer
Definition: AnimationClip.h:28