| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542 |
- #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();
- }
- 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 (!getTouchEnabled())
- stream << " touchEnabled=false";
- if (!getTouchChildrenEnabled())
- stream << " touchChildrenEnabled=false";
- 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);
- 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::setAnchorInPixels(float x, float y)
- {
- setAnchorInPixels(Vector2(x, y));
- }
- 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;
- const_cast<Actor*>(this)->transformUpdated();
- }
- 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();
- 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();
- 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();
- 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", getTouchEnabled(), true);
- setAttr(node, "inputch", getTouchChildrenEnabled(), 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);
- 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 && child != parent)
- {
- t = t * child->getTransform();
- child = child->getParent();
- }
- return t;
- }
- Transform getGlobalTransform2(spActor child, Actor* parent)
- {
- Transform t;
- t.identity();
- while (child && (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;
- }
- }
|