Allow full circle rotation with 2degs step for plantlike drawtype.
[oweals/minetest.git] / src / nodedef.cpp
index d13d0653daeed31f7aa23053f971078b167b89a9..e972ab927b28605e84e4b4333187a70388c73e96 100644 (file)
@@ -117,7 +117,7 @@ void NodeBox::deSerialize(std::istream &is)
 void TileDef::serialize(std::ostream &os, u16 protocol_version) const
 {
        if(protocol_version >= 17)
-               writeU8(os, 1); 
+               writeU8(os, 1);
        else
                writeU8(os, 0);
        os<<serializeString(name);
@@ -225,6 +225,7 @@ void ContentFeatures::reset()
        damage_per_second = 0;
        node_box = NodeBox();
        selection_box = NodeBox();
+       waving = 0;
        legacy_facedir_simple = false;
        legacy_wallmounted = false;
        sound_footstep = SimpleSoundSpec();
@@ -292,6 +293,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version)
        writeU8(os, liquid_range);
        // Stuff below should be moved to correct place in a version that otherwise changes
        // the protocol version
+       writeU8(os, waving);
 }
 
 void ContentFeatures::deSerialize(std::istream &is)
@@ -359,6 +361,7 @@ void ContentFeatures::deSerialize(std::istream &is)
        try{
                // Stuff below should be moved to correct place in a version that
                // otherwise changes the protocol version
+       waving = readU8(is);
        }catch(SerializationError &e) {};
 }
 
@@ -557,7 +560,7 @@ public:
                for (ItemGroupList::const_iterator i = def.groups.begin();
                        i != def.groups.end(); ++i) {
                        std::string group_name = i->first;
-                       
+
                        std::map<std::string, GroupItems>::iterator
                                j = m_group_to_items.find(group_name);
                        if (j == m_group_to_items.end()) {
@@ -594,7 +597,8 @@ public:
                        }
                }
        }
-       virtual void updateTextures(ITextureSource *tsrc)
+       virtual void updateTextures(ITextureSource *tsrc,
+               IShaderSource *shdsrc)
        {
 #ifndef SERVER
                infostream<<"CNodeDefManager::updateTextures(): Updating "
@@ -603,6 +607,9 @@ public:
                bool new_style_water = g_settings->getBool("new_style_water");
                bool new_style_leaves = g_settings->getBool("new_style_leaves");
                bool opaque_water = g_settings->getBool("opaque_water");
+               bool enable_shaders = g_settings->getBool("enable_shaders");
+               bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
+               bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
 
                for(u32 i=0; i<m_content_features.size(); i++)
                {
@@ -618,6 +625,11 @@ public:
                        }
 
                        bool is_liquid = false;
+                       bool is_water_surface = false;
+
+                       u8 material_type;
+                       material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
+
                        switch(f->drawtype){
                        default:
                        case NDT_NORMAL:
@@ -669,10 +681,14 @@ public:
                                                tiledef[i].name += std::string("^[noalpha");
                                        }
                                }
+                               if (f->waving == 1)
+                                       material_type = TILE_MATERIAL_WAVING_LEAVES;
                                break;
                        case NDT_PLANTLIKE:
                                f->solidness = 0;
                                f->backface_culling = false;
+                               if (f->waving == 1)
+                                       material_type = TILE_MATERIAL_WAVING_PLANTS;
                                break;
                        case NDT_TORCHLIKE:
                        case NDT_SIGNLIKE:
@@ -683,18 +699,29 @@ public:
                                break;
                        }
 
-                       u8 material_type;
-                       if (is_liquid)
+                       if (is_liquid){
                                material_type = (f->alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
-                       else
-                               material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
+                               if (f->name == "default:water_source")
+                                       is_water_surface = true;
+                       }
+                       u32 tile_shader[6];
+                       for(u16 j=0; j<6; j++)
+                               tile_shader[j] = shdsrc->getShader("nodes_shader",material_type, f->drawtype);
+
+                       if (is_water_surface)
+                               tile_shader[0] = shdsrc->getShader("water_surface_shader",material_type, f->drawtype);
 
                        // Tiles (fill in f->tiles[])
                        for(u16 j=0; j<6; j++){
+                               // Shader
+                               f->tiles[j].shader_id = tile_shader[j];
                                // Texture
                                f->tiles[j].texture = tsrc->getTexture(
                                                tiledef[j].name,
                                                &f->tiles[j].texture_id);
+                               // Normal texture
+                               if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
+                                       f->tiles[j].normal_texture = tsrc->getNormalTexture(tiledef[j].name);
                                // Alpha
                                f->tiles[j].alpha = f->alpha;
                                // Material type
@@ -706,37 +733,46 @@ public:
                                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)
-                               {
+                               int frame_count = 1;
+                               if(f->tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
                                        // Get texture size to determine frame count by
                                        // aspect ratio
                                        v2u32 size = f->tiles[j].texture->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;
+                                       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;
+                               }
+                               if(frame_count == 1) {
+                                       f->tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+                               } else {
+                                       std::ostringstream os(std::ios::binary);
+                                       for (int i = 0; i < frame_count; i++) {
+                                               FrameSpec frame;
+                                               os.str("");
+                                               os<<tiledef[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
+                                               frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
+                                               if (f->tiles[j].normal_texture)
+                                                       frame.normal_texture = tsrc->getNormalTexture(os.str());
+                                               f->tiles[j].frames[i]=frame;
                                        }
                                }
                        }
                        // Special tiles (fill in f->special_tiles[])
                        for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
+                               // Shader
+                               f->special_tiles[j].shader_id = tile_shader[j];
                                // Texture
                                f->special_tiles[j].texture = tsrc->getTexture(
                                                f->tiledef_special[j].name,
                                                &f->special_tiles[j].texture_id);
+                               // Normal texture
+                               if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
+                                       f->special_tiles[j].normal_texture = tsrc->getNormalTexture(f->tiledef_special[j].name);
                                // Alpha
                                f->special_tiles[j].alpha = f->alpha;
                                // Material type
@@ -748,28 +784,32 @@ public:
                                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)
-                               {
+                               int frame_count = 1;
+                               if(f->special_tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
                                        // Get texture size to determine frame count by
                                        // aspect ratio
                                        v2u32 size = f->special_tiles[j].texture->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;
+                                       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;
+                               }
+                               if(frame_count == 1) {
+                                       f->special_tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+                               } else {
+                                       std::ostringstream os(std::ios::binary);
+                                       for (int i = 0; i < frame_count; i++) {
+                                               FrameSpec frame;
+                                               os.str("");
+                                               os<<f->tiledef_special[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
+                                               frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
+                                               if (f->special_tiles[j].normal_texture)
+                                                       frame.normal_texture = tsrc->getNormalTexture(os.str());
+                                               f->special_tiles[j].frames[i]=frame;
                                        }
                                }
                        }
@@ -995,4 +1035,3 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
                throw SerializationError("unsupported ContentFeatures version");
        }
 }
-