Add 2D sheet animation for nodes
authorsfan5 <sfan5@live.de>
Fri, 23 Dec 2016 13:43:56 +0000 (14:43 +0100)
committersfan5 <sfan5@live.de>
Mon, 2 Jan 2017 14:28:06 +0000 (15:28 +0100)
doc/lua_api.txt
games/minimal/mods/default/init.lua
games/minimal/mods/default/textures/default_lava_source_animated.png
src/nodedef.cpp
src/particles.cpp
src/script/common/c_content.cpp
src/tileanimation.cpp
src/tileanimation.h

index 648a29303113973323f297b78cd7a34a031b5b48..6166826af241398e963e93241f184bc3c1193d93 100644 (file)
@@ -3702,7 +3702,26 @@ Definition tables
     * `image` (name)
 
 ### Tile animation definition
-* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}`
+
+       {
+               type = "vertical_frames",
+               aspect_w = 16,
+               -- ^ specify width of a frame in pixels
+               aspect_h = 16,
+               -- ^ specify height of a frame in pixels
+               length = 3.0,
+               -- ^ specify full loop length
+       }
+
+       {
+               type = "sheet_2d",
+               frames_w = 5,
+               -- ^ specify width in number of frames
+               frames_h = 3,
+               -- ^ specify height in number of frames
+               frame_length = 0.5,
+               -- ^ specify length of a single frame
+       }
 
 ### Node definition (`register_node`)
 
index f532e7193e6a35d26527c39aba2c4aac48bb6979..2f73b53efe0cb58e40ec0c10440f5f637e5ae1b7 100644 (file)
@@ -1044,8 +1044,11 @@ minetest.register_node("default:lava_source", {
        inventory_image = minetest.inventorycube("default_lava.png"),
        drawtype = "liquid",
        --tiles ={"default_lava.png"},
-       tiles ={
-               {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
+       tiles = {
+               {
+                       name = "default_lava_source_animated.png",
+                       animation = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5}
+               }
        },
        special_tiles = {
                -- New-style lava source material (mostly unused)
index aa9d57cf17d0be0dddfbb0cfe0aae10e362dac94..54f4c0ddda45bcc1bcf5b9c2aed872c64b3328f7 100644 (file)
Binary files a/games/minimal/mods/default/textures/default_lava_source_animated.png and b/games/minimal/mods/default/textures/default_lava_source_animated.png differ
index 21bceb94dd76e4d85e774e86a924f2fb00f47fdd..92cdf738ee7a6f1e15c0cddc76cd89a068ed91e8 100644 (file)
@@ -528,7 +528,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
        tile->material_flags = 0;
        if (backface_culling)
                tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
-       if (tiledef->animation.type == TAT_VERTICAL_FRAMES)
+       if (tiledef->animation.type != TAT_NONE)
                tile->material_flags |= MATERIAL_FLAG_ANIMATION;
        if (tiledef->tileable_horizontal)
                tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
index e9ddba9867a5656e93d48dc8aeef7921ab766255..97f42e2c4d5cd8261c47b86ce3f0f5ce33f9c957 100644 (file)
@@ -570,7 +570,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
        video::ITexture *texture;
 
        // Only use first frame of animated texture
-       if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION)
+       if (tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION)
                texture = tiles[texid].frames[0].texture;
        else
                texture = tiles[texid].texture;
index 6cd1d040b8755eceb8a522eabf5b215473b2303b..b9bcfef691c1e49c9e640a33457b2b5c76290a86 100644 (file)
@@ -39,6 +39,7 @@ struct EnumString es_TileAnimationType[] =
 {
        {TAT_NONE, "none"},
        {TAT_VERTICAL_FRAMES, "vertical_frames"},
+       {TAT_SHEET_2D, "sheet_2d"},
        {0, NULL},
 };
 
@@ -334,16 +335,26 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
                // animation = {}
                lua_getfield(L, index, "animation");
                if(lua_istable(L, -1)){
-                       // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
                        tiledef.animation.type = (TileAnimationType)
                                getenumfield(L, -1, "type", es_TileAnimationType,
                                TAT_NONE);
-                       tiledef.animation.vertical_frames.aspect_w =
-                               getintfield_default(L, -1, "aspect_w", 16);
-                       tiledef.animation.vertical_frames.aspect_h =
-                               getintfield_default(L, -1, "aspect_h", 16);
-                       tiledef.animation.vertical_frames.length =
-                               getfloatfield_default(L, -1, "length", 1.0);
+                       if (tiledef.animation.type == TAT_VERTICAL_FRAMES) {
+                               // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
+                               tiledef.animation.vertical_frames.aspect_w =
+                                       getintfield_default(L, -1, "aspect_w", 16);
+                               tiledef.animation.vertical_frames.aspect_h =
+                                       getintfield_default(L, -1, "aspect_h", 16);
+                               tiledef.animation.vertical_frames.length =
+                                       getfloatfield_default(L, -1, "length", 1.0);
+                       } else if (tiledef.animation.type == TAT_SHEET_2D) {
+                               // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
+                               getintfield(L, -1, "frames_w",
+                                       tiledef.animation.sheet_2d.frames_w);
+                               getintfield(L, -1, "frames_h",
+                                       tiledef.animation.sheet_2d.frames_h);
+                               getfloatfield(L, -1, "frame_length",
+                                       tiledef.animation.sheet_2d.frame_length);
+                       }
                }
                lua_pop(L, 1);
        }
index 891478c9f9b46bd0d017e97913758b51ed875859..a23eecc2ea7d6d9287db7eff77c05725988c793c 100644 (file)
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) const
 {
-       if(protocol_version < 29 /* TODO bump */) {
+       if (protocol_version < 29) {
                if (type == TAT_VERTICAL_FRAMES) {
                        writeU8(os, type);
                        writeU16(os, vertical_frames.aspect_w);
@@ -41,47 +41,69 @@ void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) cons
                writeU16(os, vertical_frames.aspect_w);
                writeU16(os, vertical_frames.aspect_h);
                writeF1000(os, vertical_frames.length);
+       } else if (type == TAT_SHEET_2D) {
+               writeU8(os, sheet_2d.frames_w);
+               writeU8(os, sheet_2d.frames_h);
+               writeF1000(os, sheet_2d.frame_length);
        }
 }
 
 void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version)
 {
        type = (TileAnimationType) readU8(is);
-       if(protocol_version < 29 /* TODO bump */) {
+       if (protocol_version < 29) {
                vertical_frames.aspect_w = readU16(is);
                vertical_frames.aspect_h = readU16(is);
                vertical_frames.length = readF1000(is);
                return;
        }
 
-       if(type == TAT_VERTICAL_FRAMES) {
+       if (type == TAT_VERTICAL_FRAMES) {
                vertical_frames.aspect_w = readU16(is);
                vertical_frames.aspect_h = readU16(is);
                vertical_frames.length = readF1000(is);
+       } else if (type == TAT_SHEET_2D) {
+               sheet_2d.frames_w = readU8(is);
+               sheet_2d.frames_h = readU8(is);
+               sheet_2d.frame_length = readF1000(is);
        }
 }
 
 void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const
 {
-       if (type == TAT_NONE) {
+       if (type == TAT_VERTICAL_FRAMES) {
+               int frame_height = (float)texture_size.X /
+                               (float)vertical_frames.aspect_w *
+                               (float)vertical_frames.aspect_h;
+               int _frame_count = texture_size.Y / frame_height;
+               if (frame_count)
+                       *frame_count = _frame_count;
+               if (frame_length_ms)
+                       *frame_length_ms = 1000.0 * vertical_frames.length / _frame_count;
+       } else if (type == TAT_SHEET_2D) {
+               if (frame_count)
+                       *frame_count = sheet_2d.frames_w * sheet_2d.frames_h;
+               if (frame_length_ms)
+                       *frame_length_ms = 1000 * sheet_2d.frame_length;
+       } else { // TAT_NONE
                *frame_count = 1;
                *frame_length_ms = 1000;
-               return;
        }
-       int frame_height = (float)texture_size.X /
-                       (float)vertical_frames.aspect_w *
-                       (float)vertical_frames.aspect_h;
-       if (frame_count)
-               *frame_count = texture_size.Y / frame_height;
-       if (frame_length_ms)
-               *frame_length_ms = 1000.0 * vertical_frames.length / (texture_size.Y / frame_height);
 }
 
 void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const
 {
        if (type == TAT_NONE)
                return;
-       int frame_count;
-       determineParams(texture_size, &frame_count, NULL);
-       os << "^[verticalframe:" << frame_count << ":" << frame;
+       if (type == TAT_VERTICAL_FRAMES) {
+               int frame_count;
+               determineParams(texture_size, &frame_count, NULL);
+               os << "^[verticalframe:" << frame_count << ":" << frame;
+       } else if (type == TAT_SHEET_2D) {
+               int q, r;
+               q = frame / sheet_2d.frames_w;
+               r = frame % sheet_2d.frames_w;
+               os << "^[sheet:" << sheet_2d.frames_w << "x" << sheet_2d.frames_h
+                       << ":" << r << "," << q;
+       }
 }
index d5172ed50f292ae9b83053bcf5921a87c9a50852..289ce515b1aa8bcf0bf3f0c50632240ad6c1c21a 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 enum TileAnimationType {
        TAT_NONE = 0,
        TAT_VERTICAL_FRAMES = 1,
+       TAT_SHEET_2D = 2,
 };
 
 struct TileAnimationParams {
@@ -38,6 +39,11 @@ struct TileAnimationParams {
                        int aspect_h; // height for aspect ratio
                        float length; // seconds
                } vertical_frames;
+               struct {
+                       int frames_w; // number of frames left-to-right
+                       int frames_h; // number of frames top-to-bottom
+                       float frame_length; // seconds
+               } sheet_2d;
        };
 
        void serialize(std::ostream &os, u16 protocol_version) const;