forked from Revolutionary-Games/Thrive
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Revolutionary-Games#26 from Revolutionary-Games/14…
…_camera Scriptable Cameras
- Loading branch information
Showing
11 changed files
with
370 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
local playerCam = Entity("playerCam") | ||
|
||
-- Camera | ||
playerCam.camera = OgreCameraComponent("playerCam") | ||
playerCam:addComponent(playerCam.camera) | ||
-- Scene node | ||
playerCam.sceneNode = OgreSceneNodeComponent() | ||
playerCam:addComponent(playerCam.sceneNode) | ||
-- Transform | ||
playerCam.transform = TransformComponent() | ||
playerCam:addComponent(playerCam.transform) | ||
|
||
playerCam.camera.workingCopy.nearClipDistance = 5 | ||
playerCam.camera:touch() | ||
|
||
playerCam.transform.workingCopy.position.z = 30 | ||
playerCam.transform:touch() | ||
|
||
-- OnUpdate | ||
playerCam.onUpdate = OnUpdateComponent() | ||
playerCam:addComponent(playerCam.onUpdate) | ||
local time = 0 | ||
playerCam.onUpdate.callback = function(entityId, milliseconds) | ||
time = time + milliseconds / 1000 | ||
playerCam.transform.workingCopy.position.z = 25 + 5 * math.sin(time) | ||
playerCam.transform:touch() | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
background.lua | ||
camera.lua | ||
light.lua | ||
player.lua |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#include "ogre/camera_system.h" | ||
|
||
#include "engine/component_registry.h" | ||
#include "engine/entity_filter.h" | ||
#include "ogre/ogre_engine.h" | ||
#include "ogre/scene_node_system.h" | ||
#include "scripting/luabind.h" | ||
|
||
#include <iostream> | ||
#include <OgreSceneManager.h> | ||
#include <OgreCamera.h> | ||
|
||
using namespace thrive; | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// OgreCameraComponent | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
static void | ||
OgreCameraComponent_touch( | ||
OgreCameraComponent* self | ||
) { | ||
return self->m_properties.touch(); | ||
} | ||
|
||
|
||
static OgreCameraComponent::Properties& | ||
OgreCameraComponent_getWorkingCopy( | ||
OgreCameraComponent* self | ||
) { | ||
return self->m_properties.workingCopy(); | ||
} | ||
|
||
|
||
static const OgreCameraComponent::Properties& | ||
OgreCameraComponent_getLatest( | ||
OgreCameraComponent* self | ||
) { | ||
return self->m_properties.latest(); | ||
} | ||
|
||
|
||
luabind::scope | ||
OgreCameraComponent::luaBindings() { | ||
using namespace luabind; | ||
return class_<OgreCameraComponent, Component, std::shared_ptr<Component>>("OgreCameraComponent") | ||
.scope [ | ||
def("TYPE_NAME", &OgreCameraComponent::TYPE_NAME), | ||
def("TYPE_ID", &OgreCameraComponent::TYPE_ID), | ||
class_<Properties>("Properties") | ||
.def_readwrite("polygonMode", &Properties::polygonMode) | ||
.def_readwrite("fovY", &Properties::fovY) | ||
.def_readwrite("nearClipDistance", &Properties::nearClipDistance) | ||
.def_readwrite("farClipDistance", &Properties::farClipDistance) | ||
.def_readwrite("aspectRatio", &Properties::aspectRatio) | ||
] | ||
.enum_("PolygonMode") [ | ||
value("PM_POINTS", Ogre::PM_POINTS), | ||
value("PM_WIREFRAME", Ogre::PM_WIREFRAME), | ||
value("PM_SOLID", Ogre::PM_SOLID) | ||
] | ||
.def(constructor<std::string>()) | ||
.property("latest", OgreCameraComponent_getLatest) | ||
.property("workingCopy", OgreCameraComponent_getWorkingCopy) | ||
.def("touch", OgreCameraComponent_touch) | ||
; | ||
} | ||
|
||
OgreCameraComponent::OgreCameraComponent( | ||
std::string name | ||
) : m_name(name) | ||
{ | ||
} | ||
|
||
REGISTER_COMPONENT(OgreCameraComponent) | ||
|
||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// OgreCameraSystem | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
struct OgreCameraSystem::Implementation { | ||
|
||
std::unordered_map<EntityId, Ogre::Camera*> m_cameras; | ||
|
||
Ogre::SceneManager* m_sceneManager = nullptr; | ||
|
||
EntityFilter< | ||
OgreSceneNodeComponent, | ||
OgreCameraComponent | ||
> m_entities = {true}; | ||
}; | ||
|
||
|
||
OgreCameraSystem::OgreCameraSystem() | ||
: m_impl(new Implementation()) | ||
{ | ||
} | ||
|
||
|
||
OgreCameraSystem::~OgreCameraSystem() {} | ||
|
||
|
||
void | ||
OgreCameraSystem::init( | ||
Engine* engine | ||
) { | ||
System::init(engine); | ||
assert(m_impl->m_sceneManager == nullptr && "Double init of system"); | ||
OgreEngine* ogreEngine = dynamic_cast<OgreEngine*>(engine); | ||
assert(ogreEngine != nullptr && "System requires an OgreEngine"); | ||
m_impl->m_sceneManager = ogreEngine->sceneManager(); | ||
m_impl->m_entities.setEngine(engine); | ||
} | ||
|
||
|
||
void | ||
OgreCameraSystem::shutdown() { | ||
m_impl->m_entities.setEngine(nullptr); | ||
m_impl->m_sceneManager = nullptr; | ||
System::shutdown(); | ||
} | ||
|
||
|
||
void | ||
OgreCameraSystem::update(int) { | ||
for (auto& value : m_impl->m_entities.addedEntities()) { | ||
EntityId entityId = value.first; | ||
OgreSceneNodeComponent* sceneNodeComponent = std::get<0>(value.second); | ||
OgreCameraComponent* cameraComponent = std::get<1>(value.second); | ||
Ogre::Camera* camera = m_impl->m_sceneManager->createCamera( | ||
cameraComponent->m_name | ||
); | ||
cameraComponent->m_camera = camera; | ||
m_impl->m_cameras[entityId] = camera; | ||
sceneNodeComponent->m_sceneNode->attachObject(camera); | ||
// Test code for scriptable cameras | ||
// TODO: Remove this when scriptable viewports are available (#24) | ||
OgreEngine* ogreEngine = dynamic_cast<OgreEngine*>(this->engine()); | ||
ogreEngine->viewport()->setCamera(camera); | ||
} | ||
for (EntityId entityId : m_impl->m_entities.removedEntities()) { | ||
Ogre::Camera* camera = m_impl->m_cameras[entityId]; | ||
Ogre::SceneNode* sceneNode = camera->getParentSceneNode(); | ||
sceneNode->detachObject(camera); | ||
m_impl->m_sceneManager->destroyCamera(camera); | ||
m_impl->m_cameras.erase(entityId); | ||
} | ||
m_impl->m_entities.clearChanges(); | ||
for (auto& value : m_impl->m_entities) { | ||
OgreCameraComponent* cameraComponent = std::get<1>(value.second); | ||
if (cameraComponent->m_properties.hasChanges()) { | ||
const auto& properties = cameraComponent->m_properties.stable(); | ||
Ogre::Camera* camera = cameraComponent->m_camera; | ||
// Update camera | ||
camera->setPolygonMode(properties.polygonMode); | ||
camera->setFOVy(properties.fovY); | ||
camera->setNearClipDistance(properties.nearClipDistance); | ||
camera->setFarClipDistance(properties.farClipDistance); | ||
camera->setAspectRatio(properties.aspectRatio); | ||
// Untouch | ||
cameraComponent->m_properties.untouch(); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#pragma once | ||
|
||
#include "engine/component.h" | ||
#include "engine/shared_data.h" | ||
#include "engine/system.h" | ||
|
||
#include <memory> | ||
#include <OgreCommon.h> | ||
#include <OgreMath.h> | ||
|
||
namespace luabind { | ||
class scope; | ||
} | ||
|
||
namespace Ogre { | ||
class Camera; | ||
} | ||
|
||
namespace thrive { | ||
|
||
/** | ||
* @brief A component for a camera | ||
* | ||
*/ | ||
class OgreCameraComponent : public Component { | ||
COMPONENT(OgreCamera) | ||
|
||
public: | ||
|
||
/** | ||
* @brief Properties | ||
*/ | ||
struct Properties { | ||
/** | ||
* @brief The level of rendering detail | ||
*/ | ||
Ogre::PolygonMode polygonMode = Ogre::PM_SOLID; | ||
|
||
/** | ||
* @brief The y-dimension field of view | ||
*/ | ||
Ogre::Radian fovY = Ogre::Radian{45.0f}; | ||
/** | ||
* @brief Near clip distance | ||
*/ | ||
Ogre::Real nearClipDistance = 100.0f; | ||
/** | ||
* @brief Far clip distance | ||
*/ | ||
Ogre::Real farClipDistance = 10000.0f; | ||
/** | ||
* @brief Aspect ratio of the frustum viewport | ||
*/ | ||
Ogre::Real aspectRatio = 1.3333f; | ||
}; | ||
|
||
/** | ||
* @brief Lua bindings | ||
* | ||
* Exposes the following \ref shared_data_lua shared properties: | ||
* - \c Properties::polygonMode | ||
* - \c Properties::fovY | ||
* - \c Properties::nearClipDistance | ||
* - \c Properties::farClipDistance | ||
* - \c Properties::aspectRatio | ||
* | ||
* @return | ||
*/ | ||
static luabind::scope | ||
luaBindings(); | ||
|
||
/** | ||
* @brief Constructor | ||
* | ||
* @param name | ||
* The camera's name | ||
*/ | ||
OgreCameraComponent( | ||
std::string name | ||
); | ||
|
||
Ogre::Camera* m_camera = nullptr; | ||
|
||
/** | ||
* @brief The camera's name | ||
*/ | ||
const std::string m_name; | ||
|
||
/** | ||
* @brief Shared properties | ||
*/ | ||
RenderData<Properties> | ||
m_properties; | ||
|
||
}; | ||
|
||
|
||
/** | ||
* @brief Creates, updates and removes cameras | ||
*/ | ||
class OgreCameraSystem : public System { | ||
|
||
public: | ||
|
||
/** | ||
* @brief Constructor | ||
*/ | ||
OgreCameraSystem(); | ||
|
||
/** | ||
* @brief Destructor | ||
*/ | ||
~OgreCameraSystem(); | ||
|
||
/** | ||
* @brief Initializes the system | ||
* | ||
* @param engine | ||
* Must be an OgreEngine | ||
*/ | ||
void init(Engine* engine) override; | ||
|
||
/** | ||
* @brief Shuts the system down | ||
*/ | ||
void shutdown() override; | ||
|
||
/** | ||
* @brief Updates the system | ||
*/ | ||
void update(int) override; | ||
|
||
private: | ||
|
||
struct Implementation; | ||
std::unique_ptr<Implementation> m_impl; | ||
}; | ||
|
||
} | ||
|
Oops, something went wrong.