Merge branch 'main' of https://github.com/aws-lumberyard/o3de into ly-as-sdk/LYN-2948-phistere
This commit is contained in:
@@ -115,7 +115,7 @@ namespace AZ::IO
|
||||
// If used, the source path will be treated as the destination path
|
||||
// and no transformations will be done. Pass this flag when the path is to be the actual
|
||||
// path on the disk/in the packs and doesn't need adjustment (or after it has come through adjustments already)
|
||||
// if this is set, AdjustFileName will not map the input path into the master folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
// if this is set, AdjustFileName will not map the input path into the folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
FLAGS_PATH_REAL = 1 << 16,
|
||||
|
||||
// AdjustFileName will always copy the file path to the destination path:
|
||||
@@ -318,7 +318,6 @@ namespace AZ::IO
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0;
|
||||
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
// virtual bool IsOutOfDate(const char * szCompiledName, const char * szMasterFile)=0;
|
||||
//returns file modification time
|
||||
virtual IArchive::FileTime GetModificationTime(AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AZ::IO
|
||||
enum EPakFlags
|
||||
{
|
||||
// support for absolute and other complex path specifications -
|
||||
// all paths will be treated relatively to the current directory (normally MasterCD)
|
||||
// all paths will be treated relatively to the current directory
|
||||
FLAGS_ABSOLUTE_PATHS = 1,
|
||||
|
||||
// if this is set, the object will only understand relative to the zip file paths,
|
||||
|
||||
@@ -432,46 +432,26 @@ namespace AzFramework
|
||||
|
||||
void TransformComponent::SetLocalRotation(const AZ::Vector3& eulerRadianAngles)
|
||||
{
|
||||
AZ::Transform newLocalTM = AZ::ConvertEulerRadiansToTransform(eulerRadianAngles);
|
||||
newLocalTM.SetScale(m_localTM.GetScale());
|
||||
newLocalTM.SetTranslation(m_localTM.GetTranslation());
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetRotation(AZ::Quaternion::CreateFromEulerAnglesRadians(eulerRadianAngles));
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ::Transform newLocalTM;
|
||||
newLocalTM.SetScale(m_localTM.GetScale());
|
||||
newLocalTM.SetTranslation(m_localTM.GetTranslation());
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetRotation(quaternion);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
static AZ::Transform RotateAroundLocalHelper(float eulerAngleRadian, const AZ::Transform& localTM, AZ::Vector3 axis)
|
||||
{
|
||||
//get the existing translation and scale
|
||||
AZ::Vector3 translation = localTM.GetTranslation();
|
||||
AZ::Vector3 scale = localTM.GetScale();
|
||||
|
||||
//normalize the axis before creating rotation
|
||||
axis.Normalize();
|
||||
AZ::Quaternion rotate = AZ::Quaternion::CreateFromAxisAngle(axis, eulerAngleRadian);
|
||||
|
||||
//create new rotation transform
|
||||
AZ::Quaternion currentRotate = localTM.GetRotation();
|
||||
AZ::Quaternion newRotate = rotate * currentRotate;
|
||||
newRotate.Normalize();
|
||||
|
||||
//scale
|
||||
AZ::Transform newLocalTM = AZ::Transform::CreateScale(scale);
|
||||
|
||||
//rotate
|
||||
AZ::Transform rotateLocalTM = AZ::Transform::CreateFromQuaternion(newRotate);
|
||||
newLocalTM = rotateLocalTM * newLocalTM;
|
||||
|
||||
//translate
|
||||
newLocalTM.SetTranslation(translation);
|
||||
|
||||
AZ::Transform newLocalTM = localTM;
|
||||
newLocalTM.SetRotation((rotate * localTM.GetRotation()).GetNormalized());
|
||||
return newLocalTM;
|
||||
}
|
||||
|
||||
@@ -512,75 +492,6 @@ namespace AzFramework
|
||||
return m_localTM.GetRotation();
|
||||
}
|
||||
|
||||
void TransformComponent::SetScale(const AZ::Vector3& scale)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScale is deprecated, please use SetLocalScale");
|
||||
|
||||
if (!m_worldTM.GetScale().IsClose(scale))
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(scale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleX(float scaleX)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleX is deprecated, please use SetLocalScaleX");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetX(scaleX);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleY(float scaleY)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleY is deprecated, please use SetLocalScaleY");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetY(scaleY);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleZ(float scaleZ)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleZ is deprecated, please use SetLocalScaleZ");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetZ(scaleZ);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetScale()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScale is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleX()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleX is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetX();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleY()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleY is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetY();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleZ()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleZ is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetZ();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
@@ -588,33 +499,6 @@ namespace AzFramework
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleX(float scaleX)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetX(scaleX);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleY(float scaleY)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetY(scaleY);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleZ(float scaleZ)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetZ(scaleZ);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetLocalScale()
|
||||
{
|
||||
return m_localTM.GetScale();
|
||||
@@ -625,6 +509,23 @@ namespace AzFramework
|
||||
return m_worldTM.GetScale();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalUniformScale(float scale)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetUniformScale(scale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
float TransformComponent::GetLocalUniformScale()
|
||||
{
|
||||
return m_localTM.GetUniformScale();
|
||||
}
|
||||
|
||||
float TransformComponent::GetWorldUniformScale()
|
||||
{
|
||||
return m_worldTM.GetUniformScale();
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::EntityId> TransformComponent::GetChildren()
|
||||
{
|
||||
AZStd::vector<AZ::EntityId> children;
|
||||
@@ -979,34 +880,7 @@ namespace AzFramework
|
||||
->Event("GetLocalRotationQuaternion", &AZ::TransformBus::Events::GetLocalRotationQuaternion)
|
||||
->Attribute("Rotation", AZ::Edit::Attributes::PropertyRotation)
|
||||
->VirtualProperty("Rotation", "GetLocalRotationQuaternion", "SetLocalRotationQuaternion")
|
||||
->Event("SetScale", &AZ::TransformBus::Events::SetScale)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleX", &AZ::TransformBus::Events::SetScaleX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleY", &AZ::TransformBus::Events::SetScaleY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleZ", &AZ::TransformBus::Events::SetScaleZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScale", &AZ::TransformBus::Events::GetScale)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleX", &AZ::TransformBus::Events::GetScaleX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleY", &AZ::TransformBus::Events::GetScaleY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleZ", &AZ::TransformBus::Events::GetScaleZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetLocalScale", &AZ::TransformBus::Events::SetLocalScale)
|
||||
->Event("SetLocalScaleX", &AZ::TransformBus::Events::SetLocalScaleX)
|
||||
->Event("SetLocalScaleY", &AZ::TransformBus::Events::SetLocalScaleY)
|
||||
->Event("SetLocalScaleZ", &AZ::TransformBus::Events::SetLocalScaleZ)
|
||||
->Event("GetLocalScale", &AZ::TransformBus::Events::GetLocalScale)
|
||||
->Attribute("Scale", AZ::Edit::Attributes::PropertyScale)
|
||||
->VirtualProperty("Scale", "GetLocalScale", "SetLocalScale")
|
||||
|
||||
@@ -143,24 +143,14 @@ namespace AzFramework
|
||||
AZ::Quaternion GetLocalRotationQuaternion() override;
|
||||
|
||||
// Scale Modifiers
|
||||
void SetScale(const AZ::Vector3& scale) override;
|
||||
void SetScaleX(float scaleX) override;
|
||||
void SetScaleY(float scaleY) override;
|
||||
void SetScaleZ(float scaleZ) override;
|
||||
|
||||
AZ::Vector3 GetScale() override;
|
||||
float GetScaleX() override;
|
||||
float GetScaleY() override;
|
||||
float GetScaleZ() override;
|
||||
|
||||
void SetLocalScale(const AZ::Vector3& scale) override;
|
||||
void SetLocalScaleX(float scaleX) override;
|
||||
void SetLocalScaleY(float scaleY) override;
|
||||
void SetLocalScaleZ(float scaleZ) override;
|
||||
|
||||
AZ::Vector3 GetLocalScale() override;
|
||||
AZ::Vector3 GetWorldScale() override;
|
||||
|
||||
void SetLocalUniformScale(float scale) override;
|
||||
float GetLocalUniformScale() override;
|
||||
float GetWorldUniformScale() override;
|
||||
|
||||
// Transform hierarchy
|
||||
AZStd::vector<AZ::EntityId> GetChildren() override;
|
||||
AZStd::vector<AZ::EntityId> GetAllDescendants() override;
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace AzFramework
|
||||
virtual void DrawTrianglesIndexed(const AZStd::vector<AZ::Vector3>& vertices, const AZStd::vector<AZ::u32>& indices, const AZ::Color& color) { (void)vertices; (void)indices, (void)color; }
|
||||
virtual void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; }
|
||||
virtual void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; }
|
||||
virtual void DrawWireOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; }
|
||||
virtual void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; }
|
||||
virtual void DrawPoint(const AZ::Vector3& p, int nSize = 1) { (void)p; (void)nSize; }
|
||||
virtual void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) { (void)p1; (void)p2; }
|
||||
@@ -70,18 +71,15 @@ namespace AzFramework
|
||||
virtual void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) { (void)p1; (void)p2; (void)z; }
|
||||
virtual void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) { (void)p1; (void)p2; (void)z; (void)firstColor; (void)secondColor; }
|
||||
virtual void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) { (void)center; (void)radius; (void)z; }
|
||||
virtual void DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) { (void)worldPos; (void)radius; (void)height; }
|
||||
virtual void DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) { (void)center; (void)radius; (void)angle1; (void)angle2; (void)height; }
|
||||
virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis = 2) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)referenceAxis; }
|
||||
virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)fixedAxis; }
|
||||
virtual void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)nUnchangedAxis; }
|
||||
virtual void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)viewPos; (void)nUnchangedAxis; }
|
||||
virtual void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) { (void)pos; (void)dir; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; }
|
||||
virtual void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; }
|
||||
virtual void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) { (void)center; (void)axis; (void)radius; (void)heightStraightSection; }
|
||||
virtual void DrawTerrainRect(float x1, float y1, float x2, float y2, float height) { (void)x1; (void)y1; (void)x2; (void)y2; (void)height; }
|
||||
virtual void DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) { (void)worldPos1; (void)worldPos2; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, float radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) { (void)pos; (void)radius; }
|
||||
virtual void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; }
|
||||
@@ -91,11 +89,8 @@ namespace AzFramework
|
||||
virtual void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) { (void)pos; (void)size; (void)text; (void)bCenter; (void)srcOffsetX; (void)srcOffsetY; }
|
||||
virtual void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) { (void)x; (void)y; (void)size; (void)text; (void)bCenter; }
|
||||
virtual void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) { (void)pos; (void)text; (void)textScale; (void)TextColor; (void)TextBackColor; }
|
||||
virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)texture; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; }
|
||||
virtual void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)textureId; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; }
|
||||
virtual void SetLineWidth(float width) { (void)width; }
|
||||
virtual bool IsVisible(const AZ::Aabb& bounds) { (void)bounds; return false; }
|
||||
virtual int SetFillMode(int nFillMode) { (void)nFillMode; return 0; }
|
||||
virtual float GetLineWidth() { return 0.0f; }
|
||||
virtual float GetAspectRatio() { return 0.0f; }
|
||||
virtual void DepthTestOff() {}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionLayers.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsTypes.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h>
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace Physics
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
ShapeConfigurationList m_shapes;
|
||||
AzPhysics::ShapeColliderPairList m_shapes;
|
||||
};
|
||||
|
||||
class CharacterColliderConfiguration
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Physics
|
||||
classElement.RemoveElement(shapesIndex);
|
||||
|
||||
// add a new vector in the new format
|
||||
const int newShapesIndex = classElement.AddElement<ShapeConfigurationList>(context, "shapes");
|
||||
const int newShapesIndex = classElement.AddElement<AzPhysics::ShapeColliderPairList>(context, "shapes");
|
||||
if (newShapesIndex != -1)
|
||||
{
|
||||
AZ::SerializeContext::DataElementNode& newShapesElement = classElement.GetSubElement(newShapesIndex);
|
||||
@@ -65,7 +65,9 @@ namespace Physics
|
||||
// convert the old shapes into the new format and add to the vector
|
||||
for (AZ::SerializeContext::DataElementNode shape : shapesCopy)
|
||||
{
|
||||
const int pairIndex = newShapesElement.AddElementWithData<ShapeConfigurationPair>(context, "element", ShapeConfigurationPair());
|
||||
const int pairIndex = newShapesElement.AddElementWithData<AzPhysics::ShapeColliderPair>(
|
||||
context, "element", AzPhysics::ShapeColliderPair());
|
||||
|
||||
AZ::SerializeContext::DataElementNode& pairElement = newShapesElement.GetSubElement(pairIndex);
|
||||
|
||||
ColliderConfiguration colliderConfig;
|
||||
@@ -131,8 +133,8 @@ namespace Physics
|
||||
AZ::SerializeContext::DataElementNode* baseBaseClass1 = baseClass1->FindSubElement(AZ_CRC("BaseClass1", 0xd4925735));
|
||||
if (baseBaseClass1 && baseBaseClass1->FindSubElementAndGetData<AZStd::string>(AZ_CRC("name", 0x5e237e06), name))
|
||||
{
|
||||
ShapeConfigurationList shapes;
|
||||
if (nodeElement.FindSubElementAndGetData<ShapeConfigurationList>(AZ_CRC("shapes", 0x93dba512), shapes))
|
||||
AzPhysics::ShapeColliderPairList shapes;
|
||||
if (nodeElement.FindSubElementAndGetData<AzPhysics::ShapeColliderPairList>(AZ_CRC("shapes", 0x93dba512), shapes))
|
||||
{
|
||||
CharacterColliderNodeConfiguration newColliderNodeConfig;
|
||||
newColliderNodeConfig.m_name = name;
|
||||
|
||||
@@ -70,7 +70,10 @@ namespace AzPhysics
|
||||
using SimulatedBodyHandleList = AZStd::vector<SimulatedBodyHandle>;
|
||||
|
||||
//! Helper used for pairing the ShapeConfiguration and ColliderConfiguration together which is used when creating a Simulated Body.
|
||||
using ShapeColliderPair = AZStd::pair<Physics::ColliderConfiguration*, Physics::ShapeConfiguration*>;
|
||||
using ShapeColliderPair = AZStd::pair<
|
||||
AZStd::shared_ptr<Physics::ColliderConfiguration>,
|
||||
AZStd::shared_ptr<Physics::ShapeConfiguration>>;
|
||||
using ShapeColliderPairList = AZStd::vector<ShapeColliderPair>;
|
||||
|
||||
//! Flags used to specifying which properties of a body to compute.
|
||||
enum class MassComputeFlags : AZ::u8
|
||||
|
||||
+11
-2
@@ -30,6 +30,16 @@ namespace AzPhysics
|
||||
classElement.AddElementWithData(context, "name", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimulatedBodyVersionConverter([[maybe_unused]] AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
|
||||
{
|
||||
if (classElement.GetVersion() <= 1)
|
||||
{
|
||||
classElement.RemoveElementByName(AZ_CRC_CE("scale"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_CLASS_ALLOCATOR_IMPL(SimulatedBodyConfiguration, AZ::SystemAllocator, 0);
|
||||
@@ -40,11 +50,10 @@ namespace AzPhysics
|
||||
{
|
||||
serializeContext->ClassDeprecate("WorldBodyConfiguration", "{6EEB377C-DC60-4E10-AF12-9626C0763B2D}", &Internal::DeprecateWorldBodyConfiguration);
|
||||
serializeContext->Class<SimulatedBodyConfiguration>()
|
||||
->Version(1)
|
||||
->Version(2, &Internal::SimulatedBodyVersionConverter)
|
||||
->Field("name", &SimulatedBodyConfiguration::m_debugName)
|
||||
->Field("position", &SimulatedBodyConfiguration::m_position)
|
||||
->Field("orientation", &SimulatedBodyConfiguration::m_orientation)
|
||||
->Field("scale", &SimulatedBodyConfiguration::m_scale)
|
||||
->Field("entityId", &SimulatedBodyConfiguration::m_entityId)
|
||||
->Field("startSimulationEnabled", &SimulatedBodyConfiguration::m_startSimulationEnabled)
|
||||
;
|
||||
|
||||
-1
@@ -38,7 +38,6 @@ namespace AzPhysics
|
||||
// Basic initial settings.
|
||||
AZ::Vector3 m_position = AZ::Vector3::CreateZero();
|
||||
AZ::Quaternion m_orientation = AZ::Quaternion::CreateIdentity();
|
||||
AZ::Vector3 m_scale = AZ::Vector3::CreateOne();
|
||||
bool m_startSimulationEnabled = true;
|
||||
|
||||
// Entity/object association.
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ namespace AzPhysics
|
||||
namespace
|
||||
{
|
||||
const float TimestepMin = 0.001f; //1000fps
|
||||
const float TimestepMax = 0.05f; //20fps
|
||||
const float TimestepMax = 0.1f; //10fps
|
||||
}
|
||||
|
||||
AZ_CLASS_ALLOCATOR_IMPL(SystemConfiguration, AZ::SystemAllocator, 0);
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace AzPhysics
|
||||
|
||||
static constexpr float DefaultFixedTimestep = 0.0166667f; //! Value represents 1/60th or 60 FPS.
|
||||
|
||||
float m_maxTimestep = 1.f / 20.f; //!< Maximum fixed timestep in seconds to run the physics update.
|
||||
float m_maxTimestep = 0.1f; //!< Maximum fixed timestep in seconds to run the physics update (10FPS).
|
||||
float m_fixedTimestep = DefaultFixedTimestep; //!< Timestep in seconds to run the physics update. See DefaultFixedTimestep.
|
||||
|
||||
AZ::u64 m_raycastBufferSize = 32; //!< Maximum number of hits that will be returned from a raycast.
|
||||
|
||||
@@ -80,9 +80,6 @@ namespace Physics
|
||||
void OnContactOffsetChanged();
|
||||
};
|
||||
|
||||
using ShapeConfigurationPair = AZStd::pair<AZStd::shared_ptr<ColliderConfiguration>, AZStd::shared_ptr<ShapeConfiguration>>;
|
||||
using ShapeConfigurationList = AZStd::vector<ShapeConfigurationPair>;
|
||||
|
||||
struct RayCastRequest;
|
||||
|
||||
class Shape
|
||||
|
||||
@@ -99,51 +99,18 @@ namespace AzFramework::ProjectManager
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
|
||||
}
|
||||
{
|
||||
const char projectsScript[] = "projects.py";
|
||||
AZStd::string filename = "o3de";
|
||||
AZ::IO::FixedMaxPath executablePath = AZ::Utils::GetExecutableDirectory();
|
||||
executablePath /= filename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION;
|
||||
|
||||
AZ_Warning("ProjectManager", false, "No project provided - launching project selector.");
|
||||
|
||||
if (engineRootPath.empty())
|
||||
if (!AZ::IO::SystemFile::Exists(executablePath.c_str()))
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Couldn't find engine root");
|
||||
AZ_Error("ProjectManager", false, "%s not found", executablePath.c_str());
|
||||
return false;
|
||||
}
|
||||
auto projectManagerPath = engineRootPath / "scripts" / "project_manager";
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists((projectManagerPath / projectsScript).c_str()))
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "%s not found at %s!", projectsScript, projectManagerPath.c_str());
|
||||
return false;
|
||||
}
|
||||
AZ::IO::FixedMaxPathString executablePath;
|
||||
AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath.data(), executablePath.capacity());
|
||||
if (result.m_pathStored != AZ::Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Could not determine executable path!");
|
||||
return false;
|
||||
}
|
||||
AZ::IO::FixedMaxPath parentPath(executablePath.c_str());
|
||||
auto exeFolder = parentPath.ParentPath();
|
||||
AZStd::fixed_string<8> debugOption;
|
||||
auto lastSep = exeFolder.Native().find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
if (lastSep != AZStd::string_view::npos)
|
||||
{
|
||||
exeFolder = exeFolder.Native().substr(lastSep + 1);
|
||||
}
|
||||
if (exeFolder == "debug")
|
||||
{
|
||||
// We need to use the debug version of the python interpreter to load up our debug version of our libraries which work with the debug version of QT living in this folder
|
||||
debugOption = "debug ";
|
||||
}
|
||||
AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python";
|
||||
pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL;
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(),
|
||||
debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId());
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = cmdPath;
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
processLaunchInfo.m_commandlineParameters = executablePath.String();
|
||||
launchSuccess = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
}
|
||||
if (ownsSystemAllocator)
|
||||
|
||||
@@ -264,12 +264,12 @@ namespace AzFramework
|
||||
// SampleRPC =
|
||||
// {
|
||||
// // Two callbacks can be registered to the NetRPC
|
||||
// // A function to be invoked on the Master - OnMaster
|
||||
// // A function to be invoked on the main server - OnServer
|
||||
// // and a function to be invoked on the Proxy - OnProxy
|
||||
// //
|
||||
// // Every NetRPC needs to have a valid OnMaster function, while OnProxy is optional.
|
||||
// OnMaster = function()
|
||||
// Debug.Log("Function to be invoked on the Master.");
|
||||
// // Every NetRPC needs to have a valid OnServer function, while OnProxy is optional.
|
||||
// OnServer = function()
|
||||
// Debug.Log("Function to be invoked on the server.");
|
||||
// end
|
||||
//
|
||||
// OnProxy = function()
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
//! SessionConnectionConfig
|
||||
//! The properties for handling join session request.
|
||||
struct SessionConnectionConfig
|
||||
{
|
||||
// A unique identifier for registered player in session.
|
||||
AZStd::string m_playerSessionId;
|
||||
|
||||
// The DNS identifier assigned to the instance that is running the session.
|
||||
AZStd::string m_dnsName;
|
||||
|
||||
// The IP address of the session.
|
||||
AZStd::string m_ipAddress;
|
||||
|
||||
// The port number for the session.
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
//! SessionConnectionConfig
|
||||
//! The properties for handling player connect/disconnect
|
||||
struct PlayerConnectionConfig
|
||||
{
|
||||
// A unique identifier for player connection.
|
||||
uint32_t m_playerConnectionId;
|
||||
|
||||
// A unique identifier for registered player in session.
|
||||
AZStd::string m_playerSessionId;
|
||||
};
|
||||
|
||||
//! ISessionHandlingClientRequests
|
||||
//! The session handling events to invoke multiplayer component handle the work on client side
|
||||
class ISessionHandlingClientRequests
|
||||
{
|
||||
public:
|
||||
// Handle the player join session process
|
||||
// @param sessionConnectionConfig The required properties to handle the player join session process
|
||||
// @return The result of player join session process
|
||||
virtual bool HandlePlayerJoinSession(const SessionConnectionConfig& sessionConnectionConfig) = 0;
|
||||
|
||||
// Handle the player leave session process
|
||||
virtual void HandlePlayerLeaveSession() = 0;
|
||||
};
|
||||
|
||||
//! ISessionHandlingServerRequests
|
||||
//! The session handling events to invoke server provider handle the work on server side
|
||||
class ISessionHandlingServerRequests
|
||||
{
|
||||
public:
|
||||
// Handle the destroy session process
|
||||
virtual void HandleDestroySession() = 0;
|
||||
|
||||
// Validate the player join session process
|
||||
// @param playerConnectionConfig The required properties to validate the player join session process
|
||||
// @return The result of player join session validation
|
||||
virtual bool ValidatePlayerJoinSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
|
||||
|
||||
// Handle the player leave session process
|
||||
// @param playerConnectionConfig The required properties to handle the player leave session process
|
||||
virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Session/ISessionRequests.h>
|
||||
#include <AzFramework/Session/SessionConfig.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void CreateSessionRequest::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<CreateSessionRequest>()
|
||||
->Version(0)
|
||||
->Field("creatorId", &CreateSessionRequest::m_creatorId)
|
||||
->Field("sessionProperties", &CreateSessionRequest::m_sessionProperties)
|
||||
->Field("sessionName", &CreateSessionRequest::m_sessionName)
|
||||
->Field("maxPlayer", &CreateSessionRequest::m_maxPlayer)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<CreateSessionRequest>("CreateSessionRequest", "The container for CreateSession request parameters")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_creatorId,
|
||||
"CreatorId", "A unique identifier for a player or entity creating the session")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionProperties,
|
||||
"SessionProperties", "A collection of custom properties for a session")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionName,
|
||||
"SessionName", "A descriptive label that is associated with a session")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_maxPlayer,
|
||||
"MaxPlayer", "The maximum number of players that can be connected simultaneously to the session")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SearchSessionsRequest::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SearchSessionsRequest>()
|
||||
->Version(0)
|
||||
->Field("filterExpression", &SearchSessionsRequest::m_filterExpression)
|
||||
->Field("sortExpression", &SearchSessionsRequest::m_sortExpression)
|
||||
->Field("maxResult", &SearchSessionsRequest::m_maxResult)
|
||||
->Field("nextToken", &SearchSessionsRequest::m_nextToken)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<SearchSessionsRequest>("SearchSessionsRequest", "The container for SearchSessions request parameters")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_filterExpression,
|
||||
"FilterExpression", "String containing the search criteria for the session search")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_sortExpression,
|
||||
"SortExpression", "Instructions on how to sort the search results")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_maxResult,
|
||||
"MaxResult", "The maximum number of results to return")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_nextToken,
|
||||
"NextToken", "A token that indicates the start of the next sequential page of results")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SearchSessionsResponse::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SearchSessionsResponse>()
|
||||
->Version(0)
|
||||
->Field("sessionConfigs", &SearchSessionsResponse::m_sessionConfigs)
|
||||
->Field("nextToken", &SearchSessionsResponse::m_nextToken)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<SearchSessionsResponse>("SearchSessionsResponse", "The container for SearchSession request results")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_sessionConfigs,
|
||||
"SessionConfigs", "A collection of sessions that match the search criteria and sorted in specific order")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_nextToken,
|
||||
"NextToken", "A token that indicates the start of the next sequential page of results")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JoinSessionRequest::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<JoinSessionRequest>()
|
||||
->Version(0)
|
||||
->Field("sessionId", &JoinSessionRequest::m_sessionId)
|
||||
->Field("playerId", &JoinSessionRequest::m_playerId)
|
||||
->Field("playerData", &JoinSessionRequest::m_playerData)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<JoinSessionRequest>("JoinSessionRequest", "The container for JoinSession request parameters")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_sessionId,
|
||||
"SessionId", "A unique identifier for the session")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerId,
|
||||
"PlayerId", "A unique identifier for a player. Player IDs are developer-defined")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerData,
|
||||
"PlayerData", "Developer-defined information related to a player")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct SessionConfig;
|
||||
|
||||
//! CreateSessionRequest
|
||||
//! The container for CreateSession request parameters.
|
||||
struct CreateSessionRequest
|
||||
{
|
||||
AZ_RTTI(CreateSessionRequest, "{E39C2A45-89C9-4CFB-B337-9734DC798930}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
CreateSessionRequest() = default;
|
||||
virtual ~CreateSessionRequest() = default;
|
||||
|
||||
// A unique identifier for a player or entity creating the session.
|
||||
AZStd::string m_creatorId;
|
||||
|
||||
// A collection of custom properties for a session.
|
||||
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
|
||||
|
||||
// A descriptive label that is associated with a session.
|
||||
AZStd::string m_sessionName;
|
||||
|
||||
// The maximum number of players that can be connected simultaneously to the session.
|
||||
uint64_t m_maxPlayer;
|
||||
};
|
||||
|
||||
//! SearchSessionsRequest
|
||||
//! The container for SearchSessions request parameters.
|
||||
struct SearchSessionsRequest
|
||||
{
|
||||
AZ_RTTI(SearchSessionsRequest, "{B49207A8-8549-4ADB-B7D9-D7A4932F9B4B}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SearchSessionsRequest() = default;
|
||||
virtual ~SearchSessionsRequest() = default;
|
||||
|
||||
// String containing the search criteria for the session search. If no filter expression is included, the request returns results
|
||||
// for all active sessions.
|
||||
AZStd::string m_filterExpression;
|
||||
|
||||
// Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order.
|
||||
AZStd::string m_sortExpression;
|
||||
|
||||
// The maximum number of results to return.
|
||||
uint8_t m_maxResult;
|
||||
|
||||
// A token that indicates the start of the next sequential page of results.
|
||||
AZStd::string m_nextToken;
|
||||
};
|
||||
|
||||
//! SearchSessionsResponse
|
||||
//! The container for SearchSession request results.
|
||||
struct SearchSessionsResponse
|
||||
{
|
||||
AZ_RTTI(SearchSessionsResponse, "{F93DE7DC-D381-4E08-8A3B-0B08F7C38714}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SearchSessionsResponse() = default;
|
||||
virtual ~SearchSessionsResponse() = default;
|
||||
|
||||
// A collection of sessions that match the search criteria and sorted in specific order.
|
||||
AZStd::vector<SessionConfig> m_sessionConfigs;
|
||||
|
||||
// A token that indicates the start of the next sequential page of results.
|
||||
AZStd::string m_nextToken;
|
||||
};
|
||||
|
||||
//! JoinSessionRequest
|
||||
//! The container for JoinSession request parameters.
|
||||
struct JoinSessionRequest
|
||||
{
|
||||
AZ_RTTI(JoinSessionRequest, "{519769E8-3CDE-4385-A0D7-24DBB3685657}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
JoinSessionRequest() = default;
|
||||
virtual ~JoinSessionRequest() = default;
|
||||
|
||||
// A unique identifier for the session.
|
||||
AZStd::string m_sessionId;
|
||||
|
||||
// A unique identifier for a player. Player IDs are developer-defined.
|
||||
AZStd::string m_playerId;
|
||||
|
||||
// Developer-defined information related to a player.
|
||||
AZStd::string m_playerData;
|
||||
};
|
||||
|
||||
//! ISessionRequests
|
||||
//! Pure virtual session interface class to abstract the details of session handling from application code.
|
||||
class ISessionRequests
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ISessionRequests, "{D6C41A71-DD8D-47FE-8515-FAF90670AE2F}");
|
||||
|
||||
ISessionRequests() = default;
|
||||
virtual ~ISessionRequests() = default;
|
||||
|
||||
// Create a session for players to find and join.
|
||||
// @param createSessionRequest The request of CreateSession operation
|
||||
// @return The request id if session creation request succeeds; empty if it fails
|
||||
virtual AZStd::string CreateSession(const CreateSessionRequest& createSessionRequest) = 0;
|
||||
|
||||
// Retrieve all active sessions that match the given search criteria and sorted in specific order.
|
||||
// @param searchSessionsRequest The request of SearchSessions operation
|
||||
// @return The response of SearchSessions operation
|
||||
virtual SearchSessionsResponse SearchSessions(const SearchSessionsRequest& searchSessionsRequest) const = 0;
|
||||
|
||||
// Reserve an open player slot in a session, and perform connection from client to server.
|
||||
// @param joinSessionRequest The request of JoinSession operation
|
||||
// @return True if joining session succeeds; False otherwise
|
||||
virtual bool JoinSession(const JoinSessionRequest& joinSessionRequest) = 0;
|
||||
|
||||
// Disconnect player from session.
|
||||
virtual void LeaveSession() = 0;
|
||||
};
|
||||
|
||||
//! ISessionAsyncRequests
|
||||
//! Async version of ISessionRequests
|
||||
class ISessionAsyncRequests
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ISessionAsyncRequests, "{471542AF-96B9-4930-82FE-242A4E68432D}");
|
||||
|
||||
ISessionAsyncRequests() = default;
|
||||
virtual ~ISessionAsyncRequests() = default;
|
||||
|
||||
// CreateSession Async
|
||||
// @param createSessionRequest The request of CreateSession operation
|
||||
virtual void CreateSessionAsync(const CreateSessionRequest& createSessionRequest) = 0;
|
||||
|
||||
// SearchSessions Async
|
||||
// @param searchSessionsRequest The request of SearchSessions operation
|
||||
virtual void SearchSessionsAsync(const SearchSessionsRequest& searchSessionsRequest) const = 0;
|
||||
|
||||
// JoinSession Async
|
||||
// @param joinSessionRequest The request of JoinSession operation
|
||||
virtual void JoinSessionAsync(const JoinSessionRequest& joinSessionRequest) = 0;
|
||||
|
||||
// LeaveSession Async
|
||||
virtual void LeaveSessionAsync() = 0;
|
||||
};
|
||||
|
||||
//! SessionAsyncRequestNotifications
|
||||
//! The notifications correspond to session async requests
|
||||
class SessionAsyncRequestNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes
|
||||
// @param createSessionResponse The request id if session creation request succeeds; empty if it fails
|
||||
virtual void OnCreateSessionAsyncComplete(const AZStd::string& createSessionReponse) = 0;
|
||||
|
||||
// OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes
|
||||
// @param searchSessionsResponse The response of SearchSessions call
|
||||
virtual void OnSearchSessionsAsyncComplete(const SearchSessionsResponse& searchSessionsResponse) = 0;
|
||||
|
||||
// OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes
|
||||
// @param joinSessionsResponse True if joining session succeeds; False otherwise
|
||||
virtual void OnJoinSessionAsyncComplete(bool joinSessionsResponse) = 0;
|
||||
|
||||
// OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes
|
||||
virtual void OnLeaveSessionAsyncComplete() = 0;
|
||||
};
|
||||
using SessionAsyncRequestNotificationBus = AZ::EBus<SessionAsyncRequestNotifications>;
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Session/SessionConfig.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void SessionConfig::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SessionConfig>()
|
||||
->Version(0)
|
||||
->Field("creationTime", &SessionConfig::m_creationTime)
|
||||
->Field("terminationTime", &SessionConfig::m_terminationTime)
|
||||
->Field("creatorId", &SessionConfig::m_creatorId)
|
||||
->Field("sessionProperties", &SessionConfig::m_sessionProperties)
|
||||
->Field("sessionId", &SessionConfig::m_sessionId)
|
||||
->Field("sessionName", &SessionConfig::m_sessionName)
|
||||
->Field("dnsName", &SessionConfig::m_dnsName)
|
||||
->Field("ipAddress", &SessionConfig::m_ipAddress)
|
||||
->Field("port", &SessionConfig::m_port)
|
||||
->Field("maxPlayer", &SessionConfig::m_maxPlayer)
|
||||
->Field("currentPlayer", &SessionConfig::m_currentPlayer)
|
||||
->Field("status", &SessionConfig::m_status)
|
||||
->Field("statusReason", &SessionConfig::m_statusReason)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<SessionConfig>("SessionConfig", "Properties describing a session")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creationTime,
|
||||
"CreationTime", "A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_terminationTime,
|
||||
"TerminationTime", "A time stamp indicating when this data object was terminated. Same format as creation time.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creatorId,
|
||||
"CreatorId", "A unique identifier for a player or entity creating the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionProperties,
|
||||
"SessionProperties", "A collection of custom properties for a session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionId,
|
||||
"SessionId", "A unique identifier for the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionName,
|
||||
"SessionName", "A descriptive label that is associated with a session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_dnsName,
|
||||
"DnsName", "The DNS identifier assigned to the instance that is running the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_ipAddress,
|
||||
"IpAddress", "The IP address of the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_port,
|
||||
"Port", "The port number for the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_maxPlayer,
|
||||
"MaxPlayer", "The maximum number of players that can be connected simultaneously to the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_currentPlayer,
|
||||
"CurrentPlayer", "Number of players currently in the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_status,
|
||||
"Status", "Current status of the session.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_statusReason,
|
||||
"StatusReason", "Provides additional information about session status.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
//! SessionConfig
|
||||
//! Properties describing a session.
|
||||
struct SessionConfig
|
||||
{
|
||||
AZ_RTTI(SessionConfig, "{992DD4BE-8BA5-4071-8818-B99FD2952086}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SessionConfig() = default;
|
||||
virtual ~SessionConfig() = default;
|
||||
|
||||
// A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
|
||||
uint64_t m_creationTime;
|
||||
|
||||
// A time stamp indicating when this data object was terminated. Same format as creation time.
|
||||
uint64_t m_terminationTime;
|
||||
|
||||
// A unique identifier for a player or entity creating the session.
|
||||
AZStd::string m_creatorId;
|
||||
|
||||
// A collection of custom properties for a session.
|
||||
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
|
||||
|
||||
// A unique identifier for the session.
|
||||
AZStd::string m_sessionId;
|
||||
|
||||
// A descriptive label that is associated with a session.
|
||||
AZStd::string m_sessionName;
|
||||
|
||||
// The DNS identifier assigned to the instance that is running the session.
|
||||
AZStd::string m_dnsName;
|
||||
|
||||
// The IP address of the session.
|
||||
AZStd::string m_ipAddress;
|
||||
|
||||
// The port number for the session.
|
||||
uint16_t m_port;
|
||||
|
||||
// The maximum number of players that can be connected simultaneously to the session.
|
||||
uint64_t m_maxPlayer;
|
||||
|
||||
// Number of players currently in the session.
|
||||
uint64_t m_currentPlayer;
|
||||
|
||||
// Current status of the session.
|
||||
AZStd::string m_status;
|
||||
|
||||
// Provides additional information about session status.
|
||||
AZStd::string m_statusReason;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct SessionConfig;
|
||||
|
||||
//! SessionNotifications
|
||||
//! The session notifications to listen for performing required operations
|
||||
class SessionNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OnSessionHealthCheck is fired in health check process
|
||||
// @return The result of all OnSessionHealthCheck
|
||||
virtual bool OnSessionHealthCheck() = 0;
|
||||
|
||||
// OnCreateSessionBegin is fired at the beginning of session creation
|
||||
// @param sessionConfig The properties to describe a session
|
||||
// @return The result of all OnCreateSessionBegin notifications
|
||||
virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0;
|
||||
|
||||
// OnDestroySessionBegin is fired at the beginning of session termination
|
||||
// @return The result of all OnDestroySessionBegin notifications
|
||||
virtual bool OnDestroySessionBegin() = 0;
|
||||
};
|
||||
using SessionNotificationBus = AZ::EBus<SessionNotifications>;
|
||||
} // namespace AzFramework
|
||||
@@ -84,6 +84,7 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
using EntitySpawnCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
using EntityPreInsertionCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableEntityContainerView)>;
|
||||
using EntityDespawnCallback = AZStd::function<void(EntitySpawnTicket&)>;
|
||||
using ReloadSpawnableCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
using ListEntitiesCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
@@ -110,7 +111,8 @@ namespace AzFramework
|
||||
//! @param completionCallback Optional callback that's called when spawning entities has completed. This can be called from
|
||||
//! a different thread than the one that made the function call. The returned list of entities contains all the newly
|
||||
//! created entities.
|
||||
virtual void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) = 0;
|
||||
virtual void SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback = {},
|
||||
EntitySpawnCallback completionCallback = {}) = 0;
|
||||
//! Spawn instances of some entities in the spawnable.
|
||||
//! @param ticket Stores the results of the call. Use this ticket to spawn additional entities or to despawn them.
|
||||
//! @param entityIndices The indices into the template entities stored in the spawnable that will be used to spawn entities from.
|
||||
@@ -118,7 +120,7 @@ namespace AzFramework
|
||||
//! a different thread than the one that made this function call. The returned list of entities contains all the newly
|
||||
//! created entities.
|
||||
virtual void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntitySpawnCallback completionCallback = {}) = 0;
|
||||
EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) = 0;
|
||||
//! Removes all entities in the provided list from the environment.
|
||||
//! @param ticket The ticket previously used to spawn entities with.
|
||||
//! @param completionCallback Optional callback that's called when despawning entities has completed. This can be called from
|
||||
|
||||
@@ -11,20 +11,24 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Serialization/IdUtils.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzFramework/Spawnable/SpawnableEntitiesManager.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void SpawnableEntitiesManager::SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback)
|
||||
void SpawnableEntitiesManager::SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback,
|
||||
EntitySpawnCallback completionCallback)
|
||||
{
|
||||
SpawnAllEntitiesCommand queueEntry;
|
||||
queueEntry.m_ticket = &ticket;
|
||||
queueEntry.m_completionCallback = AZStd::move(completionCallback);
|
||||
queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback);
|
||||
{
|
||||
AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex);
|
||||
queueEntry.m_ticketId = GetTicketPayload<Ticket>(ticket).m_nextTicketId++;
|
||||
@@ -32,13 +36,15 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnableEntitiesManager::SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntitySpawnCallback completionCallback)
|
||||
void SpawnableEntitiesManager::SpawnEntities(
|
||||
EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntityPreInsertionCallback preInsertionCallback, EntitySpawnCallback completionCallback)
|
||||
{
|
||||
SpawnEntitiesCommand queueEntry;
|
||||
queueEntry.m_ticket = &ticket;
|
||||
queueEntry.m_entityIndices = AZStd::move(entityIndices);
|
||||
queueEntry.m_completionCallback = AZStd::move(completionCallback);
|
||||
queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback);
|
||||
{
|
||||
AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex);
|
||||
queueEntry.m_ticketId = GetTicketPayload<Ticket>(ticket).m_nextTicketId++;
|
||||
@@ -205,32 +211,85 @@ namespace AzFramework
|
||||
AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
clone->SetId(AZ::Entity::MakeId());
|
||||
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate,
|
||||
EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
return AZ::IdUtils::Remapper<AZ::EntityId>::CloneObjectAndGenerateNewIdsAndFixRefs(
|
||||
&entityTemplate, templateToCloneEntityIdMap, &serializeContext);
|
||||
}
|
||||
|
||||
bool SpawnableEntitiesManager::ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
Ticket& ticket = GetTicketPayload<Ticket>(*request.m_ticket);
|
||||
if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId)
|
||||
{
|
||||
size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size();
|
||||
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
|
||||
AZStd::vector<size_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
|
||||
const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesSize = entities.size();
|
||||
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
|
||||
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
|
||||
// Keep track how many entities there were in the array initially
|
||||
size_t spawnedEntitiesInitialCount = spawnedEntities.size();
|
||||
|
||||
for(size_t i=0; i<entitiesSize; ++i)
|
||||
// These are 'template' entities we'll be cloning from
|
||||
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesToSpawnSize = entitiesToSpawn.size();
|
||||
|
||||
// Map keeps track of ids from template (spawnable) to clone (instance)
|
||||
// Allowing patch ups of fields referring to entityIds outside of a given entity
|
||||
EntityIdMap templateToCloneEntityIdMap;
|
||||
|
||||
// Reserve buffers
|
||||
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
|
||||
spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize);
|
||||
templateToCloneEntityIdMap.reserve(entitiesToSpawnSize);
|
||||
|
||||
// Mark all indices as spawned
|
||||
for (size_t i = 0; i < entitiesToSpawnSize; ++i)
|
||||
{
|
||||
ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext));
|
||||
ticket.m_spawnedEntityIndices.push_back(i);
|
||||
const AZ::Entity& entityTemplate = *entitiesToSpawn[i];
|
||||
|
||||
AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext);
|
||||
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
|
||||
spawnedEntities.emplace_back(clone);
|
||||
spawnedEntityIndices.push_back(i);
|
||||
}
|
||||
|
||||
// loadAll is true if every entity has been spawned only once
|
||||
if (spawnedEntities.size() == entitiesToSpawnSize)
|
||||
{
|
||||
ticket.m_loadAll = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case where there were already spawns from a previous request
|
||||
ticket.m_loadAll = false;
|
||||
}
|
||||
|
||||
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
|
||||
if (request.m_preInsertionCallback)
|
||||
{
|
||||
request.m_preInsertionCallback(*request.m_ticket, SpawnableEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
// Add to the game context, now the entities are active
|
||||
AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(),
|
||||
[](AZ::Entity* entity)
|
||||
{
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity);
|
||||
});
|
||||
|
||||
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
|
||||
if (request.m_completionCallback)
|
||||
{
|
||||
request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end()));
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
@@ -249,24 +308,56 @@ namespace AzFramework
|
||||
Ticket& ticket = GetTicketPayload<Ticket>(*request.m_ticket);
|
||||
if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId)
|
||||
{
|
||||
size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size();
|
||||
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
|
||||
AZStd::vector<size_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
|
||||
const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesSize = entities.size();
|
||||
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
|
||||
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
|
||||
// Keep track how many entities there were in the array initially
|
||||
size_t spawnedEntitiesInitialCount = spawnedEntities.size();
|
||||
|
||||
// These are 'template' entities we'll be cloning from
|
||||
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesToSpawnSize = request.m_entityIndices.size();
|
||||
|
||||
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
|
||||
spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize);
|
||||
|
||||
for (size_t index : request.m_entityIndices)
|
||||
{
|
||||
ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[index], serializeContext));
|
||||
ticket.m_spawnedEntityIndices.push_back(index);
|
||||
if (index < entitiesToSpawn.size())
|
||||
{
|
||||
const AZ::Entity& entityTemplate = *entitiesToSpawn[index];
|
||||
|
||||
AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
clone->SetId(AZ::Entity::MakeId());
|
||||
|
||||
spawnedEntities.push_back(clone);
|
||||
spawnedEntityIndices.push_back(index);
|
||||
|
||||
}
|
||||
}
|
||||
ticket.m_loadAll = false;
|
||||
|
||||
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
|
||||
if (request.m_preInsertionCallback)
|
||||
{
|
||||
request.m_preInsertionCallback(
|
||||
*request.m_ticket,
|
||||
SpawnableEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
// Add to the game context, now the entities are active
|
||||
AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(),
|
||||
[](AZ::Entity* entity)
|
||||
{
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity);
|
||||
});
|
||||
|
||||
if (request.m_completionCallback)
|
||||
{
|
||||
request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end()));
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
@@ -343,10 +434,23 @@ namespace AzFramework
|
||||
// to load every, simply start over.
|
||||
ticket.m_spawnedEntityIndices.clear();
|
||||
|
||||
size_t entitiesSize = entities.size();
|
||||
for (size_t i = 0; i < entitiesSize; ++i)
|
||||
size_t entitiesToSpawnSize = entities.size();
|
||||
|
||||
// Map keeps track of ids from template (spawnable) to clone (instance)
|
||||
// Allowing patch ups of fields referring to entityIds outside of a given entity
|
||||
EntityIdMap templateToCloneEntityIdMap;
|
||||
templateToCloneEntityIdMap.reserve(entitiesToSpawnSize);
|
||||
|
||||
// Mark all indices as spawned
|
||||
for (size_t i = 0; i < entitiesToSpawnSize; ++i)
|
||||
{
|
||||
ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext));
|
||||
const AZ::Entity& entityTemplate = *entities[i];
|
||||
|
||||
AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext);
|
||||
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
|
||||
ticket.m_spawnedEntities.emplace_back(clone);
|
||||
ticket.m_spawnedEntityIndices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace AZ
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
using EntityIdMap = AZStd::unordered_map<AZ::EntityId, AZ::EntityId>;
|
||||
|
||||
class SpawnableEntitiesManager
|
||||
: public SpawnableEntitiesInterface::Registrar
|
||||
{
|
||||
@@ -47,8 +49,8 @@ namespace AzFramework
|
||||
// The following functions are thread safe
|
||||
//
|
||||
|
||||
void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) override;
|
||||
void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
void SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) override;
|
||||
void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices, EntityPreInsertionCallback preInsertionCallback = {},
|
||||
EntitySpawnCallback completionCallback = {}) override;
|
||||
void DespawnAllEntities(EntitySpawnTicket& ticket, EntityDespawnCallback completionCallback = {}) override;
|
||||
|
||||
@@ -90,6 +92,7 @@ namespace AzFramework
|
||||
struct SpawnAllEntitiesCommand
|
||||
{
|
||||
EntitySpawnCallback m_completionCallback;
|
||||
EntityPreInsertionCallback m_preInsertionCallback;
|
||||
EntitySpawnTicket* m_ticket;
|
||||
uint32_t m_ticketId;
|
||||
};
|
||||
@@ -97,6 +100,7 @@ namespace AzFramework
|
||||
{
|
||||
AZStd::vector<size_t> m_entityIndices;
|
||||
EntitySpawnCallback m_completionCallback;
|
||||
EntityPreInsertionCallback m_preInsertionCallback;
|
||||
EntitySpawnTicket* m_ticket;
|
||||
uint32_t m_ticketId;
|
||||
};
|
||||
@@ -140,7 +144,11 @@ namespace AzFramework
|
||||
using Requests = AZStd::variant<SpawnAllEntitiesCommand, SpawnEntitiesCommand, DespawnAllEntitiesCommand, ReloadSpawnableCommand,
|
||||
ListEntitiesCommand, ClaimEntitiesCommand, BarrierCommand, DestroyTicketCommand>;
|
||||
|
||||
AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, AZ::SerializeContext& serializeContext);
|
||||
AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate,
|
||||
AZ::SerializeContext& serializeContext);
|
||||
|
||||
AZ::Entity* CloneSingleEntity(const AZ::Entity& entityTemplate,
|
||||
EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext);
|
||||
|
||||
bool ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext);
|
||||
bool ProcessRequest(SpawnEntitiesCommand& request, AZ::SerializeContext& serializeContext);
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Neighborhood {
|
||||
//---------------------------------------------------------------------
|
||||
void NeighborReplica::OnReplicaActivate(const GridMate::ReplicaContext& /*rc*/)
|
||||
{
|
||||
// TODO: Should we send the message to ourselves as well (master)?
|
||||
// TODO: Should we send the message to ourselves as well?
|
||||
if (IsProxy())
|
||||
{
|
||||
AZ_Assert(m_persistentName.Get().c_str(), "Received NeighborReplica with missing persistent name!");
|
||||
@@ -52,7 +52,7 @@ namespace Neighborhood {
|
||||
//---------------------------------------------------------------------
|
||||
void NeighborReplica::OnReplicaDeactivate(const GridMate::ReplicaContext& /*rc*/)
|
||||
{
|
||||
// TODO: Should we send the message to ourselves as well (master)?
|
||||
// TODO: Should we send the message to ourselves as well?
|
||||
if (IsProxy())
|
||||
{
|
||||
EBUS_EVENT(NeighborhoodBus, OnNodeLeft, *this);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <AzCore/std/numeric.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -30,7 +29,8 @@ namespace AzFramework
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 6.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
@@ -159,24 +159,27 @@ namespace AzFramework
|
||||
|
||||
bool CameraSystem::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& cursor = AZStd::get_if<CursorEvent>(&event))
|
||||
if (const auto& horizonalMotion = AZStd::get_if<HorizontalMotionEvent>(&event))
|
||||
{
|
||||
m_cursorState.SetCurrentPosition(cursor->m_position);
|
||||
m_motionDelta.m_x = horizonalMotion->m_delta;
|
||||
}
|
||||
else if (const auto& verticalMotion = AZStd::get_if<VerticalMotionEvent>(&event))
|
||||
{
|
||||
m_motionDelta.m_y = verticalMotion->m_delta;
|
||||
}
|
||||
else if (const auto& scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
m_scrollDelta = scroll->m_delta;
|
||||
}
|
||||
|
||||
return m_cameras.HandleEvents(event, m_cursorState.CursorDelta(), m_scrollDelta);
|
||||
return m_cameras.HandleEvents(event, m_motionDelta, m_scrollDelta);
|
||||
}
|
||||
|
||||
Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime)
|
||||
{
|
||||
const auto nextCamera = m_cameras.StepCamera(targetCamera, m_cursorState.CursorDelta(), m_scrollDelta, deltaTime);
|
||||
|
||||
m_cursorState.Update();
|
||||
const auto nextCamera = m_cameras.StepCamera(targetCamera, m_motionDelta, m_scrollDelta, deltaTime);
|
||||
|
||||
m_motionDelta = ScreenVector{0, 0};
|
||||
m_scrollDelta = 0.0f;
|
||||
|
||||
return nextCamera;
|
||||
@@ -192,13 +195,12 @@ namespace AzFramework
|
||||
bool handling = false;
|
||||
for (auto& cameraInput : m_activeCameraInputs)
|
||||
{
|
||||
cameraInput->HandleEvents(event, cursorDelta, scrollDelta);
|
||||
handling = !cameraInput->Idle() || handling;
|
||||
handling = cameraInput->HandleEvents(event, cursorDelta, scrollDelta) || handling;
|
||||
}
|
||||
|
||||
for (auto& cameraInput : m_idleCameraInputs)
|
||||
{
|
||||
cameraInput->HandleEvents(event, cursorDelta, scrollDelta);
|
||||
handling = cameraInput->HandleEvents(event, cursorDelta, scrollDelta) || handling;
|
||||
}
|
||||
|
||||
return handling;
|
||||
@@ -261,17 +263,26 @@ namespace AzFramework
|
||||
{
|
||||
m_activeCameraInputs[i]->Reset();
|
||||
m_idleCameraInputs.push_back(m_activeCameraInputs[i]);
|
||||
m_activeCameraInputs[i] = m_activeCameraInputs[m_activeCameraInputs.size() - 1];
|
||||
using AZStd::swap;
|
||||
swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
|
||||
m_activeCameraInputs.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Cameras::Clear()
|
||||
{
|
||||
Reset();
|
||||
AZ_Assert(m_activeCameraInputs.empty(), "Active Camera Inputs is not empty");
|
||||
|
||||
m_idleCameraInputs.clear();
|
||||
}
|
||||
|
||||
RotateCameraInput::RotateCameraInput(const InputChannelId rotateChannelId)
|
||||
: m_rotateChannelId(rotateChannelId)
|
||||
{
|
||||
}
|
||||
|
||||
void RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
bool RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
const ClickDetector::ClickEvent clickEvent = [&event, this] {
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
@@ -303,6 +314,11 @@ namespace AzFramework
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
|
||||
// note - must also check !ending to ensure the mouse up (release) event
|
||||
// is not consumed and can be propagated to other systems.
|
||||
// (don't swallow mouse up events)
|
||||
return !Idle() && !Ending();
|
||||
}
|
||||
|
||||
Camera RotateCameraInput::StepCamera(
|
||||
@@ -329,7 +345,7 @@ namespace AzFramework
|
||||
{
|
||||
}
|
||||
|
||||
void PanCameraInput::HandleEvents(
|
||||
bool PanCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
@@ -346,6 +362,8 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera PanCameraInput::StepCamera(
|
||||
@@ -410,7 +428,7 @@ namespace AzFramework
|
||||
{
|
||||
}
|
||||
|
||||
void TranslateCameraInput::HandleEvents(
|
||||
bool TranslateCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
@@ -428,7 +446,8 @@ namespace AzFramework
|
||||
m_boost = true;
|
||||
}
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
// ensure we don't process end events in the idle state
|
||||
else if (input->m_state == InputChannel::State::Ended && !Idle())
|
||||
{
|
||||
m_translation &= ~(translationFromKey(input->m_channelId));
|
||||
if (m_translation == TranslationType::Nil)
|
||||
@@ -441,6 +460,8 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera TranslateCameraInput::StepCamera(
|
||||
@@ -502,7 +523,7 @@ namespace AzFramework
|
||||
m_boost = false;
|
||||
}
|
||||
|
||||
void OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta)
|
||||
bool OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta)
|
||||
{
|
||||
if (const auto* input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
@@ -521,8 +542,10 @@ namespace AzFramework
|
||||
|
||||
if (Active())
|
||||
{
|
||||
m_orbitCameras.HandleEvents(event, cursorDelta, scrollDelta);
|
||||
return m_orbitCameras.HandleEvents(event, cursorDelta, scrollDelta);
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera OrbitCameraInput::StepCamera(
|
||||
@@ -532,20 +555,39 @@ namespace AzFramework
|
||||
|
||||
if (Beginning())
|
||||
{
|
||||
float hit_distance = 0.0f;
|
||||
AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance);
|
||||
const auto hasLookAt = [&nextCamera, &targetCamera, &lookAtFn = m_lookAtFn] {
|
||||
if (lookAtFn)
|
||||
{
|
||||
if (const auto lookAt = lookAtFn())
|
||||
{
|
||||
auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt);
|
||||
nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt);
|
||||
UpdateCameraFromTransform(nextCamera, transform);
|
||||
|
||||
if (hit_distance > 0.0f)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!hasLookAt)
|
||||
{
|
||||
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance;
|
||||
float hit_distance = 0.0f;
|
||||
AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance);
|
||||
|
||||
if (hit_distance > 0.0f)
|
||||
{
|
||||
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -ed_cameraSystemMinOrbitDistance;
|
||||
nextCamera.m_lookAt =
|
||||
targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMinOrbitDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,13 +607,15 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void OrbitDollyScrollCameraInput::HandleEvents(
|
||||
bool OrbitDollyScrollCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera OrbitDollyScrollCameraInput::StepCamera(
|
||||
@@ -589,7 +633,7 @@ namespace AzFramework
|
||||
{
|
||||
}
|
||||
|
||||
void OrbitDollyCursorMoveCameraInput::HandleEvents(
|
||||
bool OrbitDollyCursorMoveCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
@@ -606,6 +650,8 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera OrbitDollyCursorMoveCameraInput::StepCamera(
|
||||
@@ -617,13 +663,15 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void ScrollTranslationCameraInput::HandleEvents(
|
||||
bool ScrollTranslationCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera ScrollTranslationCameraInput::StepCamera(
|
||||
@@ -674,7 +722,7 @@ namespace AzFramework
|
||||
return camera;
|
||||
}
|
||||
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize)
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel)
|
||||
{
|
||||
const auto& inputChannelId = inputChannel.GetInputChannelId();
|
||||
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
|
||||
@@ -684,13 +732,13 @@ namespace AzFramework
|
||||
return button == inputChannelId;
|
||||
});
|
||||
|
||||
if (inputChannelId == InputDeviceMouse::Movement::X || inputChannelId == InputDeviceMouse::Movement::Y)
|
||||
if (inputChannelId == InputDeviceMouse::Movement::X)
|
||||
{
|
||||
const auto* position = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
|
||||
AZ_Assert(position, "Expected PositionData2D but found nullptr");
|
||||
|
||||
return CursorEvent{ScreenPoint(
|
||||
position->m_normalizedPosition.GetX() * windowSize.m_width, position->m_normalizedPosition.GetY() * windowSize.m_height)};
|
||||
return HorizontalMotionEvent{(int)inputChannel.GetValue()};
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
return VerticalMotionEvent{(int)inputChannel.GetValue()};
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzFramework/Input/Channels/InputChannel.h>
|
||||
#include <AzFramework/Viewport/ClickDetector.h>
|
||||
#include <AzFramework/Viewport/CursorState.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
@@ -72,11 +71,16 @@ namespace AzFramework
|
||||
|
||||
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform);
|
||||
|
||||
struct CursorEvent
|
||||
//! Generic motion type
|
||||
template<typename MotionTag>
|
||||
struct MotionEvent
|
||||
{
|
||||
ScreenPoint m_position;
|
||||
int m_delta;
|
||||
};
|
||||
|
||||
using HorizontalMotionEvent = MotionEvent<struct HorizontalMotionTag>;
|
||||
using VerticalMotionEvent = MotionEvent<struct VerticalMotionTag>;
|
||||
|
||||
struct ScrollEvent
|
||||
{
|
||||
float m_delta;
|
||||
@@ -88,7 +92,7 @@ namespace AzFramework
|
||||
InputChannel::State m_state; //!< Channel state. (e.g. Begin/update/end event).
|
||||
};
|
||||
|
||||
using InputEvent = AZStd::variant<AZStd::monostate, CursorEvent, ScrollEvent, DiscreteInputEvent>;
|
||||
using InputEvent = AZStd::variant<AZStd::monostate, HorizontalMotionEvent, VerticalMotionEvent, ScrollEvent, DiscreteInputEvent>;
|
||||
|
||||
class CameraInput
|
||||
{
|
||||
@@ -149,7 +153,7 @@ namespace AzFramework
|
||||
ResetImpl();
|
||||
}
|
||||
|
||||
virtual void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) = 0;
|
||||
virtual bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) = 0;
|
||||
virtual Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) = 0;
|
||||
|
||||
virtual bool Exclusive() const
|
||||
@@ -171,16 +175,30 @@ namespace AzFramework
|
||||
class Cameras
|
||||
{
|
||||
public:
|
||||
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta);
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime);
|
||||
|
||||
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
|
||||
//! Reset the state of all cameras.
|
||||
void Reset();
|
||||
//! Remove all cameras that were added.
|
||||
void Clear();
|
||||
//! Is one of the cameras in the active camera inputs marked as 'exclusive'.
|
||||
//! @note This implies no other sibling cameras can begin while the exclusive camera is running.
|
||||
bool Exclusive() const;
|
||||
|
||||
private:
|
||||
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs;
|
||||
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_idleCameraInputs;
|
||||
};
|
||||
|
||||
inline bool Cameras::Exclusive() const
|
||||
{
|
||||
return AZStd::any_of(
|
||||
m_activeCameraInputs.begin(), m_activeCameraInputs.end(), [](const auto& cameraInput) { return cameraInput->Exclusive(); });
|
||||
}
|
||||
|
||||
//! Responsible for updating a series of cameras given various inputs.
|
||||
class CameraSystem
|
||||
{
|
||||
public:
|
||||
@@ -190,8 +208,8 @@ namespace AzFramework
|
||||
Cameras m_cameras;
|
||||
|
||||
private:
|
||||
CursorState m_cursorState;
|
||||
float m_scrollDelta = 0.0f;
|
||||
ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional.
|
||||
float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional.
|
||||
};
|
||||
|
||||
class RotateCameraInput : public CameraInput
|
||||
@@ -199,7 +217,8 @@ namespace AzFramework
|
||||
public:
|
||||
explicit RotateCameraInput(InputChannelId rotateChannelId);
|
||||
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
private:
|
||||
@@ -239,7 +258,8 @@ namespace AzFramework
|
||||
public:
|
||||
PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn);
|
||||
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
private:
|
||||
@@ -279,7 +299,8 @@ namespace AzFramework
|
||||
public:
|
||||
explicit TranslateCameraInput(TranslationAxesFn translationAxesFn);
|
||||
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
void ResetImpl() override;
|
||||
|
||||
@@ -348,7 +369,8 @@ namespace AzFramework
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
};
|
||||
|
||||
@@ -357,7 +379,8 @@ namespace AzFramework
|
||||
public:
|
||||
explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId);
|
||||
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
private:
|
||||
@@ -367,25 +390,40 @@ namespace AzFramework
|
||||
class ScrollTranslationCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
};
|
||||
|
||||
class OrbitCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
using LookAtFn = AZStd::function<AZStd::optional<AZ::Vector3>()>;
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
bool Exclusive() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool Exclusive() const override;
|
||||
|
||||
Cameras m_orbitCameras;
|
||||
|
||||
//! Override the default behavior for how a look-at point is calculated.
|
||||
void SetLookAtFn(const LookAtFn& lookAtFn);
|
||||
|
||||
private:
|
||||
LookAtFn m_lookAtFn;
|
||||
};
|
||||
|
||||
struct WindowSize;
|
||||
inline void OrbitCameraInput::SetLookAtFn(const LookAtFn& lookAtFn)
|
||||
{
|
||||
m_lookAtFn = lookAtFn;
|
||||
}
|
||||
|
||||
inline bool OrbitCameraInput::Exclusive() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Map from a generic InputChannel event to a camera specific InputEvent.
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize);
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel);
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace AzFramework
|
||||
|
||||
void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView)
|
||||
{
|
||||
const float m11 = clipFromView(1, 1);
|
||||
const float m22 = clipFromView(2, 2);
|
||||
const float m23 = clipFromView(2, 3);
|
||||
cameraState.m_nearClip = m23 / m22;
|
||||
@@ -84,7 +83,12 @@ namespace AzFramework
|
||||
{
|
||||
AZStd::swap(cameraState.m_nearClip, cameraState.m_farClip);
|
||||
}
|
||||
cameraState.m_fovOrZoom = 2 * (AZ::Constants::HalfPi - atanf(m11));
|
||||
cameraState.m_fovOrZoom = RetrieveFov(clipFromView);
|
||||
}
|
||||
|
||||
float RetrieveFov(const AZ::Matrix4x4& clipFromView)
|
||||
{
|
||||
return 2.0f * (AZ::Constants::HalfPi - AZStd::atan(clipFromView(1, 1)));
|
||||
}
|
||||
|
||||
void CameraState::Reflect(AZ::SerializeContext& serializeContext)
|
||||
|
||||
@@ -17,54 +17,57 @@
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
/// Represents the camera state populated by the viewport camera.
|
||||
//! Represents the camera state populated by the viewport camera.
|
||||
struct CameraState
|
||||
{
|
||||
/// @cond
|
||||
//! @cond
|
||||
AZ_TYPE_INFO(CameraState, "{D309D934-044C-4BA8-91F1-EA3A45177A52}")
|
||||
CameraState() = default;
|
||||
/// @endcond
|
||||
//! @endcond
|
||||
|
||||
static void Reflect(AZ::SerializeContext& context);
|
||||
|
||||
/// Return the vertical fov of the camera when the view is in perspective.
|
||||
//! Return the vertical fov of the camera when the view is in perspective.
|
||||
float VerticalFovRadian() const { return m_fovOrZoom; }
|
||||
/// Return the zoom amount of the camera when the view is in orthographic.
|
||||
//! Return the zoom amount of the camera when the view is in orthographic.
|
||||
float Zoom() const { return m_fovOrZoom; }
|
||||
|
||||
AZ::Vector3 m_position = AZ::Vector3::CreateZero(); ///< World position of the camera.
|
||||
AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); ///< Forward look direction of the camera (world space).
|
||||
AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); ///< Side vector of camera (orthogonal to forward and up).
|
||||
AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); ///< Up vector of the camera (cameras frame - world space).
|
||||
AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); ///< Dimensions of the viewport.
|
||||
float m_nearClip = 0.01f; ///< Near clip plane of the camera.
|
||||
float m_farClip = 100.0f; ///< Far clip plane of the camera.
|
||||
float m_fovOrZoom = 0.0f; ///< Fov or zoom of camera depending on if it is using orthographic projection or not.
|
||||
bool m_orthographic = false; ///< Is the camera using orthographic projection or not.
|
||||
AZ::Vector3 m_position = AZ::Vector3::CreateZero(); //!< World position of the camera.
|
||||
AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); //!< Forward look direction of the camera (world space).
|
||||
AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); //!< Side vector of camera (orthogonal to forward and up).
|
||||
AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); //!< Up vector of the camera (cameras frame - world space).
|
||||
AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); //!< Dimensions of the viewport.
|
||||
float m_nearClip = 0.01f; //!< Near clip plane of the camera.
|
||||
float m_farClip = 100.0f; //!< Far clip plane of the camera.
|
||||
float m_fovOrZoom = 0.0f; //!< Fov or zoom of camera depending on if it is using orthographic projection or not.
|
||||
bool m_orthographic = false; //!< Is the camera using orthographic projection or not.
|
||||
};
|
||||
|
||||
/// Create a camera at the given transform with a specific viewport size.
|
||||
/// @note The near/far clip planes and fov are sensible default values - please
|
||||
/// use SetCameraClippingVolume to override them.
|
||||
//! Create a camera at the given transform with a specific viewport size.
|
||||
//! @note The near/far clip planes and fov are sensible default values - please
|
||||
//! use SetCameraClippingVolume to override them.
|
||||
CameraState CreateDefaultCamera(const AZ::Transform& transform, const AZ::Vector2& viewportSize);
|
||||
|
||||
/// Create a camera at the given position (no orientation) with a specific viewport size.
|
||||
/// @note The near/far clip planes and fov are sensible default values - please
|
||||
/// use SetCameraClippingVolume to override them.
|
||||
//! Create a camera at the given position (no orientation) with a specific viewport size.
|
||||
//! @note The near/far clip planes and fov are sensible default values - please
|
||||
//! use SetCameraClippingVolume to override them.
|
||||
CameraState CreateIdentityDefaultCamera(const AZ::Vector3& position, const AZ::Vector2& viewportSize);
|
||||
|
||||
/// Create a camera transformed by the given view to world matrix with a specific viewport size.
|
||||
/// @note The near/far clip planes and fov are sensible default values - please
|
||||
/// use SetCameraClippingVolume to override them.
|
||||
//! Create a camera transformed by the given view to world matrix with a specific viewport size.
|
||||
//! @note The near/far clip planes and fov are sensible default values - please
|
||||
//! use SetCameraClippingVolume to override them.
|
||||
CameraState CreateCameraFromWorldFromViewMatrix(const AZ::Matrix4x4& worldFromView, const AZ::Vector2& viewportSize);
|
||||
|
||||
/// Override the default near/far clipping planes and fov of the camera.
|
||||
//! Override the default near/far clipping planes and fov of the camera.
|
||||
void SetCameraClippingVolume(CameraState& cameraState, float nearPlane, float farPlane, float fovRad);
|
||||
|
||||
/// Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space.
|
||||
//! Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space.
|
||||
void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView);
|
||||
|
||||
/// Set the transform for an existing camera.
|
||||
//! Retrieve the field of view (Fov) from the perspective projection matrix (view space to clip space).
|
||||
float RetrieveFov(const AZ::Matrix4x4& clipFromView);
|
||||
|
||||
//! Set the transform for an existing camera.
|
||||
void SetCameraTransform(CameraState& cameraState, const AZ::Transform& transform);
|
||||
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -1,68 +1,73 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Viewport/ClickDetector.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
ClickDetector::ClickOutcome ClickDetector::DetectClick(const ClickEvent clickEvent, const ScreenVector& cursorDelta)
|
||||
{
|
||||
if (clickEvent == ClickEvent::Down)
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (m_tryBeginTime)
|
||||
{
|
||||
const std::chrono::duration<float> diff = now - m_tryBeginTime.value();
|
||||
if (diff.count() < m_doubleClickInterval)
|
||||
{
|
||||
return ClickOutcome::Nil;
|
||||
}
|
||||
}
|
||||
|
||||
m_detectionState = DetectionState::WaitingForMove;
|
||||
m_moveAccumulator = 0.0f;
|
||||
|
||||
m_tryBeginTime = now;
|
||||
}
|
||||
else if (clickEvent == ClickEvent::Up)
|
||||
{
|
||||
const auto clickOutcome = [detectionState = m_detectionState] {
|
||||
if (detectionState == DetectionState::WaitingForMove)
|
||||
{
|
||||
return ClickOutcome::Click;
|
||||
}
|
||||
if (detectionState == DetectionState::Moved)
|
||||
{
|
||||
return ClickOutcome::Release;
|
||||
}
|
||||
return ClickOutcome::Nil;
|
||||
}();
|
||||
|
||||
m_detectionState = DetectionState::Nil;
|
||||
return clickOutcome;
|
||||
}
|
||||
|
||||
if (m_detectionState == DetectionState::WaitingForMove)
|
||||
{
|
||||
// only allow the action to begin if the mouse has been moved a small amount
|
||||
m_moveAccumulator += ScreenVectorLength(cursorDelta);
|
||||
if (m_moveAccumulator > m_deadZone)
|
||||
{
|
||||
m_detectionState = DetectionState::Moved;
|
||||
return ClickOutcome::Move;
|
||||
}
|
||||
}
|
||||
|
||||
return ClickOutcome::Nil;
|
||||
}
|
||||
} // namespace AzFramework
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Viewport/ClickDetector.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
ClickDetector::ClickOutcome ClickDetector::DetectClick(const ClickEvent clickEvent, const ScreenVector& cursorDelta)
|
||||
{
|
||||
const auto previousDetectionState = m_detectionState;
|
||||
if (previousDetectionState == DetectionState::WaitingForMove)
|
||||
{
|
||||
// only allow the action to begin if the mouse has been moved a small amount
|
||||
m_moveAccumulator += ScreenVectorLength(cursorDelta);
|
||||
if (m_moveAccumulator > m_deadZone)
|
||||
{
|
||||
m_detectionState = DetectionState::Moved;
|
||||
}
|
||||
}
|
||||
|
||||
if (clickEvent == ClickEvent::Down)
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (m_tryBeginTime)
|
||||
{
|
||||
const std::chrono::duration<float> diff = now - m_tryBeginTime.value();
|
||||
if (diff.count() < m_doubleClickInterval)
|
||||
{
|
||||
return ClickOutcome::Nil;
|
||||
}
|
||||
}
|
||||
|
||||
m_detectionState = DetectionState::WaitingForMove;
|
||||
m_moveAccumulator = 0.0f;
|
||||
|
||||
m_tryBeginTime = now;
|
||||
}
|
||||
else if (clickEvent == ClickEvent::Up)
|
||||
{
|
||||
const auto clickOutcome = [detectionState = m_detectionState] {
|
||||
if (detectionState == DetectionState::WaitingForMove)
|
||||
{
|
||||
return ClickOutcome::Click;
|
||||
}
|
||||
if (detectionState == DetectionState::Moved)
|
||||
{
|
||||
return ClickOutcome::Release;
|
||||
}
|
||||
return ClickOutcome::Nil;
|
||||
}();
|
||||
|
||||
m_detectionState = DetectionState::Nil;
|
||||
return clickOutcome;
|
||||
}
|
||||
|
||||
if (previousDetectionState == DetectionState::WaitingForMove && m_detectionState == DetectionState::Moved)
|
||||
{
|
||||
return ClickOutcome::Move;
|
||||
}
|
||||
|
||||
return ClickOutcome::Nil;
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -50,7 +50,11 @@ namespace AzFramework
|
||||
//! Called from any type of 'handle event' function.
|
||||
ClickOutcome DetectClick(ClickEvent clickEvent, const ScreenVector& cursorDelta);
|
||||
|
||||
//! Override the default double click interval.
|
||||
//! @note Default is 400ms - system default.
|
||||
void SetDoubleClickInterval(float doubleClickInterval);
|
||||
//! Override the dead zone before a 'move' outcome will be triggered.
|
||||
void SetDeadZone(float deadZone);
|
||||
|
||||
private:
|
||||
//! Internal state of ClickDetector based on incoming events.
|
||||
@@ -72,4 +76,9 @@ namespace AzFramework
|
||||
{
|
||||
m_doubleClickInterval = doubleClickInterval;
|
||||
}
|
||||
|
||||
inline void ClickDetector::SetDeadZone(const float deadZone)
|
||||
{
|
||||
m_deadZone = deadZone;
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
#include <AzCore/std/optional.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
//! Utility type to wrap a current and last cursor position.
|
||||
struct CursorState
|
||||
{
|
||||
//! Returns the delta between the current and last cursor position.
|
||||
[[nodiscard]] ScreenVector CursorDelta() const;
|
||||
//! Call this in a 'handle event' call to update the most recent cursor position.
|
||||
void SetCurrentPosition(const ScreenPoint& currentPosition);
|
||||
//! Call this in an 'update' call to copy the current cursor position to the last
|
||||
//! cursor position.
|
||||
void Update();
|
||||
|
||||
private:
|
||||
AZStd::optional<ScreenPoint> m_lastCursorPosition;
|
||||
AZStd::optional<ScreenPoint> m_currentCursorPosition;
|
||||
};
|
||||
|
||||
inline void CursorState::SetCurrentPosition(const ScreenPoint& currentPosition)
|
||||
{
|
||||
m_currentCursorPosition = currentPosition;
|
||||
}
|
||||
|
||||
inline ScreenVector CursorState::CursorDelta() const
|
||||
{
|
||||
return m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value()
|
||||
? m_currentCursorPosition.value() - m_lastCursorPosition.value()
|
||||
: ScreenVector(0, 0);
|
||||
}
|
||||
|
||||
inline void CursorState::Update()
|
||||
{
|
||||
if (m_currentCursorPosition.has_value())
|
||||
{
|
||||
m_lastCursorPosition = m_currentCursorPosition;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
#include <AzCore/std/optional.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
//! Utility type to wrap a current and last cursor position.
|
||||
struct CursorState
|
||||
{
|
||||
//! Returns the delta between the current and last cursor position.
|
||||
[[nodiscard]] ScreenVector CursorDelta() const;
|
||||
//! Call this in a 'handle event' call to update the most recent cursor position.
|
||||
void SetCurrentPosition(const ScreenPoint& currentPosition);
|
||||
//! Call this in an 'update' call to copy the current cursor position to the last
|
||||
//! cursor position.
|
||||
void Update();
|
||||
|
||||
private:
|
||||
AZStd::optional<ScreenPoint> m_lastCursorPosition;
|
||||
AZStd::optional<ScreenPoint> m_currentCursorPosition;
|
||||
};
|
||||
|
||||
inline void CursorState::SetCurrentPosition(const ScreenPoint& currentPosition)
|
||||
{
|
||||
m_currentCursorPosition = currentPosition;
|
||||
}
|
||||
|
||||
inline ScreenVector CursorState::CursorDelta() const
|
||||
{
|
||||
return m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value()
|
||||
? m_currentCursorPosition.value() - m_lastCursorPosition.value()
|
||||
: ScreenVector(0, 0);
|
||||
}
|
||||
|
||||
inline void CursorState::Update()
|
||||
{
|
||||
if (m_currentCursorPosition.has_value())
|
||||
{
|
||||
m_lastCursorPosition = m_currentCursorPosition;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -123,8 +123,9 @@ namespace AzFramework
|
||||
OctreeNode* insertCheck = this;
|
||||
while (insertCheck != nullptr)
|
||||
{
|
||||
if (AZ::ShapeIntersection::Contains(insertCheck->m_bounds, boundingVolume))
|
||||
if (AZ::ShapeIntersection::Contains(insertCheck->m_bounds, boundingVolume) || !insertCheck->m_parent)
|
||||
{
|
||||
// Insert here if the entry is fully contained or if we've reached the root node
|
||||
return insertCheck->Insert(octreeScene, entry);
|
||||
}
|
||||
insertCheck = insertCheck->m_parent;
|
||||
|
||||
@@ -188,6 +188,12 @@ set(FILES
|
||||
Script/ScriptDebugMsgReflection.h
|
||||
Script/ScriptRemoteDebugging.cpp
|
||||
Script/ScriptRemoteDebugging.h
|
||||
Session/ISessionHandlingRequests.h
|
||||
Session/ISessionRequests.cpp
|
||||
Session/ISessionRequests.h
|
||||
Session/SessionConfig.cpp
|
||||
Session/SessionConfig.h
|
||||
Session/SessionNotifications.h
|
||||
StreamingInstall/StreamingInstall.h
|
||||
StreamingInstall/StreamingInstall.cpp
|
||||
StreamingInstall/StreamingInstallRequests.h
|
||||
|
||||
Reference in New Issue
Block a user