1 /*
2 * Project: VizKit
3 * Version: 2.3
4
5 * Date: 20090823
6 * File: VisualAsset.cpp
7 *
8 */
9
10 /***************************************************************************
11
12 Copyright (c) 2004-2009 Heiko Wichmann (http://www.imagomat.de/vizkit)
13
14
15 This software is provided 'as-is', without any expressed or implied warranty.
16 In no event will the authors be held liable for any damages
17 arising from the use of this software.
18
19 Permission is granted to anyone to use this software for any purpose,
20 including commercial applications, and to alter it and redistribute it
21 freely, subject to the following restrictions:
22
23 1. The origin of this software must not be misrepresented;
24 you must not claim that you wrote the original software.
25 If you use this software in a product, an acknowledgment
26 in the product documentation would be appreciated
27 but is not required.
28
29 2. Altered source versions must be plainly marked as such,
30 and must not be misrepresented as being the original software.
31
32 3. This notice may not be removed or altered from any source distribution.
33
34 ***************************************************************************/
35
36 #include "VisualAsset.h"
37 #include "VisualItemIdentifier.h"
38 #include "VisualAnimationPackage.h"
39 #include "VisualAnimationQueue.h"
40 #include "VisualErrorHandling.h"
41 #include "VisualImage.h"
42 #include "VisualStageBox.h"
43 #include "VisualGraphics.h"
44 #include "VisualGraphicTypes.h"
45 #include "VisualVertex.h"
46 #include "VisualCamera.h"
47
48
49 using namespace VizKit;
50
51
VisualAsset()52 VisualAsset::VisualAsset() {
53 image = NULL;
54 camera = NULL;
55 stageBox = NULL;
56 defaultVertexChainIdentifier = new VisualItemIdentifier;
57 rotationAngle = 0.0;
58 opacityValue = 1.0;
59 scaleFactor = 1.0;
60 init();
61 }
62
63
~VisualAsset()64 VisualAsset::~VisualAsset() {
65
66 VisualAnimationQueue::removeVisualAnimationsOfAsset(this);
67
68 delete stageBox;
69 delete camera;
70 delete defaultVertexChainIdentifier;
71 if (image != NULL) {
72 delete image;
73 }
74
75 }
76
77
VisualAsset(const VisualAsset & other)78 VisualAsset::VisualAsset(const VisualAsset& other) : VisualObject(other) {
79 copy(other);
80 }
81
82
operator =(const VisualAsset & other)83 VisualAsset& VisualAsset::operator=(const VisualAsset& other) {
84
85 if (this == &other) return *this;
86
87 VisualObject::operator=(other);
88
89 if (this->image != NULL) {
90 delete this->image;
91 }
92 delete this->stageBox;
93 delete this->camera;
94 delete this->defaultVertexChainIdentifier;
95
96 this->copy(other);
97
98 return *this;
99 }
100
101
operator <(const VisualAsset & other) const102 bool VisualAsset::operator<(const VisualAsset& other) const {
103 return (this->VisualObject::getIdentifier() < other.VisualObject::getIdentifier());
104 }
105
106
operator ==(const VisualAsset & other) const107 bool VisualAsset::operator==(const VisualAsset& other) const {
108 return (this->VisualObject::getIdentifier() == other.VisualObject::getIdentifier());
109 }
110
111
operator !=(const VisualAsset & other) const112 bool VisualAsset::operator!=(const VisualAsset& other) const {
113 return !(*this == other);
114 }
115
116
clone(void) const117 VisualAsset* VisualAsset::clone(void) const {
118 return new VisualAsset(*this);
119 }
120
121
copy(const VisualAsset & other)122 void VisualAsset::copy(const VisualAsset& other) {
123
124 if (other.image != NULL) {
125 this->image = new VisualImage(*(other.image));
126 } else {
127 this->image = NULL;
128 }
129 this->camera = new VisualCamera(*(other.camera));
130 this->stageBox = new VisualStageBox(*(other.stageBox));
131
132 this->defaultVertexChainIdentifier = new VisualItemIdentifier();
133 this->rotationAngle = other.rotationAngle;
134 this->opacityValue = other.opacityValue;
135 this->scaleFactor = other.scaleFactor;
136
137 VisualAnimationQueue::copyAnimationsFromAssetToAsset(other, *this);
138 }
139
140
init()141 void VisualAsset::init() {
142 this->camera = new VisualCamera;
143 this->stageBox = new VisualStageBox(this);
144 this->setCamera(*this->camera);
145 }
146
147
getBox() const148 VisualStageBox* VisualAsset::getBox() const {
149 return this->stageBox;
150 }
151
152
setCamera(const VisualCamera & cameraRef)153 void VisualAsset::setCamera(const VisualCamera& cameraRef) {
154 *(this->camera) = cameraRef;
155 this->camera->activate();
156 this->stageBox->setCoordDepth(cameraRef.getDepth());
157 this->stageBox->update();
158 }
159
160
getCamera(void) const161 VisualCamera& VisualAsset::getCamera(void) const {
162 return *(this->camera);
163 }
164
165
getPosition() const166 VisualStagePosition VisualAsset::getPosition() const {
167 return this->stageBox->getVisualStagePosition();
168 }
169
170
setPosition(const VisualStagePosition & aPosition)171 void VisualAsset::setPosition(const VisualStagePosition& aPosition) {
172 this->stageBox->setVisualStagePosition(aPosition);
173 }
174
175
updateCoords()176 void VisualAsset::updateCoords() {
177 this->camera->activate();
178 this->stageBox->update();
179 }
180
181
setImage(const VisualImage & anImage)182 void VisualAsset::setImage(const VisualImage& anImage) {
183 if (this->image != NULL) {
184 delete this->image;
185 this->image = NULL;
186 }
187 this->image = new VisualImage(anImage);
188
189 this->stageBox->setContentPixelWidth(this->image->getWidth());
190 this->stageBox->setContentPixelHeight(this->image->getHeight());
191
192 this->stageBox->initializeVertexChain(*(this->defaultVertexChainIdentifier));
193
194 VisualVertex* aVertex = NULL;
195 aVertex = this->stageBox->createVertex(0.0, 1.0, 0.0, 0.0, 1.0);
196 this->stageBox->addVertexToChain(*(this->defaultVertexChainIdentifier), aVertex);
197
198 aVertex = this->stageBox->createVertex(0.0, 0.0, 0.0, 0.0, 0.0);
199 this->stageBox->addVertexToChain(*(this->defaultVertexChainIdentifier), aVertex);
200
201 aVertex = this->stageBox->createVertex(1.0, 0.0, 0.0, 1.0, 0.0);
202 this->stageBox->addVertexToChain(*(this->defaultVertexChainIdentifier), aVertex);
203
204 aVertex = this->stageBox->createVertex(1.0, 1.0, 0.0, 1.0, 1.0);
205 this->stageBox->addVertexToChain(*(this->defaultVertexChainIdentifier), aVertex);
206 }
207
208
hasImage() const209 bool VisualAsset::hasImage() const {
210 if (this->image == NULL) {
211 return false;
212 }
213 return true;
214 }
215
216
getImage() const217 VisualImage* VisualAsset::getImage() const {
218 return this->image;
219 }
220
221
removeImage()222 void VisualAsset::removeImage() {
223 if (this->image != NULL) {
224 delete this->image;
225 this->image = NULL;
226 this->stageBox->setContentPixelWidth(0);
227 this->stageBox->setContentPixelHeight(0);
228 }
229 }
230
231
draw(const VisualItemIdentifier & vertexChainName) const232 void VisualAsset::draw(const VisualItemIdentifier& vertexChainName) const {
233 VertexChain* aVertexChain = this->stageBox->getVertexChain(vertexChainName);
234 this->doDraw(*aVertexChain);
235 }
236
237
draw() const238 void VisualAsset::draw() const {
239 size_t numberOfVertexChains = this->stageBox->getNumberOfVertexChains();
240 bool defaultVertexChainFound = false;
241 for (size_t i = 0; i < numberOfVertexChains; i++) {
242 if (const_cast<VisualItemIdentifier&>(this->stageBox->getVertexChainIdentifier(i)) != *(this->defaultVertexChainIdentifier)) {
243 VertexChain* defaultVertexChain = this->stageBox->getVertexChain(i);
244 this->doDraw(*defaultVertexChain);
245 } else {
246 defaultVertexChainFound = true;
247 }
248 }
249 if (defaultVertexChainFound == true && numberOfVertexChains == 1) {
250 VertexChain* defaultVertexChain = this->stageBox->getVertexChain(*(this->defaultVertexChainIdentifier));
251 this->doDraw(*defaultVertexChain);
252 }
253 }
254
255
doDraw(const VertexChain & aVertexChain) const256 void VisualAsset::doDraw(const VertexChain& aVertexChain) const {
257 this->camera->activate();
258 this->stageBox->updateIfNeeded();
259 VisualGraphics* theVisualGraphics = VisualGraphics::getInstance();
260 theVisualGraphics->rotateMatrix(this->rotationAngle, 0.0, 1.0, 0.0);
261 if (this->image != NULL) {
262 this->image->draw(&aVertexChain, this->stageBox->getDebugMode());
263 if (this->stageBox->getDebugMode() == true) {
264 theVisualGraphics->drawVertexChain(aVertexChain);
265 }
266 } else {
267 theVisualGraphics->drawVertexChain(aVertexChain);
268 }
269
270 if (this->stageBox->getDebugMode() == true) {
271 theVisualGraphics->drawDebugVertexChain(aVertexChain, *(this->camera));
272 this->drawBoxOutline();
273 }
274 }
275
276
drawBoxOutline() const277 void VisualAsset::drawBoxOutline() const {
278 VertexColor yellow;
279 yellow.r = 1.0;
280 yellow.g = 1.0;
281 yellow.b = 0.0;
282 yellow.a = 1.0;
283 Coord coordPoint;
284 VisualVertex* aVertex = NULL;
285 // front
286 VertexChain* frontBoxChain = new VertexChain;
287 coordPoint.x = this->stageBox->getLeftCoord();
288 coordPoint.y = this->stageBox->getTopCoord();
289 coordPoint.z = this->stageBox->getFrontPosition();
290 aVertex = new VisualVertex(coordPoint, yellow);
291 frontBoxChain->push_back(aVertex);
292 coordPoint.x = this->stageBox->getRightCoord();
293 coordPoint.y = this->stageBox->getTopCoord();
294 coordPoint.z = this->stageBox->getFrontPosition();
295 aVertex = new VisualVertex(coordPoint, yellow);
296 frontBoxChain->push_back(aVertex);
297 coordPoint.x = this->stageBox->getRightCoord();
298 coordPoint.y = this->stageBox->getBottomCoord();
299 coordPoint.z = this->stageBox->getFrontPosition();
300 aVertex = new VisualVertex(coordPoint, yellow);
301 frontBoxChain->push_back(aVertex);
302 coordPoint.x = this->stageBox->getLeftCoord();
303 coordPoint.y = this->stageBox->getBottomCoord();
304 coordPoint.z = this->stageBox->getFrontPosition();
305 aVertex = new VisualVertex(coordPoint, yellow);
306 frontBoxChain->push_back(aVertex);
307 // back
308 VertexChain* backBoxChain = new VertexChain;
309 coordPoint.x = this->stageBox->getLeftCoord();
310 coordPoint.y = this->stageBox->getTopCoord();
311 coordPoint.z = this->stageBox->getBackPosition();
312 aVertex = new VisualVertex(coordPoint, yellow);
313 backBoxChain->push_back(aVertex);
314 coordPoint.x = this->stageBox->getRightCoord();
315 coordPoint.y = this->stageBox->getTopCoord();
316 coordPoint.z = this->stageBox->getBackPosition();
317 aVertex = new VisualVertex(coordPoint, yellow);
318 backBoxChain->push_back(aVertex);
319 coordPoint.x = this->stageBox->getRightCoord();
320 coordPoint.y = this->stageBox->getBottomCoord();
321 coordPoint.z = this->stageBox->getBackPosition();
322 aVertex = new VisualVertex(coordPoint, yellow);
323 backBoxChain->push_back(aVertex);
324 coordPoint.x = this->stageBox->getLeftCoord();
325 coordPoint.y = this->stageBox->getBottomCoord();
326 coordPoint.z = this->stageBox->getBackPosition();
327 aVertex = new VisualVertex(coordPoint, yellow);
328 backBoxChain->push_back(aVertex);
329 // left
330 VertexChain* leftBoxChain = new VertexChain;
331 coordPoint.x = this->stageBox->getLeftCoord();
332 coordPoint.y = this->stageBox->getTopCoord();
333 coordPoint.z = this->stageBox->getFrontPosition();
334 aVertex = new VisualVertex(coordPoint, yellow);
335 leftBoxChain->push_back(aVertex);
336 coordPoint.x = this->stageBox->getLeftCoord();
337 coordPoint.y = this->stageBox->getBottomCoord();
338 coordPoint.z = this->stageBox->getFrontPosition();
339 aVertex = new VisualVertex(coordPoint, yellow);
340 leftBoxChain->push_back(aVertex);
341 coordPoint.x = this->stageBox->getLeftCoord();
342 coordPoint.y = this->stageBox->getBottomCoord();
343 coordPoint.z = this->stageBox->getBackPosition();
344 aVertex = new VisualVertex(coordPoint, yellow);
345 leftBoxChain->push_back(aVertex);
346 coordPoint.x = this->stageBox->getLeftCoord();
347 coordPoint.y = this->stageBox->getTopCoord();
348 coordPoint.z = this->stageBox->getBackPosition();
349 aVertex = new VisualVertex(coordPoint, yellow);
350 leftBoxChain->push_back(aVertex);
351 // right
352 VertexChain* rightBoxChain = new VertexChain;
353 coordPoint.x = this->stageBox->getRightCoord();
354 coordPoint.y = this->stageBox->getTopCoord();
355 coordPoint.z = this->stageBox->getFrontPosition();
356 aVertex = new VisualVertex(coordPoint, yellow);
357 rightBoxChain->push_back(aVertex);
358 coordPoint.x = this->stageBox->getRightCoord();
359 coordPoint.y = this->stageBox->getBottomCoord();
360 coordPoint.z = this->stageBox->getFrontPosition();
361 aVertex = new VisualVertex(coordPoint, yellow);
362 rightBoxChain->push_back(aVertex);
363 coordPoint.x = this->stageBox->getRightCoord();
364 coordPoint.y = this->stageBox->getBottomCoord();
365 coordPoint.z = this->stageBox->getBackPosition();
366 aVertex = new VisualVertex(coordPoint, yellow);
367 rightBoxChain->push_back(aVertex);
368 coordPoint.x = this->stageBox->getRightCoord();
369 coordPoint.y = this->stageBox->getTopCoord();
370 coordPoint.z = this->stageBox->getBackPosition();
371 aVertex = new VisualVertex(coordPoint, yellow);
372 rightBoxChain->push_back(aVertex);
373 // top
374 VertexChain* topBoxChain = new VertexChain;
375 coordPoint.x = this->stageBox->getRightCoord();
376 coordPoint.y = this->stageBox->getTopCoord();
377 coordPoint.z = this->stageBox->getFrontPosition();
378 aVertex = new VisualVertex(coordPoint, yellow);
379 topBoxChain->push_back(aVertex);
380 coordPoint.x = this->stageBox->getRightCoord();
381 coordPoint.y = this->stageBox->getTopCoord();
382 coordPoint.z = this->stageBox->getBackPosition();
383 aVertex = new VisualVertex(coordPoint, yellow);
384 topBoxChain->push_back(aVertex);
385 coordPoint.x = this->stageBox->getLeftCoord();
386 coordPoint.y = this->stageBox->getTopCoord();
387 coordPoint.z = this->stageBox->getBackPosition();
388 aVertex = new VisualVertex(coordPoint, yellow);
389 topBoxChain->push_back(aVertex);
390 coordPoint.x = this->stageBox->getLeftCoord();
391 coordPoint.y = this->stageBox->getTopCoord();
392 coordPoint.z = this->stageBox->getFrontPosition();
393 aVertex = new VisualVertex(coordPoint, yellow);
394 topBoxChain->push_back(aVertex);
395 // bottom
396 VertexChain* bottomBoxChain = new VertexChain;
397 coordPoint.x = this->stageBox->getRightCoord();
398 coordPoint.y = this->stageBox->getBottomCoord();
399 coordPoint.z = this->stageBox->getFrontPosition();
400 aVertex = new VisualVertex(coordPoint, yellow);
401 bottomBoxChain->push_back(aVertex);
402 coordPoint.x = this->stageBox->getRightCoord();
403 coordPoint.y = this->stageBox->getBottomCoord();
404 coordPoint.z = this->stageBox->getBackPosition();
405 aVertex = new VisualVertex(coordPoint, yellow);
406 bottomBoxChain->push_back(aVertex);
407 coordPoint.x = this->stageBox->getLeftCoord();
408 coordPoint.y = this->stageBox->getBottomCoord();
409 coordPoint.z = this->stageBox->getBackPosition();
410 aVertex = new VisualVertex(coordPoint, yellow);
411 bottomBoxChain->push_back(aVertex);
412 coordPoint.x = this->stageBox->getLeftCoord();
413 coordPoint.y = this->stageBox->getBottomCoord();
414 coordPoint.z = this->stageBox->getFrontPosition();
415 aVertex = new VisualVertex(coordPoint, yellow);
416 bottomBoxChain->push_back(aVertex);
417
418 VisualGraphics* theVisualGraphics = VisualGraphics::getInstance();
419 theVisualGraphics->drawVertexChain(*frontBoxChain);
420 theVisualGraphics->drawVertexChain(*backBoxChain);
421 theVisualGraphics->drawVertexChain(*leftBoxChain);
422 theVisualGraphics->drawVertexChain(*rightBoxChain);
423 theVisualGraphics->drawVertexChain(*topBoxChain);
424 theVisualGraphics->drawVertexChain(*bottomBoxChain);
425
426 for (VertexChainIterator chainIt = frontBoxChain->begin(); chainIt != frontBoxChain->end(); chainIt++) {
427 delete *chainIt;
428 chainIt = frontBoxChain->erase(chainIt);
429 }
430 delete frontBoxChain;
431 for (VertexChainIterator chainIt = backBoxChain->begin(); chainIt != backBoxChain->end(); chainIt++) {
432 delete *chainIt;
433 chainIt = backBoxChain->erase(chainIt);
434 }
435 delete backBoxChain;
436 for (VertexChainIterator chainIt = leftBoxChain->begin(); chainIt != leftBoxChain->end(); chainIt++) {
437 delete *chainIt;
438 chainIt = leftBoxChain->erase(chainIt);
439 }
440 delete leftBoxChain;
441 for (VertexChainIterator chainIt = rightBoxChain->begin(); chainIt != rightBoxChain->end(); chainIt++) {
442 delete *chainIt;
443 chainIt = rightBoxChain->erase(chainIt);
444 }
445 delete rightBoxChain;
446 for (VertexChainIterator chainIt = topBoxChain->begin(); chainIt != topBoxChain->end(); chainIt++) {
447 delete *chainIt;
448 chainIt = topBoxChain->erase(chainIt);
449 }
450 delete topBoxChain;
451 for (VertexChainIterator chainIt = bottomBoxChain->begin(); chainIt != bottomBoxChain->end(); chainIt++) {
452 delete *chainIt;
453 chainIt = bottomBoxChain->erase(chainIt);
454 }
455 delete bottomBoxChain;
456 }
457
458
setScaleFactor(double aScaleFactor)459 void VisualAsset::setScaleFactor(double aScaleFactor) {
460 this->scaleFactor = aScaleFactor;
461 this->stageBox->setScaleFactor(aScaleFactor);
462 }
463
464
getScaleFactor() const465 double VisualAsset::getScaleFactor() const {
466 return this->scaleFactor;
467 }
468
469
setOpacityValue(double anOpacityValue)470 void VisualAsset::setOpacityValue(double anOpacityValue) {
471 this->opacityValue = anOpacityValue;
472 this->stageBox->setOpacityValue(anOpacityValue);
473 }
474
475
getOpacityValue() const476 double VisualAsset::getOpacityValue() const {
477 return this->opacityValue;
478 }
479
480
setRotationAngle(double aRotationAngle)481 void VisualAsset::setRotationAngle(double aRotationAngle) {
482 this->rotationAngle = aRotationAngle;
483 }
484
485
getRotationAngle() const486 double VisualAsset::getRotationAngle() const {
487 return this->rotationAngle;
488 }
489
490
setDebugMode(bool requestedDebugMode)491 void VisualAsset::setDebugMode(bool requestedDebugMode) {
492 this->stageBox->setDebugMode(requestedDebugMode);
493 }
494
495
getDebugMode(void)496 bool VisualAsset::getDebugMode(void) {
497 return this->stageBox->getDebugMode();
498 }
499
500
addAnimation(VisualAnimationComponent & anAnimation)501 void VisualAsset::addAnimation(VisualAnimationComponent& anAnimation) {
502 anAnimation.preparePriorToAddingToAsset(*this);
503 VisualAnimationQueue::push(anAnimation, this->VisualObject::getIdentifier());
504 }
505
506
removeAnimations(AnimatedProperty anAnimatedProperty)507 void VisualAsset::removeAnimations(AnimatedProperty anAnimatedProperty) {
508 VisualAnimationQueue::removeVisualAnimationsWithOwnerIdentifier(this->VisualObject::getIdentifier(), anAnimatedProperty);
509 }
510
511
getAnimation(const AnimatedProperty & anAnimatedProperty) const512 const VisualAnimationComponent* const VisualAsset::getAnimation(const AnimatedProperty& anAnimatedProperty) const {
513 return VisualAnimationQueue::getFirstVisualAnimation(this->VisualObject::getIdentifier(), anAnimatedProperty);
514 }
515
516
getCurrentAnimationValueOfProperty(const AnimatedProperty & anAnimatedProperty) const517 double VisualAsset::getCurrentAnimationValueOfProperty(const AnimatedProperty& anAnimatedProperty) const {
518 double currentValue = 0.0;
519
520 switch (anAnimatedProperty) {
521 case kAnimatedSize:
522 currentValue = this->scaleFactor;
523 break;
524 case kAnimatedOpacity:
525 currentValue = this->opacityValue;
526 break;
527 case kAnimatedRotation:
528 currentValue = (this->rotationAngle / 360.0);
529 break;
530 case kUndefinedAnimatedProperty:
531 case kCustomAnimatedProperty:
532 // unknown
533 break;
534 default:
535 char errLog[256];
536 sprintf(errLog, "unknown AnimatedProperty %d in file: %s (line: %d) [%s])", anAnimatedProperty, __FILE__, __LINE__, __FUNCTION__);
537 writeLog(errLog);
538 }
539
540 return currentValue;
541
542 }
543
544
updateLocation(double currPosition)545 void VisualAsset::updateLocation(double currPosition) {
546 VisualStagePosition position = VisualStageBox::tweenVisualStagePosition(this->startValueVisualStagePosition, this->stopValueVisualStagePosition, currPosition, *this->stageBox);
547 this->setPosition(position);
548 }
549
550
getCurrentAnimationValueForAnimatedLocation(const VisualStagePosition & startPosition,const VisualStagePosition & stopPosition) const551 double VisualAsset::getCurrentAnimationValueForAnimatedLocation(const VisualStagePosition& startPosition, const VisualStagePosition& stopPosition) const {
552 VisualStagePosition currStagePosition = this->stageBox->getVisualStagePosition();
553 return 0.0;
554 }
555
556
setStartValueVisualStagePosition(const VisualStagePosition & position)557 void VisualAsset::setStartValueVisualStagePosition(const VisualStagePosition& position) {
558 this->startValueVisualStagePosition = position;
559 }
560
561
setStopValueVisualStagePosition(const VisualStagePosition & position)562 void VisualAsset::setStopValueVisualStagePosition(const VisualStagePosition& position) {
563 this->stopValueVisualStagePosition = position;
564 }
565
566
animateOpacity(double currentPosition,void * userData)567 void VisualAsset::animateOpacity(double currentPosition, void* userData) {
568 if (reinterpret_cast<VisualAsset*>(userData)->stageBox->getDebugMode() == true) {
569 printf("VisualAsset::animateOpacity: %f\n", currentPosition);
570 }
571 reinterpret_cast<VisualAsset*>(userData)->setOpacityValue(currentPosition);
572 }
573
574
animateRotation(double currentPosition,void * userData)575 void VisualAsset::animateRotation(double currentPosition, void* userData) {
576 double rotationAngle = currentPosition * 360.0;
577 reinterpret_cast<VisualAsset*>(userData)->setRotationAngle(rotationAngle);
578 }
579
580
animateScaleFactor(double currentPosition,void * userData)581 void VisualAsset::animateScaleFactor(double currentPosition, void* userData) {
582 reinterpret_cast<VisualAsset*>(userData)->setScaleFactor(currentPosition);
583 }
584
585
animateLocation(double currentPosition,void * userData)586 void VisualAsset::animateLocation(double currentPosition, void* userData) {
587 reinterpret_cast<VisualAsset*>(userData)->updateLocation(currentPosition);
588 }
589