[12] vec3u block pos by 16,
[18] vec3 velocity,
[30] quat orientation,
- [38] vec3 angular velocity
+ [38] 12 reserved bytes (used to be angular velocity)
Packets
glm::vec3 start_vel;
glm::vec3 target_vel;
- glm::vec3 start_rot;
- glm::vec3 target_rot;
-
int switch_time;
float lerp_max;
float lerp_time;
}
void Spawner::Spawn(Entity &reference, const glm::ivec3 &chunk, const glm::vec3 &pos) {
- glm::vec3 rot(0.000001f);
- rot.x *= (random.Next<unsigned short>() % 1024);
- rot.y *= (random.Next<unsigned short>() % 1024);
- rot.z *= (random.Next<unsigned short>() % 1024);
-
Entity &e = world.AddEntity();
e.Position(chunk, pos);
e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
e.WorldCollidable(true);
RandomModel().Instantiate(e.GetModel());
- e.AngularVelocity(rot);
Controller *ctrl;
if (random()) {
ctrl = new RandomWalk(e, random.Next<std::uint64_t>());
, random(seed)
, start_vel(e.Velocity())
, target_vel(start_vel)
-, start_rot(e.AngularVelocity())
-, target_rot(start_rot)
, switch_time(0)
, lerp_max(1.0f)
, lerp_time(0.0f) {
} else if (lerp_time > 0) {
float a = std::min(lerp_time / lerp_max, 1.0f);
Controlled().TargetVelocity(mix(target_vel, start_vel, a));
- Controlled().AngularVelocity(mix(target_rot, start_rot, a));
} else {
Controlled().TargetVelocity(target_vel);
- Controlled().AngularVelocity(target_rot);
}
}
void RandomWalk::Change() noexcept {
start_vel = target_vel;
- start_rot = target_rot;
constexpr float base = 0.001f;
target_vel.x = base * (random.Next<short>() % 1024);
target_vel.y = base * (random.Next<short>() % 1024);
target_vel.z = base * (random.Next<short>() % 1024);
-
- target_rot.x = base * (random.Next<short>() % 1024);
- target_rot.y = base * (random.Next<short>() % 1024);
- target_rot.z = base * (random.Next<short>() % 1024);
}
}
WritePackU(state.block_pos * (1.0f / 16.0f), off + 12);
Write(state.velocity, off + 18);
Write(state.orient, off + 30);
- Write(state.ang_vel, off + 38);
}
void Packet::Payload::Read(EntityState &state, size_t off) const noexcept {
ReadPackU(state.block_pos, off + 12);
Read(state.velocity, off + 18);
Read(state.orient, off + 30);
- Read(state.ang_vel, off + 38);
state.block_pos *= 16.0f;
}
WritePackU(state.block_pos * (1.0f / 16.0f), off + 3);
Write(state.velocity, off + 9);
Write(state.orient, off + 21);
- Write(state.ang_vel, off + 29);
}
void Packet::Payload::Read(EntityState &state, const glm::ivec3 &base, size_t off) const noexcept {
ReadPackU(state.block_pos, off + 3);
Read(state.velocity, off + 9);
Read(state.orient, off + 21);
- Read(state.ang_vel, off + 29);
state.chunk_pos += base;
state.block_pos *= 16.0f;
}
return state.Diff(other.state);
}
- /// direction is rotation axis, magnitude is speed in rad/s
- const glm::vec3 &AngularVelocity() const noexcept { return state.ang_vel; }
- void AngularVelocity(const glm::vec3 &v) noexcept { state.ang_vel = v; }
-
const glm::quat &Orientation() const noexcept { return state.orient; }
void Orientation(const glm::quat &o) noexcept { state.orient = o; }
glm::vec3 position;
glm::vec3 velocity;
- glm::vec3 orient;
};
glm::vec3 velocity;
glm::quat orient;
- glm::vec3 ang_vel;
EntityState();
: chunk_pos(0)
, block_pos(0.0f)
, velocity(0.0f)
-, orient(1.0f, 0.0f, 0.0f, 0.0f)
-, ang_vel(0.0f) {
+, orient(1.0f, 0.0f, 0.0f, 0.0f) {
}
}
}
-namespace {
-
-glm::quat delta_rot(const glm::vec3 &av, float dt) {
- glm::vec3 half(av * dt * 0.5f);
- float mag = length(half);
- if (mag > 0.0f) {
- float smag = std::sin(mag) / mag;
- return glm::quat(std::cos(mag), half * smag);
- } else {
- return glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
- }
-}
-
-}
-
void World::Update(Entity &entity, float dt) {
EntityState state(entity.GetState());
constexpr float sixth = 1.0f / 6.0f;
f.position = sixth * ((a.position + 2.0f * (b.position + c.position)) + d.position);
f.velocity = sixth * ((a.velocity + 2.0f * (b.velocity + c.velocity)) + d.velocity);
- f.orient = sixth * ((a.orient + 2.0f * (b.orient + c.orient)) + d.orient);
state.block_pos += f.position * dt;
state.velocity += f.velocity * dt;
- state.orient = delta_rot(f.orient, dt) * state.orient;
state.AdjustPosition();
entity.SetState(state);
EntityState next(cur);
next.block_pos += delta.position * dt;
next.velocity += delta.velocity * dt;
- next.orient = delta_rot(cur.ang_vel, dt) * cur.orient;
next.AdjustPosition();
EntityDerivative out;
write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
- write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
uint32_t read_id = 0;
EntityState read_state;
pack.WritePlayer(write_entity);
write_state.block_pos = { 1.5f, 0.9f, 12.0f };
write_state.velocity = { 0.025f, 0.001f, 0.0f };
write_state.orient = { 1.0f, 0.0f, 0.0f, 0.0f };
- write_state.ang_vel = { 0.01f, 0.00302f, 0.0985f };
glm::vec3 write_movement(0.5f, -1.0f, 1.0f);
float write_pitch = 1.25f;
float write_yaw = -2.5f;
write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
- write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
write_entity.Bounds({{ -1, -1, -1 }, { 1, 1, 1 }});
write_entity.WorldCollidable(true);
write_entity.Name("blah");
write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
- write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
pack.WriteEntity(write_entity, write_base, 1);
pack.WriteEntity(write_entity, write_base, 0);
pack.WriteEntity(write_entity, write_base, 2);
write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
- write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
pack.WritePlayer(write_entity);
EntityState read_state;
message + ": bad orientation",
expected.orient, actual.orient
);
- AssertEqual(
- message + ": bad angular velocity",
- expected.ang_vel, actual.ang_vel
- );
}
void PacketTest::AssertEqual(