Clean up compressing for network body
This commit is contained in:
parent
d00472f868
commit
733794bb3e
@ -41,6 +41,7 @@
|
||||
#include "karts/explosion_animation.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "network/compress_network_body.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
@ -426,6 +427,10 @@ bool Flyable::updateAndDelete(int ticks)
|
||||
return false;
|
||||
} // if animation
|
||||
|
||||
// Round down values in network for better synchronization
|
||||
if (NetworkConfig::get()->roundValuesNow())
|
||||
CompressNetworkBody::compress(m_body.get(), m_motion_state.get());
|
||||
|
||||
// 32767 for max m_ticks_since_thrown so the last bit for animation save
|
||||
if (m_ticks_since_thrown < 32767)
|
||||
m_ticks_since_thrown += ticks;
|
||||
@ -654,9 +659,8 @@ BareNetworkString* Flyable::saveState(std::vector<std::string>* ru)
|
||||
m_animation->saveState(buffer);
|
||||
else
|
||||
{
|
||||
CompressNetworkBody::compress(m_body->getWorldTransform(),
|
||||
m_body->getLinearVelocity(), m_body->getAngularVelocity(), buffer,
|
||||
m_body.get(), m_motion_state.get());
|
||||
CompressNetworkBody::compress(
|
||||
m_body.get(), m_motion_state.get(), buffer);
|
||||
}
|
||||
return buffer;
|
||||
} // saveState
|
||||
@ -684,14 +688,9 @@ void Flyable::restoreState(BareNetworkString *buffer, int count)
|
||||
// will set m_animation to null
|
||||
delete m_animation;
|
||||
}
|
||||
btTransform t;
|
||||
Vec3 lv, av;
|
||||
CompressNetworkBody::decompress(buffer, &t, &lv, &av);
|
||||
|
||||
m_body->setLinearVelocity(lv);
|
||||
m_body->setAngularVelocity(av);
|
||||
m_body->proceedToTransform(t);
|
||||
setTrans(t);
|
||||
CompressNetworkBody::decompress(
|
||||
buffer, m_body.get(), m_motion_state.get());
|
||||
m_transform = m_body->getWorldTransform();
|
||||
}
|
||||
m_ticks_since_thrown = ticks_since_thrown_animation & 32767;
|
||||
m_has_server_state = true;
|
||||
|
@ -46,8 +46,6 @@ class Moveable: public NoCopy,
|
||||
{
|
||||
private:
|
||||
Vec3 m_velocityLC; /**<Velocity in kart coordinates. */
|
||||
/** The bullet transform of this rigid body. */
|
||||
btTransform m_transform;
|
||||
/** The 'real' heading between -180 to 180 degrees. */
|
||||
float m_heading;
|
||||
/** The pitch between -90 and 90 degrees. */
|
||||
@ -55,6 +53,8 @@ private:
|
||||
/** The roll between -180 and 180 degrees. */
|
||||
float m_roll;
|
||||
protected:
|
||||
/** The bullet transform of this rigid body. */
|
||||
btTransform m_transform;
|
||||
UserPointer m_user_pointer;
|
||||
scene::ISceneNode *m_node;
|
||||
std::unique_ptr<btRigidBody> m_body;
|
||||
|
@ -29,49 +29,68 @@ namespace CompressNetworkBody
|
||||
{
|
||||
using namespace MiniGLM;
|
||||
// ------------------------------------------------------------------------
|
||||
inline void compress(btTransform t, const Vec3& lv, const Vec3& av,
|
||||
BareNetworkString* bns, btRigidBody* body,
|
||||
btMotionState* ms)
|
||||
inline void setRoundedDownValues(float x, float y, float z,
|
||||
uint32_t compressed_q,
|
||||
short lvx, short lvy, short lvz,
|
||||
short avx, short avy, short avz,
|
||||
btRigidBody* body, btMotionState* ms)
|
||||
{
|
||||
bns->add(t.getOrigin());
|
||||
uint32_t compressed_q = compressQuaternion(t.getRotation());
|
||||
bns->addUInt32(compressed_q);
|
||||
std::array<short, 3> lvs =
|
||||
{{ toFloat16(lv.x()), toFloat16(lv.y()), toFloat16(lv.z()) }};
|
||||
bns->addUInt16(lvs[0]).addUInt16(lvs[1]).addUInt16(lvs[2]);
|
||||
std::array<short, 3> avs =
|
||||
{{ toFloat16(av.x()), toFloat16(av.y()), toFloat16(av.z()) }};
|
||||
bns->addUInt16(avs[0]).addUInt16(avs[1]).addUInt16(avs[2]);
|
||||
btTransform trans;
|
||||
trans.setOrigin(btVector3(x,y,z));
|
||||
trans.setRotation(decompressbtQuaternion(compressed_q));
|
||||
btVector3 lv(toFloat32(lvx), toFloat32(lvy), toFloat32(lvz));
|
||||
btVector3 av(toFloat32(avx), toFloat32(avy), toFloat32(avz));
|
||||
|
||||
btQuaternion uncompressed_q = decompressbtQuaternion(compressed_q);
|
||||
t.setRotation(uncompressed_q);
|
||||
Vec3 uncompressed_lv(toFloat32(lvs[0]), toFloat32(lvs[1]),
|
||||
toFloat32(lvs[2]));
|
||||
Vec3 uncompressed_av(toFloat32(avs[0]), toFloat32(avs[1]),
|
||||
toFloat32(avs[2]));
|
||||
body->setWorldTransform(t);
|
||||
ms->setWorldTransform(t);
|
||||
body->setInterpolationWorldTransform(t);
|
||||
body->setLinearVelocity(uncompressed_lv);
|
||||
body->setAngularVelocity(uncompressed_av);
|
||||
body->setInterpolationLinearVelocity(uncompressed_lv);
|
||||
body->setInterpolationAngularVelocity(uncompressed_av);
|
||||
body->setWorldTransform(trans);
|
||||
ms->setWorldTransform(trans);
|
||||
body->setInterpolationWorldTransform(trans);
|
||||
body->setLinearVelocity(lv);
|
||||
body->setAngularVelocity(av);
|
||||
body->setInterpolationLinearVelocity(lv);
|
||||
body->setInterpolationAngularVelocity(av);
|
||||
body->updateInertiaTensor();
|
||||
} // setRoundedDownValues
|
||||
// ------------------------------------------------------------------------
|
||||
inline void compress(btRigidBody* body, btMotionState* ms,
|
||||
BareNetworkString* bns = NULL)
|
||||
{
|
||||
float x = body->getWorldTransform().getOrigin().x();
|
||||
float y = body->getWorldTransform().getOrigin().y();
|
||||
float z = body->getWorldTransform().getOrigin().z();
|
||||
uint32_t compressed_q =
|
||||
compressQuaternion(body->getWorldTransform().getRotation());
|
||||
short lvx = toFloat16(body->getLinearVelocity().x());
|
||||
short lvy = toFloat16(body->getLinearVelocity().y());
|
||||
short lvz = toFloat16(body->getLinearVelocity().z());
|
||||
short avx = toFloat16(body->getAngularVelocity().x());
|
||||
short avy = toFloat16(body->getAngularVelocity().y());
|
||||
short avz = toFloat16(body->getAngularVelocity().z());
|
||||
setRoundedDownValues(x, y, z, compressed_q, lvx, lvy, lvz, avx, avy,
|
||||
avz, body, ms);
|
||||
// if bns is null, it's locally compress (for rounding down values)
|
||||
if (!bns)
|
||||
return;
|
||||
|
||||
bns->addFloat(x).addFloat(y).addFloat(z).addUInt32(compressed_q);
|
||||
bns->addUInt16(lvx).addUInt16(lvy).addUInt16(lvz)
|
||||
.addUInt16(avx).addUInt16(avy).addUInt16(avz);
|
||||
} // compress
|
||||
// ------------------------------------------------------------------------
|
||||
inline void decompress(const BareNetworkString* bns, btTransform* t,
|
||||
Vec3* lv, Vec3* av)
|
||||
inline void decompress(const BareNetworkString* bns,
|
||||
btRigidBody* body, btMotionState* ms)
|
||||
{
|
||||
t->setOrigin(bns->getVec3());
|
||||
t->setRotation(decompressbtQuaternion(bns->getUInt32()));
|
||||
short vec[3];
|
||||
vec[0] = bns->getUInt16();
|
||||
vec[1] = bns->getUInt16();
|
||||
vec[2] = bns->getUInt16();
|
||||
*lv = Vec3(toFloat32(vec[0]), toFloat32(vec[1]), toFloat32(vec[2]));
|
||||
vec[0] = bns->getUInt16();
|
||||
vec[1] = bns->getUInt16();
|
||||
vec[2] = bns->getUInt16();
|
||||
*av = Vec3(toFloat32(vec[0]), toFloat32(vec[1]), toFloat32(vec[2]));
|
||||
float x = bns->getFloat();
|
||||
float y = bns->getFloat();
|
||||
float z = bns->getFloat();
|
||||
uint32_t compressed_q = bns->getUInt32();
|
||||
short lvx = bns->getUInt16();
|
||||
short lvy = bns->getUInt16();
|
||||
short lvz = bns->getUInt16();
|
||||
short avx = bns->getUInt16();
|
||||
short avy = bns->getUInt16();
|
||||
short avz = bns->getUInt16();
|
||||
setRoundedDownValues(x, y, z, compressed_q, lvx, lvy, lvz, avx, avy,
|
||||
avz, body, ms);
|
||||
} // decompress
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "network/server_config.hpp"
|
||||
#include "network/transport_address.hpp"
|
||||
#include "online/xml_request.hpp"
|
||||
@ -159,3 +161,12 @@ void NetworkConfig::clearActivePlayersForClient() const
|
||||
input_manager->getDeviceManager()->clearLatestUsedDevice();
|
||||
}
|
||||
} // clearActivePlayersForClient
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** True when client needs to round the bodies phyiscal info for current
|
||||
* ticks, server doesn't as it will be done implictly in save state. */
|
||||
bool NetworkConfig::roundValuesNow() const
|
||||
{
|
||||
return isNetworking() && !isServer() && RewindManager::get()
|
||||
->shouldSaveState(World::getWorld()->getTicksSinceStart());
|
||||
} // roundValuesNow
|
||||
|
@ -229,6 +229,8 @@ public:
|
||||
void setStateFrequency(int frequency) { m_state_frequency = frequency; }
|
||||
// ------------------------------------------------------------------------
|
||||
int getStateFrequency() const { return m_state_frequency; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool roundValuesNow() const;
|
||||
}; // class NetworkConfig
|
||||
|
||||
#endif // HEADER_NETWORK_CONFIG
|
||||
|
@ -37,6 +37,19 @@ void NetworkString::unitTesting()
|
||||
s.setSynchronous(false);
|
||||
assert(!s.isSynchronous());
|
||||
|
||||
// 24bit saving, min -8388608, max 8388607
|
||||
int min = -8388608;
|
||||
BareNetworkString smin;
|
||||
smin.addInt24(min);
|
||||
min = smin.getInt24();
|
||||
assert(min == -8388608);
|
||||
|
||||
int max = 8388607;
|
||||
BareNetworkString smax;
|
||||
smax.addInt24(max);
|
||||
max = smax.getInt24();
|
||||
assert(max == 8388607);
|
||||
|
||||
// Check log message format
|
||||
BareNetworkString slog(28);
|
||||
for(unsigned int i=0; i<28; i++)
|
||||
|
@ -245,6 +245,17 @@ public:
|
||||
return *this;
|
||||
} // addUInt16
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds signed 24 bit integer. */
|
||||
BareNetworkString& addInt24(const int value)
|
||||
{
|
||||
uint32_t combined = (uint32_t)value & 16777215;
|
||||
m_buffer.push_back((combined >> 16) & 0xff);
|
||||
m_buffer.push_back((combined >> 8) & 0xff);
|
||||
m_buffer.push_back(combined & 0xff);
|
||||
return *this;
|
||||
} // addInt24
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds unsigned 32 bit integer. */
|
||||
BareNetworkString& addUInt32(const uint32_t& value)
|
||||
@ -328,6 +339,16 @@ public:
|
||||
/** Returns a unsigned 32 bit integer. */
|
||||
inline uint32_t getUInt32() const { return get<uint32_t, 4>(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a signed 24 bit integer. */
|
||||
inline int getInt24() const
|
||||
{
|
||||
uint32_t combined = get<uint32_t, 3>();
|
||||
if (combined & 8388608)
|
||||
return (16777216 - (int)combined) * -1;
|
||||
else
|
||||
return (int)combined;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a unsigned 32 bit integer. */
|
||||
inline uint32_t getTime() const { return get<uint32_t, 4>(); }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config/stk_config.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/mesh_tools.hpp"
|
||||
@ -28,9 +29,9 @@
|
||||
#include "io/xml_node.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "network/protocols/lobby_protocol.hpp"
|
||||
#include "network/compress_network_body.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/protocols/lobby_protocol.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "tracks/track_object.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
@ -42,6 +43,7 @@
|
||||
#include <ITexture.h>
|
||||
using namespace irr;
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -631,8 +633,11 @@ void PhysicalObject::update(float dt)
|
||||
{
|
||||
if (!m_is_dynamic) return;
|
||||
|
||||
m_current_transform = m_body->getWorldTransform();
|
||||
// Round down values in network for better synchronization
|
||||
if (NetworkConfig::get()->roundValuesNow())
|
||||
CompressNetworkBody::compress(m_body, m_motion_state);
|
||||
|
||||
m_current_transform = m_body->getWorldTransform();
|
||||
const Vec3 &xyz = m_current_transform.getOrigin();
|
||||
if(m_reset_when_too_low && xyz.getY()<m_reset_height)
|
||||
{
|
||||
@ -809,21 +814,28 @@ BareNetworkString* PhysicalObject::saveState(std::vector<std::string>* ru)
|
||||
if (auto sl = LobbyProtocol::get<LobbyProtocol>())
|
||||
has_live_join = sl->hasLiveJoiningRecently();
|
||||
|
||||
BareNetworkString* buffer = new BareNetworkString();
|
||||
// This will compress and round down values of body, use the rounded
|
||||
// down value to test if sending state is needed
|
||||
// If any client live-joined always send new state for this object
|
||||
CompressNetworkBody::compress(m_body, m_motion_state, buffer);
|
||||
btTransform cur_transform = m_body->getWorldTransform();
|
||||
Vec3 current_lv = m_body->getLinearVelocity();
|
||||
Vec3 current_av = m_body->getAngularVelocity();
|
||||
|
||||
if ((cur_transform.getOrigin() - m_last_transform.getOrigin())
|
||||
.length() < 0.01f &&
|
||||
(m_body->getLinearVelocity() - m_last_lv).length() < 0.01f &&
|
||||
(m_body->getLinearVelocity() - m_last_av).length() < 0.01f &&
|
||||
!has_live_join)
|
||||
(current_lv - m_last_lv).length() < 0.01f &&
|
||||
(current_av - m_last_av).length() < 0.01f && !has_live_join)
|
||||
{
|
||||
delete buffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ru->push_back(getUniqueIdentity());
|
||||
BareNetworkString *buffer = new BareNetworkString();
|
||||
m_last_transform = cur_transform;
|
||||
m_last_lv = m_body->getLinearVelocity();
|
||||
m_last_av = m_body->getAngularVelocity();
|
||||
CompressNetworkBody::compress(m_last_transform, m_last_lv, m_last_av,
|
||||
buffer, m_body, m_motion_state);
|
||||
m_last_lv = current_lv;
|
||||
m_last_av = current_av;
|
||||
return buffer;
|
||||
} // saveState
|
||||
|
||||
@ -831,16 +843,11 @@ BareNetworkString* PhysicalObject::saveState(std::vector<std::string>* ru)
|
||||
void PhysicalObject::restoreState(BareNetworkString *buffer, int count)
|
||||
{
|
||||
m_no_server_state = false;
|
||||
CompressNetworkBody::decompress(buffer, &m_last_transform, &m_last_lv,
|
||||
&m_last_av);
|
||||
|
||||
m_body->setWorldTransform(m_last_transform);
|
||||
m_motion_state->setWorldTransform(m_last_transform);
|
||||
m_body->setInterpolationWorldTransform(m_last_transform);
|
||||
m_body->setLinearVelocity(m_last_lv);
|
||||
m_body->setAngularVelocity(m_last_av);
|
||||
m_body->setInterpolationLinearVelocity(m_last_lv);
|
||||
m_body->setInterpolationAngularVelocity(m_last_av);
|
||||
CompressNetworkBody::decompress(buffer, m_body, m_motion_state);
|
||||
// Save the newly decompressed value for local state restore
|
||||
m_last_transform = m_body->getWorldTransform();
|
||||
m_last_lv = m_body->getLinearVelocity();
|
||||
m_last_av = m_body->getAngularVelocity();
|
||||
} // restoreState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -188,9 +188,13 @@ private:
|
||||
/** Non-null only if the shape is exact */
|
||||
TriangleMesh *m_triangle_mesh;
|
||||
|
||||
/* Last transform and velocities recieved or saved for networking */
|
||||
btTransform m_last_transform;
|
||||
Vec3 m_last_lv;
|
||||
Vec3 m_last_av;
|
||||
|
||||
/* Used to determine if local state should be used, which is true
|
||||
* when the object is not moving */
|
||||
bool m_no_server_state;
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user