-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHitOwner.h
More file actions
175 lines (133 loc) · 4.57 KB
/
HitOwner.h
File metadata and controls
175 lines (133 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#pragma once
#include "HitManager.h"
#include <Urho3D/Scene/LogicComponent.h>
#include <EASTL/tuple.h>
namespace Urho3D
{
class HitDetector;
class HitOwner;
class HitTrigger;
class RigidBody;
/// Identifier of ongoing hit. Unique within the instance of HitOwner.
enum class HitId : unsigned
{
Invalid
};
/// Description of ongoing physical volume hit between HitTrigger and HitDetector.
/// Components that belong to the same HitOwner never hit each other.
/// There is no other filtering at this level.
struct PLUGIN_CORE_HITMANAGER_API ComponentHitInfo
{
WeakPtr<HitDetector> detector_;
WeakPtr<HitTrigger> trigger_;
};
/// Description of logical hit between two HitOwner objects.
struct PLUGIN_CORE_HITMANAGER_API GroupHitInfo
{
WeakPtr<HitOwner> detector_;
WeakPtr<HitOwner> trigger_;
ea::string detectorGroup_;
ea::string triggerGroup_;
HitId id_{};
/// Time before already stopped hit expires.
ea::optional<float> timeToExpire_;
/// Merge key is used to compare and merge sets of hits from different frames.
/// Hits that belong to the same HitOwner are supposed to have unique key triplets.
auto MergeKey() const { return ea::tie(trigger_, detectorGroup_, triggerGroup_); }
};
class PLUGIN_CORE_HITMANAGER_API HitOwner : public TrackedComponent<TrackedComponentBase, HitManager>
{
URHO3D_OBJECT(HitOwner, TrackedComponentBase);
public:
HitOwner(Context* context);
static void RegisterObject(Context* context);
/// Return all hits.
const ea::vector<GroupHitInfo>& GetHits() const { return groupHits_; }
/// Find hit by ID.
const GroupHitInfo* GetHitInfo(HitId id) const;
/// Attributes.
/// @{
void SetTriggerFadeOut(float value) { triggerFadeOut_ = value; }
float GetTriggerFadeOut() const { return triggerFadeOut_; }
/// @}
/// Internal.
/// @{
void UpdateEvents(float timeStep);
void AddOngoingHit(HitDetector* detector, HitTrigger* trigger);
void RemoveOngoingHit(HitDetector* detector, HitTrigger* trigger);
/// @}
private:
void RemoveExpiredRawHits();
void CalculateGroupHits();
void StartAndStopHits(float timeStep);
void AdvanceNextId() { nextId_ = static_cast<HitId>(static_cast<unsigned>(nextId_) + 1); }
HitId GetNextId();
void SendEvent(StringHash eventType, const GroupHitInfo& hit);
void OnHitStarted(const GroupHitInfo& hit);
void OnHitStopped(const GroupHitInfo& hit);
ea::vector<ComponentHitInfo> componentHits_;
ea::vector<GroupHitInfo> groupHits_;
ea::vector<GroupHitInfo> previousGroupHits_;
HitId nextId_{};
float triggerFadeOut_{};
};
class PLUGIN_CORE_HITMANAGER_API HitComponent : public LogicComponent
{
URHO3D_OBJECT(HitComponent, LogicComponent);
public:
HitComponent(Context* context);
~HitComponent() override;
static void RegisterObject(Context* context);
HitOwner* GetHitOwner();
bool IsSelfAndOwnerEnabled();
/// Implement LogicComponent.
/// @{
void DelayedStart() override;
/// @}
/// Attributes.
/// @{
void SetGroupId(const ea::string& value) { groupId_ = value; }
const ea::string& GetGroupId() const { return groupId_; }
/// @}
protected:
virtual void SetupRigidBody(HitManager* hitManager, RigidBody* rigidBody) {}
RigidBody* GetRigidBody() const { return rigidBody_; }
private:
WeakPtr<RigidBody> rigidBody_;
WeakPtr<HitOwner> hitOwner_;
ea::string groupId_;
};
class PLUGIN_CORE_HITMANAGER_API HitTrigger : public HitComponent
{
URHO3D_OBJECT(HitTrigger, HitComponent);
public:
using HitComponent::HitComponent;
static void RegisterObject(Context* context);
bool IsEnabledForDetector(HitDetector* hitDetector);
/// Attributes.
/// @{
void SetVelocityThreshold(float value) { velocityThreshold_ = value; }
float GetVelocityThreshold() const { return velocityThreshold_; }
/// @}
private:
void SetupRigidBody(HitManager* hitManager, RigidBody* rigidBody) override;
float GetRigidBodyVelocity() const;
bool IsVelocityThresholdSatisfied() const;
float velocityThreshold_{};
};
class PLUGIN_CORE_HITMANAGER_API HitDetector : public HitComponent
{
URHO3D_OBJECT(HitDetector, HitComponent);
public:
using HitComponent::HitComponent;
static void RegisterObject(Context* context);
/// Implement LogicComponent.
/// @{
void DelayedStart() override;
/// @}
private:
void SetupRigidBody(HitManager* hitManager, RigidBody* rigidBody) override;
void OnHitStarted(HitTrigger* hitTrigger);
void OnHitStopped(HitTrigger* hitTrigger);
};
} // namespace Urho3D