Proselytize the network. Use IEEE F32 (#8030)

* Proselytize the network. Use IEEE F32
* Remove unused V2F1000 functions
This commit is contained in:
SmallJoker 2019-01-03 17:04:26 +01:00 committed by Loïc Blot
parent ceacff13a6
commit bba4563d89
19 changed files with 237 additions and 262 deletions

View File

@ -5482,9 +5482,9 @@ Used by `ObjectRef` methods. Part of an Entity definition.
-- 'inventory_image'.
-- "item" is similar to "wielditem" but ignores the 'wield_image' parameter.
visual_size = {x = 1, y = 1},
-- `x` multiplies horizontal (X and Z) visual size.
-- `y` multiplies vertical (Y) visual size.
visual_size = {x = 1, y = 1, z = 1},
-- Multipliers for the visual size. If `z` is not specified, `x` will be used
-- to scale the entity along both horizontal axes.
mesh = "model",

View File

@ -357,24 +357,23 @@ void GenericCAO::initialize(const std::string &data)
void GenericCAO::processInitData(const std::string &data)
{
std::istringstream is(data, std::ios::binary);
int num_messages = 0;
// version
u8 version = readU8(is);
// check version
if (version == 1) { // In PROTOCOL_VERSION 14
m_name = deSerializeString(is);
m_is_player = readU8(is);
m_id = readU16(is);
m_position = readV3F1000(is);
m_rotation = readV3F1000(is);
m_hp = readS16(is);
num_messages = readU8(is);
} else {
errorstream<<"GenericCAO: Unsupported init data version"
<<std::endl;
const u8 version = readU8(is);
if (version < 1) {
errorstream << "GenericCAO: Unsupported init data version"
<< std::endl;
return;
}
// PROTOCOL_VERSION >= 37
m_name = deSerializeString(is);
m_is_player = readU8(is);
m_id = readU16(is);
m_position = readV3F32(is);
m_rotation = readV3F32(is);
m_hp = readS16(is);
const u8 num_messages = readU8(is);
for (int i = 0; i < num_messages; i++) {
std::string message = deSerializeLongString(is);
processMessage(message);
@ -546,7 +545,8 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
u8 li = m_last_light;
m_spritenode->setColor(video::SColor(255,li,li,li));
m_spritenode->setSize(m_prop.visual_size*BS);
m_spritenode->setSize(v2f(m_prop.visual_size.X,
m_prop.visual_size.Y) * BS);
{
const float txs = 1.0 / 1;
const float tys = 1.0 / 1;
@ -622,9 +622,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
m_meshnode->grab();
mesh->drop();
m_meshnode->setScale(v3f(m_prop.visual_size.X,
m_prop.visual_size.Y,
m_prop.visual_size.X));
m_meshnode->setScale(m_prop.visual_size);
u8 li = m_last_light;
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
@ -643,9 +641,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
m_animated_meshnode->grab();
mesh->drop(); // The scene node took hold of it
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));
m_animated_meshnode->setScale(m_prop.visual_size);
u8 li = m_last_light;
// set vertex colors to ensure alpha is set
@ -683,9 +679,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
m_wield_meshnode->setItem(item, m_client,
(m_prop.visual == "wielditem"));
m_wield_meshnode->setScale(
v3f(m_prop.visual_size.X / 2, m_prop.visual_size.Y / 2,
m_prop.visual_size.X / 2));
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
u8 li = m_last_light;
m_wield_meshnode->setColor(video::SColor(255, li, li, li));
} else {
@ -1393,7 +1387,7 @@ void GenericCAO::processMessage(const std::string &data)
} else if (cmd == GENERIC_CMD_SET_SPRITE) {
v2s16 p = readV2S16(is);
int num_frames = readU16(is);
float framelength = readF1000(is);
float framelength = readF32(is);
bool select_horiz_by_yawpitch = readU8(is);
m_tx_basepos = p;
@ -1403,9 +1397,9 @@ void GenericCAO::processMessage(const std::string &data)
updateTexturePos();
} else if (cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) {
float override_speed = readF1000(is);
float override_jump = readF1000(is);
float override_gravity = readF1000(is);
float override_speed = readF32(is);
float override_jump = readF32(is);
float override_gravity = readF32(is);
// these are sent inverted so we get true when the server sends nothing
bool sneak = !readU8(is);
bool sneak_glitch = !readU8(is);
@ -1424,11 +1418,11 @@ void GenericCAO::processMessage(const std::string &data)
}
} else if (cmd == GENERIC_CMD_SET_ANIMATION) {
// TODO: change frames send as v2s32 value
v2f range = readV2F1000(is);
v2f range = readV2F32(is);
if (!m_is_local_player) {
m_animation_range = v2s32((s32)range.X, (s32)range.Y);
m_animation_speed = readF1000(is);
m_animation_blend = readF1000(is);
m_animation_speed = readF32(is);
m_animation_blend = readF32(is);
// these are sent inverted so we get true when the server sends nothing
m_animation_loop = !readU8(is);
updateAnimation();
@ -1437,8 +1431,8 @@ void GenericCAO::processMessage(const std::string &data)
if(player->last_animation == NO_ANIM)
{
m_animation_range = v2s32((s32)range.X, (s32)range.Y);
m_animation_speed = readF1000(is);
m_animation_blend = readF1000(is);
m_animation_speed = readF32(is);
m_animation_blend = readF32(is);
// these are sent inverted so we get true when the server sends nothing
m_animation_loop = !readU8(is);
}
@ -1457,12 +1451,12 @@ void GenericCAO::processMessage(const std::string &data)
}
}
} else if (cmd == GENERIC_CMD_SET_ANIMATION_SPEED) {
m_animation_speed = readF1000(is);
m_animation_speed = readF32(is);
updateAnimationSpeed();
} else if (cmd == GENERIC_CMD_SET_BONE_POSITION) {
std::string bone = deSerializeString(is);
v3f position = readV3F1000(is);
v3f rotation = readV3F1000(is);
v3f position = readV3F32(is);
v3f rotation = readV3F32(is);
m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
updateBonePosition();
@ -1482,8 +1476,8 @@ void GenericCAO::processMessage(const std::string &data)
}
m_attachment_bone = deSerializeString(is);
m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is);
m_attachment_position = readV3F32(is);
m_attachment_rotation = readV3F32(is);
// localplayer itself can't be attached to localplayer
if (!m_is_local_player) {
@ -1510,7 +1504,7 @@ void GenericCAO::processMessage(const std::string &data)
// As there is no definition, make a smoke puff
ClientSimpleObject *simple = createSmokePuff(
m_smgr, m_env, m_position,
m_prop.visual_size * BS);
v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS);
m_env->addSimpleObject(simple);
} else if (m_reset_textures_timer < 0) {
// TODO: Execute defined fast response
@ -1581,7 +1575,7 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
// As there is no definition, make a smoke puff
ClientSimpleObject *simple = createSmokePuff(
m_smgr, m_env, m_position,
m_prop.visual_size * BS);
v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS);
m_env->addSimpleObject(simple);
}
// TODO: Execute defined fast response

View File

@ -549,8 +549,8 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
os << serializeString(""); // name
writeU8(os, 0); // is_player
writeS16(os, getId()); //id
writeV3F1000(os, m_base_position);
writeV3F1000(os, m_rotation);
writeV3F32(os, m_base_position);
writeV3F32(os, m_rotation);
writeS16(os, m_hp);
std::ostringstream msg_os(std::ios::binary);
@ -873,7 +873,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p
m_prop.pointable = true;
// Start of default appearance, this should be overwritten by Lua
m_prop.visual = "upright_sprite";
m_prop.visual_size = v2f(1, 2);
m_prop.visual_size = v3f(1, 2, 1);
m_prop.textures.clear();
m_prop.textures.emplace_back("player.png");
m_prop.textures.emplace_back("player_back.png");
@ -947,8 +947,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
os << serializeString(m_player->getName()); // name
writeU8(os, 1); // is_player
writeS16(os, getId()); // id
writeV3F1000(os, m_base_position);
writeV3F1000(os, m_rotation);
writeV3F32(os, m_base_position);
writeV3F32(os, m_rotation);
writeS16(os, getHP());
std::ostringstream msg_os(std::ios::binary);

View File

@ -87,7 +87,7 @@ std::string gob_cmd_set_sprite(
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF1000(os, framelength);
writeF32(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
return os.str();
}
@ -123,9 +123,9 @@ std::string gob_cmd_update_physics_override(float physics_override_speed, float
// command
writeU8(os, GENERIC_CMD_SET_PHYSICS_OVERRIDE);
// parameters
writeF1000(os, physics_override_speed);
writeF1000(os, physics_override_jump);
writeF1000(os, physics_override_gravity);
writeF32(os, physics_override_speed);
writeF32(os, physics_override_jump);
writeF32(os, physics_override_gravity);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !sneak);
writeU8(os, !sneak_glitch);
@ -139,9 +139,9 @@ std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_
// command
writeU8(os, GENERIC_CMD_SET_ANIMATION);
// parameters
writeV2F1000(os, frames);
writeF1000(os, frame_speed);
writeF1000(os, frame_blend);
writeV2F32(os, frames);
writeF32(os, frame_speed);
writeF32(os, frame_blend);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !frame_loop);
return os.str();
@ -153,7 +153,7 @@ std::string gob_cmd_update_animation_speed(float frame_speed)
// command
writeU8(os, GENERIC_CMD_SET_ANIMATION_SPEED);
// parameters
writeF1000(os, frame_speed);
writeF32(os, frame_speed);
return os.str();
}
@ -165,8 +165,8 @@ std::string gob_cmd_update_bone_position(const std::string &bone, v3f position,
writeU8(os, GENERIC_CMD_SET_BONE_POSITION);
// parameters
os<<serializeString(bone);
writeV3F1000(os, position);
writeV3F1000(os, rotation);
writeV3F32(os, position);
writeV3F32(os, rotation);
return os.str();
}
@ -179,8 +179,8 @@ std::string gob_cmd_update_attachment(int parent_id, const std::string &bone,
// parameters
writeS16(os, parent_id);
os<<serializeString(bone);
writeV3F1000(os, position);
writeV3F1000(os, rotation);
writeV3F32(os, position);
writeV3F32(os, rotation);
return os.str();
}

View File

@ -128,41 +128,42 @@ void ItemDefinition::reset()
void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
{
// protocol_version >= 36
u8 version = 5;
// protocol_version >= 37
u8 version = 6;
writeU8(os, version);
writeU8(os, type);
os << serializeString(name);
os << serializeString(description);
os << serializeString(inventory_image);
os << serializeString(wield_image);
writeV3F1000(os, wield_scale);
writeV3F32(os, wield_scale);
writeS16(os, stack_max);
writeU8(os, usable);
writeU8(os, liquids_pointable);
std::string tool_capabilities_s;
if(tool_capabilities){
if (tool_capabilities) {
std::ostringstream tmp_os(std::ios::binary);
tool_capabilities->serialize(tmp_os, protocol_version);
tool_capabilities_s = tmp_os.str();
}
os << serializeString(tool_capabilities_s);
writeU16(os, groups.size());
for (const auto &group : groups) {
os << serializeString(group.first);
writeS16(os, group.second);
}
os << serializeString(node_placement_prediction);
os << serializeString(sound_place.name);
writeF1000(os, sound_place.gain);
writeF1000(os, range);
os << serializeString(sound_place_failed.name);
writeF1000(os, sound_place_failed.gain);
// Version from ContentFeatures::serialize to keep in sync
sound_place.serialize(os, CONTENTFEATURES_VERSION);
sound_place_failed.serialize(os, CONTENTFEATURES_VERSION);
writeF32(os, range);
os << serializeString(palette_image);
writeARGB8(os, color);
writeF1000(os, sound_place.pitch);
writeF1000(os, sound_place_failed.pitch);
os << serializeString(inventory_overlay);
os << serializeString(wield_overlay);
}
@ -174,7 +175,7 @@ void ItemDefinition::deSerialize(std::istream &is)
// Deserialize
int version = readU8(is);
if (version < 5)
if (version < 6)
throw SerializationError("unsupported ItemDefinition version");
type = (enum ItemType)readU8(is);
@ -182,17 +183,18 @@ void ItemDefinition::deSerialize(std::istream &is)
description = deSerializeString(is);
inventory_image = deSerializeString(is);
wield_image = deSerializeString(is);
wield_scale = readV3F1000(is);
wield_scale = readV3F32(is);
stack_max = readS16(is);
usable = readU8(is);
liquids_pointable = readU8(is);
std::string tool_capabilities_s = deSerializeString(is);
if(!tool_capabilities_s.empty())
{
if (!tool_capabilities_s.empty()) {
std::istringstream tmp_is(tool_capabilities_s, std::ios::binary);
tool_capabilities = new ToolCapabilities;
tool_capabilities->deSerialize(tmp_is);
}
groups.clear();
u32 groups_size = readU16(is);
for(u32 i=0; i<groups_size; i++){
@ -202,18 +204,14 @@ void ItemDefinition::deSerialize(std::istream &is)
}
node_placement_prediction = deSerializeString(is);
//deserializeSimpleSoundSpec(sound_place, is);
sound_place.name = deSerializeString(is);
sound_place.gain = readF1000(is);
range = readF1000(is);
sound_place_failed.name = deSerializeString(is);
sound_place_failed.gain = readF1000(is);
// Version from ContentFeatures::serialize to keep in sync
sound_place.deSerialize(is, CONTENTFEATURES_VERSION);
sound_place_failed.deSerialize(is, CONTENTFEATURES_VERSION);
range = readF32(is);
palette_image = deSerializeString(is);
color = readARGB8(is);
sound_place.pitch = readF1000(is);
sound_place_failed.pitch = readF1000(is);
inventory_overlay = deSerializeString(is);
wield_overlay = deSerializeString(is);
@ -223,6 +221,7 @@ void ItemDefinition::deSerialize(std::istream &is)
//} catch(SerializationError &e) {};
}
/*
CItemDefManager
*/

View File

@ -446,9 +446,7 @@ void MapBlock::serializeNetworkSpecific(std::ostream &os)
throw SerializationError("ERROR: Not writing dummy block.");
}
writeU8(os, 1); // version
writeF1000(os, 0); // deprecated heat
writeF1000(os, 0); // deprecated humidity
writeU8(os, 2); // version
}
void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
@ -559,16 +557,11 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
void MapBlock::deSerializeNetworkSpecific(std::istream &is)
{
try {
int version = readU8(is);
const u8 version = readU8(is);
//if(version != 1)
// throw SerializationError("unsupported MapBlock version");
if(version >= 1) {
readF1000(is); // deprecated heat
readF1000(is); // deprecated humidity
}
}
catch(SerializationError &e)
{
} catch(SerializationError &e) {
warningstream<<"MapBlock::deSerializeNetworkSpecific(): Ignoring an error"
<<": "<<e.what()<<std::endl;
}

View File

@ -920,11 +920,11 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
std::string datastring(pkt->getString(0), pkt->getSize());
std::istringstream is(datastring, std::ios_base::binary);
v3f pos = readV3F1000(is);
v3f vel = readV3F1000(is);
v3f acc = readV3F1000(is);
float expirationtime = readF1000(is);
float size = readF1000(is);
v3f pos = readV3F32(is);
v3f vel = readV3F32(is);
v3f acc = readV3F32(is);
float expirationtime = readF32(is);
float size = readF32(is);
bool collisiondetection = readU8(is);
std::string texture = deSerializeLongString(is);

View File

@ -288,7 +288,7 @@ NetworkPacket& NetworkPacket::operator<<(float src)
{
checkDataSize(4);
writeF1000(&m_data[m_read_offset], src);
writeF32(&m_data[m_read_offset], src);
m_read_offset += 4;
return *this;
@ -383,7 +383,7 @@ NetworkPacket& NetworkPacket::operator>>(float& dst)
{
checkReadOffset(m_read_offset, 4);
dst = readF1000(&m_data[m_read_offset]);
dst = readF32(&m_data[m_read_offset]);
m_read_offset += 4;
return *this;
@ -393,7 +393,7 @@ NetworkPacket& NetworkPacket::operator>>(v2f& dst)
{
checkReadOffset(m_read_offset, 8);
dst = readV2F1000(&m_data[m_read_offset]);
dst = readV2F32(&m_data[m_read_offset]);
m_read_offset += 8;
return *this;
@ -403,7 +403,7 @@ NetworkPacket& NetworkPacket::operator>>(v3f& dst)
{
checkReadOffset(m_read_offset, 12);
dst = readV3F1000(&m_data[m_read_offset]);
dst = readV3F32(&m_data[m_read_offset]);
m_read_offset += 12;
return *this;

View File

@ -192,6 +192,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Redo detached inventory sending
Add TOCLIENT_NODEMETA_CHANGED
New network float format
ContentFeatures version 13
*/
#define LATEST_PROTOCOL_VERSION 37

View File

@ -74,7 +74,7 @@ void NodeBox::reset()
void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
{
// Protocol >= 36
int version = 5;
const u8 version = 6;
writeU8(os, version);
switch (type) {
@ -84,19 +84,19 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
writeU16(os, fixed.size());
for (const aabb3f &nodebox : fixed) {
writeV3F1000(os, nodebox.MinEdge);
writeV3F1000(os, nodebox.MaxEdge);
writeV3F32(os, nodebox.MinEdge);
writeV3F32(os, nodebox.MaxEdge);
}
break;
case NODEBOX_WALLMOUNTED:
writeU8(os, type);
writeV3F1000(os, wall_top.MinEdge);
writeV3F1000(os, wall_top.MaxEdge);
writeV3F1000(os, wall_bottom.MinEdge);
writeV3F1000(os, wall_bottom.MaxEdge);
writeV3F1000(os, wall_side.MinEdge);
writeV3F1000(os, wall_side.MaxEdge);
writeV3F32(os, wall_top.MinEdge);
writeV3F32(os, wall_top.MaxEdge);
writeV3F32(os, wall_bottom.MinEdge);
writeV3F32(os, wall_bottom.MaxEdge);
writeV3F32(os, wall_side.MinEdge);
writeV3F32(os, wall_side.MaxEdge);
break;
case NODEBOX_CONNECTED:
writeU8(os, type);
@ -104,8 +104,8 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
#define WRITEBOX(box) \
writeU16(os, (box).size()); \
for (const aabb3f &i: (box)) { \
writeV3F1000(os, i.MinEdge); \
writeV3F1000(os, i.MaxEdge); \
writeV3F32(os, i.MinEdge); \
writeV3F32(os, i.MaxEdge); \
};
WRITEBOX(fixed);
@ -133,7 +133,7 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
void NodeBox::deSerialize(std::istream &is)
{
int version = readU8(is);
if (version < 4)
if (version < 6)
throw SerializationError("unsupported NodeBox version");
reset();
@ -146,19 +146,19 @@ void NodeBox::deSerialize(std::istream &is)
while(fixed_count--)
{
aabb3f box;
box.MinEdge = readV3F1000(is);
box.MaxEdge = readV3F1000(is);
box.MinEdge = readV3F32(is);
box.MaxEdge = readV3F32(is);
fixed.push_back(box);
}
}
else if(type == NODEBOX_WALLMOUNTED)
{
wall_top.MinEdge = readV3F1000(is);
wall_top.MaxEdge = readV3F1000(is);
wall_bottom.MinEdge = readV3F1000(is);
wall_bottom.MaxEdge = readV3F1000(is);
wall_side.MinEdge = readV3F1000(is);
wall_side.MaxEdge = readV3F1000(is);
wall_top.MinEdge = readV3F32(is);
wall_top.MaxEdge = readV3F32(is);
wall_bottom.MinEdge = readV3F32(is);
wall_bottom.MaxEdge = readV3F32(is);
wall_side.MinEdge = readV3F32(is);
wall_side.MaxEdge = readV3F32(is);
}
else if (type == NODEBOX_CONNECTED)
{
@ -166,8 +166,8 @@ void NodeBox::deSerialize(std::istream &is)
count = readU16(is); \
(box).reserve(count); \
while (count--) { \
v3f min = readV3F1000(is); \
v3f max = readV3F1000(is); \
v3f min = readV3F32(is); \
v3f max = readV3F32(is); \
(box).emplace_back(min, max); }; }
u16 count;
@ -179,16 +179,14 @@ void NodeBox::deSerialize(std::istream &is)
READBOXES(connect_left);
READBOXES(connect_back);
READBOXES(connect_right);
if (version >= 5) {
READBOXES(disconnected_top);
READBOXES(disconnected_bottom);
READBOXES(disconnected_front);
READBOXES(disconnected_left);
READBOXES(disconnected_back);
READBOXES(disconnected_right);
READBOXES(disconnected);
READBOXES(disconnected_sides);
}
READBOXES(disconnected_top);
READBOXES(disconnected_bottom);
READBOXES(disconnected_front);
READBOXES(disconnected_left);
READBOXES(disconnected_back);
READBOXES(disconnected_right);
READBOXES(disconnected);
READBOXES(disconnected_sides);
}
}
@ -264,26 +262,6 @@ void TileDef::deSerialize(std::istream &is, u8 contentfeatures_version,
align_style = ALIGN_STYLE_NODE;
}
/*
SimpleSoundSpec serialization
*/
static void serializeSimpleSoundSpec(const SimpleSoundSpec &ss,
std::ostream &os, u8 version)
{
os<<serializeString(ss.name);
writeF1000(os, ss.gain);
writeF1000(os, ss.pitch);
}
static void deSerializeSimpleSoundSpec(SimpleSoundSpec &ss,
std::istream &is, u8 version)
{
ss.name = deSerializeString(is);
ss.gain = readF1000(is);
ss.pitch = readF1000(is);
}
void TextureSettings::readSettings()
{
connected_glass = g_settings->getBool("connected_glass");
@ -419,8 +397,7 @@ void ContentFeatures::reset()
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
{
// protocol_version >= 36
u8 version = 12;
const u8 version = CONTENTFEATURES_VERSION;
writeU8(os, version);
// general
@ -436,7 +413,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
// visual
writeU8(os, drawtype);
os << serializeString(mesh);
writeF1000(os, visual_scale);
writeF32(os, visual_scale);
writeU8(os, 6);
for (const TileDef &td : tiledef)
td.serialize(os, protocol_version);
@ -456,10 +433,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
writeU16(os, connects_to_ids.size());
for (u16 connects_to_id : connects_to_ids)
writeU16(os, connects_to_id);
writeU8(os, post_effect_color.getAlpha());
writeU8(os, post_effect_color.getRed());
writeU8(os, post_effect_color.getGreen());
writeU8(os, post_effect_color.getBlue());
writeARGB8(os, post_effect_color);
writeU8(os, leveled);
// lighting
@ -495,9 +469,9 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
collision_box.serialize(os, protocol_version);
// sound
serializeSimpleSoundSpec(sound_footstep, os, version);
serializeSimpleSoundSpec(sound_dig, os, version);
serializeSimpleSoundSpec(sound_dug, os, version);
sound_footstep.serialize(os, version);
sound_dig.serialize(os, version);
sound_dug.serialize(os, version);
// legacy
writeU8(os, legacy_facedir_simple);
@ -524,8 +498,8 @@ void ContentFeatures::correctAlpha(TileDef *tiles, int length)
void ContentFeatures::deSerialize(std::istream &is)
{
// version detection
int version = readU8(is);
if (version < 12)
const u8 version = readU8(is);
if (version < CONTENTFEATURES_VERSION)
throw SerializationError("unsupported ContentFeatures version");
// general
@ -543,7 +517,7 @@ void ContentFeatures::deSerialize(std::istream &is)
// visual
drawtype = (enum NodeDrawType) readU8(is);
mesh = deSerializeString(is);
visual_scale = readF1000(is);
visual_scale = readF32(is);
if (readU8(is) != 6)
throw SerializationError("unsupported tile count");
for (TileDef &td : tiledef)
@ -565,10 +539,7 @@ void ContentFeatures::deSerialize(std::istream &is)
connects_to_ids.clear();
for (u16 i = 0; i < connects_to_size; i++)
connects_to_ids.push_back(readU16(is));
post_effect_color.setAlpha(readU8(is));
post_effect_color.setRed(readU8(is));
post_effect_color.setGreen(readU8(is));
post_effect_color.setBlue(readU8(is));
post_effect_color = readARGB8(is);
leveled = readU8(is);
// lighting-related
@ -605,9 +576,9 @@ void ContentFeatures::deSerialize(std::istream &is)
collision_box.deSerialize(is);
// sounds
deSerializeSimpleSoundSpec(sound_footstep, is, version);
deSerializeSimpleSoundSpec(sound_dig, is, version);
deSerializeSimpleSoundSpec(sound_dug, is, version);
sound_footstep.deSerialize(is, version);
sound_dig.deSerialize(is, version);
sound_dug.deSerialize(is, version);
// read legacy properties
legacy_facedir_simple = readU8(is);

View File

@ -35,6 +35,9 @@ class Client;
#include "constants.h" // BS
#include "tileanimation.h"
// PROTOCOL_VERSION >= 37
static const u8 CONTENTFEATURES_VERSION = 13;
class IItemDefManager;
class ITextureSource;
class IShaderSource;

View File

@ -41,7 +41,7 @@ std::string ObjectProperties::dump()
os << ", collisionbox=" << PP(collisionbox.MinEdge) << "," << PP(collisionbox.MaxEdge);
os << ", visual=" << visual;
os << ", mesh=" << mesh;
os << ", visual_size=" << PP2(visual_size);
os << ", visual_size=" << PP(visual_size);
os << ", textures=[";
for (const std::string &texture : textures) {
os << "\"" << texture << "\" ";
@ -74,17 +74,17 @@ std::string ObjectProperties::dump()
void ObjectProperties::serialize(std::ostream &os) const
{
writeU8(os, 3); // version, protocol_version >= 36
writeU8(os, 4); // PROTOCOL_VERSION >= 37
writeS16(os, hp_max);
writeU8(os, physical);
writeF1000(os, weight);
writeV3F1000(os, collisionbox.MinEdge);
writeV3F1000(os, collisionbox.MaxEdge);
writeV3F1000(os, selectionbox.MinEdge);
writeV3F1000(os, selectionbox.MaxEdge);
writeF32(os, weight);
writeV3F32(os, collisionbox.MinEdge);
writeV3F32(os, collisionbox.MaxEdge);
writeV3F32(os, selectionbox.MinEdge);
writeV3F32(os, selectionbox.MaxEdge);
writeU8(os, pointable);
os << serializeString(visual);
writeV2F1000(os, visual_size);
writeV3F32(os, visual_size);
writeU16(os, textures.size());
for (const std::string &texture : textures) {
os << serializeString(texture);
@ -93,7 +93,7 @@ void ObjectProperties::serialize(std::ostream &os) const
writeV2S16(os, initial_sprite_basepos);
writeU8(os, is_visible);
writeU8(os, makes_footstep_sound);
writeF1000(os, automatic_rotate);
writeF32(os, automatic_rotate);
// Added in protocol version 14
os << serializeString(mesh);
writeU16(os, colors.size());
@ -101,19 +101,19 @@ void ObjectProperties::serialize(std::ostream &os) const
writeARGB8(os, color);
}
writeU8(os, collideWithObjects);
writeF1000(os, stepheight);
writeF32(os, stepheight);
writeU8(os, automatic_face_movement_dir);
writeF1000(os, automatic_face_movement_dir_offset);
writeF32(os, automatic_face_movement_dir_offset);
writeU8(os, backface_culling);
os << serializeString(nametag);
writeARGB8(os, nametag_color);
writeF1000(os, automatic_face_movement_max_rotation_per_sec);
writeF32(os, automatic_face_movement_max_rotation_per_sec);
os << serializeString(infotext);
os << serializeString(wield_item);
writeS8(os, glow);
writeU16(os, breath_max);
writeF1000(os, eye_height);
writeF1000(os, zoom_fov);
writeF32(os, eye_height);
writeF32(os, zoom_fov);
writeU8(os, use_texture_alpha);
// Add stuff only at the bottom.
@ -123,19 +123,19 @@ void ObjectProperties::serialize(std::ostream &os) const
void ObjectProperties::deSerialize(std::istream &is)
{
int version = readU8(is);
if (version != 3)
if (version != 4)
throw SerializationError("unsupported ObjectProperties version");
hp_max = readS16(is);
physical = readU8(is);
weight = readF1000(is);
collisionbox.MinEdge = readV3F1000(is);
collisionbox.MaxEdge = readV3F1000(is);
selectionbox.MinEdge = readV3F1000(is);
selectionbox.MaxEdge = readV3F1000(is);
weight = readF32(is);
collisionbox.MinEdge = readV3F32(is);
collisionbox.MaxEdge = readV3F32(is);
selectionbox.MinEdge = readV3F32(is);
selectionbox.MaxEdge = readV3F32(is);
pointable = readU8(is);
visual = deSerializeString(is);
visual_size = readV2F1000(is);
visual_size = readV3F32(is);
textures.clear();
u32 texture_count = readU16(is);
for (u32 i = 0; i < texture_count; i++){
@ -145,7 +145,7 @@ void ObjectProperties::deSerialize(std::istream &is)
initial_sprite_basepos = readV2S16(is);
is_visible = readU8(is);
makes_footstep_sound = readU8(is);
automatic_rotate = readF1000(is);
automatic_rotate = readF32(is);
mesh = deSerializeString(is);
colors.clear();
u32 color_count = readU16(is);
@ -153,18 +153,18 @@ void ObjectProperties::deSerialize(std::istream &is)
colors.push_back(readARGB8(is));
}
collideWithObjects = readU8(is);
stepheight = readF1000(is);
stepheight = readF32(is);
automatic_face_movement_dir = readU8(is);
automatic_face_movement_dir_offset = readF1000(is);
automatic_face_movement_dir_offset = readF32(is);
backface_culling = readU8(is);
nametag = deSerializeString(is);
nametag_color = readARGB8(is);
automatic_face_movement_max_rotation_per_sec = readF1000(is);
automatic_face_movement_max_rotation_per_sec = readF32(is);
infotext = deSerializeString(is);
wield_item = deSerializeString(is);
glow = readS8(is);
breath_max = readU16(is);
eye_height = readF1000(is);
zoom_fov = readF1000(is);
eye_height = readF32(is);
zoom_fov = readF32(is);
use_texture_alpha = readU8(is);
}

View File

@ -38,7 +38,7 @@ struct ObjectProperties
bool pointable = true;
std::string visual = "sprite";
std::string mesh = "";
v2f visual_size = v2f(1, 1);
v3f visual_size = v3f(1, 1, 1);
std::vector<std::string> textures;
std::vector<video::SColor> colors;
v2s16 spritediv = v2s16(1, 1);

View File

@ -218,8 +218,18 @@ void read_object_properties(lua_State *L, int index,
getstringfield(L, -1, "mesh", prop->mesh);
lua_getfield(L, -1, "visual_size");
if(lua_istable(L, -1))
prop->visual_size = read_v2f(L, -1);
if (lua_istable(L, -1)) {
// Backwards compatibility: Also accept { x = ?, y = ? }
v2f scale_xy = read_v2f(L, -1);
f32 scale_z = scale_xy.X;
lua_getfield(L, -1, "z");
if (lua_isnumber(L, -1))
scale_z = lua_tonumber(L, -1);
lua_pop(L, 1);
prop->visual_size = v3f(scale_xy.X, scale_xy.Y, scale_z);
}
lua_pop(L, 1);
lua_getfield(L, -1, "textures");
@ -331,7 +341,7 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
lua_setfield(L, -2, "visual");
lua_pushlstring(L, prop->mesh.c_str(), prop->mesh.size());
lua_setfield(L, -2, "mesh");
push_v2f(L, prop->visual_size);
push_v3f(L, prop->visual_size);
lua_setfield(L, -2, "visual_size");
lua_newtable(L);

View File

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <set>
#include <string>
#include "util/serialize.h"
#include "irrlichttypes_bloated.h"
struct SimpleSoundSpec
@ -34,6 +35,26 @@ struct SimpleSoundSpec
bool exists() const { return !name.empty(); }
// Take cf_version from ContentFeatures::serialize to
// keep in sync with item definitions
void serialize(std::ostream &os, u8 cf_version) const
{
os << serializeString(name);
writeF32(os, gain);
writeF32(os, pitch);
writeF32(os, fade);
// if (cf_version < ?)
// return;
}
void deSerialize(std::istream &is, u8 cf_version)
{
name = deSerializeString(is);
gain = readF32(is);
pitch = readF32(is);
fade = readF32(is);
}
std::string name;
float gain = 1.0f;
float fade = 0.0f;

View File

@ -25,11 +25,11 @@ void TileAnimationParams::serialize(std::ostream &os, u8 tiledef_version) const
if (type == TAT_VERTICAL_FRAMES) {
writeU16(os, vertical_frames.aspect_w);
writeU16(os, vertical_frames.aspect_h);
writeF1000(os, vertical_frames.length);
writeF32(os, vertical_frames.length);
} else if (type == TAT_SHEET_2D) {
writeU8(os, sheet_2d.frames_w);
writeU8(os, sheet_2d.frames_h);
writeF1000(os, sheet_2d.frame_length);
writeF32(os, sheet_2d.frame_length);
}
}
@ -40,11 +40,11 @@ void TileAnimationParams::deSerialize(std::istream &is, u8 tiledef_version)
if (type == TAT_VERTICAL_FRAMES) {
vertical_frames.aspect_w = readU16(is);
vertical_frames.aspect_h = readU16(is);
vertical_frames.length = readF1000(is);
vertical_frames.length = readF32(is);
} else if (type == TAT_SHEET_2D) {
sheet_2d.frames_w = readU8(is);
sheet_2d.frames_h = readU8(is);
sheet_2d.frame_length = readF1000(is);
sheet_2d.frame_length = readF32(is);
}
}

View File

@ -55,8 +55,8 @@ void ToolGroupCap::fromJson(const Json::Value &json)
void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const
{
writeU8(os, 3); // protocol_version >= 36
writeF1000(os, full_punch_interval);
writeU8(os, 4); // protocol_version >= 37
writeF32(os, full_punch_interval);
writeS16(os, max_drop_level);
writeU32(os, groupcaps.size());
for (const auto &groupcap : groupcaps) {
@ -68,7 +68,7 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const
writeU32(os, cap->times.size());
for (const auto &time : cap->times) {
writeS16(os, time.first);
writeF1000(os, time.second);
writeF32(os, time.second);
}
}
@ -83,10 +83,10 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const
void ToolCapabilities::deSerialize(std::istream &is)
{
int version = readU8(is);
if (version < 3)
if (version < 4)
throw SerializationError("unsupported ToolCapabilities version");
full_punch_interval = readF1000(is);
full_punch_interval = readF32(is);
max_drop_level = readS16(is);
groupcaps.clear();
u32 groupcaps_size = readU32(is);
@ -98,7 +98,7 @@ void ToolCapabilities::deSerialize(std::istream &is)
u32 times_size = readU32(is);
for(u32 i = 0; i < times_size; i++) {
int level = readS16(is);
float time = readF1000(is);
float time = readF32(is);
cap.times[level] = time;
}
groupcaps[name] = cap;

View File

@ -50,7 +50,7 @@ public:
std::wstring teststring2_w;
std::string teststring2_w_encoded;
static const u8 test_serialized_data[12 * 13];
static const u8 test_serialized_data[12 * 13 - 8];
};
static TestSerialization g_test_instance;
@ -316,7 +316,6 @@ void TestSerialization::testStreamRead()
UASSERT(readV3S16(is) == v3s16(4207, 604, -30));
UASSERT(readV2S32(is) == v2s32(1920, 1080));
UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855));
UASSERT(readV2F1000(is) == v2f(500.656f, 350.345f));
UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455");
@ -361,7 +360,6 @@ void TestSerialization::testStreamWrite()
writeV3S16(os, v3s16(4207, 604, -30));
writeV2S32(os, v2s32(1920, 1080));
writeV3S32(os, v3s32(-400, 6400054, 290549855));
writeV2F1000(os, v2f(500.65661f, 350.34567f));
os << serializeWideString(L"\x02~woof~\x5455");
@ -403,7 +401,6 @@ void TestSerialization::testVecPut()
putV3S16(&buf, v3s16(4207, 604, -30));
putV2S32(&buf, v2s32(1920, 1080));
putV3S32(&buf, v3s32(-400, 6400054, 290549855));
putV2F1000(&buf, v2f(500.65661f, 350.34567f));
putWideString(&buf, L"\x02~woof~\x5455");
@ -454,7 +451,6 @@ void TestSerialization::testBufReader()
v3s16 v3s16_data;
v2s32 v2s32_data;
v3s32 v3s32_data;
v2f v2f_data;
v3f v3f_data;
std::string string_data;
std::wstring widestring_data;
@ -481,7 +477,6 @@ void TestSerialization::testBufReader()
UASSERT(buf.getV3S16() == v3s16(4207, 604, -30));
UASSERT(buf.getV2S32() == v2s32(1920, 1080));
UASSERT(buf.getV3S32() == v3s32(-400, 6400054, 290549855));
UASSERT(buf.getV2F1000() == v2f(500.656f, 350.345f));
UASSERT(buf.getWideString() == L"\x02~woof~\x5455");
UASSERT(buf.getV3F1000() == v3f(500, 10024.2f, -192.54f));
UASSERT(buf.getARGB8() == video::SColor(255, 128, 50, 128));
@ -526,7 +521,6 @@ void TestSerialization::testBufReader()
EXCEPTION_CHECK(SerializationError, buf.getV3S16());
EXCEPTION_CHECK(SerializationError, buf.getV2S32());
EXCEPTION_CHECK(SerializationError, buf.getV3S32());
EXCEPTION_CHECK(SerializationError, buf.getV2F1000());
EXCEPTION_CHECK(SerializationError, buf.getV3F1000());
EXCEPTION_CHECK(SerializationError, buf.getString());
@ -568,7 +562,6 @@ void TestSerialization::testBufReader()
UASSERT(buf.getV3S16NoEx(&v3s16_data));
UASSERT(buf.getV2S32NoEx(&v2s32_data));
UASSERT(buf.getV3S32NoEx(&v3s32_data));
UASSERT(buf.getV2F1000NoEx(&v2f_data));
UASSERT(buf.getWideStringNoEx(&widestring_data));
UASSERT(buf.getV3F1000NoEx(&v3f_data));
UASSERT(buf.getARGB8NoEx(&scolor_data));
@ -593,7 +586,6 @@ void TestSerialization::testBufReader()
UASSERT(v3s16_data == v3s16(4207, 604, -30));
UASSERT(v2s32_data == v2s32(1920, 1080));
UASSERT(v3s32_data == v3s32(-400, 6400054, 290549855));
UASSERT(v2f_data == v2f(500.656f, 350.345f));
UASSERT(widestring_data == L"\x02~woof~\x5455");
UASSERT(v3f_data == v3f(500, 10024.2f, -192.54f));
UASSERT(scolor_data == video::SColor(255, 128, 50, 128));
@ -625,7 +617,6 @@ void TestSerialization::testBufReader()
UASSERT(!buf.getV3S16NoEx(&v3s16_data));
UASSERT(!buf.getV2S32NoEx(&v2s32_data));
UASSERT(!buf.getV3S32NoEx(&v3s32_data));
UASSERT(!buf.getV2F1000NoEx(&v2f_data));
UASSERT(!buf.getV3F1000NoEx(&v3f_data));
UASSERT(!buf.getStringNoEx(&string_data));
@ -717,7 +708,7 @@ void TestSerialization::testFloatFormat()
UASSERT(test_single(i));
}
const u8 TestSerialization::test_serialized_data[12 * 13] = {
const u8 TestSerialization::test_serialized_data[12 * 13 - 8] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e,
@ -725,8 +716,8 @@ const u8 TestSerialization::test_serialized_data[12 * 13] = {
0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10,
0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04,
0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70,
0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00,
0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00,
0x5f, 0x00, 0x08, 0x00,
0x02, 0x00, 0x7e, 0x00, 'w', 0x00, 'o', 0x00, 'o', 0x00, 'f', 0x00, // \x02~woof~\x5455
0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff,
0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73,
0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73,

View File

@ -250,29 +250,29 @@ inline v3s32 readV3S32(const u8 *data)
return p;
}
inline v2f readV2F1000(const u8 *data)
{
v2f p;
p.X = (float)readF1000(&data[0]);
p.Y = (float)readF1000(&data[4]);
return p;
}
inline v3f readV3F1000(const u8 *data)
{
v3f p;
p.X = (float)readF1000(&data[0]);
p.Y = (float)readF1000(&data[4]);
p.Z = (float)readF1000(&data[8]);
p.X = readF1000(&data[0]);
p.Y = readF1000(&data[4]);
p.Z = readF1000(&data[8]);
return p;
}
inline v2f readV2F32(const u8 *data)
{
v2f p;
p.X = readF32(&data[0]);
p.Y = readF32(&data[4]);
return p;
}
inline v3f readV3F32(const u8 *data)
{
v3f p;
p.X = (float)readF32(&data[0]);
p.Y = (float)readF32(&data[4]);
p.Z = (float)readF32(&data[8]);
p.X = readF32(&data[0]);
p.Y = readF32(&data[4]);
p.Z = readF32(&data[8]);
return p;
}
@ -357,12 +357,6 @@ inline void writeV3S32(u8 *data, v3s32 p)
writeS32(&data[8], p.Z);
}
inline void writeV2F1000(u8 *data, v2f p)
{
writeF1000(&data[0], p.X);
writeF1000(&data[4], p.Y);
}
inline void writeV3F1000(u8 *data, v3f p)
{
writeF1000(&data[0], p.X);
@ -370,6 +364,12 @@ inline void writeV3F1000(u8 *data, v3f p)
writeF1000(&data[8], p.Z);
}
inline void writeV2F32(u8 *data, v2f p)
{
writeF32(&data[0], p.X);
writeF32(&data[4], p.Y);
}
inline void writeV3F32(u8 *data, v3f p)
{
writeF32(&data[0], p.X);
@ -411,8 +411,8 @@ MAKE_STREAM_READ_FXN(v2s16, V2S16, 4);
MAKE_STREAM_READ_FXN(v3s16, V3S16, 6);
MAKE_STREAM_READ_FXN(v2s32, V2S32, 8);
MAKE_STREAM_READ_FXN(v3s32, V3S32, 12);
MAKE_STREAM_READ_FXN(v2f, V2F1000, 8);
MAKE_STREAM_READ_FXN(v3f, V3F1000, 12);
MAKE_STREAM_READ_FXN(v2f, V2F32, 8);
MAKE_STREAM_READ_FXN(v3f, V3F32, 12);
MAKE_STREAM_READ_FXN(video::SColor, ARGB8, 4);
@ -430,8 +430,8 @@ MAKE_STREAM_WRITE_FXN(v2s16, V2S16, 4);
MAKE_STREAM_WRITE_FXN(v3s16, V3S16, 6);
MAKE_STREAM_WRITE_FXN(v2s32, V2S32, 8);
MAKE_STREAM_WRITE_FXN(v3s32, V3S32, 12);
MAKE_STREAM_WRITE_FXN(v2f, V2F1000, 8);
MAKE_STREAM_WRITE_FXN(v3f, V3F1000, 12);
MAKE_STREAM_WRITE_FXN(v2f, V2F32, 8);
MAKE_STREAM_WRITE_FXN(v3f, V3F32, 12);
MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4);
@ -527,7 +527,6 @@ public:
MAKE_BUFREADER_GETNOEX_FXN(v3s16, V3S16, 6);
MAKE_BUFREADER_GETNOEX_FXN(v2s32, V2S32, 8);
MAKE_BUFREADER_GETNOEX_FXN(v3s32, V3S32, 12);
MAKE_BUFREADER_GETNOEX_FXN(v2f, V2F1000, 8);
MAKE_BUFREADER_GETNOEX_FXN(v3f, V3F1000, 12);
MAKE_BUFREADER_GETNOEX_FXN(video::SColor, ARGB8, 4);
@ -549,7 +548,6 @@ public:
MAKE_BUFREADER_GET_FXN(v3s16, V3S16);
MAKE_BUFREADER_GET_FXN(v2s32, V2S32);
MAKE_BUFREADER_GET_FXN(v3s32, V3S32);
MAKE_BUFREADER_GET_FXN(v2f, V2F1000);
MAKE_BUFREADER_GET_FXN(v3f, V3F1000);
MAKE_BUFREADER_GET_FXN(video::SColor, ARGB8);
MAKE_BUFREADER_GET_FXN(std::string, String);
@ -663,12 +661,6 @@ inline void putV3S32(std::vector<u8> *dest, v3s32 val)
putS32(dest, val.Z);
}
inline void putV2F1000(std::vector<u8> *dest, v2f val)
{
putF1000(dest, val.X);
putF1000(dest, val.Y);
}
inline void putV3F1000(std::vector<u8> *dest, v3f val)
{
putF1000(dest, val.X);