inline IntVector2 operator-(IntVector2 const &v1, IntVector2 const &v2) { return IntVector2(v1) -= v2; }
inline IntVector2 operator*(IntVector2 const &v, int i) { return IntVector2(v) *= i; }
IntVector2 Deserializer::ReadIntVector2() { int data[2]; Read(data, sizeof data); return IntVector2(data); }
IntVector2 operator-() const { return IntVector2(-x, -y); }
const Matrix3x4& Sprite::GetTransform() const { if (positionDirty_) { Vector2 pos = floatPosition_; Matrix3x4 parentTransform; if (parent_) { Sprite* parentSprite = dynamic_cast<Sprite*>(parent_); if (parentSprite) parentTransform = parentSprite->GetTransform(); else { const IntVector2& parentScreenPos = parent_->GetScreenPosition() + parent_->GetChildOffset(); parentTransform = Matrix3x4::IDENTITY; parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f)); } switch (GetHorizontalAlignment()) { case HA_LEFT: break; case HA_CENTER: pos.x_ += (float)(parent_->GetSize().x_ / 2); break; case HA_RIGHT: pos.x_ += (float)parent_->GetSize().x_; break; } switch (GetVerticalAlignment()) { case VA_TOP: break; case VA_CENTER: pos.y_ += (float)(parent_->GetSize().y_ / 2); break; case VA_BOTTOM: pos.y_ += (float)(parent_->GetSize().y_); break; } } else parentTransform = Matrix3x4::IDENTITY; Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY); hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f)); Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f)); transform_ = parentTransform * mainTransform * hotspotAdjust; positionDirty_ = false; // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements Vector3 topLeftCorner = transform_ * Vector3::ZERO; screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_); } return transform_; }
IntVector2 Sprite::ScreenToElement(const IntVector2& screenPosition) { Vector3 floatPos(screenPosition.x_, screenPosition.y_, 0.0f); Vector3 transformedPos = GetTransform().Inverse() * floatPos; return IntVector2((int)transformedPos.x_, (int)transformedPos.y_); }
IntVector2 Sprite::ElementToScreen(const IntVector2& position) { Vector3 floatPos(position.x_, position.y_, 0.0f); Vector3 transformedPos = GetTransform() * floatPos; return IntVector2((int)transformedPos.x_, (int)transformedPos.y_); }
void Sprite::SetHotSpot(int x, int y) { SetHotSpot(IntVector2(x, y)); }
#include "Game/GameCommon.hpp" const IntVector2 CELL_SIZE = IntVector2(20, 20); const bool DEBUG_DRAW_TILES = false; const RGBA NPC_DEFAULT_COLOR = RGBA::MAGENTA; const RangeInt NPC_DEFAULT_HEALTH = RangeInt(10, 10); const RangeInt NPC_DEFAULT_DAMAGE = RangeInt(2, 3); const RGBA HIGHLIGHT_COLOR = RGBA(0.f, 1.f, 1.f, 0.4f); const RGBA HIGHLIGHT_DOWN_COLOR = RGBA(0.f, 1.f, 1.f, 0.1f); bool DEBUG_RENDER_PATH_FIND = true; //--------------------------------------------------------------------------------------------------------------------------- //TILE DEFINITIONS //---------------------------------------------------------------------------------------------------------------------------
void Text::UpdateCharLocations() { // Remember the font face to see if it's still valid when it's time to render FontFace* face = font_ ? font_->GetFace(fontSize_) : (FontFace*)0; if (!face) return; fontFace_ = face; int rowHeight = (int)(rowSpacing_ * rowHeight_); // Store position & size of each character, and locations per texture page unsigned numChars = unicodeText_.Size(); charLocations_.Resize(numChars + 1); pageGlyphLocations_.Resize(face->GetTextures().Size()); for (unsigned i = 0; i < pageGlyphLocations_.Size(); ++i) pageGlyphLocations_[i].Clear(); IntVector2 offset = font_->GetTotalGlyphOffset(fontSize_); unsigned rowIndex = 0; unsigned lastFilled = 0; int x = GetRowStartPosition(rowIndex) + offset.x_; int y = offset.y_; for (unsigned i = 0; i < printText_.Size(); ++i) { CharLocation loc; loc.position_ = IntVector2(x, y); unsigned c = printText_[i]; if (c != '\n') { const FontGlyph* glyph = face->GetGlyph(c); loc.size_ = IntVector2(glyph ? glyph->advanceX_ : 0, rowHeight_); if (glyph) { // Store glyph's location for rendering. Verify that glyph page is valid if (glyph->page_ < pageGlyphLocations_.Size()) pageGlyphLocations_[glyph->page_].Push(GlyphLocation(x, y, glyph)); x += glyph->advanceX_; if (i < printText_.Size() - 1) x += face->GetKerning(c, printText_[i + 1]); } } else { loc.size_ = IntVector2::ZERO; x = GetRowStartPosition(++rowIndex); y += rowHeight; } // Fill gaps in case characters were skipped from printing for (unsigned j = lastFilled; j <= printToText_[i]; ++j) charLocations_[j] = loc; lastFilled = printToText_[i] + 1; } // Store the ending position charLocations_[numChars].position_ = IntVector2(x, y); charLocations_[numChars].size_ = IntVector2::ZERO; charLocationsDirty_ = false; }
void Button::SetPressedChildOffset(int x, int y) { pressedChildOffset_ = IntVector2(x, y); }
void Button::SetDisabledOffset(int x, int y) { disabledOffset_ = IntVector2(x, y); }
/// Convert screen coordinates to element coordinates. IntVector2 ScreenToElement(const IntVector2& screenPos) override { IntVector2 result(-1, -1); if (node_.Expired()) return result; Scene* scene = node_->GetScene(); auto* model = node_->GetComponent<StaticModel>(); if (scene == nullptr || model == nullptr) return result; auto* renderer = GetSubsystem<Renderer>(); if (renderer == nullptr) return result; // \todo Always uses the first viewport, in case there are multiple auto* octree = scene->GetComponent<Octree>(); if (viewport_ == nullptr) viewport_ = renderer->GetViewportForScene(scene, 0); if (viewport_.Expired() || octree == nullptr) return result; if (viewport_->GetScene() != scene) { URHO3D_LOGERROR("UIComponent and Viewport set to component's root element belong to different scenes."); return result; } Camera* camera = viewport_->GetCamera(); if (camera == nullptr) return result; IntRect rect = viewport_->GetRect(); if (rect == IntRect::ZERO) { auto* graphics = GetSubsystem<Graphics>(); rect.right_ = graphics->GetWidth(); rect.bottom_ = graphics->GetHeight(); } Ray ray(camera->GetScreenRay((float)screenPos.x_ / rect.Width(), (float)screenPos.y_ / rect.Height())); PODVector<RayQueryResult> queryResultVector; RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK); octree->Raycast(query); if (queryResultVector.Empty()) return result; for (unsigned i = 0; i < queryResultVector.Size(); i++) { RayQueryResult& queryResult = queryResultVector[i]; if (queryResult.drawable_ != model) { // ignore billboard sets by default if (queryResult.drawable_->GetTypeInfo()->IsTypeOf(BillboardSet::GetTypeStatic())) continue; return result; } Vector2& uv = queryResult.textureUV_; result = IntVector2(static_cast<int>(uv.x_ * GetWidth()), static_cast<int>(uv.y_ * GetHeight())); return result; } return result; }