diff --git a/Engine/Core/CMakeLists.txt b/Engine/Core/CMakeLists.txt index 13c69d9f..e1e9f759 100644 --- a/Engine/Core/CMakeLists.txt +++ b/Engine/Core/CMakeLists.txt @@ -44,6 +44,7 @@ set(RECLUSE_CORE_FILES ${RECLUSE_CORE_PUB_DIR}/Utility/Image.hpp ${RECLUSE_CORE_PUB_DIR}/Utility/Archive.hpp ${RECLUSE_CORE_PUB_DIR}/Utility/Cpu.hpp + ${RECLUSE_CORE_PUB_DIR}/Utility/CharHash.hpp ${RECLUSE_CORE_PRIVATE_DIR}/Utility/Archive.cpp ${RECLUSE_CORE_PRIVATE_DIR}/Win32/Window.cpp ${RECLUSE_CORE_PRIVATE_DIR}/Win32/Win32Time.cpp diff --git a/Engine/Core/Public/Core/Utility/CharHash.hpp b/Engine/Core/Public/Core/Utility/CharHash.hpp new file mode 100644 index 00000000..151014ef --- /dev/null +++ b/Engine/Core/Public/Core/Utility/CharHash.hpp @@ -0,0 +1,81 @@ +// Copyright (c) 2018 Recluse Project. All rights reserved. +#pragma once + +#include "Core/Types.hpp" +#include "Core/Utility/Archive.hpp" + +#include +#include + +namespace Recluse { + +// Implementation of char hash FNV-1a taken from: +// https://stackoverflow.com/questions/34597260/stdhash-value-on-char-value-and-not-on-memory-address +template +class basic_fnv1a { + + static_assert(std::is_unsigned::value, "need unsigned integer"); + +public: + + using result_type = ResultT; + +private: + + result_type state_ { }; + +public: + + constexpr + basic_fnv1a() : state_ {OffsetBasis} + { } + + constexpr void + update(const void *const data, const std::size_t size) { + const auto cdata = static_cast(data); + auto acc = this->state_; + for (auto i = std::size_t {}; i < size; ++i) + { + const auto next = std::size_t {cdata[i]}; + acc = (acc ^ next) * Prime; + } + this->state_ = acc; + } + + constexpr result_type + digest() const { + return this->state_; + } +}; + + +using fnv1a_32 = basic_fnv1a; +using fnv1a_64 = basic_fnv1a; + + +template +struct fnv1a; + +template <> +struct fnv1a<32> { + using type = fnv1a_32; +}; + +template <> +struct fnv1a<64> { + using type = fnv1a_64; +}; + +template +using fnv1a_t = typename fnv1a::type; + + +constexpr std::size_t +hash_bytes(const void *const data, const std::size_t size) { + auto hashfn = fnv1a_t{}; + hashfn.update(data, size); + return hashfn.digest(); +} +} // Recluse \ No newline at end of file diff --git a/Engine/Game/Private/GameObject.cpp b/Engine/Game/Private/GameObject.cpp index 3ded1a0d..8b9f557f 100644 --- a/Engine/Game/Private/GameObject.cpp +++ b/Engine/Game/Private/GameObject.cpp @@ -14,7 +14,9 @@ GameObject::GameObject() : m_pParent(nullptr) , m_id(std::hash()(sGameObjectCount++)) , m_name("Default Name") + , m_objTypeId(0) { + m_objTypeId = GetObjectId(); m_transform.Initialize(this); } diff --git a/Engine/Game/Private/PhysicsComponent.cpp b/Engine/Game/Private/PhysicsComponent.cpp index da55f7c1..255ce36c 100644 --- a/Engine/Game/Private/PhysicsComponent.cpp +++ b/Engine/Game/Private/PhysicsComponent.cpp @@ -15,7 +15,7 @@ DEFINE_COMPONENT_MAP(PhysicsComponent); void PhysicsComponent::OnInitialize(GameObject* owner) { if (!m_pRigidBody) m_pRigidBody = gPhysics().CreateRigidBody(m_pCollider); - m_pRigidBody->m_gameObjUUID = owner->GetId(); + m_pRigidBody->m_gameObj = owner; REGISTER_COMPONENT(PhysicsComponent, this); } diff --git a/Engine/Game/Public/Game/Engine.hpp b/Engine/Game/Public/Game/Engine.hpp index 1d7e504b..be0034b6 100644 --- a/Engine/Game/Public/Game/Engine.hpp +++ b/Engine/Game/Public/Game/Engine.hpp @@ -95,7 +95,9 @@ class Engine { void LoadSceneTransition(); std::vector& GetGameObjectCache() { return m_cachedGameObjects; } - std::vector& GetGameObjectKeys() { return m_cachedGameObjectKeys; } + std::vector& GetGameObjectKeys() { return m_cachedGameObjectKeys; } + + Scene* GetScene() { return m_pPushedScene; } r64 GameMousePosX() const { return m_gameMouseX; } r64 GameMousePosY() const { return m_gameMouseY; } diff --git a/Engine/Game/Public/Game/GameObject.hpp b/Engine/Game/Public/Game/GameObject.hpp index baf99e5f..d089a9e3 100644 --- a/Engine/Game/Public/Game/GameObject.hpp +++ b/Engine/Game/Public/Game/GameObject.hpp @@ -7,6 +7,7 @@ #include "Core/Utility/Vector.hpp" #include "Core/Memory/SmartPointer.hpp" #include "Core/Logging/Log.hpp" +#include "Core/Utility/CharHash.hpp" #include "Component.hpp" #include "Scripts/Behavior.hpp" @@ -16,7 +17,15 @@ namespace Recluse { -typedef uuid64 game_uuid_t; +typedef uuid64 game_uuid_t; +typedef uuid64 object_uuid_t; + + +// Always define this macro when inheriting GameObject (or any child objects that have +// GameObject as it's hierarchial parent. +#define R_GAME_OBJECT(cls) \ + virtual object_uuid_t GetObjectId() const override { return cls :: GlobalId(); } \ + static game_uuid_t GlobalId() { return hash_bytes(#cls, strlen(#cls)); } // Game Object, used for the game itself. These objects are the fundamental data type // in our game, which hold important info regarding various data about transformation, @@ -32,6 +41,7 @@ class GameObject : public ISerializable { public: static u64 NumGameObjectsCreated() { return sGameObjectCount; } + static game_uuid_t GlobalId() { return hash_bytes("GameObject", strlen("GameObject")); } GameObject(); ~GameObject(); @@ -42,6 +52,7 @@ class GameObject : public ISerializable { virtual void Deserialize(IArchive& archive) override; void SetParent(GameObject* parent) { m_pParent = parent; } void SetName(std::string name) { m_name = name; } + void SetTag(std::string tag) { m_tag = tag; } void AddChild(GameObject* child) { child->SetParent(this); m_children.push_back(child); } // Update the object. Can be overridable from inherited classes. @@ -56,17 +67,30 @@ class GameObject : public ISerializable { // Puts game object to sleep. This will cause engine to ignore updating this object. virtual void Sleep() { } + virtual object_uuid_t GetObjectId() const { return 0; } + GameObject* GetParent() { return m_pParent; } GameObject* GetChild(std::string id); GameObject* GetChild(size_t idx) { if (m_children.size() > idx) return m_children[idx]; return nullptr; } Transform* GetTransform() { return &m_transform; } std::string GetName() const { return m_name; } + std::string GetTag() const { return m_tag; } game_uuid_t GetId() const { return m_id; } size_t GetChildrenCount() const { return m_children.size(); } + template + static T* Cast(GameObject* obj) { + T* n = nullptr; + if (obj) { + n = obj->GetObjectId() == T :: GlobalId() ? static_cast(obj) : nullptr; + } + return n; + } + private: std::string m_name; + std::string m_tag; // List of associated children. std::vector m_children; @@ -75,7 +99,8 @@ class GameObject : public ISerializable { GameObject* m_pParent; Transform m_transform; game_uuid_t m_id; - + object_uuid_t m_objTypeId; + friend class GameObjectManager; friend class Component; friend class Scene; diff --git a/Engine/Game/Public/Game/Scene/Scene.hpp b/Engine/Game/Public/Game/Scene/Scene.hpp index 90ad5857..0a298c7d 100644 --- a/Engine/Game/Public/Game/Scene/Scene.hpp +++ b/Engine/Game/Public/Game/Scene/Scene.hpp @@ -62,6 +62,7 @@ class Scene : public ISerializable { std::string m_SceneName; SceneNode m_Root; + // Global illumination Lighting information cache. //std::vector m_lightProbes; //std::vector m_reflectionProbes; diff --git a/Engine/Physics/Private/BulletPhysics.cpp b/Engine/Physics/Private/BulletPhysics.cpp index a2ee958d..6676af22 100644 --- a/Engine/Physics/Private/BulletPhysics.cpp +++ b/Engine/Physics/Private/BulletPhysics.cpp @@ -131,6 +131,7 @@ void BulletPhysics::CleanUp() RigidBody* BulletPhysics::CreateRigidBody(Collider* shape, const Vector3& centerOfMassOffset) { RigidBody* rigidbody = new RigidBody(); + rigidbody->m_pCollider = shape; btCollisionShape* pShape = GetCollisionShape(shape); btDefaultMotionState* pMotionState = new btDefaultMotionState( btTransform(btQuaternion(0.f, 0.f, 0.f, 1.f), @@ -307,7 +308,7 @@ void BulletPhysics::ApplyImpulse(RigidBody* body, const Vector3& impulse, const } -b32 BulletPhysics::RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance) +b32 BulletPhysics::RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance, RayTestHit* output) { btVector3 start(btScalar(origin.x), btScalar(origin.y), @@ -325,7 +326,12 @@ b32 BulletPhysics::RayTest(const Vector3& origin, const Vector3& direction, cons // Register hit. if (!hit.hasHit()) return false; RigidBody* rbHit = static_cast(hit.m_collisionObject->getUserPointer()); - + output->_rigidbody = rbHit; + output->_collider = rbHit->GetCollider(); + output->_normal = Vector3(hit.m_hitNormalWorld.x(), + hit.m_hitNormalWorld.y(), + hit.m_hitNormalWorld.z()); + hit.m_closestHitFraction; return true; } diff --git a/Engine/Physics/Private/BulletPhysics.hpp b/Engine/Physics/Private/BulletPhysics.hpp index 3b79b584..52d2a395 100644 --- a/Engine/Physics/Private/BulletPhysics.hpp +++ b/Engine/Physics/Private/BulletPhysics.hpp @@ -52,7 +52,7 @@ class BulletPhysics : public Physics, public EngineModule { void SetWorldGravity(const Vector3& gravity) override; void SetTransform(RigidBody* body, const Vector3& pos, const Quaternion& rot) override; - b32 RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance) override; + b32 RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance, RayTestHit* output) override; b32 RayTestAll(const Vector3& origin, const Vector3& direction, const r32 maxDistance) override; private: btDynamicsWorld* m_pWorld; diff --git a/Engine/Physics/Public/Physics/Physics.hpp b/Engine/Physics/Public/Physics/Physics.hpp index 987915db..76e9c374 100644 --- a/Engine/Physics/Public/Physics/Physics.hpp +++ b/Engine/Physics/Public/Physics/Physics.hpp @@ -19,6 +19,16 @@ namespace Recluse { class Actor; class BulletPhysics; + +struct RayTestHit { + // Rigid body that was hit by the ray. + RigidBody* _rigidbody; + // Collider of the rigidbody hit by the ray. + Collider* _collider; + + Vector3 _normal; +}; + // Our physics engine. class Physics : public EngineModule { public: @@ -48,7 +58,7 @@ class Physics : public EngineModule { virtual void SetTransform(RigidBody* body, const Vector3& pos, const Quaternion& rot) { } virtual void UpdateState(r64 dt, r64 fixedTime) { } - virtual b32 RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance) { return false; } + virtual b32 RayTest(const Vector3& origin, const Vector3& direction, const r32 maxDistance, RayTestHit* output) { return false; } virtual b32 RayTestAll(const Vector3& origin, const Vector3& direction, const r32 maxDistance) { return false; } private: diff --git a/Engine/Physics/Public/Physics/RigidBody.hpp b/Engine/Physics/Public/Physics/RigidBody.hpp index 3da6b7c3..93d7badf 100644 --- a/Engine/Physics/Public/Physics/RigidBody.hpp +++ b/Engine/Physics/Public/Physics/RigidBody.hpp @@ -17,7 +17,7 @@ typedef std::function OnCollisionCallback; class Collider; - +class GameObject; enum ContactType { START_COLLISION, @@ -26,28 +26,33 @@ enum ContactType { }; -// +// RigidBody object create by Physics interface. Be sue to assign the proper +// game object id to this body, otherwise nullptr will be returned! class RigidBody : public PhysicsObject { public: RigidBody() : onCollisionCallback(nullptr) - , m_bActivated(true) { } + , m_bActivated(true) + , m_pCollider(nullptr) + , m_gameObj(nullptr) { } - void ObjectCollided(); - void EnableKinematic(b8 enable); + void ObjectCollided(); + void EnableKinematic(b8 enable); + void SetTransform(const Vector3& newPos, const Quaternion& newRot); + void SetMass(r32 mass); - void SetTransform(const Vector3& newPos, const Quaternion& newRot); - void SetMass(r32 mass); b32 Kinematic() const { return m_bKinematic; } b32 Activated() const { return m_bActivated; } - uuid64 GetGameObjectUUID() const { return m_gameObjUUID; } + GameObject* GetGameObject() const { return m_gameObj; } + Collider* GetCollider() { return m_pCollider; } OnCollisionCallback onCollisionCallback; - r32 m_mass; + Collider* m_pCollider; Vector3 m_vPosition; + r32 m_mass; Quaternion m_qRotation; - b32 m_bKinematic : 1; - b32 m_bActivated : 1; - uuid64 m_gameObjUUID; + b32 m_bKinematic; + b32 m_bActivated; + GameObject* m_gameObj; }; } // Recluse \ No newline at end of file diff --git a/Test/Game/Main.cpp b/Test/Game/Main.cpp index 0eb5da11..af24ff4a 100644 --- a/Test/Game/Main.cpp +++ b/Test/Game/Main.cpp @@ -7,6 +7,8 @@ #include "Game/Scene/ModelLoader.hpp" #include "../DemoTextureLoad.hpp" #include "Scripts/FlyViewCamera.hpp" +#include "Scripts/Helmet.hpp" +#include "Scripts/CubeObject.hpp" #include "Scripts/Lantern.hpp" // Scripts. @@ -16,208 +18,6 @@ using namespace Recluse; - -// Helmet object example, on how to set up and update a game object for the engine. -class HelmetObject : public GameObject -{ -public: - - HelmetObject() - { - m_pMeshComponent = new MeshComponent(); - m_pMaterialComponent = new MaterialComponent(); - m_pRendererComponent = new RendererComponent(); - m_pPhysicsComponent = new PhysicsComponent(); - - m_pCollider = gPhysics().CreateBoxCollider(Vector3(0.4f, 0.5f, 0.4f)); - m_pPhysicsComponent->SetRelativeOffset(Vector3(0.0f, -0.1f, 0.0f)); - m_pPhysicsComponent->SetCollider(m_pCollider); - m_pPhysicsComponent->Initialize(this); - - Mesh* mesh = nullptr; - //MeshCache::Get("mesh_helmet_LP_13930damagedHelmet", &mesh); - MeshCache::Get("mesh_helmet_LP_13930damagedHelmet", &mesh); - m_pMeshComponent->Initialize(this); - m_pMeshComponent->SetMeshRef(mesh); - - Material* material = nullptr; - MaterialCache::Get( -#if 0 - "StingrayPBS1SG" -#else - "Material_MR" -#endif - , &material); - m_pMaterialComponent->SetMaterialRef(material); - m_pMaterialComponent->Initialize(this); - //material->SetEmissiveFactor(1.0f); - material->SetRoughnessFactor(1.0f); - material->SetMetallicFactor(1.0f); - material->SetEmissiveFactor(1.0f); - m_pRendererComponent->SetMaterialComponent(m_pMaterialComponent); - m_pRendererComponent->SetMeshComponent(m_pMeshComponent); - m_pRendererComponent->Initialize(this); - - std::random_device r; - std::mt19937 twist(r()); - std::uniform_real_distribution dist(0.0f, 1.0f); - Transform* trans = GetTransform(); - trans->Scale = Vector3(0.5f, 0.5f, 0.5f); - trans->Position = Vector3(dist(twist), dist(twist), dist(twist)); - trans->Rotation = Quaternion::AngleAxis(Radians(45.0f), Vector3(1.0f, 0.0f, 0.0f)); - m_vRandDir = Vector3(dist(twist), dist(twist), dist(twist)).Normalize(); - - m_pPhysicsComponent->Enable(false); - } - - - void Awake() override - { - } - - // Updating game logic... - void Update(r32 tick) override - { -#define FOLLOW_CAMERA_FORWARD 0 - Transform* transform = GetTransform(); - // transform->Position += m_vRandDir * tick; - //Quaternion q = Quaternion::AngleAxis(Radians(0.1f), Vector3(0.0f, 1.0, 0.0f)); - //transform->Rotation = transform->Rotation * q; -#if FOLLOW_CAMERA_FORWARD - // Have helmet rotate with camera look around. - Quaternion targ = Camera::GetMain()->GetTransform()->Rotation; - transform->Rotation = targ; -#endif - if (Keyboard::KeyPressed(KEY_CODE_UP_ARROW)) { - transform->Position.x += 1.0f * tick; - } - if (Keyboard::KeyPressed(KEY_CODE_DOWN_ARROW)) { - transform->Position.x -= 1.0f * tick; - } - if (Keyboard::KeyPressed(KEY_CODE_RIGHT_ARROW)) { - transform->Position.z += 1.0f * tick; - } - if (Keyboard::KeyPressed(KEY_CODE_LEFT_ARROW)) { - transform->Position.z -= 1.0f * tick; - } - - if (Keyboard::KeyPressed(KEY_CODE_V)) { - m_pPhysicsComponent->Enable(true); - } - - if (Keyboard::KeyPressed(KEY_CODE_B) && Keyboard::KeyPressed(KEY_CODE_SHIFT)) { - m_pPhysicsComponent->ApplyImpulse(m_vRandDir, Vector3(0.0f, 0.0f, 0.0f)); - } - } - - void CleanUp() override - { - m_pMeshComponent->CleanUp(); - m_pMaterialComponent->CleanUp(); - m_pRendererComponent->CleanUp(); - m_pPhysicsComponent->CleanUp(); - - delete m_pMeshComponent; - delete m_pMaterialComponent; - delete m_pRendererComponent; - delete m_pPhysicsComponent; - delete m_pCollider; - } - -private: - Vector3 m_vRandDir; - RendererComponent* m_pRendererComponent; - MeshComponent* m_pMeshComponent; - MaterialComponent* m_pMaterialComponent; - PhysicsComponent* m_pPhysicsComponent; - Collider* m_pCollider; -}; - - -// Spehere object example, on how to set up and update a game object for the engine. -class CubeObject : public GameObject -{ -public: - - CubeObject() - { - m_pMeshComponent = new MeshComponent(); - m_pMaterialComponent = new MaterialComponent(); - m_pRendererComponent = new RendererComponent(); - m_pPhysicsComponent = new PhysicsComponent(); - m_pCollider = gPhysics().CreateBoxCollider(Vector3(5.0f, 5.0f, 5.0f)); - - m_pPhysicsComponent->SetCollider(m_pCollider); - m_pPhysicsComponent->Initialize(this); - m_pPhysicsComponent->SetMass(0.0f); - - Mesh* mesh = nullptr; - MeshCache::Get("NativeCube", &mesh); - m_pMeshComponent->Initialize(this); - m_pMeshComponent->SetMeshRef(mesh); - - Material* material = nullptr; - MaterialCache::Get( -#if 1 - "RustySample" -#else - "Material_MR" -#endif - , &material); - m_pMaterialComponent->SetMaterialRef(material); - m_pMaterialComponent->Initialize(this); - m_pRendererComponent->SetMaterialComponent(m_pMaterialComponent); - m_pRendererComponent->SetMeshComponent(m_pMeshComponent); - m_pRendererComponent->Initialize(this); - - std::random_device r; - std::mt19937 twist(r()); - std::uniform_real_distribution dist(-4.0f, 4.0f); - Transform* trans = GetTransform(); - trans->Rotation = Quaternion::AngleAxis(Radians(90.0f), Vector3(1.0f, 0.0f, 0.0f)); - trans->Scale = Vector3(5.0f, 5.0f, 5.0f); - trans->Position = Vector3(0.0f, -5.0f, 0.0f); - //m_vRandDir = Vector3(dist(twist), dist(twist), dist(twist)).Normalize(); - } - - - void Awake() override - { - } - - void Update(r32 tick) override - { - Transform* transform = GetTransform(); - //transform->Position += m_vRandDir * tick; - //Quaternion q = Quaternion::AngleAxis(-Radians(0.1f), Vector3(0.0f, 0.0, 1.0f)); - //transform->Rotation = transform->Rotation * q; - } - - void CleanUp() override - { - m_pMeshComponent->CleanUp(); - m_pMaterialComponent->CleanUp(); - m_pRendererComponent->CleanUp(); - m_pPhysicsComponent->CleanUp(); - - delete m_pMeshComponent; - delete m_pMaterialComponent; - delete m_pRendererComponent; - delete m_pPhysicsComponent; - delete m_pCollider; - } - -private: - Vector3 m_vRandDir; - RendererComponent* m_pRendererComponent; - MeshComponent* m_pMeshComponent; - MaterialComponent* m_pMaterialComponent; - PhysicsComponent* m_pPhysicsComponent; - Collider* m_pCollider; -}; - - - /* Requirements for rendering something on screen: Material -> MaterialComponent. diff --git a/Test/Game/Scripts/CubeObject.hpp b/Test/Game/Scripts/CubeObject.hpp new file mode 100644 index 00000000..1a01c77e --- /dev/null +++ b/Test/Game/Scripts/CubeObject.hpp @@ -0,0 +1,102 @@ +// Copyright (c) 2018 Recluse Project. All rights reserved. +#pragma once +#include "Game/Engine.hpp" +#include "Game/Scene/Scene.hpp" +#include "Game/Geometry/UVSphere.hpp" +#include "Renderer/UserParams.hpp" + + +#include "Game/Scene/ModelLoader.hpp" +#include "../DemoTextureLoad.hpp" + +// Scripts. +#include +#include +#include + +using namespace Recluse; + + +// Spehere object example, on how to set up and update a game object for the engine. +class CubeObject : public GameObject +{ +public: + + R_GAME_OBJECT(CubeObject) + + CubeObject() + { + m_pMeshComponent = new MeshComponent(); + m_pMaterialComponent = new MaterialComponent(); + m_pRendererComponent = new RendererComponent(); + m_pPhysicsComponent = new PhysicsComponent(); + m_pCollider = gPhysics().CreateBoxCollider(Vector3(5.0f, 5.0f, 5.0f)); + + m_pPhysicsComponent->SetCollider(m_pCollider); + m_pPhysicsComponent->Initialize(this); + m_pPhysicsComponent->SetMass(0.0f); + + Mesh* mesh = nullptr; + MeshCache::Get("NativeCube", &mesh); + m_pMeshComponent->Initialize(this); + m_pMeshComponent->SetMeshRef(mesh); + + Material* material = nullptr; + MaterialCache::Get( +#if 1 + "RustySample" +#else + "Material_MR" +#endif + , &material); + m_pMaterialComponent->SetMaterialRef(material); + m_pMaterialComponent->Initialize(this); + m_pRendererComponent->SetMaterialComponent(m_pMaterialComponent); + m_pRendererComponent->SetMeshComponent(m_pMeshComponent); + m_pRendererComponent->Initialize(this); + + std::random_device r; + std::mt19937 twist(r()); + std::uniform_real_distribution dist(-4.0f, 4.0f); + Transform* trans = GetTransform(); + trans->Rotation = Quaternion::AngleAxis(Radians(90.0f), Vector3(1.0f, 0.0f, 0.0f)); + trans->Scale = Vector3(5.0f, 5.0f, 5.0f); + trans->Position = Vector3(0.0f, -5.0f, 0.0f); + //m_vRandDir = Vector3(dist(twist), dist(twist), dist(twist)).Normalize(); + } + + + void Awake() override + { + } + + void Update(r32 tick) override + { + Transform* transform = GetTransform(); + //transform->Position += m_vRandDir * tick; + //Quaternion q = Quaternion::AngleAxis(-Radians(0.1f), Vector3(0.0f, 0.0, 1.0f)); + //transform->Rotation = transform->Rotation * q; + } + + void CleanUp() override + { + m_pMeshComponent->CleanUp(); + m_pMaterialComponent->CleanUp(); + m_pRendererComponent->CleanUp(); + m_pPhysicsComponent->CleanUp(); + + delete m_pMeshComponent; + delete m_pMaterialComponent; + delete m_pRendererComponent; + delete m_pPhysicsComponent; + delete m_pCollider; + } + +private: + Vector3 m_vRandDir; + RendererComponent* m_pRendererComponent; + MeshComponent* m_pMeshComponent; + MaterialComponent* m_pMaterialComponent; + PhysicsComponent* m_pPhysicsComponent; + Collider* m_pCollider; +}; \ No newline at end of file diff --git a/Test/Game/Scripts/FlyViewCamera.hpp b/Test/Game/Scripts/FlyViewCamera.hpp index 170acb0b..f277e3ba 100644 --- a/Test/Game/Scripts/FlyViewCamera.hpp +++ b/Test/Game/Scripts/FlyViewCamera.hpp @@ -9,6 +9,8 @@ #include "Game/Scene/ModelLoader.hpp" #include "../DemoTextureLoad.hpp" +#include "Helmet.hpp" + // Scripts. #include #include @@ -94,9 +96,16 @@ class MainCamera : public GameObject Vector3 euler = Vector3(m_pitch, m_yaw, m_roll); transform->Rotation = Quaternion::EulerAnglesToQuaternion(euler); + // Testing ray cast. if (Mouse::ButtonDown(Mouse::LEFT)) { - if (gPhysics().RayTest(transform->Position, transform->Forward(), 50.0f)) { - Log() << "Ray hit something!\n"; + RayTestHit hitOut; + if (gPhysics().RayTest(transform->Position, transform->Forward(), 50.0f, &hitOut)) { + GameObject* obj = hitOut._rigidbody->GetGameObject(); + Log() << "You hit " << obj->GetName() << "!!\n"; + HelmetObject* helmet = GameObject::Cast(obj); + if (helmet) { + + } } } } diff --git a/Test/Game/Scripts/Helmet.hpp b/Test/Game/Scripts/Helmet.hpp new file mode 100644 index 00000000..2561d3aa --- /dev/null +++ b/Test/Game/Scripts/Helmet.hpp @@ -0,0 +1,137 @@ +// Copyright (c) 2018 Recluse Project. All rights reserved. +#pragma once +#include "Game/Engine.hpp" +#include "Game/Scene/Scene.hpp" +#include "Game/Geometry/UVSphere.hpp" +#include "Renderer/UserParams.hpp" + + +#include "Game/Scene/ModelLoader.hpp" +#include "../DemoTextureLoad.hpp" + +// Scripts. +#include +#include +#include + +using namespace Recluse; + + +// Helmet object example, on how to set up and update a game object for the engine. +class HelmetObject : public GameObject +{ +public: + + R_GAME_OBJECT(HelmetObject) + + HelmetObject() + { + SetName("Mister helmet"); + m_pMeshComponent = new MeshComponent(); + m_pMaterialComponent = new MaterialComponent(); + m_pRendererComponent = new RendererComponent(); + m_pPhysicsComponent = new PhysicsComponent(); + + m_pCollider = gPhysics().CreateBoxCollider(Vector3(0.4f, 0.5f, 0.4f)); + m_pPhysicsComponent->SetRelativeOffset(Vector3(0.0f, -0.1f, 0.0f)); + m_pPhysicsComponent->SetCollider(m_pCollider); + m_pPhysicsComponent->Initialize(this); + + Mesh* mesh = nullptr; + //MeshCache::Get("mesh_helmet_LP_13930damagedHelmet", &mesh); + MeshCache::Get("mesh_helmet_LP_13930damagedHelmet", &mesh); + m_pMeshComponent->Initialize(this); + m_pMeshComponent->SetMeshRef(mesh); + + Material* material = nullptr; + MaterialCache::Get( +#if 0 + "StingrayPBS1SG" +#else + "Material_MR" +#endif + , &material); + m_pMaterialComponent->SetMaterialRef(material); + m_pMaterialComponent->Initialize(this); + //material->SetEmissiveFactor(1.0f); + material->SetRoughnessFactor(1.0f); + material->SetMetallicFactor(1.0f); + material->SetEmissiveFactor(1.0f); + m_pRendererComponent->SetMaterialComponent(m_pMaterialComponent); + m_pRendererComponent->SetMeshComponent(m_pMeshComponent); + m_pRendererComponent->Initialize(this); + + std::random_device r; + std::mt19937 twist(r()); + std::uniform_real_distribution dist(0.0f, 1.0f); + Transform* trans = GetTransform(); + trans->Scale = Vector3(0.5f, 0.5f, 0.5f); + trans->Position = Vector3(dist(twist), dist(twist), dist(twist)); + trans->Rotation = Quaternion::AngleAxis(Radians(45.0f), Vector3(1.0f, 0.0f, 0.0f)); + m_vRandDir = Vector3(dist(twist), dist(twist), dist(twist)).Normalize(); + + m_pPhysicsComponent->Enable(false); + } + + + void Awake() override + { + } + + // Updating game logic... + void Update(r32 tick) override + { +#define FOLLOW_CAMERA_FORWARD 0 + Transform* transform = GetTransform(); + // transform->Position += m_vRandDir * tick; + //Quaternion q = Quaternion::AngleAxis(Radians(0.1f), Vector3(0.0f, 1.0, 0.0f)); + //transform->Rotation = transform->Rotation * q; +#if FOLLOW_CAMERA_FORWARD + // Have helmet rotate with camera look around. + Quaternion targ = Camera::GetMain()->GetTransform()->Rotation; + transform->Rotation = targ; +#endif + if (Keyboard::KeyPressed(KEY_CODE_UP_ARROW)) { + transform->Position.x += 1.0f * tick; + } + if (Keyboard::KeyPressed(KEY_CODE_DOWN_ARROW)) { + transform->Position.x -= 1.0f * tick; + } + if (Keyboard::KeyPressed(KEY_CODE_RIGHT_ARROW)) { + transform->Position.z += 1.0f * tick; + } + if (Keyboard::KeyPressed(KEY_CODE_LEFT_ARROW)) { + transform->Position.z -= 1.0f * tick; + } + + if (Keyboard::KeyPressed(KEY_CODE_V)) { + m_pPhysicsComponent->Enable(true); + } + + if (Keyboard::KeyPressed(KEY_CODE_B) && Keyboard::KeyPressed(KEY_CODE_SHIFT)) { + m_pPhysicsComponent->ApplyImpulse(m_vRandDir, Vector3(0.0f, 0.0f, 0.0f)); + } + } + + void CleanUp() override + { + m_pMeshComponent->CleanUp(); + m_pMaterialComponent->CleanUp(); + m_pRendererComponent->CleanUp(); + m_pPhysicsComponent->CleanUp(); + + delete m_pMeshComponent; + delete m_pMaterialComponent; + delete m_pRendererComponent; + delete m_pPhysicsComponent; + delete m_pCollider; + } + +private: + Vector3 m_vRandDir; + RendererComponent* m_pRendererComponent; + MeshComponent* m_pMeshComponent; + MaterialComponent* m_pMaterialComponent; + PhysicsComponent* m_pPhysicsComponent; + Collider* m_pCollider; +}; \ No newline at end of file diff --git a/Test/Game/Scripts/Lantern.hpp b/Test/Game/Scripts/Lantern.hpp index 2c35933d..2b19dd49 100644 --- a/Test/Game/Scripts/Lantern.hpp +++ b/Test/Game/Scripts/Lantern.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2018 Recluse Project. All rights reserved. +#pragma once #include "Game/Engine.hpp" #include "Game/Scene/Scene.hpp" #include "Game/Geometry/UVSphere.hpp" @@ -163,17 +164,19 @@ class LanternObject : public GameObject { public: + R_GAME_OBJECT(LanternObject) + LanternObject() { m_pMeshComponent = new MeshComponent(); m_pMaterialComponent = new MaterialComponent(); m_pRendererComponent = new RendererComponent(); m_pPhysicsComponent = new PhysicsComponent(); - m_pCollider = gPhysics().CreateBoxCollider(Vector3(0.4f, 1.0f, 0.4f)); + m_pCollider = gPhysics().CreateBoxCollider(Vector3(0.5f, 1.0f, 0.5f)); m_pPhysicsComponent->SetCollider(m_pCollider); m_pPhysicsComponent->Initialize(this); - m_pPhysicsComponent->SetRelativeOffset(Vector3(0.0f, 1.0f, 0.0f)); + m_pPhysicsComponent->SetRelativeOffset(Vector3(0.0f, 0.95f, 0.0f)); Mesh* mesh = nullptr; MeshCache::Get("lantern lantern_base", &mesh); @@ -220,7 +223,7 @@ class LanternObject : public GameObject { Transform* transform = GetTransform(); // transform->Position += m_vRandDir * tick; - Quaternion q = Quaternion::AngleAxis(Radians(90.0f * tick), Vector3(0.0f, 1.0, 0.0f)); + Quaternion q = Quaternion::AngleAxis(Radians(45.0f * tick), Vector3(0.0f, 1.0, 0.0f)); transform->Rotation = transform->Rotation * q; }