Allow the LUA API to set animations to meshes as well as the animation speed. Also...
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Thu, 25 Oct 2012 20:29:07 +0000 (23:29 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 25 Nov 2012 16:14:15 +0000 (18:14 +0200)
Support for animation blending, though for some reason it doesn't work.

Don't enable animation transitions by default for many reaosons

Object property to store individual bone positions. LUA can specify a bone name followed by a bone position. No functionality yet. Bone rotation to be added in the following commit

Same system for bone rotation, plus a few other things I missed

doc/lua_api.txt
src/content_cao.cpp
src/object_properties.cpp
src/object_properties.h
src/scriptapi.cpp

index 84c86061fd9520828255bc6a496bd020f6cdbf59..2b2b6c6f152941ed210c2ba347b3fbebc70ae1d5 100644 (file)
@@ -1230,6 +1230,11 @@ Object Properties
     visual = "cube"/"sprite"/"upright_sprite"/"mesh",
     visual_size = {x=1, y=1},
     mesh = "model",
+    animation_frames = {1, 1},
+    animation_speed = 15,
+    animation_blend = 0,
+    animation_bone_position = {"", {x=0, y=0, z=0}}, -- bone name followed by position vector
+    animation_bone_rotation = {"", {x=0, y=0, z=0}}, -- bone name followed by rotation vector
     textures = {}, -- number of required textures depends on visual
     spritediv = {x=1, y=1},
     initial_sprite_basepos = {x=0, y=0},
index cd822cb332386f7f3f019eba492315f82f4ec54f..4df238b249c551ced6bf3a38cf7137b4d8581895 100644 (file)
@@ -42,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include <IMeshManipulator.h>
 #include <IAnimatedMeshSceneNode.h>
+#include <IBoneSceneNode.h>
 
 class Settings;
 struct ToolCapabilities;
@@ -805,7 +806,8 @@ public:
                        if(mesh)
                        {
                                m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL);
-                               
+                               m_animated_meshnode->setMD2Animation(scene::EMAT_STAND);
+                               m_animated_meshnode->animateJoints(); // Needed for some animations
                                m_animated_meshnode->setScale(v3f(m_prop.visual_size.X,
                                                m_prop.visual_size.Y,
                                                m_prop.visual_size.X));
@@ -922,6 +924,7 @@ public:
                        m_visuals_expired = false;
                        removeFromScene();
                        addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
+                       updateAnimations();
                }
 
                if(m_prop.physical){
@@ -979,8 +982,6 @@ public:
 
                updateTexturePos();
 
-               updateAnimations();
-
                if(m_reset_textures_timer >= 0){
                        m_reset_textures_timer -= dtime;
                        if(m_reset_textures_timer <= 0){
@@ -1141,7 +1142,18 @@ public:
                if(!m_animated_meshnode)
                        return;
 
-               m_animated_meshnode->setFrameLoop(0, 50);
+               m_animated_meshnode->setFrameLoop(m_prop.animation_frames.X, m_prop.animation_frames.Y);
+               m_animated_meshnode->setAnimationSpeed(m_prop.animation_speed);
+               m_animated_meshnode->setTransitionTime(m_prop.animation_blend);
+
+               for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_position.begin(); ii != m_prop.animation_bone_position.end(); ++ii){
+                       if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { }
+                       // Bone positioning code will go here
+               }
+               for(std::map<std::string, v3f>::const_iterator ii = m_prop.animation_bone_rotation.begin(); ii != m_prop.animation_bone_rotation.end(); ++ii){
+                       if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { }
+                       // Bone rotation code will go here
+               }
        }
 
        void processMessage(const std::string &data)
index c91384ada3569643534ea426ad1208825a2db962..eb26db8d3f5a01fafc067dbbabc29ef05d706a74 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "object_properties.h"
 #include "util/serialize.h"
 #include <sstream>
+#include <map>
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 #define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
@@ -31,6 +32,9 @@ ObjectProperties::ObjectProperties():
        collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
        visual("sprite"),
        mesh(""),
+       animation_frames(1,1),
+       animation_speed(15),
+       animation_blend(0),
        visual_size(1,1),
        spritediv(1,1),
        initial_sprite_basepos(0,0),
@@ -38,6 +42,8 @@ ObjectProperties::ObjectProperties():
        makes_footstep_sound(false),
        automatic_rotate(0)
 {
+       animation_bone_position[""] = v3f(0,0,0);
+       animation_bone_rotation[""] = v3f(0,0,0);
        textures.push_back("unknown_object.png");
 }
 
@@ -50,7 +56,26 @@ std::string ObjectProperties::dump()
        os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
        os<<", visual="<<visual;
        os<<", mesh="<<mesh;
+       os<<", animation_frames="<<animation_frames.X<<","<<animation_frames.Y;
+       os<<", animation_speed="<<animation_speed;
+       os<<", animation_blend="<<animation_blend;
        os<<", visual_size="<<PP2(visual_size);
+
+       os<<", animation_bone_position=[";
+       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
+               std::string bone_name = (*ii).first;
+               v3f bone_pos = (*ii).second;
+               os<<bone_name<<" "<<bone_pos.X<<","<<bone_pos.Y<<","<<bone_pos.Z<<"\"";
+       }
+       os<<"]";
+       os<<", animation_bone_rotation=[";
+       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
+               std::string bone_name = (*ii).first;
+               v3f bone_rot = (*ii).second;
+               os<<bone_name<<" "<<bone_rot.X<<","<<bone_rot.Y<<","<<bone_rot.Z<<"\"";
+       }
+       os<<"]";
+
        os<<", textures=[";
        for(u32 i=0; i<textures.size(); i++){
                os<<"\""<<textures[i]<<"\" ";
@@ -74,11 +99,28 @@ void ObjectProperties::serialize(std::ostream &os) const
        writeV3F1000(os, collisionbox.MaxEdge);
        os<<serializeString(visual);
        os<<serializeString(mesh);
+       writeF1000(os, animation_frames.X);
+       writeF1000(os, animation_frames.Y);
+       writeF1000(os, animation_speed);
+       writeF1000(os, animation_blend);
+
+       writeU16(os, animation_bone_position.size());
+       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
+               os<<serializeString((*ii).first);
+               writeV3F1000(os, (*ii).second);
+       }
+       writeU16(os, animation_bone_rotation.size());
+       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
+               os<<serializeString((*ii).first);
+               writeV3F1000(os, (*ii).second);
+       }
+
        writeV2F1000(os, visual_size);
        writeU16(os, textures.size());
        for(u32 i=0; i<textures.size(); i++){
                os<<serializeString(textures[i]);
        }
+
        writeV2S16(os, spritediv);
        writeV2S16(os, initial_sprite_basepos);
        writeU8(os, is_visible);
@@ -98,12 +140,31 @@ void ObjectProperties::deSerialize(std::istream &is)
        collisionbox.MaxEdge = readV3F1000(is);
        visual = deSerializeString(is);
        mesh = deSerializeString(is);
+       animation_frames.X = readF1000(is);
+       animation_frames.Y = readF1000(is);
+       animation_speed = readF1000(is);
+       animation_blend = readF1000(is);
+
+       u32 animation_bone_position_count = readU16(is);
+       for(u32 i=0; i<animation_bone_position_count; i++){
+               std::string bone_name = deSerializeString(is);
+               v3f bone_pos = readV3F1000(is);
+               animation_bone_position[bone_name] = bone_pos;
+       }
+       u32 animation_bone_rotation_count = readU16(is);
+       for(u32 i=0; i<animation_bone_rotation_count; i++){
+               std::string bone_name = deSerializeString(is);
+               v3f bone_rot = readV3F1000(is);
+               animation_bone_rotation[bone_name] = bone_rot;
+       }
+
        visual_size = readV2F1000(is);
        textures.clear();
        u32 texture_count = readU16(is);
        for(u32 i=0; i<texture_count; i++){
                textures.push_back(deSerializeString(is));
        }
+
        spritediv = readV2S16(is);
        initial_sprite_basepos = readV2S16(is);
        is_visible = readU8(is);
index 48240e6ea45fc9c3bf46f93d5ff772fa459b2396..3ab488f92bade29b843425926888dcd5bc225753 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 #include "irrlichttypes_bloated.h"
 #include <iostream>
+#include <map>
 
 struct ObjectProperties
 {
@@ -33,6 +34,11 @@ struct ObjectProperties
        core::aabbox3d<f32> collisionbox;
        std::string visual;
        std::string mesh;
+       core::vector2d<int> animation_frames;
+       float animation_speed;
+       float animation_blend;
+       std::map<std::string, v3f> animation_bone_position;
+       std::map<std::string, v3f> animation_bone_rotation;
        v2f visual_size;
        core::array<std::string> textures;
        v2s16 spritediv;
@@ -41,6 +47,7 @@ struct ObjectProperties
        bool makes_footstep_sound;
        float automatic_rotate;
 
+
        ObjectProperties();
        std::string dump();
        void serialize(std::ostream &os) const;
index 9293e2b6535b2d62a96bcdfd6204b3f46201ff64..74de50ef8c3e4e551e5075194540ba32ec45ad65 100644 (file)
@@ -944,6 +944,45 @@ static void read_object_properties(lua_State *L, int index,
                prop->visual_size = read_v2f(L, -1);
        lua_pop(L, 1);
 
+       lua_getfield(L, -1, "animation_frames");
+       if(lua_istable(L, -1))
+       {
+               lua_rawgeti (L, -1, 1);
+               lua_rawgeti (L, -2, 2);
+               prop->animation_frames.X = lua_tonumber(L, -2);
+               prop->animation_frames.Y = lua_tonumber(L, -1);
+               lua_pop(L, 2);
+       }
+       lua_pop(L, 1);
+
+       getfloatfield(L, -1, "animation_speed", prop->animation_speed);
+
+       getfloatfield(L, -1, "animation_blend", prop->animation_blend);
+
+       lua_getfield(L, -1, "animation_bone_position");
+       if(lua_istable(L, -1))
+       {
+               lua_rawgeti (L, -1, 1);
+               lua_rawgeti (L, -2, 2);
+               std::string bone_name = lua_tostring(L, -2);
+               v3f bone_pos = read_v3f(L, -1);
+               prop->animation_bone_position[bone_name] = bone_pos;
+               lua_pop(L, 2);
+       }
+       lua_pop(L, 1);
+
+       lua_getfield(L, -1, "animation_bone_rotation");
+       if(lua_istable(L, -1))
+       {
+               lua_rawgeti (L, -1, 1);
+               lua_rawgeti (L, -2, 2);
+               std::string bone_name = lua_tostring(L, -2);
+               v3f bone_rot = read_v3f(L, -1);
+               prop->animation_bone_rotation[bone_name] = bone_rot;
+               lua_pop(L, 2);
+       }
+       lua_pop(L, 1);
+
        lua_getfield(L, -1, "textures");
        if(lua_istable(L, -1)){
                prop->textures.clear();