Framework for the attachment system, new object property which allows changing the color and alpha of mesh materials

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
This commit is contained in:
MirceaKitsune 2012-10-27 01:49:01 +03:00 committed by Perttu Ahola
parent 118285e6ba
commit e42eeec8f6
11 changed files with 181 additions and 4 deletions

@ -1232,9 +1232,8 @@ Object Properties
visual = "cube"/"sprite"/"upright_sprite"/"mesh", visual = "cube"/"sprite"/"upright_sprite"/"mesh",
visual_size = {x=1, y=1}, visual_size = {x=1, y=1},
mesh = "model", 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 textures = {}, -- number of required textures depends on visual
colors = {}, -- number of required colors depends on visual
spritediv = {x=1, y=1}, spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0}, initial_sprite_basepos = {x=0, y=0},
is_visible = true, is_visible = true,

@ -555,6 +555,7 @@ private:
std::string m_name; std::string m_name;
bool m_is_player; bool m_is_player;
bool m_is_local_player; // determined locally bool m_is_local_player; // determined locally
int m_id;
// Property-ish things // Property-ish things
ObjectProperties m_prop; ObjectProperties m_prop;
// //
@ -596,6 +597,7 @@ public:
// //
m_is_player(false), m_is_player(false),
m_is_local_player(false), m_is_local_player(false),
m_id(0),
// //
m_smgr(NULL), m_smgr(NULL),
m_irr(NULL), m_irr(NULL),
@ -640,6 +642,7 @@ public:
} }
m_name = deSerializeString(is); m_name = deSerializeString(is);
m_is_player = readU8(is); m_is_player = readU8(is);
m_id = readS16(is);
m_position = readV3F1000(is); m_position = readV3F1000(is);
m_yaw = readF1000(is); m_yaw = readF1000(is);
m_hp = readS16(is); m_hp = readS16(is);
@ -930,6 +933,7 @@ public:
addToScene(m_smgr, m_gamedef->tsrc(), m_irr); addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
updateAnimations(); updateAnimations();
updateBonePosRot(); updateBonePosRot();
updateAttachment();
} }
if(m_prop.physical){ if(m_prop.physical){
@ -1062,6 +1066,10 @@ public:
texturestring += mod; texturestring += mod;
m_spritenode->setMaterialTexture(0, m_spritenode->setMaterialTexture(0,
tsrc->getTextureRaw(texturestring)); 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) if(m_animated_meshnode)
@ -1087,6 +1095,12 @@ public:
material.setFlag(video::EMF_LIGHTING, false); material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, 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) if(m_meshnode)
@ -1113,6 +1127,10 @@ public:
material.setTexture(0, atlas); material.setTexture(0, atlas);
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y); material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
material.getTextureMatrix(0).setTextureScale(size.X, size.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") else if(m_prop.visual == "upright_sprite")
@ -1126,6 +1144,10 @@ public:
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0); scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
buf->getMaterial().setTexture(0, buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname)); 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"; std::string tname = "unknown_object.png";
@ -1137,6 +1159,10 @@ public:
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1); scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
buf->getMaterial().setTexture(0, buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname)); 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) void processMessage(const std::string &data)
{ {
//infostream<<"GenericCAO: Got message"<<std::endl; //infostream<<"GenericCAO: Got message"<<std::endl;
@ -1254,6 +1285,15 @@ public:
updateBonePosRot(); updateBonePosRot();
expireVisuals(); 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) else if(cmd == GENERIC_CMD_PUNCHED)
{ {
/*s16 damage =*/ readS16(is); /*s16 damage =*/ readS16(is);

@ -504,6 +504,7 @@ std::string LuaEntitySAO::getClientInitializationData()
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
writeU8(os, 0); // version writeU8(os, 0); // version
os<<serializeString(""); // name os<<serializeString(""); // name
writeS16(os, getId()); //id
writeU8(os, 0); // is_player writeU8(os, 0); // is_player
writeV3F1000(os, m_base_position); writeV3F1000(os, m_base_position);
writeF1000(os, m_yaw); writeF1000(os, m_yaw);
@ -660,6 +661,19 @@ void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
m_messages_out.push_back(aom); 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() ObjectProperties* LuaEntitySAO::accessObjectProperties()
{ {
return &m_prop; return &m_prop;
@ -804,6 +818,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
m_prop.textures.clear(); m_prop.textures.clear();
m_prop.textures.push_back("player.png"); m_prop.textures.push_back("player.png");
m_prop.textures.push_back("player_back.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); m_prop.spritediv = v2s16(1,1);
// end of default appearance // end of default appearance
m_prop.is_visible = (getHP() != 0); // TODO: Use a death animation instead for mesh players 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 writeU8(os, 0); // version
os<<serializeString(m_player->getName()); // name os<<serializeString(m_player->getName()); // name
writeU8(os, 1); // is_player writeU8(os, 1); // is_player
writeS16(os, getId()); //id
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
writeF1000(os, m_player->getYaw()); writeF1000(os, m_player->getYaw());
writeS16(os, getHP()); writeS16(os, getHP());
@ -1109,6 +1126,15 @@ void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation)
m_messages_out.push_back(aom); 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() ObjectProperties* PlayerSAO::accessObjectProperties()
{ {
return &m_prop; return &m_prop;

@ -63,6 +63,7 @@ public:
void setArmorGroups(const ItemGroupList &armor_groups); void setArmorGroups(const ItemGroupList &armor_groups);
void setAnimations(v2f frames, float frame_speed, float frame_blend); void setAnimations(v2f frames, float frame_speed, float frame_blend);
void setBonePosRot(std::string bone, v3f position, v3f rotation); void setBonePosRot(std::string bone, v3f position, v3f rotation);
void setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation);
ObjectProperties* accessObjectProperties(); ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified(); void notifyObjectPropertiesModified();
/* LuaEntitySAO-specific */ /* LuaEntitySAO-specific */
@ -146,6 +147,7 @@ public:
void setArmorGroups(const ItemGroupList &armor_groups); void setArmorGroups(const ItemGroupList &armor_groups);
void setAnimations(v2f frames, float frame_speed, float frame_blend); void setAnimations(v2f frames, float frame_speed, float frame_blend);
void setBonePosRot(std::string bone, v3f position, v3f rotation); void setBonePosRot(std::string bone, v3f position, v3f rotation);
void setAttachment(ServerActiveObject *parent, std::string bone, v3f position, v3f rotation);
ObjectProperties* accessObjectProperties(); ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified(); void notifyObjectPropertiesModified();

@ -104,6 +104,17 @@ std::string gob_cmd_set_animations(v2f frames, float frame_speed, float frame_bl
return os.str(); 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::string gob_cmd_set_bone_posrot(std::string bone, v3f position, v3f rotation)
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);

@ -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_SPRITE 3
#define GENERIC_CMD_SET_ANIMATIONS 4 #define GENERIC_CMD_SET_ANIMATIONS 4
#define GENERIC_CMD_SET_BONE_POSROT 5 #define GENERIC_CMD_SET_BONE_POSROT 5
#define GENERIC_CMD_PUNCHED 6 #define GENERIC_CMD_SET_ATTACHMENT 6
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 7 #define GENERIC_CMD_PUNCHED 7
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 8
#include "object_properties.h" #include "object_properties.h"
std::string gob_cmd_set_properties(const ObjectProperties &prop); 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_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); std::string gob_cmd_punched(s16 damage, s16 result_hp);
#include "itemgroup.h" #include "itemgroup.h"

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "object_properties.h" #include "object_properties.h"
#include "irrlichttypes_bloated.h"
#include "util/serialize.h" #include "util/serialize.h"
#include <sstream> #include <sstream>
#include <map> #include <map>
@ -40,6 +41,7 @@ ObjectProperties::ObjectProperties():
automatic_rotate(0) automatic_rotate(0)
{ {
textures.push_back("unknown_object.png"); textures.push_back("unknown_object.png");
colors.push_back(video::SColor(255,255,255,255));
} }
std::string ObjectProperties::dump() std::string ObjectProperties::dump()
@ -57,6 +59,11 @@ std::string ObjectProperties::dump()
os<<"\""<<textures[i]<<"\" "; os<<"\""<<textures[i]<<"\" ";
} }
os<<"]"; 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<<", spritediv="<<PP2(spritediv);
os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos); os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos);
os<<", is_visible="<<is_visible; os<<", is_visible="<<is_visible;
@ -80,6 +87,10 @@ void ObjectProperties::serialize(std::ostream &os) const
for(u32 i=0; i<textures.size(); i++){ for(u32 i=0; i<textures.size(); i++){
os<<serializeString(textures[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, spritediv);
writeV2S16(os, initial_sprite_basepos); writeV2S16(os, initial_sprite_basepos);
writeU8(os, is_visible); writeU8(os, is_visible);
@ -105,6 +116,10 @@ void ObjectProperties::deSerialize(std::istream &is)
for(u32 i=0; i<texture_count; i++){ for(u32 i=0; i<texture_count; i++){
textures.push_back(deSerializeString(is)); 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); spritediv = readV2S16(is);
initial_sprite_basepos = readV2S16(is); initial_sprite_basepos = readV2S16(is);
is_visible = readU8(is); is_visible = readU8(is);

@ -36,6 +36,7 @@ struct ObjectProperties
std::string mesh; std::string mesh;
v2f visual_size; v2f visual_size;
core::array<std::string> textures; core::array<std::string> textures;
core::array<video::SColor> colors;
v2s16 spritediv; v2s16 spritediv;
v2s16 initial_sprite_basepos; v2s16 initial_sprite_basepos;
bool is_visible; bool is_visible;

@ -961,6 +961,23 @@ static void read_object_properties(lua_State *L, int index,
} }
lua_pop(L, 1); 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"); lua_getfield(L, -1, "spritediv");
if(lua_istable(L, -1)) if(lua_istable(L, -1))
prop->spritediv = read_v2s16(L, -1); prop->spritediv = read_v2s16(L, -1);
@ -2741,6 +2758,33 @@ private:
return 0; 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) // set_properties(self, properties)
static int l_set_properties(lua_State *L) 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_armor_groups),
method(ObjectRef, set_animations), method(ObjectRef, set_animations),
method(ObjectRef, set_bone_posrot), method(ObjectRef, set_bone_posrot),
method(ObjectRef, set_attachment),
method(ObjectRef, set_properties), method(ObjectRef, set_properties),
// LuaEntitySAO-only // LuaEntitySAO-only
method(ObjectRef, setvelocity), method(ObjectRef, setvelocity),

@ -156,6 +156,8 @@ public:
{} {}
virtual void setBonePosRot(std::string bone, v3f position, v3f rotation) 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() virtual ObjectProperties* accessObjectProperties()
{ return NULL; } { return NULL; }
virtual void notifyObjectPropertiesModified() virtual void notifyObjectPropertiesModified()

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define UTIL_SERIALIZE_HEADER #define UTIL_SERIALIZE_HEADER
#include "../irrlichttypes.h" #include "../irrlichttypes.h"
#include "../irrlichttypes_bloated.h"
#include "../irr_v2d.h" #include "../irr_v2d.h"
#include "../irr_v3d.h" #include "../irr_v3d.h"
#include <iostream> #include <iostream>
@ -197,6 +198,24 @@ inline v3s16 readV3S16(u8 *data)
return p; 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 The above stuff directly interfaced to iostream
*/ */
@ -344,6 +363,20 @@ inline v3s16 readV3S16(std::istream &is)
return readV3S16((u8*)buf); 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 More serialization stuff
*/ */