Add NetworkTransform component
This commit is contained in:
169
Source/Engine/Networking/Components/NetworkTransform.cpp
Normal file
169
Source/Engine/Networking/Components/NetworkTransform.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkTransform.h"
|
||||
#include "Engine/Core/Math/Transform.h"
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Networking/NetworkReplicator.h"
|
||||
#include "Engine/Networking/NetworkStream.h"
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
uint8 LocalSpace : 1;
|
||||
NetworkTransform::SyncModes SyncMode : 9;
|
||||
});
|
||||
|
||||
static_assert((int32)NetworkTransform::SyncModes::All + 1 == 512, "Invalid SyncModes bit count for Data.");
|
||||
|
||||
NetworkTransform::NetworkTransform(const SpawnParams& params)
|
||||
: Script(params)
|
||||
{
|
||||
}
|
||||
|
||||
void NetworkTransform::OnEnable()
|
||||
{
|
||||
// Register for replication
|
||||
NetworkReplicator::AddObject(this);
|
||||
}
|
||||
|
||||
void NetworkTransform::OnDisable()
|
||||
{
|
||||
// Unregister from replication
|
||||
NetworkReplicator::RemoveObject(this);
|
||||
}
|
||||
|
||||
void NetworkTransform::Serialize(NetworkStream* stream)
|
||||
{
|
||||
// Get transform
|
||||
Transform transform;
|
||||
if (const auto* parent = GetParent())
|
||||
transform = LocalSpace ? parent->GetLocalTransform() : parent->GetTransform();
|
||||
else
|
||||
transform = Transform::Identity;
|
||||
|
||||
// Encode data
|
||||
Data data;
|
||||
data.LocalSpace = LocalSpace;
|
||||
data.SyncMode = SyncMode;
|
||||
stream->Write(data);
|
||||
if ((data.SyncMode & SyncModes::All) == (int)SyncModes::All)
|
||||
{
|
||||
stream->Write(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((data.SyncMode & SyncModes::Position) == (int)SyncModes::Position)
|
||||
{
|
||||
stream->Write(transform.Translation);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Position)
|
||||
{
|
||||
if (data.SyncMode & SyncModes::PositionX)
|
||||
stream->Write(transform.Translation.X);
|
||||
if (data.SyncMode & SyncModes::PositionY)
|
||||
stream->Write(transform.Translation.X);
|
||||
if (data.SyncMode & SyncModes::PositionZ)
|
||||
stream->Write(transform.Translation.X);
|
||||
}
|
||||
if ((data.SyncMode & SyncModes::Scale) == (int)SyncModes::Scale)
|
||||
{
|
||||
stream->Write(transform.Scale);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Scale)
|
||||
{
|
||||
if (data.SyncMode & SyncModes::ScaleX)
|
||||
stream->Write(transform.Scale.X);
|
||||
if (data.SyncMode & SyncModes::ScaleY)
|
||||
stream->Write(transform.Scale.X);
|
||||
if (data.SyncMode & SyncModes::ScaleZ)
|
||||
stream->Write(transform.Scale.X);
|
||||
}
|
||||
if ((data.SyncMode & SyncModes::Rotation) == (int)SyncModes::Rotation)
|
||||
{
|
||||
const Float3 rotation = transform.Orientation.GetEuler();
|
||||
stream->Write(rotation);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Rotation)
|
||||
{
|
||||
const Float3 rotation = transform.Orientation.GetEuler();
|
||||
if (data.SyncMode & SyncModes::RotationX)
|
||||
stream->Write(rotation.X);
|
||||
if (data.SyncMode & SyncModes::RotationY)
|
||||
stream->Write(rotation.Y);
|
||||
if (data.SyncMode & SyncModes::RotationZ)
|
||||
stream->Write(rotation.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkTransform::Deserialize(NetworkStream* stream)
|
||||
{
|
||||
// Get transform
|
||||
Transform transform;
|
||||
if (const auto* parent = GetParent())
|
||||
transform = LocalSpace ? parent->GetLocalTransform() : parent->GetTransform();
|
||||
else
|
||||
transform = Transform::Identity;
|
||||
|
||||
// Decode data
|
||||
Data data;
|
||||
stream->Read(data);
|
||||
if ((data.SyncMode & SyncModes::All) == (int)SyncModes::All)
|
||||
{
|
||||
stream->Read(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((data.SyncMode & SyncModes::Position) == (int)SyncModes::Position)
|
||||
{
|
||||
stream->Read(transform.Translation);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Position)
|
||||
{
|
||||
if (data.SyncMode & SyncModes::PositionX)
|
||||
stream->Read(transform.Translation.X);
|
||||
if (data.SyncMode & SyncModes::PositionY)
|
||||
stream->Read(transform.Translation.X);
|
||||
if (data.SyncMode & SyncModes::PositionZ)
|
||||
stream->Read(transform.Translation.X);
|
||||
}
|
||||
if ((data.SyncMode & SyncModes::Scale) == (int)SyncModes::Scale)
|
||||
{
|
||||
stream->Read(transform.Scale);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Scale)
|
||||
{
|
||||
if (data.SyncMode & SyncModes::ScaleX)
|
||||
stream->Read(transform.Scale.X);
|
||||
if (data.SyncMode & SyncModes::ScaleY)
|
||||
stream->Read(transform.Scale.X);
|
||||
if (data.SyncMode & SyncModes::ScaleZ)
|
||||
stream->Read(transform.Scale.X);
|
||||
}
|
||||
if ((data.SyncMode & SyncModes::Rotation) == (int)SyncModes::Rotation)
|
||||
{
|
||||
Float3 rotation;
|
||||
stream->Read(rotation);
|
||||
transform.Orientation = Quaternion::Euler(rotation);
|
||||
}
|
||||
else if (data.SyncMode & SyncModes::Rotation)
|
||||
{
|
||||
Float3 rotation = transform.Orientation.GetEuler();
|
||||
if (data.SyncMode & SyncModes::RotationX)
|
||||
stream->Read(rotation.X);
|
||||
if (data.SyncMode & SyncModes::RotationY)
|
||||
stream->Read(rotation.Y);
|
||||
if (data.SyncMode & SyncModes::RotationZ)
|
||||
stream->Read(rotation.Z);
|
||||
transform.Orientation = Quaternion::Euler(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Set transform
|
||||
if (auto* parent = GetParent())
|
||||
{
|
||||
if (data.LocalSpace)
|
||||
parent->SetLocalTransform(transform);
|
||||
else
|
||||
parent->SetTransform(transform);
|
||||
}
|
||||
}
|
||||
78
Source/Engine/Networking/Components/NetworkTransform.h
Normal file
78
Source/Engine/Networking/Components/NetworkTransform.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "Engine/Networking/INetworkSerializable.h"
|
||||
|
||||
/// <summary>
|
||||
/// Actor script component that synchronizes the Transform over the network.
|
||||
/// </summary>
|
||||
API_CLASS(Namespace="FlaxEngine.Networking") class FLAXENGINE_API NetworkTransform : public Script, public INetworkSerializable
|
||||
{
|
||||
API_AUTO_SERIALIZATION();
|
||||
DECLARE_SCRIPTING_TYPE(NetworkTransform);
|
||||
|
||||
/// <summary>
|
||||
/// Actor transform synchronization modes (flags).
|
||||
/// </summary>
|
||||
API_ENUM(Attributes="Flags") enum class SyncModes
|
||||
{
|
||||
// No sync.
|
||||
None = 0,
|
||||
|
||||
// Position X component.
|
||||
PositionX = 1 << 0,
|
||||
// Position Y component.
|
||||
PositionY = 1 << 1,
|
||||
// Position Z component.
|
||||
PositionZ = 1 << 2,
|
||||
// Position XYZ components (full).
|
||||
Position = PositionX | PositionY | PositionZ,
|
||||
|
||||
// Scale X component.
|
||||
ScaleX = 1 << 3,
|
||||
// Scale Y component.
|
||||
ScaleY = 1 << 4,
|
||||
// Scale Z component.
|
||||
ScaleZ = 1 << 5,
|
||||
// Scale XYZ components (full).
|
||||
Scale = ScaleX | ScaleY | ScaleZ,
|
||||
|
||||
// Position X component.
|
||||
RotationX = 1 << 6,
|
||||
// Position Y component.
|
||||
RotationY = 1 << 7,
|
||||
// Position Z component.
|
||||
RotationZ = 1 << 8,
|
||||
// Rotation XYZ components (full).
|
||||
Rotation = RotationX | RotationY | RotationZ,
|
||||
|
||||
// All components fully synchronized.
|
||||
All = Position | Scale | Rotation,
|
||||
};
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// If checked, actor transform will be synchronized in local space of the parent actor (otherwise in world space).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10)")
|
||||
bool LocalSpace = false;
|
||||
|
||||
/// <summary>
|
||||
/// Actor transform synchronization mode (flags).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20)")
|
||||
SyncModes SyncMode = SyncModes::All;
|
||||
|
||||
public:
|
||||
// [Script]
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
|
||||
// [INetworkSerializable]
|
||||
void Serialize(NetworkStream* stream) override;
|
||||
void Deserialize(NetworkStream* stream) override;
|
||||
};
|
||||
|
||||
DECLARE_ENUM_OPERATORS(NetworkTransform::SyncModes);
|
||||
Reference in New Issue
Block a user