Framework for the attachment system, new object property which allows changing the...
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Fri, 26 Oct 2012 22:49:01 +0000 (01:49 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 25 Nov 2012 16:14:15 +0000 (18:14 +0200)
New object property which allows changing the color and alpha of mesh materials. Due to the current lighting systems it doesn't work yet, but the full implementation is there

Framework for the attachment system, with no actual functionality yet

Send bone and player object to the setAttachment function in content_sao.cpp, but we need a way to translate it there and send it to the client

I will also want position and rotation offsets to be possible to apply to attachments

Network object ID from server to client. This will be used to identify the parent client-side and know what to attach to

doc/lua_api.txt
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h
src/genericobject.cpp
src/genericobject.h
src/object_properties.cpp
src/object_properties.h
src/scriptapi.cpp
src/serverobject.h
src/util/serialize.h

index c99e8035a471a707bf27d77021b5bbfd5eb57faf..cb84b54593786da357f6bb0a13c674c0311ea39e 100644 (file)
@@ -1232,9 +1232,8 @@ Object Properties
     visual = "cube"/"sprite"/"upright_sprite"/"mesh",
     visual_size = {x=1, y=1},
     mesh = "model",
-    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
+    colors = {}, -- number of required colors depends on visual
     spritediv = {x=1, y=1},
     initial_sprite_basepos = {x=0, y=0},
     is_visible = true,
index b12bfe1c858a0bf0ee3d6c5854d2de2755823d54..3e18337d27e5fbd8b1af1191dd3da99ee93b9e70 100644 (file)
@@ -555,6 +555,7 @@ private:
        std::string m_name;
        bool m_is_player;
        bool m_is_local_player; // determined locally
+       int m_id;
        // Property-ish things
        ObjectProperties m_prop;
        //
@@ -596,6 +597,7 @@ public:
                //
                m_is_player(false),
                m_is_local_player(false),
+               m_id(0),
                //
                m_smgr(NULL),
                m_irr(NULL),
@@ -640,6 +642,7 @@ public:
                }
                m_name = deSerializeString(is);
                m_is_player = readU8(is);
+               m_id = readS16(is);
                m_position = readV3F1000(is);
                m_yaw = readF1000(is);
                m_hp = readS16(is);
@@ -930,6 +933,7 @@ public:
                        addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
                        updateAnimations();
                        updateBonePosRot();
+                       updateAttachment();
                }
 
                if(m_prop.physical){
@@ -1062,6 +1066,10 @@ public:
                                texturestring += mod;
                                m_spritenode->setMaterialTexture(0,
                                                tsrc->getTextureRaw(texturestring));
+
+                               // Does not work yet with the current lighting settings
+                               m_meshnode->getMaterial(0).AmbientColor = m_prop.colors[0];
+                               m_meshnode->getMaterial(0).DiffuseColor = m_prop.colors[0];
                        }
                }
                if(m_animated_meshnode)
@@ -1087,6 +1095,12 @@ public:
                                        material.setFlag(video::EMF_LIGHTING, false);
                                        material.setFlag(video::EMF_BILINEAR_FILTER, false);
                                }
+                               for (u32 i = 0; i < m_prop.colors.size(); ++i)
+                               {
+                                       // Does not work yet with the current lighting settings
+                                       m_animated_meshnode->getMaterial(i).AmbientColor = m_prop.colors[i];
+                                       m_animated_meshnode->getMaterial(i).DiffuseColor = m_prop.colors[i];
+                               }
                        }
                }
                if(m_meshnode)
@@ -1113,6 +1127,10 @@ public:
                                        material.setTexture(0, atlas);
                                        material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
                                        material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
+
+                                       // Does not work yet with the current lighting settings
+                                       m_meshnode->getMaterial(i).AmbientColor = m_prop.colors[i];
+                                       m_meshnode->getMaterial(i).DiffuseColor = m_prop.colors[i];
                                }
                        }
                        else if(m_prop.visual == "upright_sprite")
@@ -1126,6 +1144,10 @@ public:
                                        scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
                                        buf->getMaterial().setTexture(0,
                                                        tsrc->getTextureRaw(tname));
+                                       
+                                       // Does not work yet with the current lighting settings
+                                       m_meshnode->getMaterial(0).AmbientColor = m_prop.colors[0];
+                                       m_meshnode->getMaterial(0).DiffuseColor = m_prop.colors[0];
                                }
                                {
                                        std::string tname = "unknown_object.png";
@@ -1137,6 +1159,10 @@ public:
                                        scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
                                        buf->getMaterial().setTexture(0,
                                                        tsrc->getTextureRaw(tname));
+
+                                       // Does not work yet with the current lighting settings
+                                       m_meshnode->getMaterial(1).AmbientColor = m_prop.colors[1]; 
+                                       m_meshnode->getMaterial(1).DiffuseColor = m_prop.colors[1]; 
                                }
                        }
                }
@@ -1168,6 +1194,11 @@ public:
                }
        }
 
+       void updateAttachment()
+       {
+               // Code for attachments goes here
+       }
+
        void processMessage(const std::string &data)
        {
                //infostream<<"GenericCAO: Got message"<<std::endl;
@@ -1254,6 +1285,15 @@ public:
                        updateBonePosRot();
                        expireVisuals();
                }
+               else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
+               {
+                       // Part of the attachment structure, not used yet!
+
+                       // Get properties here.
+
+                       updateAttachment();
+                       expireVisuals();
+               }
                else if(cmd == GENERIC_CMD_PUNCHED)
                {
                        /*s16 damage =*/ readS16(is);
index bb38fa10ec7a7e8bda49faf11c807d3e691a8bae..b23d287f406bbb70de2e02bba2056556b867bb60 100644 (file)
@@ -504,6 +504,7 @@ std::string LuaEntitySAO::getClientInitializationData()
        std::ostringstream os(std::ios::binary);
        writeU8(os, 0); // version
        os<<serializeString(""); // name
+       writeS16(os, getId()); //id
        writeU8(os, 0); // is_player
        writeV3F1000(os, m_base_position);
        writeF1000(os, m_yaw);
@@ -660,6 +661,19 @@ void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
        m_messages_out.push_back(aom);
 }
 
+// Part of the attachment structure, not used yet!
+void LuaEntitySAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation)
+{
+       // Parent should be translated from a ServerActiveObject into something
+       // the client will recognize (as a ClientActiveObject) then sent in
+       // gob_cmd_set_attachment that way.
+
+       std::string str = gob_cmd_set_attachment(); // <- parameters here
+       // create message and add to list
+       ActiveObjectMessage aom(getId(), true, str);
+       m_messages_out.push_back(aom);
+}
+
 ObjectProperties* LuaEntitySAO::accessObjectProperties()
 {
        return &m_prop;
@@ -804,6 +818,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
        m_prop.textures.clear();
        m_prop.textures.push_back("player.png");
        m_prop.textures.push_back("player_back.png");
+       m_prop.colors.clear();
+       m_prop.colors.push_back(video::SColor(255, 255, 255, 255));
        m_prop.spritediv = v2s16(1,1);
        // end of default appearance
        m_prop.is_visible = (getHP() != 0); // TODO: Use a death animation instead for mesh players
@@ -860,6 +876,7 @@ std::string PlayerSAO::getClientInitializationData()
        writeU8(os, 0); // version
        os<<serializeString(m_player->getName()); // name
        writeU8(os, 1); // is_player
+       writeS16(os, getId()); //id
        writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
        writeF1000(os, m_player->getYaw());
        writeS16(os, getHP());
@@ -1109,6 +1126,15 @@ void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
        m_messages_out.push_back(aom);
 }
 
+// Part of the attachment structure, not used yet!
+void PlayerSAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation)
+{      
+       std::string str = gob_cmd_set_attachment(); // <- parameters here
+       // create message and add to list
+       ActiveObjectMessage aom(getId(), true, str);
+       m_messages_out.push_back(aom);
+}
+
 ObjectProperties* PlayerSAO::accessObjectProperties()
 {
        return &m_prop;
index cba2729aea7bbfb392fdc577f73300ef9be627a3..a89f2ddd4adbd43ef6f12d525c03110722ec0992 100644 (file)
@@ -63,6 +63,7 @@ public:
        void setArmorGroups(const ItemGroupList &armor_groups);
        void setAnimations(v2f frames, float frame_speed, float frame_blend);
        void setBonePosRot(std::string bone, v3f position, v3f rotation);
+       void setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation);
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
        /* LuaEntitySAO-specific */
@@ -146,6 +147,7 @@ public:
        void setArmorGroups(const ItemGroupList &armor_groups);
        void setAnimations(v2f frames, float frame_speed, float frame_blend);
        void setBonePosRot(std::string bone, v3f position, v3f rotation);
+       void setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation);
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
 
index d915d78a548c55b12a43a07a1c87e6023b41fae1..482dbbc78d56eb2c05b287cc6bbd6e1cb9ef1210 100644 (file)
@@ -104,6 +104,17 @@ std::string gob_cmd_set_animations(v2f frames, float frame_speed, float frame_bl
        return os.str();
 }
 
+// Part of the attachment structure, not used yet!
+std::string gob_cmd_set_attachment() // <- parameters here
+{
+       std::ostringstream os(std::ios::binary);
+       // command 
+       writeU8(os, GENERIC_CMD_SET_ATTACHMENT);
+       // parameters
+       // Parameters go here
+       return os.str();
+}
+
 std::string gob_cmd_set_bone_posrot(std::string bone, v3f position, v3f rotation)
 {
        std::ostringstream os(std::ios::binary);
index 7e3e9d96f766835faf9e446113c116f3dfde0dfb..d20e7b3d0a6246f4f880ce3f1796baf2c9bafc9d 100644 (file)
@@ -30,8 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GENERIC_CMD_SET_SPRITE 3
 #define GENERIC_CMD_SET_ANIMATIONS 4
 #define GENERIC_CMD_SET_BONE_POSROT 5
-#define GENERIC_CMD_PUNCHED 6
-#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 7
+#define GENERIC_CMD_SET_ATTACHMENT 6
+#define GENERIC_CMD_PUNCHED 7
+#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 8
 
 #include "object_properties.h"
 std::string gob_cmd_set_properties(const ObjectProperties &prop);
@@ -60,6 +61,8 @@ std::string gob_cmd_set_animations(v2f frames, float frame_speed, float frame_bl
 
 std::string gob_cmd_set_bone_posrot(std::string bone, v3f position, v3f rotation);
 
+std::string gob_cmd_set_attachment(); // <- parameters here
+
 std::string gob_cmd_punched(s16 damage, s16 result_hp);
 
 #include "itemgroup.h"
index 57e255f583f0b584d76960caaffd84674ac6cc53..79b3eaf7287639595318c40316848d1b44301393 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "object_properties.h"
+#include "irrlichttypes_bloated.h"
 #include "util/serialize.h"
 #include <sstream>
 #include <map>
@@ -40,6 +41,7 @@ ObjectProperties::ObjectProperties():
        automatic_rotate(0)
 {
        textures.push_back("unknown_object.png");
+       colors.push_back(video::SColor(255,255,255,255));
 }
 
 std::string ObjectProperties::dump()
@@ -57,6 +59,11 @@ std::string ObjectProperties::dump()
                os<<"\""<<textures[i]<<"\" ";
        }
        os<<"]";
+       os<<", colors=[";
+       for(u32 i=0; i<colors.size(); i++){
+               os<<"\""<<colors[i].getAlpha()<<","<<colors[i].getRed()<<","<<colors[i].getGreen()<<","<<colors[i].getBlue()<<"\" ";
+       }
+       os<<"]";
        os<<", spritediv="<<PP2(spritediv);
        os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos);
        os<<", is_visible="<<is_visible;
@@ -80,6 +87,10 @@ void ObjectProperties::serialize(std::ostream &os) const
        for(u32 i=0; i<textures.size(); i++){
                os<<serializeString(textures[i]);
        }
+       writeU16(os, colors.size());
+       for(u32 i=0; i<colors.size(); i++){
+               writeARGB8(os, colors[i]);
+       }
        writeV2S16(os, spritediv);
        writeV2S16(os, initial_sprite_basepos);
        writeU8(os, is_visible);
@@ -105,6 +116,10 @@ void ObjectProperties::deSerialize(std::istream &is)
        for(u32 i=0; i<texture_count; i++){
                textures.push_back(deSerializeString(is));
        }
+       u32 color_count = readU16(is);
+       for(u32 i=0; i<color_count; i++){
+               colors.push_back(readARGB8(is));
+       }
        spritediv = readV2S16(is);
        initial_sprite_basepos = readV2S16(is);
        is_visible = readU8(is);
index 53d482904680b814758c00b4e1e01aedf4870762..d7d44625e273745dff63c38fed6ccd740674c2fb 100644 (file)
@@ -36,6 +36,7 @@ struct ObjectProperties
        std::string mesh;
        v2f visual_size;
        core::array<std::string> textures;
+       core::array<video::SColor> colors;
        v2s16 spritediv;
        v2s16 initial_sprite_basepos;
        bool is_visible;
index 3e187d2f627e53aaa19e2be3f52c11084a3c720d..9c5bbcc5bff252c4080a8a467aef1cf5d6ef9dc2 100644 (file)
@@ -960,6 +960,23 @@ static void read_object_properties(lua_State *L, int index,
                }
        }
        lua_pop(L, 1);
+
+       lua_getfield(L, -1, "colors");
+       if(lua_istable(L, -1)){
+               prop->colors.clear();
+               int table = lua_gettop(L);
+               lua_pushnil(L);
+               while(lua_next(L, table) != 0){
+                       // key at index -2 and value at index -1
+                       if(lua_isstring(L, -1))
+                               prop->colors.push_back(readARGB8(L, -1));
+                       else
+                               prop->colors.push_back(video::SColor(255, 255, 255, 255));
+                       // removes value, keeps key for next iteration
+                       lua_pop(L, 1);
+               }
+       }
+       lua_pop(L, 1);
        
        lua_getfield(L, -1, "spritediv");
        if(lua_istable(L, -1))
@@ -2741,6 +2758,33 @@ private:
                return 0;
        }
 
+// Part of the attachment structure, not used yet!
+       // set_attachment() // <- parameters here
+       static int l_set_attachment(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ObjectRef *parent_ref = checkobject(L, 2);
+               ServerActiveObject *co = getobject(ref);
+               ServerActiveObject *parent = getobject(parent_ref);
+               if(co == NULL) return 0;
+               if(parent == NULL) return 0;
+               std::string bone = "";
+               if(!lua_isnil(L, 3))
+                       bone = lua_tostring(L, 3);
+               v3f position = v3f(0, 0, 0);
+               if(!lua_isnil(L, 4))
+                       position = read_v3f(L, 4);
+               v3f rotation = v3f(0, 0, 0);
+               if(!lua_isnil(L, 5))
+                       rotation = read_v3f(L, 5);
+               // Do it
+       
+//lua_pushnumber(L, cobj->getId()); // Push id
+
+               co->setAttachment(parent, bone, position, rotation);
+               return 0;
+       }
+
        // set_properties(self, properties)
        static int l_set_properties(lua_State *L)
        {
@@ -3057,6 +3101,7 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, set_armor_groups),
        method(ObjectRef, set_animations),
        method(ObjectRef, set_bone_posrot),
+       method(ObjectRef, set_attachment),
        method(ObjectRef, set_properties),
        // LuaEntitySAO-only
        method(ObjectRef, setvelocity),
index 61991bedf5944100b40257bb1b858e2dbbf448bd..3dcb99552a5a8aeeacff1535a6daf46fa9199237 100644 (file)
@@ -156,6 +156,8 @@ public:
        {}
        virtual void setBonePosRot(std::string bone, v3f position, v3f rotation)
        {}
+       virtual void setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation)
+       {}
        virtual ObjectProperties* accessObjectProperties()
        { return NULL; }
        virtual void notifyObjectPropertiesModified()
index 50a002c102882e9ce102dbaf5d1ebcfce745a2b1..d552dec9460efbbc4496495c6482d51eabb085a4 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define UTIL_SERIALIZE_HEADER
 
 #include "../irrlichttypes.h"
+#include "../irrlichttypes_bloated.h"
 #include "../irr_v2d.h"
 #include "../irr_v3d.h"
 #include <iostream>
@@ -197,6 +198,24 @@ inline v3s16 readV3S16(u8 *data)
        return p;
 }
 
+inline void writeARGB8(u8 *data, video::SColor p)
+{
+       writeU8(&data[0], p.getAlpha());
+       writeU8(&data[1], p.getRed());
+       writeU8(&data[2], p.getGreen());
+       writeU8(&data[3], p.getBlue());
+}
+
+inline video::SColor readARGB8(u8 *data)
+{
+       video::SColor p;
+       p.setAlpha(readU8(&data[0]));
+       p.setRed(readU8(&data[1]));
+       p.setGreen(readU8(&data[2]));
+       p.setBlue(readU8(&data[3]));
+       return p;
+}
+
 /*
        The above stuff directly interfaced to iostream
 */
@@ -344,6 +363,20 @@ inline v3s16 readV3S16(std::istream &is)
        return readV3S16((u8*)buf);
 }
 
+inline void writeARGB8(std::ostream &os, video::SColor p)
+{
+       char buf[4] = {0};
+       writeARGB8((u8*)buf, p);
+       os.write(buf, 4);
+}
+
+inline video::SColor readARGB8(std::istream &is)
+{
+       char buf[4] = {0};
+       is.read(buf, 4);
+       return readARGB8((u8*)buf);
+}
+
 /*
        More serialization stuff
 */