summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt5
-rw-r--r--src/content_cao.cpp20
-rw-r--r--src/object_properties.cpp61
-rw-r--r--src/object_properties.h7
-rw-r--r--src/scriptapi.cpp39
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();