Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions projs/shadow/shadow-engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

FILE(GLOB_RECURSE SOURCES
core/src/*.cpp
shadow-entity/src/*.cpp
shadow-renderer/src/*.cpp
shadow-reflection/src/*.cpp
shadow-utility/src/*.cpp
)
FILE(GLOB_RECURSE HEADERS
core/inc/*.h
shadow-entity/inc/*.h
shadow-renderer/inc/*.h
shadow-reflection/inc/*.h
shadow-utility/inc/*.h
Expand All @@ -24,6 +26,7 @@ target_include_directories(shadow-engine
PRIVATE ${SDL2_INCLUDE_DIRS}
PUBLIC
core/inc
shadow-entity/inc
shadow-renderer/inc
shadow-reflection/inc
shadow-utility/inc
Expand Down
64 changes: 64 additions & 0 deletions projs/shadow/shadow-engine/core/inc/id/UUID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once
#include <cstdint>
#include <cstring>
#include <string>

// ShadowEntity temporary namespace
namespace SE {

/**
* Universally Unique ID.
* 128 Bits.
*
* Unique per runtime only - the suitability for serialization is undetermined.
*/

class UUID {

/**
* Data storage; 128 bits.
* 2 x 64 bit
* 4 x 32 bit
* 16 x 8 bit
*/

union Data {
uint64_t u64[2];
uint32_t u32[4];
uint8_t u8[16];
};

public:
// Create a new, unused, UUID.
static UUID Generate();
// Check whether the UUID is correctly formed.
static bool IsValidStr(char const* str);

// Create an empty UUID.
inline UUID() { std::memset(&data.u8, 0, 16); }
// Create a UUID based on the given values.
inline UUID(uint64_t i0, uint64_t i1) { data.u64[0] = i0; data.u64[1] = i1; }
inline UUID(uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) { data.u32[0] = i0; data.u32[1] = i1; data.u32[2] = i2; data.u32[3] = i3; }
inline explicit UUID(std::string const& str) : UUID(str.c_str()) {}
// Create a UUID from the given format.
explicit UUID(char const* str);

// Check whether the UUID is nonzero.
inline bool IsValid() const { return data.u64[0] != 0 && data.u64[1] != 0; }
// Set the UUID to zero.
inline void Clear() { std::memset(&data.u8, 0, 16); }

// Get a section of the UUID's data as the given bit width.
inline uint8_t GetU8(size_t idx) const { return data.u8[idx]; }
inline uint32_t GetU32(size_t idx) const { return data.u32[idx]; }
inline uint64_t GetU64(size_t idx) const { return data.u64[idx]; }

// Check whether this and a given UUID are in/equal.
__inline bool operator==(UUID const& other) const { return data.u64[0] == other.data.u64[0] && data.u64[1] == other.data.u64[1]; }
__inline bool operator!=(UUID const& other) const { return !(*this == other); }

private:

Data data {};
};
}
23 changes: 23 additions & 0 deletions projs/shadow/shadow-engine/core/inc/math/bounds.h
Original file line number Diff line number Diff line change
@@ -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 changes: 47 additions & 0 deletions projs/shadow/shadow-engine/core/inc/math/transform.h
Original file line number Diff line number Diff line change
@@ -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;
};
}
56 changes: 56 additions & 0 deletions projs/shadow/shadow-engine/core/src/id/UUID.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <id/UUID.h>

namespace SE {
static_assert(sizeof(UUID) == 16, "UUID has incorrect size");

/**
* Verify that a string has the correct format;
* XXXXXXXX-XXXX-XXX-XXXXX-XXXXXXXXXXXX
*
* The length must be 36.
* There must be dashes at index 8, 13, 18 and 23.
* @param str the input string
* @return whether the UUID string is correctly formed
*/
bool UUID::IsValidStr(const char *str) {
size_t const len = strlen(str);
if (len != 36) return false;

for (size_t i = 0; i < len; i++) {
char c = str[i];
if (c == '-') {
if (i != 8 && i != 13 && i != 18 && i != 23) return false;
} else if (! std::isxdigit(c)) {
return false;
}
}

return true;
}

UUID::UUID(char const* str ) {
// A single byte is two hex characters.
// Store them here so that we can use them later.
char c0 = '\0', c1;

size_t const len = strlen( str );
uint32_t byteIdx = 0;

for (size_t i = 0; i < len; i++ ) {
char const c = str[i];
if ( c == '-' )
continue;

// Scan for pairs of characters.
// Only assign a byte if two have been parsed.
if (c0 == '\0') {
c0 = c;
} else {
c1 = c;
data.u8[byteIdx++] = std::stoi(std::string(c0, c1));
// Reset the first char so that we can return to scanning a pair.
c0 = '\0';
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once
#include <cstdint>
#include "id/ID.h"

namespace SE {

/**
* A Component is a part of an Entity that stores and manages data.
* This data is held separately from the Entity that requests it.
*
* Components can be Spatial (ie. Position, Rotation).
* Components can also be Visual (ie. Mesh, Collider).
* Components are part of the larger Entity-Component-System architecture.
*
* Systems operate over these Components.
* Entities may have their own Systems, and each Scene has its own set of global Systems.
* Components may be registered to only one of these.
*
* EntityComponent classes are not singleton; new EntityComponent(..) is valid.
*
*/
class EntityComponent {
public:

/**
* The Component's possible statuses.
*/
enum class Status: uint8_t {
Unloaded, // The component is not yet loaded.
Loading, // The component is being loaded.
Loaded, // The component is finished loading, but is not yet populated with data.
Failed, // The component encountered an error while loading.
Initialized // The component is finished loading, and is populated with data.
};

virtual ~EntityComponent();

// Get the ComponentID.
inline ComponentID const& GetID() const { return id; }
// Get the Name of this Component; guaranteed to be unique in a given entity.
inline std::string& GetName() { return name; }
// Get the Entity that owns this Component.
inline EntityID const& GetParent() const { return owner; }

inline Status GetStatus() const { return status; }
// Check Status
inline bool IsLoaded() const { return status == Status::Loaded; }
inline bool IsLoading() const { return status == Status::Loading; }
inline bool IsUnloaded() const { return status == Status::Unloaded; }
inline bool Failed() const { return status == Status::Failed; }
inline bool Initialized() const { return status == Status::Initialized; }

// Whether one instance of this Component is allowed per Entity
virtual bool IsSingleton() const { return false; }

protected:

EntityComponent() = default;
EntityComponent(std::string& name) : name(name) {}

// Load Component data. May perform background ops.
virtual void Load() = 0;
// Unload Component data. Must be blocking.
virtual void Unload() = 0;

// Check that everything went properly.
virtual void UpdateStatus() = 0;

// Update the status to Initialized. Must only be called if checks passed.
// The status must be Loaded.
virtual void Initialize() { status = Status::Initialized; }

// Prepare for unloading the Component. Must be called before the process begins.
// The status must be Initialized.
virtual void Close() { status == Status::Loaded; }

private:
// This Component's unique ID.
ComponentID id = ComponentID::Generate();
// The Entity that requested this Component.
EntityID owner;
// The name of the Component, for visualization
std::string name;
// The status of the Component
Status status = Status::Unloaded;

// Whether this Component is registered to the Entity's Local Systems.
bool localComponent = false;
// Whether this Component is registered to the Scene's Global Systems.
bool globalComponent = false;
};
}
Loading