Entity Spatial Component API draft.
This commit is contained in:
parent
4ab31de209
commit
cb545da50f
23
projs/shadow/shadow-engine/core/inc/math/bounds.h
Normal file
23
projs/shadow/shadow-engine/core/inc/math/bounds.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
#include <math/transform.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A temporary header that contains some of the bounds implementations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bounding box that can be rotated freely.
|
||||||
|
* Can be used as the collision box for an entity.
|
||||||
|
*/
|
||||||
|
struct OrientedBB {
|
||||||
|
|
||||||
|
OrientedBB() = default;
|
||||||
|
|
||||||
|
|
||||||
|
Quaternion orientation;
|
||||||
|
Vector center;
|
||||||
|
Vector extent;
|
||||||
|
};
|
||||||
|
}
|
47
projs/shadow/shadow-engine/core/inc/math/transform.h
Normal file
47
projs/shadow/shadow-engine/core/inc/math/transform.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A temporary header that contains some of the core transform logic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
|
||||||
|
struct alignas(16) Vector {
|
||||||
|
Vector() = default;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct { float x, y, z, w; };
|
||||||
|
__m128 data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alignas(16) Quaternion {
|
||||||
|
|
||||||
|
inline Quaternion() = default;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct { float x, y, z, w; };
|
||||||
|
__m128 data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Transform {
|
||||||
|
public:
|
||||||
|
Transform() = default;
|
||||||
|
|
||||||
|
const Vector& GetTranslation() const { return translation; }
|
||||||
|
const Quaternion& GetRotation() const { return rotation; }
|
||||||
|
|
||||||
|
inline Vector GetRightVector() const;
|
||||||
|
inline Vector GetForwardVector() const;
|
||||||
|
inline Vector GetUpVector() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Quaternion rotation;
|
||||||
|
Vector translation;
|
||||||
|
Vector scale;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace SE {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Entity Component that has a Spatial context.
|
||||||
|
* AKA, a Component with a position, a rotation, and a size.
|
||||||
|
*
|
||||||
|
* Spatial Components may exist in a hierarchy; where each subsequent object inherits the spatial positions of its' parents.
|
||||||
|
* This allows for things like complex articulation of large machines, etc.
|
||||||
|
*/
|
||||||
|
class EntitySpatialComponent : public EntityComponent {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Whether this is the root spatial component for this Entity.
|
||||||
|
inline bool IsSpatialRoot() const { return parent == nullptr; }
|
||||||
|
|
||||||
|
// Fetch the transforms and bounds.
|
||||||
|
inline Math::Transform const& GetLocalTransform() const { return transform; }
|
||||||
|
inline Math::OrientedBB const& GetLocalBounds() const { return bounds; }
|
||||||
|
|
||||||
|
inline Math::Transform const& GetWorldTransform() const { return worldTransform; }
|
||||||
|
inline Math::OrientedBB const& GetWorldBounds() const { return worldBounds; }
|
||||||
|
|
||||||
|
// Get the position in world-space.
|
||||||
|
inline Math::Vector const& GetPosition() const { return worldTransform.GetTranslation(); }
|
||||||
|
|
||||||
|
// Get the rotation in world-space.
|
||||||
|
inline Math::Quaternion const& GetRotation() const { return worldTransform.GetRotation(); }
|
||||||
|
|
||||||
|
// Get vectors relative to this spatial component.
|
||||||
|
inline Math::Vector GetForwardVector() const { return worldTransform.GetForwardVector(); }
|
||||||
|
inline Math::Vector GetUpVector() const { return worldTransform.GetUpVector(); }
|
||||||
|
inline Math::Vector GetRightVector() const { return worldTransform.GetRightVector(); }
|
||||||
|
|
||||||
|
// Update the local and world transforms
|
||||||
|
inline void SetLocalTransform(Math::Transform const& newTransform);
|
||||||
|
inline void SetWorldTransform(Math::Transform const& newTransform);
|
||||||
|
|
||||||
|
// Move this component by the specified amount of transform, rotation
|
||||||
|
inline void MoveBy(Math::Transform const& delta);
|
||||||
|
|
||||||
|
|
||||||
|
// Is there a child spatial component
|
||||||
|
inline bool HasChildren() const { return !children.empty(); }
|
||||||
|
|
||||||
|
// Get the ID of the parent of this Spatial Component
|
||||||
|
inline ComponentID const& GetParentID() const { return parent->GetID(); }
|
||||||
|
|
||||||
|
// Get the transform of the parent component
|
||||||
|
inline Math::Transform const& GetParentTransform() const { return parent->worldTransform; }
|
||||||
|
|
||||||
|
// Fetch how deep in the spatial hierarchy this Component is.
|
||||||
|
size_t GetHierarchyDepth(bool singleEntity = true) const;
|
||||||
|
|
||||||
|
// Check if we are a child of a given Component
|
||||||
|
bool IsChildOf(EntitySpatialComponent const* parent) const;
|
||||||
|
|
||||||
|
// Get the ID of the socket we are attached to
|
||||||
|
inline std::string const& GetAttachmentSocketID() const { return attachmentSocket; }
|
||||||
|
|
||||||
|
// Set the name of the socket we wish to be attached to.
|
||||||
|
inline void SetAttachmentSocket(std::string& id) { attachmentSocket = id;}
|
||||||
|
|
||||||
|
// Fetch the transform of a specific attachment.
|
||||||
|
Math::Transform const& GetAttachmentTransform(std::string& id) const;
|
||||||
|
|
||||||
|
// Whether this Component supports local scaling
|
||||||
|
virtual bool LocalScale() const { return false; }
|
||||||
|
// Fetch the local scale, if supported. { 1, 1, 1 } otherwise.
|
||||||
|
virtual std::array<float, 3> const& GetLocalScale() const { static auto ones = std::array<float, 3> { 1, 1, 1 }; return ones; }
|
||||||
|
|
||||||
|
// Convert a given world-space transform to a model-space transform.
|
||||||
|
inline Math::Transform const& ConvertWorldToLocalTransform(Math::Transform const& world);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void Initialize() override;
|
||||||
|
|
||||||
|
// Set the local scale, if supported
|
||||||
|
virtual void SetLocalScale(std::array<float, 3> const& newScale) {}
|
||||||
|
|
||||||
|
// Calculate the local bounding box for the Component; the position should always be close to origin.
|
||||||
|
virtual Math::OrientedBB CalculateBounds() const;
|
||||||
|
|
||||||
|
// Update the local and world bounds for the Component.
|
||||||
|
void UpdateBounds();
|
||||||
|
|
||||||
|
// Attempt to find the given Socket in this Component, and return its' Transform if present.
|
||||||
|
bool GetAttachmentTransform(std::string& socketId, Math::Transform& out) const;
|
||||||
|
virtual bool FindAttachmentTransform(std::string& socketId, Math::Transform& out) const;
|
||||||
|
|
||||||
|
// Whether this Component has the given Socket.
|
||||||
|
// Default: No sockets.
|
||||||
|
virtual bool HasSocket(std::string& socket) const { return false;}
|
||||||
|
|
||||||
|
// Process the creation/destruction/movement of a Socket.
|
||||||
|
void UpdateSockets();
|
||||||
|
|
||||||
|
// Called whenever the World Transform is updated.
|
||||||
|
virtual void OnMoved() {}
|
||||||
|
|
||||||
|
// Set the World Transform for a component.
|
||||||
|
// Skips a lot of internal processing.
|
||||||
|
inline void SetWorldTransform(Math::Transform& newTransform, bool callback = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
inline void CalculateWorldTransform(bool callback = true);
|
||||||
|
|
||||||
|
// The location of this Component, relative to the world.
|
||||||
|
Math::Transform transform;
|
||||||
|
// The collision boundary of this Component.
|
||||||
|
Math::OrientedBB bounds;
|
||||||
|
|
||||||
|
// The world transform of this component; how to get to the position from the world origin.
|
||||||
|
Math::Transform worldTransform;
|
||||||
|
Math::OrientedBB worldBounds;
|
||||||
|
|
||||||
|
// The parent of this Spatial Component
|
||||||
|
EntitySpatialComponent* parent = nullptr;
|
||||||
|
// The socket (attachment point) of the parent entity that this Component is attached to.
|
||||||
|
std::string attachmentSocket;
|
||||||
|
// The Components that are attached to this Component.
|
||||||
|
std::vector<EntitySpatialComponent*> children;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user