Atoms Crowd  4.1.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  };
80 
81  class ClipData
82  {
83  public:
84  ClipData() :
85  clipPtr(nullptr),
86  tag(""),
87  start(0.0),
88  end(0.0),
89  //blend(0.0),
90  frame(0.0),
91  weight(0.0),
92  fps(30.0),
93  framesBlendInOffset(0),
94  resetTime(0.0),
95  mergeType(0),
96  motionType(0),
97  angle(0.0),
98  blendAngle(0.0),
99  maxTurnAngle(0.0),
100  previousAngle(0.0),
101  numBlendFrames(1),
102  hasLoop(false),
103  synced(false),
104  useClipDirection(false),
105  timePort(nullptr),
106  weightPort(nullptr),
107  activePort(nullptr)
108  {}
109 
110  AnimationClipPtr clipPtr;
111  std::string tag;
112  double start;
113  double end;
114  //double blend;
115  double frame;
116  double weight;
117  double fps;
118  double framesBlendInOffset;
119  double resetTime;
120  unsigned int mergeType;
121  unsigned int motionType;
122  double angle;
123  double blendAngle;
124  double maxTurnAngle;
125  double previousAngle;
126  unsigned int numBlendFrames;
127  bool hasLoop;
128  bool synced;
129  bool useClipDirection;
130 
131  AtomsGraph::DoublePort* timePort;
132  AtomsGraph::DoublePort* weightPort;
133  AtomsGraph::BooleanPort* activePort;
134  };
135 
136  NODE_STANDARD_MEMBERS
137 
139 
140  virtual ~AnimationStateOperator();
141 
142  bool compute(const AtomsGraph::ComputeData* computeData);
143 
144  void reset();
145 
146  void updateTurningData(
147  AtomsCore::Vector3& direction,
148  AtomsCore::Vector3& upDirVec,
149  AtomsCore::Vector3& projDir,
150  AtomsCore::Vector3& agentTurnAngle,
151  bool behave3d,
152  bool isFirst);
153 
154  void initializeFirstFrame(
155  AtomsCore::Vector3& direction,
156  AtomsCore::Vector3& upDirVec,
157  AtomsCore::Vector3& projDir);
158 
159  void advanceSingleClip(double timeStep, double frameStep, bool randomClip = false);
160 
161  int pickNewRandomClipId(AnimationStateOperator::MotionType& motionType);
162 
163  double getMergeWeight(const AnimationStateOperator::ClipData& clipData);
164 
165  double updateTurnWeights(MotionType& motionType, double turnAngled, double& straight_weight, double maxWeight);
166 
167  void computeTurnWeights(double maxWeight);
168 
169  std::pair<int, int> getUnsyncedClipId();
170 
171  int getUnsyncedClip(MotionType& motionData, double turnAngled);
172 
173  void buildNetwork(const AtomsPtr<Atoms::StateMachine>& stateMachine, const Atoms::AnimationState &state, std::map<std::string, std::string>& clipToAgentTypeNames, std::mutex& mutex, AtomsCore::Rand32* idRandom);
174 
175  bool isReadyToTransition(double frameRate = 1.0, bool checkTransitionFrames = true, bool checkForceTransition = true);
176  double computeBlendInOffset(double frameRate, bool checkTransitionFrames = true);
177  void computeBlendInOffsetInPlace(double frameRate, bool checkTransitionFrames = true);
178  double getBlendInOffset();
179  double getBlendInOffset(int clipId);
180  void prepareForBlendIn(double offset, double timeStep);
181  void prepareClipForBlendIn(int clipId, double offset);
182  int getActiveClipId();
183  bool isBlendInStage(double offset, unsigned int blend);
184  bool isBlendInStage(int clipId, double offset, unsigned int blend);
185  bool isBlendOutStage(double& frameDifference, unsigned int blend);
186  double computeBlendInWeight(double offset, unsigned int blend);
187  double computeBlendInWeight(int clipId, double offset, unsigned int blend);
188  double computeBlendOutWeight(unsigned int blend);
189  double computeBlendOutWeight(int clipId, unsigned int blend);
190  void setUpBlendOutFrame(double offset, double timeStep);
191  bool isBlendOutFinished(unsigned int blend);
192  void setClipFrameAndWeights();
193  void initSubState(double frame);
194 
195  bool hasClips() { return m_clips.size() > 0; };
196 
197  protected:
198 
199  std::vector<double> m_frames;
200 
201  std::vector<MotionType> m_motionInfo;
202 
203  std::vector<ClipData> m_clips;
204 
205  std::vector<AdditiveClipData> m_additiveClips;
206 
207  std::vector<std::string> m_clipNames;
208 
209  std::list<SubState> m_subStateQueue;
210 
211  AtomsCore::Rand32* m_idRandom;
212 
213  AtomsCore::Vector3 m_previousDirection;
214  AtomsCore::Vector3 m_cacheUpVector;
215  AtomsCore::Vector3 m_cacheDirectionVector;
216 
217  AtomsCore::Vector3 m_turnAngle;
218  AtomsCore::Vector3 m_prevTurnAngle;
219  AtomsCore::Vector3 m_maxTurnAngle;
220 
221  double m_previousTime;
222 
223  int m_currentState;
224 
225  unsigned int m_postRandClipId;
226 
227 
228  bool m_oneShot;
229  bool m_transitionStarted;
230  bool m_skipCycle;
231  bool m_randomLoop;
232  bool m_needLockDirectionForTurning;
233 
234  };
235 }
Atoms::AnimationStateOperator
Definition: AnimationStateOperator.h:27
Atoms::AnimationStateOperator::ClipData
Definition: AnimationStateOperator.h:82
Atoms::AnimationState
Animation State.
Definition: AnimationState.h:25
AtomsCore::Vector3
AtomsMath::Vector3 Vector3
Vector3 class.
Definition: AtomsMath.h:57
Atoms::StateMachineBaseNodeOperator
Definition: StateMachineBaseNodeOperator.h:27
Atoms::AnimationStateOperator::compute
bool compute(const AtomsGraph::ComputeData *computeData)
Compute function.
Atoms::AnimationStateOperator::AdditiveClipData
Definition: AnimationStateOperator.h:56
AtomsGraph::PortTemplate
Generic node port class.
Definition: PortTemplate.h:24
Atoms::AnimationStateOperator::MotionType
Definition: AnimationStateOperator.h:31
Atoms
Atoms namespace.
Definition: Agent.h:28
Atoms::AnimationStateOperator::SubState
Definition: AnimationStateOperator.h:44
Atoms::AnimationStateOperator::reset
void reset()
Operator reset function.
AtomsGraph::ComputeData
Definition: Node.h:21
Atoms::AnimationClipPtr
AtomsPtr< AnimationClip > AnimationClipPtr
animation clip pointer
Definition: AnimationClip.h:27