adding and integrating ImGuizmo
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include <sophia/entity.hpp>
|
||||
#include <sophia/handles.hpp>
|
||||
#include <sophia/scene.hpp>
|
||||
#include <sophia/scene_registry.hpp>
|
||||
#include <sophia/scene_view_registry.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* What the editor is working on, shared by its panels. Panels read it every
|
||||
* frame instead of holding on to a scene, so switching scenes is one call.
|
||||
*/
|
||||
class EditorContext {
|
||||
public:
|
||||
// A scene the editor has open, and can switch to.
|
||||
struct OpenScene {
|
||||
sophia::SceneHandle handle;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
explicit EditorContext(sophia::SceneRegistry& scenes) : scenes{scenes} {}
|
||||
|
||||
// Creates an open scene with a "Main Camera", without switching to it.
|
||||
sophia::SceneHandle createScene(std::string name) {
|
||||
sophia::SceneHandle handle = scenes.create();
|
||||
scenes.get(handle).createCamera("Main Camera");
|
||||
openScenes.push_back({handle, std::move(name)});
|
||||
return handle;
|
||||
}
|
||||
|
||||
const std::vector<OpenScene>& getOpenScenes() const { return openScenes; }
|
||||
|
||||
// Null if `handle` isn't an open scene.
|
||||
const std::string* getSceneName(sophia::SceneHandle handle) const {
|
||||
for (const OpenScene& open : openScenes) {
|
||||
if (open.handle == handle) {
|
||||
return &open.name;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void renameScene(sophia::SceneHandle handle, std::string name) {
|
||||
for (OpenScene& open : openScenes) {
|
||||
if (open.handle == handle) {
|
||||
open.name = std::move(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasScene() const { return scenes.isAlive(activeScene); }
|
||||
sophia::SceneHandle getSceneHandle() const { return activeScene; }
|
||||
sophia::Scene& getScene() { return scenes.get(activeScene); }
|
||||
|
||||
// Also clears the selection, which belonged to the previous scene.
|
||||
void setScene(sophia::SceneHandle handle) {
|
||||
activeScene = handle;
|
||||
selected = {};
|
||||
}
|
||||
|
||||
// Null when nothing is selected. Always an entity of the active scene.
|
||||
sophia::Entity selected;
|
||||
|
||||
private:
|
||||
sophia::SceneRegistry& scenes;
|
||||
sophia::SceneHandle activeScene = sophia::INVALID_HANDLE;
|
||||
// Kept open even when not active: with no saving yet, closing one would
|
||||
// lose it.
|
||||
std::vector<OpenScene> openScenes;
|
||||
};
|
||||
|
||||
// Points `view` at the context's active scene, and renders it only while
|
||||
// there is one and its panel is `shown`. Call every frame from the panel that
|
||||
// owns the view.
|
||||
inline void syncSceneView(EditorContext& context,
|
||||
sophia::SceneViewRegistry& sceneViews,
|
||||
sophia::SceneViewHandle view, bool shown) {
|
||||
bool enabled = shown && context.hasScene();
|
||||
const sophia::SceneView& current = sceneViews.peek(view);
|
||||
// get() re-sorts the render queue, so only use it when something changed.
|
||||
if (current.enabled != enabled ||
|
||||
(context.hasScene() && current.scene != context.getSceneHandle())) {
|
||||
sophia::SceneView& updated = sceneViews.get(view);
|
||||
updated.enabled = enabled;
|
||||
updated.scene = context.getSceneHandle();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user