diff options
-rw-r--r-- | doc/lua_api.txt | 5 | ||||
-rw-r--r-- | src/content_cao.cpp | 20 | ||||
-rw-r--r-- | src/object_properties.cpp | 61 | ||||
-rw-r--r-- | src/object_properties.h | 7 | ||||
-rw-r--r-- | src/scriptapi.cpp | 39 |
5 files changed, 128 insertions, 4 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 84c86061f..2b2b6c6f1 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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}, diff --git a/src/content_cao.cpp b/src/content_cao.cpp index cd822cb33..4df238b24 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -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) diff --git a/src/object_properties.cpp b/src/object_properties.cpp index c91384ada..eb26db8d3 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -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); diff --git a/src/object_properties.h b/src/object_properties.h index 48240e6ea..3ab488f92 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -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; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 9293e2b65..74de50ef8 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -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(); |