Allowed scene items cleanup to happen earlier to prevent access null weak pointers. Also added Sphere Mesh and Sphere Collider(s)
This commit is contained in:
@ -1,14 +0,0 @@
|
|||||||
// Copyright (c) 2024 Dominic Masters
|
|
||||||
//
|
|
||||||
// This software is released under the MIT License.
|
|
||||||
// https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
#include "BoxCollider.hpp"
|
|
||||||
|
|
||||||
using namespace Dawn;
|
|
||||||
|
|
||||||
std::shared_ptr<JPH::ShapeSettings> BoxCollider::getShapeSettings() {
|
|
||||||
return std::make_shared<JPH::BoxShapeSettings>(
|
|
||||||
JPH::Vec3(shape.x, shape.y, shape.z)
|
|
||||||
);
|
|
||||||
}
|
|
@ -6,5 +6,6 @@
|
|||||||
target_sources(${DAWN_TARGET_NAME}
|
target_sources(${DAWN_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
Collider.cpp
|
Collider.cpp
|
||||||
BoxCollider.cpp
|
CubeCollider.cpp
|
||||||
|
SphereCollider.cpp
|
||||||
)
|
)
|
@ -11,6 +11,29 @@ using namespace Dawn;
|
|||||||
using namespace JPH;
|
using namespace JPH;
|
||||||
using namespace JPH::literals;
|
using namespace JPH::literals;
|
||||||
|
|
||||||
|
EMotionType Collider::getMotionType(const ColliderType colliderType) {
|
||||||
|
EMotionType motionType;
|
||||||
|
|
||||||
|
switch(colliderType) {
|
||||||
|
case ColliderType::DYNAMIC:
|
||||||
|
return EMotionType::Dynamic;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColliderType::STATIC:
|
||||||
|
return EMotionType::Static;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColliderType::KINEMATIC:
|
||||||
|
return EMotionType::Kinematic;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertUnreachable("Invalid ColliderType");
|
||||||
|
return EMotionType::Kinematic;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
void Collider::onInit() {
|
void Collider::onInit() {
|
||||||
assertNull(this->body, "Body is not NULL?");
|
assertNull(this->body, "Body is not NULL?");
|
||||||
|
|
||||||
@ -24,7 +47,7 @@ void Collider::onInit() {
|
|||||||
shape,
|
shape,
|
||||||
RVec3(pos.x, pos.y, pos.z),
|
RVec3(pos.x, pos.y, pos.z),
|
||||||
Quat::sIdentity(),
|
Quat::sIdentity(),
|
||||||
EMotionType::Dynamic,
|
Collider::getMotionType(this->colliderType),
|
||||||
layer
|
layer
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -40,10 +63,46 @@ void Collider::onDispose() {
|
|||||||
getBodyInterface().DestroyBody(this->bodyId);
|
getBodyInterface().DestroyBody(this->bodyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Collider::notifyShapeChanged() {
|
||||||
|
if(!this->isColliderReady()) return;
|
||||||
|
|
||||||
|
auto settings = this->getShapeSettings();
|
||||||
|
auto shapeResult = settings->Create();
|
||||||
|
auto shape = shapeResult.Get();
|
||||||
|
|
||||||
|
getBodyInterface().SetShape(
|
||||||
|
this->bodyId,
|
||||||
|
shape,
|
||||||
|
// TODO: I may not always need to re-activate the body here.
|
||||||
|
true,
|
||||||
|
EActivation::Activate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t Collider::isColliderReady() {
|
||||||
|
return this->body != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
BodyInterface & Collider::getBodyInterface() {
|
BodyInterface & Collider::getBodyInterface() {
|
||||||
return getGame()->physicsManager->getBodyInterface();
|
return getGame()->physicsManager->getBodyInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColliderType Collider::getColliderType() {
|
||||||
|
return colliderType;
|
||||||
|
}
|
||||||
|
|
||||||
BodyID Collider::getBodyId() {
|
BodyID Collider::getBodyId() {
|
||||||
return bodyId;
|
return bodyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collider::setColliderType(const ColliderType type) {
|
||||||
|
this->colliderType = type;
|
||||||
|
|
||||||
|
if(!this->isColliderReady()) return;
|
||||||
|
|
||||||
|
getBodyInterface().SetMotionType(
|
||||||
|
this->bodyId,
|
||||||
|
Collider::getMotionType(type),
|
||||||
|
EActivation::Activate// TODO: Should be false on kinematics
|
||||||
|
);
|
||||||
}
|
}
|
@ -16,10 +16,18 @@ namespace Dawn {
|
|||||||
class Collider : public SceneComponent {
|
class Collider : public SceneComponent {
|
||||||
private:
|
private:
|
||||||
JPH::Body *body = nullptr;
|
JPH::Body *body = nullptr;
|
||||||
|
ColliderType colliderType = ColliderType::DYNAMIC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JoltPhysics motion type for the collider type.
|
||||||
|
*
|
||||||
|
* @param colliderType The collider type.
|
||||||
|
* @return The JoltPhysics motion type.
|
||||||
|
*/
|
||||||
|
static JPH::EMotionType getMotionType(const ColliderType colliderType);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
JPH::BodyID bodyId;
|
JPH::BodyID bodyId;
|
||||||
JPH::EMotionType emotionType = JPH::EMotionType::Dynamic;
|
|
||||||
JPH::ObjectLayer layer = 1;
|
JPH::ObjectLayer layer = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,17 +44,41 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
JPH::BodyInterface & getBodyInterface();
|
JPH::BodyInterface & getBodyInterface();
|
||||||
|
|
||||||
public:
|
/**
|
||||||
ColliderType type = ColliderType::KINEMATIC;
|
* Callable by subclasses to notify that the shape has changed.
|
||||||
|
*/
|
||||||
|
void notifyShapeChanged();
|
||||||
|
|
||||||
|
public:
|
||||||
void onInit() override;
|
void onInit() override;
|
||||||
void onDispose() override;
|
void onDispose() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the collider is ready.
|
||||||
|
*
|
||||||
|
* @return Whether the collider is ready.
|
||||||
|
*/
|
||||||
|
bool_t isColliderReady();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the collider type.
|
||||||
|
*
|
||||||
|
* @return The collider type.
|
||||||
|
*/
|
||||||
|
ColliderType getColliderType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the JoltPhysics body ID of the collider.
|
* Returns the JoltPhysics body ID of the collider.
|
||||||
*
|
*
|
||||||
* @return The body ID of the collider.
|
* @return The body ID of the collider.
|
||||||
*/
|
*/
|
||||||
JPH::BodyID getBodyId();
|
JPH::BodyID getBodyId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the collider type.
|
||||||
|
*
|
||||||
|
* @param colliderType The collider type.
|
||||||
|
*/
|
||||||
|
void setColliderType(ColliderType colliderType);
|
||||||
};
|
};
|
||||||
}
|
}
|
23
src/dawn/component/physics/CubeCollider.cpp
Normal file
23
src/dawn/component/physics/CubeCollider.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2024 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#include "CubeCollider.hpp"
|
||||||
|
|
||||||
|
using namespace Dawn;
|
||||||
|
|
||||||
|
std::shared_ptr<JPH::ShapeSettings> CubeCollider::getShapeSettings() {
|
||||||
|
return std::make_shared<JPH::BoxShapeSettings>(
|
||||||
|
JPH::Vec3(shape.x, shape.y, shape.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 CubeCollider::getShape() {
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CubeCollider::setShape(const glm::vec3 &shape) {
|
||||||
|
this->shape = shape;
|
||||||
|
this->notifyShapeChanged();
|
||||||
|
}
|
32
src/dawn/component/physics/CubeCollider.hpp
Normal file
32
src/dawn/component/physics/CubeCollider.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2024 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "Collider.hpp"
|
||||||
|
|
||||||
|
namespace Dawn {
|
||||||
|
class CubeCollider : public Collider {
|
||||||
|
private:
|
||||||
|
glm::vec3 shape = glm::vec3(1, 1, 1);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<JPH::ShapeSettings> getShapeSettings() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Returns the shape of the cube collider.
|
||||||
|
*
|
||||||
|
* @return The shape of the cube collider.
|
||||||
|
*/
|
||||||
|
glm::vec3 getShape();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the shape of the cube collider.
|
||||||
|
*
|
||||||
|
* @param shape The shape of the cube collider.
|
||||||
|
*/
|
||||||
|
void setShape(const glm::vec3 &shape);
|
||||||
|
};
|
||||||
|
}
|
12
src/dawn/component/physics/SphereCollider.cpp
Normal file
12
src/dawn/component/physics/SphereCollider.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2024 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#include "SphereCollider.hpp"
|
||||||
|
|
||||||
|
using namespace Dawn;
|
||||||
|
|
||||||
|
std::shared_ptr<JPH::ShapeSettings> SphereCollider::getShapeSettings() {
|
||||||
|
return std::make_shared<JPH::SphereShapeSettings>(radius);
|
||||||
|
}
|
@ -7,11 +7,11 @@
|
|||||||
#include "Collider.hpp"
|
#include "Collider.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class BoxCollider : public Collider {
|
class SphereCollider : public Collider {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<JPH::ShapeSettings> getShapeSettings() override;
|
std::shared_ptr<JPH::ShapeSettings> getShapeSettings() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
glm::vec3 shape = glm::vec3(1, 1, 1);
|
float radius = 1.0f;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -8,4 +8,5 @@ target_sources(${DAWN_TARGET_NAME}
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
CubeMesh.cpp
|
CubeMesh.cpp
|
||||||
QuadMesh.cpp
|
QuadMesh.cpp
|
||||||
|
SphereMesh.cpp
|
||||||
)
|
)
|
44
src/dawn/display/mesh/SphereMesh.cpp
Normal file
44
src/dawn/display/mesh/SphereMesh.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2024 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#include "SphereMesh.hpp"
|
||||||
|
|
||||||
|
using namespace Dawn;
|
||||||
|
|
||||||
|
void SphereMesh::create(
|
||||||
|
std::shared_ptr<Mesh> mesh,
|
||||||
|
const float radius,
|
||||||
|
const uint32_t segments,
|
||||||
|
const uint32_t rings
|
||||||
|
) {
|
||||||
|
// Create the vertices
|
||||||
|
std::vector<glm::vec3> vertices;
|
||||||
|
for(uint32_t r = 0; r < rings; ++r) {
|
||||||
|
for(uint32_t s = 0; s < segments; ++s) {
|
||||||
|
float const y = sin(-M_PI_2 + M_PI * r / rings);
|
||||||
|
float const x = cos(2 * M_PI * s / segments) * sin(M_PI * r / rings);
|
||||||
|
float const z = sin(2 * M_PI * s / segments) * sin(M_PI * r / rings);
|
||||||
|
vertices.push_back(glm::vec3(x, y, z) * radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the indices
|
||||||
|
std::vector<int32_t> indices;
|
||||||
|
for(uint32_t r = 0; r < rings - 1; ++r) {
|
||||||
|
for(uint32_t s = 0; s < segments - 1; ++s) {
|
||||||
|
indices.push_back(r * segments + s);
|
||||||
|
indices.push_back(r * segments + (s + 1));
|
||||||
|
indices.push_back((r + 1) * segments + (s + 1));
|
||||||
|
|
||||||
|
indices.push_back(r * segments + s);
|
||||||
|
indices.push_back((r + 1) * segments + (s + 1));
|
||||||
|
indices.push_back((r + 1) * segments + s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->createBuffers(vertices.size(), indices.size());
|
||||||
|
mesh->bufferPositions(0, vertices.data(), vertices.size());
|
||||||
|
mesh->bufferIndices(0, indices.data(), indices.size());
|
||||||
|
}
|
27
src/dawn/display/mesh/SphereMesh.hpp
Normal file
27
src/dawn/display/mesh/SphereMesh.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) 2024 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "display/mesh/Mesh.hpp"
|
||||||
|
|
||||||
|
namespace Dawn {
|
||||||
|
class SphereMesh {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a sphere mesh.
|
||||||
|
*
|
||||||
|
* @param mesh The mesh to buffer into.
|
||||||
|
* @param radius The radius of the sphere.
|
||||||
|
* @param segments The number of segments.
|
||||||
|
* @param rings The number of rings.
|
||||||
|
*/
|
||||||
|
static void create(
|
||||||
|
std::shared_ptr<Mesh> mesh,
|
||||||
|
const float radius = 1.0f,
|
||||||
|
const uint32_t segments = 16,
|
||||||
|
const uint32_t rings = 16
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "game/Game.hpp"
|
#include "game/Game.hpp"
|
||||||
#include "scene/Scene.hpp"
|
#include "scene/Scene.hpp"
|
||||||
|
#include "util/Flag.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
@ -13,6 +14,9 @@ IGame::IGame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IGame::init() {
|
void IGame::init() {
|
||||||
|
assertFlagOff(state, GAME_STATE_INITIALIZED, "Game already initialized?");
|
||||||
|
Flag::turnOn<uint8_t>(state, GAME_STATE_INITIALIZED);
|
||||||
|
|
||||||
auto selfAsGame = this->getSelfAsGame();
|
auto selfAsGame = this->getSelfAsGame();
|
||||||
|
|
||||||
renderHost = std::make_shared<RenderHost>();
|
renderHost = std::make_shared<RenderHost>();
|
||||||
@ -36,12 +40,29 @@ void IGame::init() {
|
|||||||
nextFrameScene = std::make_shared<Scene>(selfAsGame, initialScene);
|
nextFrameScene = std::make_shared<Scene>(selfAsGame, initialScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IGame::deinit() {
|
||||||
|
assertFlagOn(state, GAME_STATE_INITIALIZED, "Game not initialized?");
|
||||||
|
|
||||||
|
if(currentScene) currentScene->deinit();
|
||||||
|
currentScene = nullptr;
|
||||||
|
|
||||||
|
if(nextFrameScene) nextFrameScene->deinit();
|
||||||
|
nextFrameScene = nullptr;
|
||||||
|
|
||||||
|
physicsManager = nullptr;
|
||||||
|
assetManager = nullptr;
|
||||||
|
renderHost = nullptr;
|
||||||
|
|
||||||
|
Flag::turnOff<uint8_t>(state, GAME_STATE_INITIALIZED);
|
||||||
|
}
|
||||||
|
|
||||||
void IGame::update() {
|
void IGame::update() {
|
||||||
this->assetManager->update();
|
this->assetManager->update();
|
||||||
this->inputManager.update();
|
this->inputManager.update();
|
||||||
|
|
||||||
if(nextFrameScene) {
|
if(nextFrameScene) {
|
||||||
nextFrameScene->stage();
|
if(currentScene) currentScene->deinit();
|
||||||
|
nextFrameScene->init();
|
||||||
currentScene = nextFrameScene;
|
currentScene = nextFrameScene;
|
||||||
nextFrameScene = nullptr;
|
nextFrameScene = nullptr;
|
||||||
}
|
}
|
||||||
@ -67,8 +88,5 @@ std::shared_ptr<Game> IGame::getSelfAsGame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IGame::~IGame() {
|
IGame::~IGame() {
|
||||||
currentScene = nullptr;
|
assertFlagOff(state, GAME_STATE_INITIALIZED, "Game not deinited properly?");
|
||||||
nextFrameScene = nullptr;
|
|
||||||
assetManager = nullptr;
|
|
||||||
renderHost = nullptr;
|
|
||||||
}
|
}
|
@ -13,6 +13,8 @@
|
|||||||
#include "save/SaveManager.hpp"
|
#include "save/SaveManager.hpp"
|
||||||
#include "physics/PhysicsManager.hpp"
|
#include "physics/PhysicsManager.hpp"
|
||||||
|
|
||||||
|
#define GAME_STATE_INITIALIZED 0x01
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Scene;
|
class Scene;
|
||||||
class Game;
|
class Game;
|
||||||
@ -21,6 +23,7 @@ namespace Dawn {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<Scene> currentScene = nullptr;
|
std::shared_ptr<Scene> currentScene = nullptr;
|
||||||
std::shared_ptr<Scene> nextFrameScene = nullptr;
|
std::shared_ptr<Scene> nextFrameScene = nullptr;
|
||||||
|
uint8_t state = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -62,6 +65,11 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize the game and all of its components.
|
||||||
|
*/
|
||||||
|
void deinit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a single update tick on the game engine, and in turn all of
|
* Performs a single update tick on the game engine, and in turn all of
|
||||||
* the game's sub systems.
|
* the game's sub systems.
|
||||||
|
@ -232,38 +232,7 @@ void PhysicsManager::init(const std::shared_ptr<Game> &game) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
physicsSystem.SetBodyActivationListener(&bodyActivationListener);
|
physicsSystem.SetBodyActivationListener(&bodyActivationListener);
|
||||||
|
|
||||||
physicsSystem.SetContactListener(&contactListener);
|
physicsSystem.SetContactListener(&contactListener);
|
||||||
|
|
||||||
BodyInterface &bodyInterface = physicsSystem.GetBodyInterface();
|
|
||||||
|
|
||||||
BoxShapeSettings floorShapeSettings(Vec3(100.0f, 1.0f, 100.0f));
|
|
||||||
floorShapeSettings.SetEmbedded();
|
|
||||||
ShapeSettings::ShapeResult floorShapeResult = floorShapeSettings.Create();
|
|
||||||
ShapeRefC floorShape = floorShapeResult.Get();
|
|
||||||
BodyCreationSettings floorSettings(
|
|
||||||
floorShape,
|
|
||||||
RVec3(0.0_r, -1.0_r, 0.0_r),
|
|
||||||
Quat::sIdentity(),
|
|
||||||
EMotionType::Static,
|
|
||||||
Layers::NON_MOVING
|
|
||||||
);
|
|
||||||
Body *floor = bodyInterface.CreateBody(floorSettings);
|
|
||||||
bodyInterface.AddBody(floor->GetID(), EActivation::DontActivate);
|
|
||||||
|
|
||||||
// BodyCreationSettings sphereSettings(
|
|
||||||
// new SphereShape(0.5f),
|
|
||||||
// RVec3(0.0_r, 2.0_r, 0.0_r),
|
|
||||||
// Quat::sIdentity(),
|
|
||||||
// EMotionType::Dynamic,
|
|
||||||
// Layers::MOVING
|
|
||||||
// );
|
|
||||||
// sphereId = bodyInterface.CreateAndAddBody(
|
|
||||||
// sphereSettings,
|
|
||||||
// EActivation::Activate
|
|
||||||
// );
|
|
||||||
// bodyInterface.SetLinearVelocity(sphereId, Vec3(0.0f, -5.0f, 0.0f));
|
|
||||||
// physicsSystem.OptimizeBroadPhase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsManager::update() {
|
void PhysicsManager::update() {
|
||||||
|
@ -16,11 +16,22 @@ Scene::Scene(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::stage() {
|
void Scene::init() {
|
||||||
Scene &selfReference = *this;
|
Scene &selfReference = *this;
|
||||||
sceneInitializer(selfReference);
|
sceneInitializer(selfReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::deinit() {
|
||||||
|
if(!this->hasInitialized) return;
|
||||||
|
this->hasInitialized = false;
|
||||||
|
|
||||||
|
auto items = this->sceneItems;
|
||||||
|
for(auto &item : items) {
|
||||||
|
item->deinit();
|
||||||
|
}
|
||||||
|
sceneItems.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::update() {
|
void Scene::update() {
|
||||||
// Initialize new scene items
|
// Initialize new scene items
|
||||||
if(!hasInitialized) {
|
if(!hasInitialized) {
|
||||||
@ -34,8 +45,11 @@ void Scene::update() {
|
|||||||
auto itRemove = sceneItemsToRemove.begin();
|
auto itRemove = sceneItemsToRemove.begin();
|
||||||
while(itRemove != sceneItemsToRemove.end()) {
|
while(itRemove != sceneItemsToRemove.end()) {
|
||||||
auto item = *itRemove;
|
auto item = *itRemove;
|
||||||
|
item->deinit();
|
||||||
auto it = std::find(sceneItems.begin(), sceneItems.end(), item);
|
auto it = std::find(sceneItems.begin(), sceneItems.end(), item);
|
||||||
if(it != sceneItems.end()) sceneItems.erase(it);
|
if(it != sceneItems.end()) {
|
||||||
|
sceneItems.erase(it);
|
||||||
|
}
|
||||||
itRemove++;
|
itRemove++;
|
||||||
}
|
}
|
||||||
sceneItemsToRemove.clear();
|
sceneItemsToRemove.clear();
|
||||||
@ -63,8 +77,12 @@ std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Scene::removeItem(const std::shared_ptr<SceneItem> item) {
|
void Scene::removeItem(const std::shared_ptr<SceneItem> item) {
|
||||||
|
auto index = std::find(sceneItems.begin(), sceneItems.end(), item);
|
||||||
|
if(index == sceneItems.end()) return;
|
||||||
|
|
||||||
sceneItemsToRemove.push_back(item);
|
sceneItemsToRemove.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
|
this->deinit();
|
||||||
}
|
}
|
@ -44,7 +44,12 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Stages all of the scene items on the scene.
|
* Stages all of the scene items on the scene.
|
||||||
*/
|
*/
|
||||||
void stage();
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the scene is supposed to be deinitialized.
|
||||||
|
*/
|
||||||
|
void deinit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the game every frame that the scene is set as the currently
|
* Called by the game every frame that the scene is set as the currently
|
||||||
|
@ -57,17 +57,17 @@ bool_t SceneComponent::isInitialized() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SceneItem> SceneComponent::getItem() {
|
std::shared_ptr<SceneItem> SceneComponent::getItem() {
|
||||||
return this->item.lock();
|
auto item = this->item.lock();
|
||||||
|
assertNotNull(item, "SceneItem has unloaded?");
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Scene> SceneComponent::getScene() {
|
std::shared_ptr<Scene> SceneComponent::getScene() {
|
||||||
auto item = this->getItem();
|
return this->getItem()->getScene();
|
||||||
return item->getScene();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Game> SceneComponent::getGame() {
|
std::shared_ptr<Game> SceneComponent::getGame() {
|
||||||
auto scene = this->getScene();
|
return this->getScene()->getGame();
|
||||||
return scene->getGame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneComponent::~SceneComponent() {
|
SceneComponent::~SceneComponent() {
|
||||||
|
@ -20,7 +20,9 @@ std::shared_ptr<SceneItem> SceneItem::sceneItemComponentsSelf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Scene> SceneItem::getScene() {
|
std::shared_ptr<Scene> SceneItem::getScene() {
|
||||||
return scene.lock();
|
auto s = scene.lock();
|
||||||
|
assertNotNull(s, "Scene has unloaded?");
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneItem::init() {
|
void SceneItem::init() {
|
||||||
@ -50,6 +52,19 @@ void SceneItem::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneItem::deinit() {
|
||||||
|
// Create copy of the components, components may chose to add more components
|
||||||
|
// but those sub components will not be disposed at this time.
|
||||||
|
auto components = this->components;
|
||||||
|
|
||||||
|
for(auto &component : components) {
|
||||||
|
if(!component->isInitialized()) continue;
|
||||||
|
component->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->components.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void SceneItem::remove() {
|
void SceneItem::remove() {
|
||||||
auto scene = getScene();
|
auto scene = getScene();
|
||||||
if(!scene) return;
|
if(!scene) return;
|
||||||
@ -57,11 +72,5 @@ void SceneItem::remove() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneItem::~SceneItem() {
|
SceneItem::~SceneItem() {
|
||||||
std::for_each(
|
this->deinit();
|
||||||
components.begin(),
|
|
||||||
components.end(),
|
|
||||||
[](auto &component) {
|
|
||||||
component->dispose();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
@ -35,6 +35,12 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the scene item is supposed to deinitialize. Should happen
|
||||||
|
* when the scene item is removed from the scene.
|
||||||
|
*/
|
||||||
|
void deinit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scene that this scene item belongs to.
|
* Returns the scene that this scene item belongs to.
|
||||||
*
|
*
|
||||||
|
@ -103,7 +103,7 @@ void RenderHost::update(const std::shared_ptr<Game> game) {
|
|||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
assertNoGLError();
|
assertNoGLError();
|
||||||
|
|
||||||
// glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
assertNoGLError();
|
assertNoGLError();
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -73,6 +73,7 @@ int32_t main(int32_t argc, const char **argv) {
|
|||||||
game->update();
|
game->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game->deinit();
|
||||||
game = nullptr;
|
game = nullptr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -11,17 +11,44 @@
|
|||||||
#include "component/display/material/SimpleTexturedMaterial.hpp"
|
#include "component/display/material/SimpleTexturedMaterial.hpp"
|
||||||
#include "component/display/MeshRenderer.hpp"
|
#include "component/display/MeshRenderer.hpp"
|
||||||
#include "display/mesh/CubeMesh.hpp"
|
#include "display/mesh/CubeMesh.hpp"
|
||||||
#include "component/physics/BoxCollider.hpp"
|
#include "display/mesh/SphereMesh.hpp"
|
||||||
|
#include "component/physics/CubeCollider.hpp"
|
||||||
|
#include "component/physics/SphereCollider.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
void Dawn::helloWorldScene(Scene &s) {
|
void Dawn::helloWorldScene(Scene &s) {
|
||||||
auto cameraItem = s.createSceneItem();
|
auto cameraItem = s.createSceneItem();
|
||||||
auto camera = cameraItem->addComponent<Camera>();
|
auto camera = cameraItem->addComponent<Camera>();
|
||||||
cameraItem->lookAt({ 5, 5, 5 }, { 0, 0, 0 }, { 0, 1, 0 });
|
cameraItem->lookAt({ 20, 20, 20 }, { 0, 0, 0 }, { 0, 1, 0 });
|
||||||
camera->clipFar = 99999.99f;
|
camera->clipFar = 99999.99f;
|
||||||
|
|
||||||
// Ground
|
// Ground
|
||||||
|
{
|
||||||
|
// Create the scene item.
|
||||||
|
auto groundItem = s.createSceneItem();
|
||||||
|
groundItem->setLocalPosition(glm::vec3(0, 0, 0));
|
||||||
|
|
||||||
|
// Create a simple cube mesh.
|
||||||
|
auto groundMesh = std::make_shared<Mesh>();
|
||||||
|
groundMesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
|
||||||
|
CubeMesh::buffer(groundMesh, glm::vec3(-15, -1, -15), glm::vec3(30, 2, 30), 0, 0);
|
||||||
|
|
||||||
|
// Add a renderer to the scene item.
|
||||||
|
auto groundMeshRenderer = groundItem->addComponent<MeshRenderer>();
|
||||||
|
groundMeshRenderer->mesh = groundMesh;
|
||||||
|
|
||||||
|
// Add a material to the scene item.
|
||||||
|
auto groundMaterial = groundItem->addComponent<SimpleTexturedMaterial>();
|
||||||
|
groundMaterial->setColor(COLOR_LIGHT_GREY);
|
||||||
|
|
||||||
|
// Add collider
|
||||||
|
auto groundCollider = groundItem->addComponent<CubeCollider>();
|
||||||
|
groundCollider->setColliderType(ColliderType::STATIC);
|
||||||
|
groundCollider->setShape(glm::vec3(15, 1, 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box
|
||||||
{
|
{
|
||||||
// Create the scene item.
|
// Create the scene item.
|
||||||
auto cubeItem = s.createSceneItem();
|
auto cubeItem = s.createSceneItem();
|
||||||
@ -41,13 +68,14 @@ void Dawn::helloWorldScene(Scene &s) {
|
|||||||
cubeMaterial->setColor(COLOR_MAGENTA);
|
cubeMaterial->setColor(COLOR_MAGENTA);
|
||||||
|
|
||||||
// Add collider
|
// Add collider
|
||||||
auto boxCollider = cubeItem->addComponent<BoxCollider>();
|
auto cubeCollider = cubeItem->addComponent<CubeCollider>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Other Box
|
||||||
{
|
{
|
||||||
// Create the scene item.
|
// Create the scene item.
|
||||||
auto cubeItem = s.createSceneItem();
|
auto cubeItem = s.createSceneItem();
|
||||||
cubeItem->setLocalPosition(glm::vec3(0.88f, 13, 0.1f));
|
cubeItem->setLocalPosition(glm::vec3(0.75f, 15, 0.1f));
|
||||||
|
|
||||||
// Create a simple cube mesh.
|
// Create a simple cube mesh.
|
||||||
auto cubeMesh = std::make_shared<Mesh>();
|
auto cubeMesh = std::make_shared<Mesh>();
|
||||||
@ -63,6 +91,28 @@ void Dawn::helloWorldScene(Scene &s) {
|
|||||||
cubeMaterial->setColor(COLOR_MAGENTA);
|
cubeMaterial->setColor(COLOR_MAGENTA);
|
||||||
|
|
||||||
// Add collider
|
// Add collider
|
||||||
auto boxCollider = cubeItem->addComponent<BoxCollider>();
|
auto cubeCollider = cubeItem->addComponent<CubeCollider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ball
|
||||||
|
{
|
||||||
|
// Create the scene item.
|
||||||
|
auto sphereItem = s.createSceneItem();
|
||||||
|
sphereItem->setLocalPosition(glm::vec3(-1.0f, 13, -0.6f));
|
||||||
|
|
||||||
|
// Create a simple cube mesh.
|
||||||
|
auto sphereMesh = std::make_shared<Mesh>();
|
||||||
|
SphereMesh::create(sphereMesh, 1.0f);
|
||||||
|
|
||||||
|
// Add a renderer to the scene item.
|
||||||
|
auto sphereMeshRenderer = sphereItem->addComponent<MeshRenderer>();
|
||||||
|
sphereMeshRenderer->mesh = sphereMesh;
|
||||||
|
|
||||||
|
// Add a material to the scene item.
|
||||||
|
auto sphereMaterial = sphereItem->addComponent<SimpleTexturedMaterial>();
|
||||||
|
sphereMaterial->setColor(COLOR_CYAN);
|
||||||
|
|
||||||
|
// Add collider
|
||||||
|
auto sphereCollider = sphereItem->addComponent<SphereCollider>();
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user