diff options
author | Perttu Ahola <celeron55@gmail.com> | 2012-06-16 03:40:45 +0300 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2012-06-16 16:47:28 +0300 |
commit | fd1135c7af46eb2f5b99a11f48bf9f9ae335ea9c (patch) | |
tree | 69fe59e684b1e75e817b5a31cfc9a147c2d0a3da /src/nodedef.cpp | |
parent | f0678979b1ed5c70095a48820a8110eb631ed74d (diff) | |
download | minetest-fd1135c7af46eb2f5b99a11f48bf9f9ae335ea9c.tar.gz minetest-fd1135c7af46eb2f5b99a11f48bf9f9ae335ea9c.tar.bz2 minetest-fd1135c7af46eb2f5b99a11f48bf9f9ae335ea9c.zip |
Node texture animation
Diffstat (limited to 'src/nodedef.cpp')
-rw-r--r-- | src/nodedef.cpp | 147 |
1 files changed, 115 insertions, 32 deletions
diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 72f1ea2ea..d0ce3c19d 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -63,19 +63,29 @@ void NodeBox::deSerialize(std::istream &is) } /* - MaterialSpec + TileDef */ - -void MaterialSpec::serialize(std::ostream &os) const + +void TileDef::serialize(std::ostream &os) const { - os<<serializeString(tname); - writeU8(os, backface_culling); + writeU8(os, 0); // version + os<<serializeString(name); + writeU8(os, animation.type); + writeU16(os, animation.aspect_w); + writeU16(os, animation.aspect_h); + writeF1000(os, animation.length); } -void MaterialSpec::deSerialize(std::istream &is) +void TileDef::deSerialize(std::istream &is) { - tname = deSerializeString(is); - backface_culling = readU8(is); + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported TileDef version"); + name = deSerializeString(is); + animation.type = (TileAnimationType)readU8(is); + animation.aspect_w = readU16(is); + animation.aspect_h = readU16(is); + animation.length = readF1000(is); } /* @@ -133,9 +143,9 @@ void ContentFeatures::reset() drawtype = NDT_NORMAL; visual_scale = 1.0; for(u32 i=0; i<6; i++) - tname_tiles[i] = ""; + tiledef[i] = TileDef(); for(u16 j=0; j<CF_SPECIAL_COUNT; j++) - mspec_special[j] = MaterialSpec(); + tiledef_special[j] = TileDef(); alpha = 255; post_effect_color = video::SColor(0, 0, 0, 0); param_type = CPT_NONE; @@ -164,7 +174,7 @@ void ContentFeatures::reset() void ContentFeatures::serialize(std::ostream &os) { - writeU8(os, 3); // version + writeU8(os, 4); // version os<<serializeString(name); writeU16(os, groups.size()); for(ItemGroupList::const_iterator @@ -176,10 +186,10 @@ void ContentFeatures::serialize(std::ostream &os) writeF1000(os, visual_scale); writeU8(os, 6); for(u32 i=0; i<6; i++) - os<<serializeString(tname_tiles[i]); + tiledef[i].serialize(os); writeU8(os, CF_SPECIAL_COUNT); for(u32 i=0; i<CF_SPECIAL_COUNT; i++){ - mspec_special[i].serialize(os); + tiledef_special[i].serialize(os); } writeU8(os, alpha); writeU8(os, post_effect_color.getAlpha()); @@ -214,7 +224,7 @@ void ContentFeatures::serialize(std::ostream &os) void ContentFeatures::deSerialize(std::istream &is) { int version = readU8(is); - if(version != 3) + if(version != 4 && version != 3) throw SerializationError("unsupported ContentFeatures version"); name = deSerializeString(is); groups.clear(); @@ -228,12 +238,21 @@ void ContentFeatures::deSerialize(std::istream &is) visual_scale = readF1000(is); if(readU8(is) != 6) throw SerializationError("unsupported tile count"); - for(u32 i=0; i<6; i++) - tname_tiles[i] = deSerializeString(is); + for(u32 i=0; i<6; i++){ + if(version == 4) + tiledef[i].deSerialize(is); + else if(version == 3) // Allow connecting to older servers + tiledef[i].name = deSerializeString(is); + } if(readU8(is) != CF_SPECIAL_COUNT) throw SerializationError("unsupported CF_SPECIAL_COUNT"); for(u32 i=0; i<CF_SPECIAL_COUNT; i++){ - mspec_special[i].deSerialize(is); + if(version == 4){ + tiledef_special[i].deSerialize(is); + } else if(version == 3){ // Allow connecting to older servers + tiledef_special[i].name = deSerializeString(is); + tiledef_special[i].backface_culling = readU8(is); + } } alpha = readU8(is); post_effect_color.setAlpha(readU8(is)); @@ -260,12 +279,12 @@ void ContentFeatures::deSerialize(std::istream &is) selection_box.deSerialize(is); legacy_facedir_simple = readU8(is); legacy_wallmounted = readU8(is); + deSerializeSimpleSoundSpec(sound_footstep, is); + deSerializeSimpleSoundSpec(sound_dig, is); + deSerializeSimpleSoundSpec(sound_dug, is); // If you add anything here, insert it primarily inside the try-catch // block to not need to increase the version. try{ - deSerializeSimpleSoundSpec(sound_footstep, is); - deSerializeSimpleSoundSpec(sound_dig, is); - deSerializeSimpleSoundSpec(sound_dug, is); }catch(SerializationError &e) {}; } @@ -494,14 +513,15 @@ public: for(u16 i=0; i<=MAX_CONTENT; i++) { ContentFeatures *f = &m_content_features[i]; - - std::string tname_tiles[6]; + + // Figure out the actual tiles to use + TileDef tiledef[6]; for(u32 j=0; j<6; j++) { - tname_tiles[j] = f->tname_tiles[j]; - if(tname_tiles[j] == "") - tname_tiles[j] = "unknown_block.png"; - } + tiledef[j] = f->tiledef[j]; + if(tiledef[j].name == "") + tiledef[j].name = "unknown_block.png"; + } switch(f->drawtype){ default: @@ -547,7 +567,7 @@ public: f->drawtype = NDT_NORMAL; f->solidness = 2; for(u32 i=0; i<6; i++){ - tname_tiles[i] += std::string("^[noalpha"); + tiledef[i].name += std::string("^[noalpha"); } } break; @@ -560,29 +580,92 @@ public: break; } - // Tile textures + // Tiles (fill in f->tiles[]) for(u16 j=0; j<6; j++){ - f->tiles[j].texture = tsrc->getTexture(tname_tiles[j]); + // Texture + f->tiles[j].texture = tsrc->getTexture(tiledef[j].name); + // Alpha f->tiles[j].alpha = f->alpha; if(f->alpha == 255) f->tiles[j].material_type = MATERIAL_ALPHA_SIMPLE; else f->tiles[j].material_type = MATERIAL_ALPHA_VERTEX; + // Material flags f->tiles[j].material_flags = 0; if(f->backface_culling) f->tiles[j].material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; + if(tiledef[j].animation.type == TAT_VERTICAL_FRAMES) + f->tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + // Animation parameters + if(f->tiles[j].material_flags & + MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) + { + // Get raw texture size to determine frame count by + // aspect ratio + video::ITexture *t = tsrc->getTextureRaw(tiledef[j].name); + v2u32 size = t->getOriginalSize(); + int frame_height = (float)size.X / + (float)tiledef[j].animation.aspect_w * + (float)tiledef[j].animation.aspect_h; + int frame_count = size.Y / frame_height; + int frame_length_ms = 1000.0 * + tiledef[j].animation.length / frame_count; + f->tiles[j].animation_frame_count = frame_count; + f->tiles[j].animation_frame_length_ms = frame_length_ms; + + // If there are no frames for an animation, switch + // animation off (so that having specified an animation + // for something but not using it in the texture pack + // gives no overhead) + if(frame_count == 1){ + f->tiles[j].material_flags &= + ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + } + } } - // Special tiles + // Special tiles (fill in f->special_tiles[]) for(u16 j=0; j<CF_SPECIAL_COUNT; j++){ - f->special_tiles[j].texture = tsrc->getTexture(f->mspec_special[j].tname); + // Texture + f->special_tiles[j].texture = + tsrc->getTexture(f->tiledef_special[j].name); + // Alpha f->special_tiles[j].alpha = f->alpha; if(f->alpha == 255) f->special_tiles[j].material_type = MATERIAL_ALPHA_SIMPLE; else f->special_tiles[j].material_type = MATERIAL_ALPHA_VERTEX; + // Material flags f->special_tiles[j].material_flags = 0; - if(f->mspec_special[j].backface_culling) + if(f->tiledef_special[j].backface_culling) f->special_tiles[j].material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; + if(f->tiledef_special[j].animation.type == TAT_VERTICAL_FRAMES) + f->special_tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + // Animation parameters + if(f->special_tiles[j].material_flags & + MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) + { + // Get raw texture size to determine frame count by + // aspect ratio + video::ITexture *t = tsrc->getTextureRaw(f->tiledef_special[j].name); + v2u32 size = t->getOriginalSize(); + int frame_height = (float)size.X / + (float)f->tiledef_special[j].animation.aspect_w * + (float)f->tiledef_special[j].animation.aspect_h; + int frame_count = size.Y / frame_height; + int frame_length_ms = 1000.0 * + f->tiledef_special[j].animation.length / frame_count; + f->special_tiles[j].animation_frame_count = frame_count; + f->special_tiles[j].animation_frame_length_ms = frame_length_ms; + + // If there are no frames for an animation, switch + // animation off (so that having specified an animation + // for something but not using it in the texture pack + // gives no overhead) + if(frame_count == 1){ + f->special_tiles[j].material_flags &= + ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + } + } } } #endif |