Browse Source

Recalculate hotspot for trimmed sprite in AnimationSet2D.

aster2013 11 years ago
parent
commit
08e270df0b

+ 3 - 0
Source/Engine/LuaScript/pkgs/Urho2D/Sprite2D.pkg

@@ -6,15 +6,18 @@ public:
     void SetTexture(Texture2D* texture);
     void SetRectangle(const IntRect& rectangle);
     void SetHotSpot(const Vector2& hotSpot);
+    void SetOffset(const IntVector2& offset);
     void SetSpriteSheet(SpriteSheet2D* spriteSheet);
 
     Texture2D* GetTexture() const;
     const IntRect& GetRectangle() const;
     const Vector2& GetHotSpot() const;
+    const IntVector2& GetOffset() const;
     SpriteSheet2D* GetSpriteSheet() const;
 
     tolua_property__get_set Texture2D* texture;
     tolua_property__get_set IntRect rectangle;
     tolua_property__get_set Vector2 hotSpot;
+    tolua_property__get_set IntVector2 offset;
     tolua_property__get_set SpriteSheet2D* spriteSheet;
 };

+ 1 - 2
Source/Engine/LuaScript/pkgs/Urho2D/SpriteSheet2D.pkg

@@ -5,6 +5,5 @@ class SpriteSheet2D : public Resource
 public:
     Texture2D* GetTexture() const;
     Sprite2D* GetSprite(const String name) const;
-    void DefineSprite(const String name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f));
-    void UpdateSprite(const String name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f));
+    void DefineSprite(const String name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f), const IntVector2& originSize = IntVector2::ZERO);
 };

+ 3 - 2
Source/Engine/Script/Urho2DAPI.cpp

@@ -69,6 +69,8 @@ static void RegisterSprite2D(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Sprite2D", "const IntRect& get_rectangle() const", asMETHOD(Sprite2D, GetRectangle), asCALL_THISCALL);
     engine->RegisterObjectMethod("Sprite2D", "void set_hotSpot(const Vector2&in)", asMETHOD(Sprite2D, SetHotSpot), asCALL_THISCALL);
     engine->RegisterObjectMethod("Sprite2D", "const Vector2& get_hotSpot() const", asMETHOD(Sprite2D, GetHotSpot), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Sprite2D", "void set_offset(const IntVector2&in)", asMETHOD(Sprite2D, SetOffset), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Sprite2D", "const IntVector2& get_offset() const", asMETHOD(Sprite2D, GetOffset), asCALL_THISCALL);
 }
 
 static void RegisterSpriteSheet2D(asIScriptEngine* engine)
@@ -76,8 +78,7 @@ static void RegisterSpriteSheet2D(asIScriptEngine* engine)
     RegisterResource<SpriteSheet2D>(engine, "SpriteSheet2D");
     engine->RegisterObjectMethod("SpriteSheet2D", "Texture2D@+ get_texture() const", asMETHOD(SpriteSheet2D, GetTexture), asCALL_THISCALL);
     engine->RegisterObjectMethod("SpriteSheet2D", "Sprite2D@+ GetSprite(const String&)", asMETHOD(SpriteSheet2D, GetSprite), asCALL_THISCALL);
-    engine->RegisterObjectMethod("SpriteSheet2D", "void DefineSprite(const String&, const IntRect&, const Vector2&)", asMETHOD(SpriteSheet2D, DefineSprite), asCALL_THISCALL);
-    engine->RegisterObjectMethod("SpriteSheet2D", "void UpdateSprite(const String&, const IntRect&, const Vector2&)", asMETHOD(SpriteSheet2D, UpdateSprite), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SpriteSheet2D", "void DefineSprite(const String&, const IntRect&, const Vector2& hotSpot=Vector2(0.5f, 0.5f), const IntVector2& offset = IntVector2::ZERO)", asMETHOD(SpriteSheet2D, DefineSprite), asCALL_THISCALL);
 }
 
 // Template function for registering a class derived from Drawable2D.

+ 20 - 2
Source/Engine/Urho2D/AnimationSet2D.cpp

@@ -126,21 +126,39 @@ bool AnimationSet2D::LoadFolders(const XMLElement& rootElem)
             String fileName = fileElem.GetAttribute("name");
 
             SharedPtr<Sprite2D> sprite;
+            
             if (spriterSheet)
                 sprite = spriterSheet->GetSprite(GetFileName(fileName));
             else
                 sprite = (cache->GetResource<Sprite2D>(parentPath + fileName));
+
             if (!sprite)
             {
-                LOGERROR("Could not load sprite " + parentPath + fileName);
+                LOGERROR("Could not load sprite " + fileName);
                 return false;
             }
-            
+
             Vector2 hotSpot(0.0f, 1.0f);
             if (fileElem.HasAttribute("pivot_x"))
                 hotSpot.x_ = fileElem.GetFloat("pivot_x");
             if (fileElem.HasAttribute("pivot_y"))
                 hotSpot.y_ = fileElem.GetFloat("pivot_y");
+
+            // If sprite is trimmed, recalculate hot spot
+            const IntVector2& offset = sprite->GetOffset();
+            if (offset != IntVector2::ZERO)
+            {
+                int width = fileElem.GetInt("width");
+                int height = fileElem.GetInt("height");
+
+                int pivotX = width * hotSpot.x_;
+                int pivotY = height * (1.0f - hotSpot.y_);
+
+                const IntRect& rectangle = sprite->GetRectangle();
+                hotSpot.x_ = ((float)offset.x_ + pivotX) / rectangle.Width();
+                hotSpot.y_ = 1.0f - ((float)offset.y_ + pivotY) / rectangle.Height();
+            }
+
             sprite->SetHotSpot(hotSpot);
 
             sprites_[(folderId << 16) + fileId] = sprite;

+ 9 - 3
Source/Engine/Urho2D/Sprite2D.cpp

@@ -33,7 +33,8 @@ namespace Urho3D
 
 Sprite2D::Sprite2D(Context* context) :
     Resource(context), 
-    hotSpot_(0.5f, 0.5f)
+    hotSpot_(0.5f, 0.5f),
+    offset_(0, 0)
 {
 
 }
@@ -57,8 +58,8 @@ bool Sprite2D::Load(Deserializer& source)
 
     SetTexture(texture);
 
-    if (texture)
-        SetRectangle(IntRect(0, 0, texture->GetWidth(), texture->GetHeight()));
+    if (texture_)
+        SetRectangle(IntRect(0, 0, texture_->GetWidth(), texture_->GetHeight()));
 
     return true;
 }
@@ -78,6 +79,11 @@ void Sprite2D::SetHotSpot(const Vector2& hotSpot)
     hotSpot_ = hotSpot;
 }
 
+void Sprite2D::SetOffset(const IntVector2& offset)
+{
+    offset_ = offset;
+}
+
 void Sprite2D::SetSpriteSheet(SpriteSheet2D* spriteSheet)
 {
     spriteSheet_ = spriteSheet;

+ 6 - 0
Source/Engine/Urho2D/Sprite2D.h

@@ -66,6 +66,8 @@ public:
     void SetRectangle(const IntRect& rectangle);
     /// Set hot spot.
     void SetHotSpot(const Vector2& hotSpot);
+    /// Set offset.
+    void SetOffset(const IntVector2& offset);
     /// Set sprite sheet.
     void SetSpriteSheet(SpriteSheet2D* spriteSheet);
 
@@ -75,6 +77,8 @@ public:
     const IntRect& GetRectangle() const { return rectangle_; }
     /// Return hot spot.
     const Vector2& GetHotSpot() const { return hotSpot_; }
+    /// Return offset.
+    const IntVector2& GetOffset() const { return offset_; }
     /// Return sprite sheet.
     SpriteSheet2D* GetSpriteSheet() const { return spriteSheet_; }
 
@@ -85,6 +89,8 @@ private:
     IntRect rectangle_;
     /// Hot spot.
     Vector2 hotSpot_;
+    /// Offset.
+    IntVector2 offset_;
     /// Sprite sheet.
     WeakPtr<SpriteSheet2D> spriteSheet_;
 };

+ 8 - 19
Source/Engine/Urho2D/SpriteSheet2D.cpp

@@ -95,17 +95,18 @@ bool SpriteSheet2D::Load(Deserializer& source)
         IntRect rectangle(x, y, x + width, y + height);
 
         Vector2 hotSpot(0.5f, 0.5f);
+        IntVector2 offset(0, 0);
         if (subTextureElem.HasAttribute("frameWidth") && subTextureElem.HasAttribute("frameHeight"))
         {
-            int frameX = subTextureElem.GetInt("frameX");
-            int frameY = subTextureElem.GetInt("frameY");
+            offset.x_ = subTextureElem.GetInt("frameX");
+            offset.y_ = subTextureElem.GetInt("frameY");
             int frameWidth = subTextureElem.GetInt("frameWidth");
             int frameHeight = subTextureElem.GetInt("frameHeight");
-            hotSpot.x_ = ((float)frameX + frameWidth / 2) / width;
-            hotSpot.y_ = 1.0f - ((float)frameY + frameHeight / 2) / height;
+            hotSpot.x_ = ((float)offset.x_ + frameWidth / 2) / width;
+            hotSpot.y_ = 1.0f - ((float)offset.y_ + frameHeight / 2) / height;
         }
 
-        DefineSprite(name, rectangle, hotSpot);
+        DefineSprite(name, rectangle, hotSpot, offset);
 
         subTextureElem = subTextureElem.GetNext("SubTexture");
     }
@@ -122,7 +123,7 @@ Sprite2D* SpriteSheet2D::GetSprite(const String& name) const
     return i->second_;
 }
 
-void SpriteSheet2D::DefineSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot)
+void SpriteSheet2D::DefineSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot, const IntVector2& offset)
 {
     if (!texture_)
         return;
@@ -135,22 +136,10 @@ void SpriteSheet2D::DefineSprite(const String& name, const IntRect& rectangle, c
     sprite->SetTexture(texture_);
     sprite->SetRectangle(rectangle);
     sprite->SetHotSpot(hotSpot);
+    sprite->SetOffset(offset);
     sprite->SetSpriteSheet(this);
 
     spriteMapping_[name] = sprite;
 }
 
-void SpriteSheet2D::UpdateSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot)
-{
-    if (!texture_)
-        return;
-
-    Sprite2D* sprite = GetSprite(name);
-    if (sprite)
-    {
-        sprite->SetRectangle(rectangle);
-        sprite->SetHotSpot(hotSpot);
-    }
-}
-
 }

+ 1 - 3
Source/Engine/Urho2D/SpriteSheet2D.h

@@ -51,9 +51,7 @@ public:
     /// Return sprite.
     Sprite2D* GetSprite(const String& name) const;
     /// Define sprite.
-    void DefineSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f));
-    /// Update sprite.
-    void UpdateSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f));
+    void DefineSprite(const String& name, const IntRect& rectangle, const Vector2& hotSpot = Vector2(0.5f, 0.5f), const IntVector2& offset = IntVector2::ZERO);
 
     /// Return sprite mapping.
     const HashMap<String, SharedPtr<Sprite2D> >& GetSpriteMapping() const { return spriteMapping_; }