Move TileAnimation code to seperate file

This commit is contained in:
sfan5 2016-12-23 13:48:32 +01:00
parent e2e8da5ee4
commit 523f0e8c5b
10 changed files with 168 additions and 48 deletions

@ -459,6 +459,7 @@ set(common_SRCS
staticobject.cpp staticobject.cpp
subgame.cpp subgame.cpp
terminal_chat_console.cpp terminal_chat_console.cpp
tileanimation.cpp
tool.cpp tool.cpp
treegen.cpp treegen.cpp
version.cpp version.cpp

@ -161,9 +161,7 @@ enum MaterialType{
// Should the crack be drawn on transparent pixels (unset) or not (set)? // Should the crack be drawn on transparent pixels (unset) or not (set)?
// Ignored if MATERIAL_FLAG_CRACK is not set. // Ignored if MATERIAL_FLAG_CRACK is not set.
#define MATERIAL_FLAG_CRACK_OVERLAY 0x04 #define MATERIAL_FLAG_CRACK_OVERLAY 0x04
// Animation made up by splitting the texture to vertical frames, as #define MATERIAL_FLAG_ANIMATION 0x08
// defined by extra parameters
#define MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES 0x08
#define MATERIAL_FLAG_HIGHLIGHTED 0x10 #define MATERIAL_FLAG_HIGHLIGHTED 0x10
#define MATERIAL_FLAG_TILEABLE_HORIZONTAL 0x20 #define MATERIAL_FLAG_TILEABLE_HORIZONTAL 0x20
#define MATERIAL_FLAG_TILEABLE_VERTICAL 0x40 #define MATERIAL_FLAG_TILEABLE_VERTICAL 0x40

@ -1131,8 +1131,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
&p.tile.texture_id); &p.tile.texture_id);
} }
// - Texture animation // - 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 // Add to MapBlockMesh in order to animate these tiles
m_animation_tiles[i] = p.tile; m_animation_tiles[i] = p.tile;
m_animation_frames[i] = 0; m_animation_frames[i] = 0;

@ -140,6 +140,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
CPT2_MESHOPTIONS CPT2_MESHOPTIONS
PROTOCOL_VERSION 29: PROTOCOL_VERSION 29:
Server doesn't accept TOSERVER_BREATH anymore Server doesn't accept TOSERVER_BREATH anymore
serialization of TileAnimation params changed
TAT_SHEET_2D
*/ */
#define LATEST_PROTOCOL_VERSION 29 #define LATEST_PROTOCOL_VERSION 29

@ -188,17 +188,16 @@ void NodeBox::deSerialize(std::istream &is)
void TileDef::serialize(std::ostream &os, u16 protocol_version) const 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); writeU8(os, 2);
else if (protocol_version >= 17) else if (protocol_version >= 17)
writeU8(os, 1); writeU8(os, 1);
else else
writeU8(os, 0); writeU8(os, 0);
os<<serializeString(name); os<<serializeString(name);
writeU8(os, animation.type); animation.serialize(os, protocol_version);
writeU16(os, animation.aspect_w);
writeU16(os, animation.aspect_h);
writeF1000(os, animation.length);
if (protocol_version >= 17) if (protocol_version >= 17)
writeU8(os, backface_culling); writeU8(os, backface_culling);
if (protocol_version >= 26) { if (protocol_version >= 26) {
@ -211,10 +210,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con
{ {
int version = readU8(is); int version = readU8(is);
name = deSerializeString(is); name = deSerializeString(is);
animation.type = (TileAnimationType)readU8(is); animation.deSerialize(is, version >= 3 ? 29 : 26);
animation.aspect_w = readU16(is);
animation.aspect_h = readU16(is);
animation.length = readF1000(is);
if (version >= 1) if (version >= 1)
backface_culling = readU8(is); backface_culling = readU8(is);
if (version >= 2) { if (version >= 2) {
@ -533,7 +529,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
if (backface_culling) if (backface_culling)
tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
if (tiledef->animation.type == TAT_VERTICAL_FRAMES) 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) if (tiledef->tileable_horizontal)
tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
if (tiledef->tileable_vertical) if (tiledef->tileable_vertical)
@ -541,20 +537,16 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
// Animation parameters // Animation parameters
int frame_count = 1; int frame_count = 1;
if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { if (tile->material_flags & MATERIAL_FLAG_ANIMATION) {
// Get texture size to determine frame count by aspect ratio int frame_length_ms;
v2u32 size = tile->texture->getOriginalSize(); tiledef->animation.determineParams(tile->texture->getOriginalSize(),
int frame_height = (float)size.X / &frame_count, &frame_length_ms);
(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;
tile->animation_frame_count = frame_count; tile->animation_frame_count = frame_count;
tile->animation_frame_length_ms = frame_length_ms; tile->animation_frame_length_ms = frame_length_ms;
} }
if (frame_count == 1) { if (frame_count == 1) {
tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; tile->material_flags &= ~MATERIAL_FLAG_ANIMATION;
} else { } else {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
tile->frames.resize(frame_count); tile->frames.resize(frame_count);
@ -564,8 +556,9 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
FrameSpec frame; FrameSpec frame;
os.str(""); os.str("");
os << tiledef->name << "^[verticalframe:" os << tiledef->name;
<< frame_count << ":" << i; tiledef->animation.getTextureModifer(os,
tile->texture->getOriginalSize(), i);
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id); frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
if (tile->normal_texture) if (tile->normal_texture)

@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "itemgroup.h" #include "itemgroup.h"
#include "sound.h" // SimpleSoundSpec #include "sound.h" // SimpleSoundSpec
#include "constants.h" // BS #include "constants.h" // BS
#include "tileanimation.h"
class INodeDefManager; class INodeDefManager;
class IItemDefManager; class IItemDefManager;
@ -161,22 +162,14 @@ enum NodeDrawType
/* /*
Stand-alone definition of a TileSpec (basically a server-side TileSpec) Stand-alone definition of a TileSpec (basically a server-side TileSpec)
*/ */
enum TileAnimationType{
TAT_NONE=0,
TAT_VERTICAL_FRAMES=1,
};
struct TileDef struct TileDef
{ {
std::string name; std::string name;
bool backface_culling; // Takes effect only in special cases bool backface_culling; // Takes effect only in special cases
bool tileable_horizontal; bool tileable_horizontal;
bool tileable_vertical; bool tileable_vertical;
struct{ struct TileAnimationParams animation;
enum TileAnimationType type;
int aspect_w; // width for aspect ratio
int aspect_h; // height for aspect ratio
float length; // seconds
} animation;
TileDef() TileDef()
{ {
@ -185,9 +178,6 @@ struct TileDef
tileable_horizontal = true; tileable_horizontal = true;
tileable_vertical = true; tileable_vertical = true;
animation.type = TAT_NONE; 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; void serialize(std::ostream &os, u16 protocol_version) const;

@ -567,19 +567,20 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
{ {
// Texture // Texture
u8 texid = myrand_range(0, 5); u8 texid = myrand_range(0, 5);
video::ITexture *texture = tiles[texid].texture; video::ITexture *texture;
// Only use first frame of animated texture // Only use first frame of animated texture
f32 ymax = 1; if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION)
if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) texture = tiles[texid].frames[0].texture;
ymax /= tiles[texid].animation_frame_count; else
texture = tiles[texid].texture;
float size = rand() % 64 / 512.; float size = rand() % 64 / 512.;
float visual_size = BS * size; float visual_size = BS * size;
v2f texsize(size * 2, ymax * size * 2); v2f texsize(size * 2, size * 2);
v2f texpos; v2f texpos;
texpos.X = ((rand() % 64) / 64. - texsize.X); texpos.X = ((rand() % 64) / 64. - texsize.X);
texpos.Y = ymax * ((rand() % 64) / 64. - texsize.Y); texpos.Y = ((rand() % 64) / 64. - texsize.Y);
// Physics // Physics
v3f velocity((rand() % 100 / 50. - 1) / 1.5, v3f velocity((rand() % 100 / 50. - 1) / 1.5,

@ -338,11 +338,11 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
tiledef.animation.type = (TileAnimationType) tiledef.animation.type = (TileAnimationType)
getenumfield(L, -1, "type", es_TileAnimationType, getenumfield(L, -1, "type", es_TileAnimationType,
TAT_NONE); TAT_NONE);
tiledef.animation.aspect_w = tiledef.animation.vertical_frames.aspect_w =
getintfield_default(L, -1, "aspect_w", 16); getintfield_default(L, -1, "aspect_w", 16);
tiledef.animation.aspect_h = tiledef.animation.vertical_frames.aspect_h =
getintfield_default(L, -1, "aspect_h", 16); getintfield_default(L, -1, "aspect_h", 16);
tiledef.animation.length = tiledef.animation.vertical_frames.length =
getfloatfield_default(L, -1, "length", 1.0); getfloatfield_default(L, -1, "length", 1.0);
} }
lua_pop(L, 1); lua_pop(L, 1);

87
src/tileanimation.cpp Normal file

@ -0,0 +1,87 @@
/*
Minetest
Copyright (C) 2016 sfan5 <sfan5@live.de>
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;
}

49
src/tileanimation.h Normal file

@ -0,0 +1,49 @@
/*
Minetest
Copyright (C) 2016 sfan5 <sfan5@live.de>
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 <iostream>
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