Skip to content

Commit

Permalink
RayTestHit and gameobject casting.
Browse files Browse the repository at this point in the history
  • Loading branch information
CheezBoiger committed May 10, 2018
1 parent 1c6c73f commit 34d6468
Show file tree
Hide file tree
Showing 16 changed files with 411 additions and 227 deletions.
1 change: 1 addition & 0 deletions Engine/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
81 changes: 81 additions & 0 deletions Engine/Core/Public/Core/Utility/CharHash.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2018 Recluse Project. All rights reserved.
#pragma once

#include "Core/Types.hpp"
#include "Core/Utility/Archive.hpp"

#include <stdlib.h>
#include <stdint.h>

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<typename ResultT,
ResultT OffsetBasis,
ResultT Prime>
class basic_fnv1a {

static_assert(std::is_unsigned<ResultT>::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<const u8* >(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<std::uint32_t, UINT32_C(2166136261), UINT32_C(16777619)>;
using fnv1a_64 = basic_fnv1a<std::uint64_t, UINT64_C(14695981039346656037), UINT64_C(1099511628211)>;


template <std::size_t Bits>
struct fnv1a;

template <>
struct fnv1a<32> {
using type = fnv1a_32;
};

template <>
struct fnv1a<64> {
using type = fnv1a_64;
};

template <std::size_t Bits>
using fnv1a_t = typename fnv1a<Bits>::type;


constexpr std::size_t
hash_bytes(const void *const data, const std::size_t size) {
auto hashfn = fnv1a_t<CHAR_BIT * sizeof(std::size_t)>{};
hashfn.update(data, size);
return hashfn.digest();
}
} // Recluse
2 changes: 2 additions & 0 deletions Engine/Game/Private/GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ GameObject::GameObject()
: m_pParent(nullptr)
, m_id(std::hash<game_uuid_t>()(sGameObjectCount++))
, m_name("Default Name")
, m_objTypeId(0)
{
m_objTypeId = GetObjectId();
m_transform.Initialize(this);
}

Expand Down
2 changes: 1 addition & 1 deletion Engine/Game/Private/PhysicsComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
4 changes: 3 additions & 1 deletion Engine/Game/Public/Game/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ class Engine {
void LoadSceneTransition();

std::vector<GameObject*>& GetGameObjectCache() { return m_cachedGameObjects; }
std::vector<game_uuid_t>& GetGameObjectKeys() { return m_cachedGameObjectKeys; }
std::vector<game_uuid_t>& GetGameObjectKeys() { return m_cachedGameObjectKeys; }

Scene* GetScene() { return m_pPushedScene; }

r64 GameMousePosX() const { return m_gameMouseX; }
r64 GameMousePosY() const { return m_gameMouseY; }
Expand Down
29 changes: 27 additions & 2 deletions Engine/Game/Public/Game/GameObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand All @@ -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();
Expand All @@ -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.
Expand All @@ -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<typename T>
static T* Cast(GameObject* obj) {
T* n = nullptr;
if (obj) {
n = obj->GetObjectId() == T :: GlobalId() ? static_cast<T*>(obj) : nullptr;
}
return n;
}

private:
std::string m_name;
std::string m_tag;

// List of associated children.
std::vector<GameObject*> m_children;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Engine/Game/Public/Game/Scene/Scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class Scene : public ISerializable {

std::string m_SceneName;
SceneNode m_Root;

// Global illumination Lighting information cache.
//std::vector<LightProbe*> m_lightProbes;
//std::vector<ReflectionProbe*> m_reflectionProbes;
Expand Down
10 changes: 8 additions & 2 deletions Engine/Physics/Private/BulletPhysics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -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<RigidBody*>(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;
}

Expand Down
2 changes: 1 addition & 1 deletion Engine/Physics/Private/BulletPhysics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class BulletPhysics : public Physics, public EngineModule<BulletPhysics> {
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;
Expand Down
12 changes: 11 additions & 1 deletion Engine/Physics/Public/Physics/Physics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Physics> {
public:
Expand Down Expand Up @@ -48,7 +58,7 @@ class Physics : public EngineModule<Physics> {
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:
Expand Down
29 changes: 17 additions & 12 deletions Engine/Physics/Public/Physics/RigidBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef std::function<void()> OnCollisionCallback;


class Collider;

class GameObject;

enum ContactType {
START_COLLISION,
Expand All @@ -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
Loading

0 comments on commit 34d6468

Please sign in to comment.