| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552 |
- #include "Actor.h"
- #include "core/Texture.h"
- #include "res/ResAnim.h"
- #include "Stage.h"
- #include "Clock.h"
- #include "Tween.h"
- #include "math/AffineTransform.h"
- #include <sstream>
- #include <typeinfo>
- #define _USE_MATH_DEFINES
- #include <math.h>
- #include "utils/stringUtils.h"
- #include "RenderState.h"
- #include <stdio.h>
- #include "Serialize.h"
- #include "Material.h"
- //#include ""
- namespace oxygine
- {
- CREATE_COPYCLONE_NEW(Actor);
- std::string div(const std::string& val, const Color& color)
- {
- char str[255];
- safe_sprintf(str, "<div c='%s'>%s</div>", color2hex(color).c_str(), val.c_str());
- return str;
- }
- Actor::Actor():
- _extendedIsOn(0),
- _zOrder(0),
- _scale(1, 1),
- _rotation(0),
- _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_childrenRelative | flag_fastTransform),
- _parent(0),
- _alpha(255),
- _pressed(0),
- _overred(0),
- _stage(0),
- _material(0)
- {
- _transform.identity();
- _transformInvert.identity();
- }
- void Actor::copyFrom(const Actor& src, cloneOptions opt)
- {
- _stage = 0;
- _pos = src._pos;
- _extendedIsOn = src._extendedIsOn;
- _size = src._size;
- _zOrder = src._zOrder;
- _anchor = src._anchor;
- _scale = src._scale;
- _rotation = src._rotation;
- _flags = src._flags;
- _parent = 0;
- _alpha = src._alpha;
- _overred = 0;
- _pressed = 0;
- _transform = src._transform;
- _transformInvert = src._transformInvert;
- if (!(opt & cloneOptionsDoNotCloneClildren))
- {
- spActor child = src.getFirstChild();
- while (child)
- {
- spActor copy = child->clone(opt);
- addChild(copy);
- child = child->getNextSibling();
- }
- }
- if (opt & cloneOptionsResetTransform)
- {
- setPosition(0, 0);
- setRotation(0);
- setScale(1);
- }
- if (src.__getName())
- setName(src.getName());
- }
- Actor::~Actor()
- {
- //printf("Actor::~Actor %s\n", getName().c_str());
- removeTweens();
- removeChildren();
- if (_getStage())
- {
- //OX_ASSERT(_getStage()->hasEventListeners(this) == false);
- //_getStage()->removeEventListeners(this);
- }
- }
- Stage* Actor::_getStage()
- {
- return _stage;
- }
- void Actor::added2stage(Stage* stage)
- {
- OX_ASSERT(_stage == 0);
- _stage = stage;
- onAdded2Stage();
- spActor actor = _children._first;
- while (actor)
- {
- spActor next = actor->_next;
- actor->added2stage(stage);
- actor = next;
- }
- }
- void Actor::removedFromStage()
- {
- OX_ASSERT(_stage);
- onRemovedFromStage();
- _stage->removeEventListeners(this);
- _stage = 0;
- _pressed = 0;
- _overred = 0;
- spActor actor = _children._first;
- while (actor)
- {
- spActor next = actor->_next;
- actor->removedFromStage();
- actor = next;
- }
- }
- std::string Actor::dump(const dumpOptions& opt) const
- {
- std::stringstream stream;
- stream << "{" << typeid(*this).name() << "}";
- //stream << this;
- #if DYNAMIC_OBJECT_NAME
- if (__name && __name->size())
- stream << " name='" << div(*__name, Color::Red) << "'";
- #else
- if (__name.size())
- stream << " name='" << div(__name, Color::Red) << "'";
- #endif
- stream << " id='" << getObjectID() << "'";
- stream << "\n";
- if (!getVisible())
- stream << " invisible";
- if (getAlpha() != 255)
- stream << " alpha=" << (int)getAlpha();
- if (getWidth() || getHeight())
- stream << " size=(" << getWidth() << "," << getHeight() << ")";
- if (getPriority())
- stream << " priority=" << getPriority();
- if (_extendedIsOn)
- stream << " extendedClickArea=" << (int)_extendedIsOn;
- if (getX() != 0.0f || getY() != 0.0f)
- stream << " pos=(" << getX() << "," << getY() << ")";
- if (getScaleX() != 1.0f || getScaleY() != 1.0f)
- stream << " scale=(" << getScaleX() << "," << getScaleY() << ")";
- if (getAnchor().x || getAnchor().y)
- stream << " anchor=(" << getAnchor().x << "," << getAnchor().y << ")";
- if (getRotation() != 0.0f)
- stream << " rot=" << getRotation() / MATH_PI * 360.0f << "";
- int tweensCount = 0;
- spTween t = _tweens._first;
- while (t)
- {
- t = t->getNextSibling();
- tweensCount++;
- }
- if (tweensCount)
- stream << " tweens=" << tweensCount << "";
- if (getListenersCount())
- stream << " listeners=" << (int)getListenersCount() << "";
- /*
- int handlersCount = 0;
- spEventHandler eh = _eventHandlers._first;
- while (eh)
- {
- eh = eh->getNextSibling();
- handlersCount++;
- }
- if (handlersCount)
- stream << " handlers=" << handlersCount << "";
- */
- if (getClock())
- stream << " " << getClock()->dump();
- return stream.str();
- }
- pointer_index Actor::getPressed() const
- {
- return _pressed;
- }
- pointer_index Actor::getOvered() const
- {
- return _overred;
- }
- void Actor::setNotPressed()
- {
- _pressed = 0;
- _getStage()->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
- updateState();
- }
- void Actor::_onGlobalTouchUpEvent(Event* ev)
- {
- TouchEvent* te = safeCast<TouchEvent*>(ev);
- if (te->index != _pressed)
- return;
- setNotPressed();
- TouchEvent up = *te;
- up.bubbles = false;
- up.localPosition = convert_global2local(this, _getStage(), te->localPosition);
- dispatchEvent(&up);
- }
- void Actor::_onGlobalTouchMoveEvent(Event* ev)
- {
- TouchEvent* te = safeCast<TouchEvent*>(ev);
- if (te->index != _overred)
- return;
- if (isDescendant(safeCast<Actor*>(ev->target.get())))
- return;
- _overred = 0;
- _getStage()->removeEventListener(TouchEvent::MOVE, CLOSURE(this, &Actor::_onGlobalTouchMoveEvent));
- TouchEvent up = *te;
- up.type = TouchEvent::OUT;
- up.bubbles = false;
- up.localPosition = convert_global2local(this, _getStage(), te->localPosition);
- dispatchEvent(&up);
- //log::messageln("out %s", getName().c_str());
- updateState();
- }
- void Actor::dispatchEvent(Event* event)
- {
- if (event->type == TouchEvent::MOVE)
- {
- TouchEvent* te = safeCast<TouchEvent*>(event);
- if (!_overred)
- {
- _overred = te->index;
- updateState();
- TouchEvent over = *te;
- over.type = TouchEvent::OVER;
- over.bubbles = false;
- dispatchEvent(&over);
- _getStage()->addEventListener(TouchEvent::MOVE, CLOSURE(this, &Actor::_onGlobalTouchMoveEvent));
- }
- }
- if (event->type == TouchEvent::TOUCH_DOWN)
- {
- TouchEvent* te = safeCast<TouchEvent*>(event);
- if (!_pressed)
- {
- _pressed = te->index;
- _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
- updateState();
- }
- }
- TouchEvent click(0);
- if (event->type == TouchEvent::TOUCH_UP)
- {
- TouchEvent* te = safeCast<TouchEvent*>(event);
- if (_pressed == te->index)
- {
- click = *te;
- click.type = TouchEvent::CLICK;
- click.bubbles = false;
- //will be dispatched later after UP
- setNotPressed();
- }
- }
- EventDispatcher::dispatchEvent(event);
- if (!event->stopsImmediatePropagation && event->bubbles && !event->stopsPropagation)
- {
- if (_parent)
- {
- if (TouchEvent::isTouchEvent(event->type))
- {
- TouchEvent* me = safeCast<TouchEvent*>(event);
- me->localPosition = local2global(me->localPosition);
- }
- event->phase = Event::phase_bubbling;
- event->currentTarget = 0;
- _parent->dispatchEvent(event);
- }
- }
- if (click.type)
- {
- //send click event at the end after TOUCH_UP event
- dispatchEvent(&click);
- }
- }
- void Actor::handleEvent(Event* event)
- {
- bool touchEvent = TouchEvent::isTouchEvent(event->type);
- if (touchEvent)
- {
- if (!(_flags & flag_visible) || getAlpha() == 0)
- return;
- }
- Vector2 originalLocalPos;
- if (touchEvent)
- {
- TouchEvent* me = safeCast<TouchEvent*>(event);
- originalLocalPos = me->localPosition;
- me->localPosition = global2local(originalLocalPos);
- }
- event->phase = Event::phase_capturing;
- spActor actor = _children._last;
- while (actor)
- {
- spActor prev = actor->_prev;
- if (!touchEvent || (_flags & flag_touchChildrenEnabled))
- actor->handleEvent(event);
- //if (event->target)
- // break;
- actor = prev;
- }
- if (touchEvent)
- {
- TouchEvent* me = safeCast<TouchEvent*>(event);
- if (!event->target)
- {
- if ((_flags & flag_touchEnabled) && isOn(me->localPosition))
- {
- event->phase = Event::phase_target;
- event->target = this;
- me->position = me->localPosition;
- dispatchEvent(event);
- }
- }
- me->localPosition = originalLocalPos;
- }
- }
- void Actor::setAnchor(const Vector2& anchor)
- {
- _anchor = anchor;
- _flags &= ~flag_anchorInPixels;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setAnchor(float ax, float ay)
- {
- setAnchor(Vector2(ax, ay));
- }
- void Actor::setAnchorInPixels(const Vector2& anchor)
- {
- _anchor = anchor;
- _flags |= flag_anchorInPixels;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setPosition(const Vector2& pos)
- {
- if (_pos == pos)
- return;
- _pos = pos;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setPosition(float x, float y)
- {
- setPosition(Vector2(x, y));
- }
- void Actor::setX(float x)
- {
- _pos.x = x;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setY(float y)
- {
- _pos.y = y;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setAnchorX(float x)
- {
- _anchor.x = x;
- _flags &= ~flag_anchorInPixels;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setAnchorY(float y)
- {
- _anchor.y = y;
- _flags &= ~flag_anchorInPixels;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setTransform(const AffineTransform& tr)
- {
- _transform = tr;
- _flags &= ~flag_transformDirty;
- _flags &= ~flag_fastTransform;
- _flags |= flag_transformInvertDirty;
- }
- void Actor::setPriority(short zorder)
- {
- if (_zOrder == zorder) // fixed by Evgeniy Golovin
- return;
- _zOrder = zorder;
- if (_parent)
- {
- Actor* parent = _parent;
- addRef();
- parent->removeChild(this);
- parent->addChild(this);
- releaseRef();
- }
- }
- void Actor::setScale(float scale)
- {
- setScale(Vector2(scale, scale));
- }
- void Actor::setScale(const Vector2& scale)
- {
- if (_scale == scale)
- return;
- _scale = scale;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- _flags &= ~flag_fastTransform;
- }
- void Actor::setScale(float scaleX, float scaleY)
- {
- setScale(Vector2(scaleX, scaleY));
- }
- void Actor::setScaleX(float sx)
- {
- if (_scale.x == sx)
- return;
- _scale.x = sx;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- _flags &= ~flag_fastTransform;
- }
- void Actor::setScaleY(float sy)
- {
- if (_scale.y == sy)
- return;
- _scale.y = sy;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- _flags &= ~flag_fastTransform;
- }
- void Actor::setRotation(float rotation)
- {
- if (_rotation == rotation)
- return;
- _rotation = rotation;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- _flags &= ~flag_fastTransform;
- }
- void Actor::setRotationDegrees(float degr)
- {
- float rad = degr * MATH_PI / 180.0f;
- setRotation(rad);
- }
- void Actor::sizeChanged(const Vector2& size)
- {
- }
- void Actor::_setSize(const Vector2& size)
- {
- _size = size;
- _flags |= flag_transformDirty | flag_transformInvertDirty;
- }
- void Actor::setSize(const Vector2& size)
- {
- _setSize(size);
- sizeChanged(size);
- }
- void Actor::setSize(float w, float h)
- {
- setSize(Vector2(w, h));
- }
- void Actor::setWidth(float w)
- {
- setSize(Vector2(w, _size.y));
- }
- void Actor::setHeight(float h)
- {
- setSize(Vector2(_size.x, h));
- }
- void Actor::setClock(spClock clock)
- {
- _clock = clock;
- }
- void Actor::setAlpha(unsigned char alpha)
- {
- _alpha = alpha;
- }
- void Actor::setMaterial(Material* mat)
- {
- _material = mat;
- }
- const Transform& Actor::getTransform() const
- {
- updateTransform();
- return _transform;
- }
- const Transform& Actor::getTransformInvert() const
- {
- if (_flags & flag_transformInvertDirty)
- {
- _flags &= ~flag_transformInvertDirty;
- _transformInvert = getTransform();
- _transformInvert.invert();
- }
- return _transformInvert;
- }
- float Actor::getWidth() const
- {
- return _size.x;
- }
- float Actor::getHeight() const
- {
- return _size.y;
- }
- unsigned char Actor::getAlpha() const
- {
- return _alpha;
- }
- const spClock& Actor::getClock() const
- {
- return _clock;
- }
- void Actor::updateTransform() const
- {
- if (!(_flags & flag_transformDirty))
- return;
- AffineTransform tr;
- if (_flags & flag_fastTransform)
- {
- tr = AffineTransform(1, 0, 0, 1, _pos.x, _pos.y);
- }
- else
- {
- float c = 1.0f;
- float s = 0.0f;
- if (_rotation)
- {
- c = cosf(_rotation);
- s = sinf(_rotation);
- }
- tr = AffineTransform(
- c * _scale.x, s * _scale.x,
- -s * _scale.y, c * _scale.y,
- _pos.x, _pos.y);
- }
- if (_flags & flag_childrenRelative)
- {
- Vector2 offset;
- if (_flags & flag_anchorInPixels)
- {
- offset.x = -_anchor.x;
- offset.y = -_anchor.y;
- }
- else
- {
- offset.x = -float(_size.x * _anchor.x);
- offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality)
- }
- tr.translate(offset);
- }
- _transform = tr;
- _flags &= ~flag_transformDirty;
- }
- bool Actor::isOn(const Vector2& localPosition)
- {
- RectF r = getDestRect();
- r.expand(Vector2(_extendedIsOn, _extendedIsOn), Vector2(_extendedIsOn, _extendedIsOn));
- if (r.pointIn(localPosition))
- {
- return true;
- }
- return false;
- }
- bool Actor::isDescendant(spActor actor)
- {
- Actor* act = actor.get();
- while (act)
- {
- if (act == this)
- return true;
- act = act->getParent();
- }
- return false;
- }
- Actor* Actor::getDescendant(const std::string& name, error_policy ep)
- {
- if (isName(name.c_str()))
- return this;
- Actor* actor = _getDescendant(name);
- if (!actor)
- {
- handleErrorPolicy(ep, "can't find descendant: %s", name.c_str());
- }
- return actor;
- }
- Actor* Actor::_getDescendant(const std::string& name)
- {
- Actor* child = _children._first.get();
- while (child)
- {
- if (child->isName(name.c_str()))
- return child;
- child = child->getNextSibling().get();
- }
- child = _children._first.get();
- while (child)
- {
- Actor* des = child->_getDescendant(name);
- if (des)
- return des;
- child = child->getNextSibling().get();
- }
- return 0;
- }
- spActor Actor::getChild(const std::string& name, error_policy ep) const
- {
- spActor actor = _children._first;
- while (actor)
- {
- if (actor->isName(name))
- return actor;
- actor = actor->_next;
- }
- handleErrorPolicy(ep, "can't find child: %s", name.c_str());
- return 0;
- }
- void Actor::setParent(Actor* actor, Actor* parent)
- {
- actor->_parent = parent;
- if (parent && parent->_getStage())
- actor->added2stage(parent->_getStage());
- else
- {
- if (actor->_getStage())
- actor->removedFromStage();
- }
- }
- void Actor::insertChildAfter(spActor actor, spActor insertAfter)
- {
- OX_ASSERT(actor);
- if (!actor)
- return;
- if (insertAfter)
- {
- OX_ASSERT(insertAfter->getParent() == this);
- }
- actor->detach();
- /*
- OX_ASSERT(actor->getParent() == 0);
- if (actor->getParent())
- return;
- */
- if (insertAfter)
- _children.insert_after(actor, insertAfter);
- else
- _children.append(actor);
- setParent(actor.get(), this);
- }
- void Actor::insertChildBefore(spActor actor, spActor insertBefore)
- {
- OX_ASSERT(actor);
- if (!actor)
- return;
- if (insertBefore)
- {
- OX_ASSERT(insertBefore->getParent() == this);
- }
- actor->detach();
- /*
- OX_ASSERT(actor->getParent() == 0);
- if (actor->getParent())
- return;
- */
- if (insertBefore)
- _children.insert_before(actor, insertBefore);
- else
- _children.prepend(actor);
- setParent(actor.get(), this);
- }
- void Actor::attachTo(spActor parent)
- {
- OX_ASSERT(parent != this);
- attachTo(parent.get());
- }
- void Actor::attachTo(Actor* parent)
- {
- OX_ASSERT(parent != this);
- OX_ASSERT(parent);
- if (!parent)
- return;
- parent->addChild(this);
- }
- void Actor::addChild(Actor* actor)
- {
- OX_ASSERT(actor);
- if (!actor)
- return;
- OX_ASSERT(actor != this);
- actor->detach();
- //assert(actor->_parent == 0 && "child should be removed from previous parent");
- int z = actor->getPriority();
- spActor sibling = _children._last;
- //try to insert at the end of list first
- if (sibling && sibling->getPriority() > z)
- {
- sibling = sibling->getPrevSibling();
- while (sibling)
- {
- if (sibling->getPriority() <= z)
- break;
- sibling = sibling->getPrevSibling();
- }
- }
- if (sibling)
- insertChildAfter(actor, sibling);
- else
- insertChildBefore(actor, 0);
- }
- void Actor::prependChild(spActor actor)
- {
- prependChild(actor.get());
- }
- void Actor::prependChild(Actor* actor)
- {
- if (getFirstChild())
- insertChildBefore(actor, getFirstChild());
- else
- addChild(actor);
- }
- void Actor::addChild(spActor actor)
- {
- addChild(actor.get());
- }
- void Actor::removeChild(spActor actor)
- {
- OX_ASSERT(actor);
- if (actor)
- {
- OX_ASSERT(actor->_parent == this);
- if (actor->_parent == this)
- {
- setParent(actor.get(), 0);
- _children.remove(actor);
- }
- }
- }
- void Actor::removeChildren()
- {
- spActor child = getFirstChild();
- while (child)
- {
- spActor copy = child;
- child = child->getNextSibling();
- removeChild(copy);
- }
- }
- Actor* Actor::detach()
- {
- Actor* parent = getParent();
- if (parent)
- parent->removeChild(this);
- return parent;
- }
- void Actor::internalUpdate(const UpdateState& us)
- {
- spTween tween = _tweens._first;
- while (tween)
- {
- spTween tweenNext = tween->getNextSibling();
- if (tween->getParentList())
- tween->update(*this, us);
- if (tween->isDone() && tween->getParentList())
- _tweens.remove(tween);
- tween = tweenNext;
- }
- if (_cbDoUpdate)
- _cbDoUpdate(us);
- doUpdate(us);
- spActor actor = _children._first;
- while (actor)
- {
- spActor next = actor->_next;
- if (actor->getParent())
- actor->update(us);
- if (!next)
- {
- //OX_ASSERT(actor == _children._last);
- }
- actor = next;
- }
- }
- void Actor::update(const UpdateState& parentUS)
- {
- UpdateState us = parentUS;
- if (_clock)
- {
- us.iteration = 0;
- _clock->update();
- timeMS dt = _clock->doTick();
- while (dt > 0)
- {
- us.dt = dt;
- us.time = _clock->getTime();
- internalUpdate(us);
- dt = _clock->doTick();
- us.iteration += 1;
- }
- }
- else
- {
- internalUpdate(us);
- }
- }
- void Actor::doUpdate(const UpdateState& us)
- {
- }
- Vector2 Actor::global2local(const Vector2& global) const
- {
- const AffineTransform& t = getTransformInvert();
- return t.transform(global);
- }
- Vector2 Actor::local2global(const Vector2& local) const
- {
- const AffineTransform& t = getTransform();
- return t.transform(local);
- }
- bool Actor::prepareRender(RenderState& rs, const RenderState& parentRS)
- {
- if (!(_flags & flag_visible))
- return false;
- unsigned char alpha = (parentRS.alpha * _alpha) / 255;
- if (!alpha)
- return false;
- rs = parentRS;
- rs.alpha = alpha;
- const Transform& tr = getTransform();
- if (_flags & flag_fastTransform)
- {
- rs.transform = parentRS.transform;
- rs.transform.translate(Vector2(tr.x, tr.y));
- }
- else
- Transform::multiply(rs.transform, tr, parentRS.transform);
- if (_flags & flag_cull)
- {
- RectF ss_rect = getActorTransformedDestRect(this, rs.transform);
- RectF intersection = ss_rect;
- intersection.clip(*rs.clip);
- if (intersection.isEmpty())
- return false;
- }
- return true;
- }
- void Actor::completeRender(const RenderState& rs)
- {
- }
- bool Actor::internalRender(RenderState& rs, const RenderState& parentRS)
- {
- if (!prepareRender(rs, parentRS))
- return false;
- //if (!_renderer->render(this, rs))
- doRender(rs);
- completeRender(rs);
- return true;
- }
- void Actor::render(const RenderState& parentRS)
- {
- RenderState rs = parentRS;
- if (_material)
- rs.material = _material;
- rs.material->render(this, rs);
- }
- RectF Actor::calcDestRectF(const RectF& destRect_, const Vector2& size) const
- {
- RectF destRect = destRect_;
- if (!(_flags & flag_childrenRelative))
- {
- Vector2 a;
- if ((_flags & flag_anchorInPixels))
- a = Vector2(_anchor.x, _anchor.y);
- else
- a = Vector2(_anchor.x * size.x, _anchor.y * size.y);
- destRect.pos -= a;
- }
- return destRect;
- }
- RectF Actor::getDestRect() const
- {
- return calcDestRectF(RectF(Vector2(0, 0), getSize()), getSize());
- }
- spTween Actor::_addTween(spTween tween, bool rel)
- {
- OX_ASSERT(tween);
- if (!tween)
- return 0;
- tween->start(*this);
- _tweens.append(tween);
- return tween;
- }
- spTween Actor::addTween(spTween tween)
- {
- return _addTween(tween, false);
- }
- spTween Actor::addTween2(spTween tween, const TweenOptions& opt)
- {
- tween->init2(opt);
- return _addTween(tween, false);
- }
- spTween Actor::getTween(const std::string& name, error_policy ep)
- {
- spTween tween = _tweens._first;
- while (tween)
- {
- if (tween->isName(name))
- return tween;
- tween = tween->getNextSibling();
- }
- handleErrorPolicy(ep, "can't find tween: %s", name.c_str());
- return 0;
- }
- void Actor::removeTween(spTween v)
- {
- OX_ASSERT(v);
- if (!v)
- return;
- if (v->getParentList() == &_tweens)
- {
- v->setClient(0);
- _tweens.remove(v);
- }
- }
- void Actor::removeTweens(bool callComplete)
- {
- spTween t = _tweens._first;
- while (t)
- {
- spTween c = t;
- t = t->getNextSibling();
- if (callComplete)
- c->complete();
- else
- removeTween(c);
- }
- }
- void Actor::removeTweensByName(const std::string& name)
- {
- spTween t = _tweens._first;
- while (t)
- {
- spTween c = t;
- t = t->getNextSibling();
- if (c->isName(name))
- {
- removeTween(c);
- }
- }
- }
- void Actor::serialize(serializedata* data)
- {
- //node.set_name("actor");
- pugi::xml_node node = data->node;
- node.append_attribute("name").set_value(getName().c_str());
- setAttrV2(node, "pos", getPosition(), Vector2(0, 0));
- setAttrV2(node, "scale", getScale(), Vector2(1, 1));
- setAttrV2(node, "size", getSize(), Vector2(0, 0));
- setAttr(node, "rotation", getRotation(), 0.0f);
- setAttr(node, "visible", getVisible(), true);
- setAttr(node, "input", getInputEnabled(), true);
- setAttr(node, "inputch", getInputChildrenEnabled(), true);
- setAttr(node, "alpha", getAlpha(), (unsigned char)255);
- setAttrV2(node, "anchor", getAnchor(), Vector2(0, 0));
- if (data->withChildren)
- {
- spActor child = getFirstChild();
- while (child)
- {
- serializedata d = *data;
- d.node = node.append_child("-");
- child->serialize(&d);
- child = child->getNextSibling();
- }
- }
- node.set_name("Actor");
- }
- Vector2 attr2Vector2(const char* data)
- {
- Vector2 v;
- sscanf(data, "%f,%f", &v.x, &v.y);
- return v;
- }
- void Actor::deserialize(const deserializedata* data)
- {
- pugi::xml_node node = data->node;
- pugi::xml_attribute attr = node.first_attribute();
- while (attr)
- {
- const char* name = attr.name();
- do
- {
- if (!strcmp(name, "name"))
- {
- setName(attr.as_string());
- break;
- }
- if (!strcmp(name, "pos"))
- {
- setPosition(attr2Vector2(attr.as_string()));
- break;
- }
- if (!strcmp(name, "anchor"))
- {
- setAnchor(attr2Vector2(attr.as_string()));
- break;
- }
- if (!strcmp(name, "scale"))
- {
- setScale(attr2Vector2(attr.as_string()));
- break;
- }
- if (!strcmp(name, "size"))
- {
- setSize(attr2Vector2(attr.as_string()));
- break;
- }
- if (!strcmp(name, "rotation"))
- {
- setRotation(attr.as_float());
- break;
- }
- if (!strcmp(name, "visible"))
- {
- setVisible(attr.as_bool());
- break;
- }
- if (!strcmp(name, "input"))
- {
- setTouchEnabled(attr.as_bool());
- break;
- }
- if (!strcmp(name, "inputch"))
- {
- setTouchChildrenEnabled(attr.as_bool());
- break;
- }
- if (!strcmp(name, "alpha"))
- {
- setAlpha(static_cast<unsigned char>(attr.as_int()));
- break;
- }
- }
- while (0);
- attr = attr.next_attribute();
- }
- pugi::xml_node item = node.first_child();
- while (!item.empty())
- {
- spActor actor = deserializedata::deser(item, data->factory);
- addChild(actor);
- item = item.next_sibling();
- }
- }
- Vector2 convert_global2local_(const Actor* child, const Actor* parent, Vector2 pos)
- {
- if (child->getParent() && child->getParent() != parent)
- pos = convert_global2local_(child->getParent(), parent, pos);
- /*
- Actor *p = child->getParent();
- if (p && child != parent)
- pos = convert_global2local(p, parent, pos);
- */
- pos = child->global2local(pos);
- return pos;
- }
- Vector2 convert_global2local(spActor child, spActor parent, const Vector2& pos)
- {
- return convert_global2local_(child.get(), parent.get(), pos);
- }
- Vector2 convert_local2global_(const Actor* child, const Actor* parent, Vector2 pos)
- {
- while (child && child != parent)
- {
- pos = child->local2global(pos);
- child = child->getParent();
- }
- return pos;
- }
- Vector2 convert_local2global(spActor child, spActor parent, const Vector2& pos)
- {
- return convert_local2global_(child.get(), parent.get(), pos);
- }
- Vector2 convert_local2stage(spActor actor, const Vector2& pos, spActor root)
- {
- if (!root)
- root = getStage();
- return convert_local2global(actor, root, pos);
- }
- Vector2 convert_local2stage(const Actor* actor, const Vector2& pos, const Actor* root)
- {
- if (!root)
- root = getStage().get();
- return convert_local2global_(actor, root, pos);
- }
- Vector2 convert_stage2local(spActor actor, const Vector2& pos, spActor root)
- {
- if (!root)
- root = getStage();
- return convert_global2local(actor, root, pos);
- }
- Vector2 convert_stage2local(const Actor* actor, const Vector2& pos, const Actor* root)
- {
- if (!root)
- root = getStage().get();
- return convert_global2local_(actor, root, pos);
- }
- Transform getGlobalTransform(spActor child, spActor parent)
- {
- Transform t;
- t.identity();
- while (child != parent)
- {
- t = t * child->getTransform();
- child = child->getParent();
- }
- return t;
- }
- Transform getGlobalTransform2(spActor child, Actor* parent)
- {
- Transform t;
- t.identity();
- while (child.get() != parent)
- {
- t = t * child->getTransform();
- child = child->getParent();
- }
- return t;
- }
- void changeParentAndSavePosition(spActor mutualParent, spActor actor, spActor newParent)
- {
- Vector2 pos = actor->getPosition();
- spActor act = actor->getParent();
- while (act && act != mutualParent)
- {
- pos = act->local2global(pos);
- act = act->getParent();
- }
- if (newParent != mutualParent)
- pos = convert_global2local(newParent, mutualParent, pos);
- actor->setPosition(pos);
- actor->attachTo(newParent);
- }
- RectF getActorTransformedDestRect(Actor* actor, const Transform& tr)
- {
- RectF rect = actor->getDestRect();
- Vector2 tl = rect.pos;
- Vector2 br = rect.pos + rect.size;
- tl = tr.transform(tl);
- br = tr.transform(br);
- Vector2 size = br - tl;
- return RectF(tl, size);
- }
- class OBB2D
- {
- private:
- /** Corners of the box, where 0 is the lower left. */
- Vector2 corner[4];
- /** Two edges of the box extended away from corner[0]. */
- Vector2 axis[2];
- /** origin[a] = corner[0].dot(axis[a]); */
- double origin[2];
- /** Returns true if other overlaps one dimension of this. */
- bool overlaps1Way(const OBB2D& other) const
- {
- for (int a = 0; a < 2; ++a)
- {
- float t = other.corner[0].dot(axis[a]);
- // Find the extent of box 2 on axis a
- float tMin = t;
- float tMax = t;
- for (int c = 1; c < 4; ++c)
- {
- t = other.corner[c].dot(axis[a]);
- if (t < tMin)
- {
- tMin = t;
- }
- else if (t > tMax)
- {
- tMax = t;
- }
- }
- // We have to subtract off the origin
- // See if [tMin, tMax] intersects [0, 1]
- if ((tMin > 1 + origin[a]) || (tMax < origin[a]))
- {
- // There was no intersection along this dimension;
- // the boxes cannot possibly overlap.
- return false;
- }
- }
- // There was no dimension along which there is no intersection.
- // Therefore the boxes overlap.
- return true;
- }
- /** Updates the axes after the corners move. Assumes the
- corners actually form a rectangle. */
- void computeAxes()
- {
- axis[0] = corner[1] - corner[0];
- axis[1] = corner[3] - corner[0];
- // Make the length of each axis 1/edge length so we know any
- // dot product must be less than 1 to fall within the edge.
- for (int a = 0; a < 2; ++a)
- {
- axis[a] /= axis[a].sqlength();
- origin[a] = corner[0].dot(axis[a]);
- }
- }
- public:
- OBB2D(const RectF& rect, const AffineTransform& tr)
- {
- corner[0] = tr.transform(rect.getLeftTop());
- corner[1] = tr.transform(rect.getRightTop());
- corner[2] = tr.transform(rect.getRightBottom());
- corner[3] = tr.transform(rect.getLeftBottom());
- computeAxes();
- }
- /** Returns true if the intersection of the boxes is non-empty. */
- bool overlaps(const OBB2D& other) const
- {
- return overlaps1Way(other) && other.overlaps1Way(*this);
- }
- };
- extern int HIT_TEST_DOWNSCALE;
- bool testIntersection(spActor objA, spActor objB, spActor parent, Vector2* contact)
- {
- float s1 = objB->getSize().x * objB->getSize().y;
- float s2 = objA->getSize().x * objA->getSize().y;
- bool swapped = false;
- if (s2 < s1)
- {
- swapped = true;
- std::swap(objA, objB);
- }
- Transform transA = getGlobalTransform(objA, parent);
- Transform transB = getGlobalTransform(objB, parent);
- //Transform transBInv = getGlobalTransform(objB, parent);
- transB.invert();
- Transform n = transA * transB;
- AffineTransform ident;
- ident.identity();
- OBB2D a(objB->getDestRect(), ident);
- OBB2D b(objA->getDestRect(), n);
- if (!a.overlaps(b))
- return false;
- /*
- float s1 = objB->getSize().x * objB->getSize().y;
- float s2 = objA->getSize().x * objA->getSize().y;
- bool swapped = false;
- if (s2 < s1)
- {
- swapped = true;
- std::swap(objA, objB);
- std::swap(transA, transB);
- n = transA * transB;
- }
- */
- int w = (int)objA->getWidth();
- int h = (int)objA->getHeight();
- for (int y = 0; y < h; y += HIT_TEST_DOWNSCALE)
- {
- for (int x = 0; x < w; x += HIT_TEST_DOWNSCALE)
- {
- Vector2 posA = Vector2(float(x), float(y));
- if (!objA->isOn(posA))
- continue;
- Vector2 posB = n.transform(posA);
- if (!objB->isOn(posB))
- continue;
- if (contact)
- *contact = swapped ? posB : posA;
- return true;
- }
- }
- return false;
- }
- }
|