1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
---|---|
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "Components/BsCAudioSource.h" |
4 | #include "Scene/BsSceneObject.h" |
5 | #include "Utility/BsTime.h" |
6 | #include "Private/RTTI/BsCAudioSourceRTTI.h" |
7 | |
8 | using namespace std::placeholders; |
9 | |
10 | namespace bs |
11 | { |
12 | CAudioSource::CAudioSource() |
13 | { |
14 | setName("AudioSource"); |
15 | |
16 | mNotifyFlags = TCF_Transform; |
17 | } |
18 | |
19 | CAudioSource::CAudioSource(const HSceneObject& parent) |
20 | : Component(parent) |
21 | { |
22 | setName("AudioSource"); |
23 | |
24 | mNotifyFlags = TCF_Transform; |
25 | } |
26 | |
27 | void CAudioSource::setClip(const HAudioClip& clip) |
28 | { |
29 | if (mAudioClip == clip) |
30 | return; |
31 | |
32 | mAudioClip = clip; |
33 | |
34 | if (mInternal != nullptr) |
35 | mInternal->setClip(clip); |
36 | } |
37 | |
38 | void CAudioSource::setVolume(float volume) |
39 | { |
40 | if (mVolume == volume) |
41 | return; |
42 | |
43 | mVolume = volume; |
44 | |
45 | if (mInternal != nullptr) |
46 | mInternal->setVolume(volume); |
47 | } |
48 | |
49 | void CAudioSource::setPitch(float pitch) |
50 | { |
51 | if (mPitch == pitch) |
52 | return; |
53 | |
54 | mPitch = pitch; |
55 | |
56 | if (mInternal != nullptr) |
57 | mInternal->setPitch(pitch); |
58 | } |
59 | |
60 | void CAudioSource::setIsLooping(bool loop) |
61 | { |
62 | if (mLoop == loop) |
63 | return; |
64 | |
65 | mLoop = loop; |
66 | |
67 | if (mInternal != nullptr) |
68 | mInternal->setIsLooping(loop); |
69 | } |
70 | |
71 | void CAudioSource::setPriority(UINT32 priority) |
72 | { |
73 | if (mPriority == priority) |
74 | return; |
75 | |
76 | mPriority = priority; |
77 | |
78 | if (mInternal != nullptr) |
79 | mInternal->setPriority(priority); |
80 | } |
81 | |
82 | void CAudioSource::setMinDistance(float distance) |
83 | { |
84 | if (mMinDistance == distance) |
85 | return; |
86 | |
87 | mMinDistance = distance; |
88 | |
89 | if (mInternal != nullptr) |
90 | mInternal->setMinDistance(distance); |
91 | } |
92 | |
93 | void CAudioSource::setAttenuation(float attenuation) |
94 | { |
95 | if (mAttenuation == attenuation) |
96 | return; |
97 | |
98 | mAttenuation = attenuation; |
99 | |
100 | if (mInternal != nullptr) |
101 | mInternal->setAttenuation(attenuation); |
102 | } |
103 | |
104 | void CAudioSource::play() |
105 | { |
106 | if (mInternal != nullptr) |
107 | mInternal->play(); |
108 | } |
109 | |
110 | void CAudioSource::pause() |
111 | { |
112 | if (mInternal != nullptr) |
113 | mInternal->pause(); |
114 | } |
115 | |
116 | void CAudioSource::stop() |
117 | { |
118 | if (mInternal != nullptr) |
119 | mInternal->stop(); |
120 | } |
121 | |
122 | void CAudioSource::setTime(float position) |
123 | { |
124 | if (mInternal != nullptr) |
125 | mInternal->setTime(position); |
126 | } |
127 | |
128 | float CAudioSource::getTime() const |
129 | { |
130 | if (mInternal != nullptr) |
131 | return mInternal->getTime(); |
132 | |
133 | return 0.0f; |
134 | } |
135 | |
136 | AudioSourceState CAudioSource::getState() const |
137 | { |
138 | if (mInternal != nullptr) |
139 | return mInternal->getState(); |
140 | |
141 | return AudioSourceState::Stopped; |
142 | } |
143 | |
144 | void CAudioSource::onInitialized() |
145 | { |
146 | |
147 | } |
148 | |
149 | void CAudioSource::onDestroyed() |
150 | { |
151 | destroyInternal(); |
152 | } |
153 | |
154 | void CAudioSource::onDisabled() |
155 | { |
156 | destroyInternal(); |
157 | } |
158 | |
159 | void CAudioSource::onEnabled() |
160 | { |
161 | restoreInternal(); |
162 | |
163 | if (mPlayOnStart) |
164 | play(); |
165 | } |
166 | |
167 | void CAudioSource::onTransformChanged(TransformChangedFlags flags) |
168 | { |
169 | if (!SO()->getActive()) |
170 | return; |
171 | |
172 | if ((flags & (TCF_Parent | TCF_Transform)) != 0) |
173 | updateTransform(); |
174 | } |
175 | |
176 | void CAudioSource::update() |
177 | { |
178 | const Vector3 worldPos = SO()->getTransform().getPosition(); |
179 | |
180 | const float frameDelta = gTime().getFrameDelta(); |
181 | if(frameDelta > 0.0f) |
182 | mVelocity = (worldPos - mLastPosition) / frameDelta; |
183 | else |
184 | mVelocity = Vector3::ZERO; |
185 | |
186 | mLastPosition = worldPos; |
187 | } |
188 | |
189 | void CAudioSource::restoreInternal() |
190 | { |
191 | if (mInternal == nullptr) |
192 | mInternal = AudioSource::create(); |
193 | |
194 | // Note: Merge into one call to avoid many virtual function calls |
195 | mInternal->setClip(mAudioClip); |
196 | mInternal->setVolume(mVolume); |
197 | mInternal->setPitch(mPitch); |
198 | mInternal->setIsLooping(mLoop); |
199 | mInternal->setPriority(mPriority); |
200 | mInternal->setMinDistance(mMinDistance); |
201 | mInternal->setAttenuation(mAttenuation); |
202 | |
203 | updateTransform(); |
204 | } |
205 | |
206 | void CAudioSource::destroyInternal() |
207 | { |
208 | // This should release the last reference and destroy the internal listener |
209 | mInternal = nullptr; |
210 | } |
211 | |
212 | void CAudioSource::updateTransform() |
213 | { |
214 | mInternal->setTransform(SO()->getTransform()); |
215 | mInternal->setVelocity(mVelocity); |
216 | } |
217 | |
218 | RTTITypeBase* CAudioSource::getRTTIStatic() |
219 | { |
220 | return CAudioSourceRTTI::instance(); |
221 | } |
222 | |
223 | RTTITypeBase* CAudioSource::getRTTI() const |
224 | { |
225 | return CAudioSource::getRTTIStatic(); |
226 | } |
227 | } |