From 523f0e8c5bce0cb58215dc1f9d027cf32394e3c3 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 23 Dec 2016 13:48:32 +0100 Subject: [PATCH] Move TileAnimation code to seperate file --- src/CMakeLists.txt | 1 + src/client/tile.h | 4 +- src/mapblock_mesh.cpp | 3 +- src/network/networkprotocol.h | 2 + src/nodedef.cpp | 35 ++++++------- src/nodedef.h | 16 ++---- src/particles.cpp | 13 ++--- src/script/common/c_content.cpp | 6 +-- src/tileanimation.cpp | 87 +++++++++++++++++++++++++++++++++ src/tileanimation.h | 49 +++++++++++++++++++ 10 files changed, 168 insertions(+), 48 deletions(-) create mode 100644 src/tileanimation.cpp create mode 100644 src/tileanimation.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3aa645df9..51cf88063 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -459,6 +459,7 @@ set(common_SRCS staticobject.cpp subgame.cpp terminal_chat_console.cpp + tileanimation.cpp tool.cpp treegen.cpp version.cpp diff --git a/src/client/tile.h b/src/client/tile.h index b75916841..452804801 100644 --- a/src/client/tile.h +++ b/src/client/tile.h @@ -161,9 +161,7 @@ enum MaterialType{ // Should the crack be drawn on transparent pixels (unset) or not (set)? // Ignored if MATERIAL_FLAG_CRACK is not set. #define MATERIAL_FLAG_CRACK_OVERLAY 0x04 -// Animation made up by splitting the texture to vertical frames, as -// defined by extra parameters -#define MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES 0x08 +#define MATERIAL_FLAG_ANIMATION 0x08 #define MATERIAL_FLAG_HIGHLIGHTED 0x10 #define MATERIAL_FLAG_TILEABLE_HORIZONTAL 0x20 #define MATERIAL_FLAG_TILEABLE_VERTICAL 0x40 diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 00f83e7ab..977eabb6e 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -1131,8 +1131,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): &p.tile.texture_id); } // - Texture animation - if(p.tile.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) - { + if (p.tile.material_flags & MATERIAL_FLAG_ANIMATION) { // Add to MapBlockMesh in order to animate these tiles m_animation_tiles[i] = p.tile; m_animation_frames[i] = 0; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index f65167380..45bf76ff8 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -140,6 +140,8 @@ with this program; if not, write to the Free Software Foundation, Inc., CPT2_MESHOPTIONS PROTOCOL_VERSION 29: Server doesn't accept TOSERVER_BREATH anymore + serialization of TileAnimation params changed + TAT_SHEET_2D */ #define LATEST_PROTOCOL_VERSION 29 diff --git a/src/nodedef.cpp b/src/nodedef.cpp index ccbb42c66..21bceb94d 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -188,17 +188,16 @@ void NodeBox::deSerialize(std::istream &is) void TileDef::serialize(std::ostream &os, u16 protocol_version) const { - if (protocol_version >= 26) + if (protocol_version >= 29) + writeU8(os, 3); + else if (protocol_version >= 26) writeU8(os, 2); else if (protocol_version >= 17) writeU8(os, 1); else writeU8(os, 0); os<= 17) writeU8(os, backface_culling); if (protocol_version >= 26) { @@ -211,10 +210,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con { int version = readU8(is); name = deSerializeString(is); - animation.type = (TileAnimationType)readU8(is); - animation.aspect_w = readU16(is); - animation.aspect_h = readU16(is); - animation.length = readF1000(is); + animation.deSerialize(is, version >= 3 ? 29 : 26); if (version >= 1) backface_culling = readU8(is); if (version >= 2) { @@ -533,7 +529,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; if (tiledef->animation.type == TAT_VERTICAL_FRAMES) - tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + tile->material_flags |= MATERIAL_FLAG_ANIMATION; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; if (tiledef->tileable_vertical) @@ -541,20 +537,16 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, // Animation parameters int frame_count = 1; - if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { - // Get texture size to determine frame count by aspect ratio - v2u32 size = tile->texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)tiledef->animation.aspect_w * - (float)tiledef->animation.aspect_h; - frame_count = size.Y / frame_height; - int frame_length_ms = 1000.0 * tiledef->animation.length / frame_count; + if (tile->material_flags & MATERIAL_FLAG_ANIMATION) { + int frame_length_ms; + tiledef->animation.determineParams(tile->texture->getOriginalSize(), + &frame_count, &frame_length_ms); tile->animation_frame_count = frame_count; tile->animation_frame_length_ms = frame_length_ms; } if (frame_count == 1) { - tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + tile->material_flags &= ~MATERIAL_FLAG_ANIMATION; } else { std::ostringstream os(std::ios::binary); tile->frames.resize(frame_count); @@ -564,8 +556,9 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, FrameSpec frame; os.str(""); - os << tiledef->name << "^[verticalframe:" - << frame_count << ":" << i; + os << tiledef->name; + tiledef->animation.getTextureModifer(os, + tile->texture->getOriginalSize(), i); frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id); if (tile->normal_texture) diff --git a/src/nodedef.h b/src/nodedef.h index 80396f992..b5639b516 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemgroup.h" #include "sound.h" // SimpleSoundSpec #include "constants.h" // BS +#include "tileanimation.h" class INodeDefManager; class IItemDefManager; @@ -161,22 +162,14 @@ enum NodeDrawType /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ -enum TileAnimationType{ - TAT_NONE=0, - TAT_VERTICAL_FRAMES=1, -}; + struct TileDef { std::string name; bool backface_culling; // Takes effect only in special cases bool tileable_horizontal; bool tileable_vertical; - struct{ - enum TileAnimationType type; - int aspect_w; // width for aspect ratio - int aspect_h; // height for aspect ratio - float length; // seconds - } animation; + struct TileAnimationParams animation; TileDef() { @@ -185,9 +178,6 @@ struct TileDef tileable_horizontal = true; tileable_vertical = true; animation.type = TAT_NONE; - animation.aspect_w = 1; - animation.aspect_h = 1; - animation.length = 1.0; } void serialize(std::ostream &os, u16 protocol_version) const; diff --git a/src/particles.cpp b/src/particles.cpp index acf9cc815..e9ddba986 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -567,19 +567,20 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s { // Texture u8 texid = myrand_range(0, 5); - video::ITexture *texture = tiles[texid].texture; + video::ITexture *texture; // Only use first frame of animated texture - f32 ymax = 1; - if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) - ymax /= tiles[texid].animation_frame_count; + if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION) + texture = tiles[texid].frames[0].texture; + else + texture = tiles[texid].texture; float size = rand() % 64 / 512.; float visual_size = BS * size; - v2f texsize(size * 2, ymax * size * 2); + v2f texsize(size * 2, size * 2); v2f texpos; texpos.X = ((rand() % 64) / 64. - texsize.X); - texpos.Y = ymax * ((rand() % 64) / 64. - texsize.Y); + texpos.Y = ((rand() % 64) / 64. - texsize.Y); // Physics v3f velocity((rand() % 100 / 50. - 1) / 1.5, diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 541744895..6cd1d040b 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -338,11 +338,11 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) tiledef.animation.type = (TileAnimationType) getenumfield(L, -1, "type", es_TileAnimationType, TAT_NONE); - tiledef.animation.aspect_w = + tiledef.animation.vertical_frames.aspect_w = getintfield_default(L, -1, "aspect_w", 16); - tiledef.animation.aspect_h = + tiledef.animation.vertical_frames.aspect_h = getintfield_default(L, -1, "aspect_h", 16); - tiledef.animation.length = + tiledef.animation.vertical_frames.length = getfloatfield_default(L, -1, "length", 1.0); } lua_pop(L, 1); diff --git a/src/tileanimation.cpp b/src/tileanimation.cpp new file mode 100644 index 000000000..891478c9f --- /dev/null +++ b/src/tileanimation.cpp @@ -0,0 +1,87 @@ +/* +Minetest +Copyright (C) 2016 sfan5 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "tileanimation.h" +#include "util/serialize.h" + +void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) const +{ + if(protocol_version < 29 /* TODO bump */) { + if (type == TAT_VERTICAL_FRAMES) { + writeU8(os, type); + writeU16(os, vertical_frames.aspect_w); + writeU16(os, vertical_frames.aspect_h); + writeF1000(os, vertical_frames.length); + } else { + writeU8(os, TAT_NONE); + writeU16(os, 1); + writeU16(os, 1); + writeF1000(os, 1.0); + } + return; + } + + writeU8(os, type); + if (type == TAT_VERTICAL_FRAMES) { + writeU16(os, vertical_frames.aspect_w); + writeU16(os, vertical_frames.aspect_h); + writeF1000(os, vertical_frames.length); + } +} + +void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version) +{ + type = (TileAnimationType) readU8(is); + if(protocol_version < 29 /* TODO bump */) { + vertical_frames.aspect_w = readU16(is); + vertical_frames.aspect_h = readU16(is); + vertical_frames.length = readF1000(is); + return; + } + + if(type == TAT_VERTICAL_FRAMES) { + vertical_frames.aspect_w = readU16(is); + vertical_frames.aspect_h = readU16(is); + vertical_frames.length = readF1000(is); + } +} + +void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const +{ + if (type == 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; +} diff --git a/src/tileanimation.h b/src/tileanimation.h new file mode 100644 index 000000000..d5172ed50 --- /dev/null +++ b/src/tileanimation.h @@ -0,0 +1,49 @@ +/* +Minetest +Copyright (C) 2016 sfan5 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef TILEANIMATION_HEADER +#define TILEANIMATION_HEADER + +#include "irrlichttypes_bloated.h" +#include + +enum TileAnimationType { + TAT_NONE = 0, + TAT_VERTICAL_FRAMES = 1, +}; + +struct TileAnimationParams { + enum TileAnimationType type; + union { + // struct { + // } none; + struct { + int aspect_w; // width for aspect ratio + int aspect_h; // height for aspect ratio + float length; // seconds + } vertical_frames; + }; + + void serialize(std::ostream &os, u16 protocol_version) const; + void deSerialize(std::istream &is, u16 protocol_version); + void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const; + void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const; +}; + +#endif