Added camera relative UI support.

This commit is contained in:
2023-03-08 17:37:08 -08:00
parent 186ac8bc3f
commit 326e42bef3
9 changed files with 76 additions and 39 deletions

View File

@ -134,21 +134,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
auto canvas = *itCanvas; auto canvas = *itCanvas;
glm::mat4 projection; glm::mat4 projection;
glm::mat4 view; glm::mat4 view;
canvas->getProjectionAndView(&projection, &view);
switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
projection = camera->getProjection();
view = camera->transform->getWorldTransform();
break;
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
projection = glm::ortho(0.0f, renderTarget->getWidth(), renderTarget->getHeight(), 0.0f);
view = glm::mat4(1.0f);
break;
default:
assertUnreachable();
}
auto renderables = canvas->item->findChildrenDeep<UIComponentRenderable>(); auto renderables = canvas->item->findChildrenDeep<UIComponentRenderable>();
auto itChild = renderables.begin(); auto itChild = renderables.begin();

View File

@ -36,6 +36,31 @@ float_t UICanvas::getContentHeight() {
return this->getHeight(); return this->getHeight();
} }
void UICanvas::getProjectionAndView(glm::mat4 *proj, glm::mat4 *view) {
assertNotNull(proj);
assertNotNull(view);
switch(this->drawType) {
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
*proj = camera->getProjection();
*view = camera->transform->getWorldTransform();
break;
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
*proj = glm::ortho(
0.0f,
camera->getRenderTarget()->getWidth(),
camera->getRenderTarget()->getHeight(),
0.0f
);
*view = glm::mat4(1.0f);
break;
default:
assertUnreachable();
}
}
void UICanvas::onStart() { void UICanvas::onStart() {
if(camera == nullptr) camera = getScene()->findComponent<Camera>(); if(camera == nullptr) camera = getScene()->findComponent<Camera>();

View File

@ -64,7 +64,7 @@ namespace Dawn {
//======================================================================// //======================================================================//
StateProperty<Camera*> camera; StateProperty<Camera*> camera;
enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_ABSOLUTE; enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
/** /**
* Constructs the UI Canvas Scene Item Component. * Constructs the UI Canvas Scene Item Component.
@ -73,6 +73,14 @@ namespace Dawn {
*/ */
UICanvas(SceneItem *item); UICanvas(SceneItem *item);
/**
* Return the type of projection and view matrixes are used.
*
* @param proj Projection matrix output.
* @param view View matrix ouput.
*/
void getProjectionAndView(glm::mat4 *proj, glm::mat4 *view);
float_t getWidth() override; float_t getWidth() override;
float_t getHeight() override; float_t getHeight() override;
float_t getContentWidth() override; float_t getContentWidth() override;

View File

@ -54,6 +54,7 @@ void UIMenuController::onStart() {
menuY = mathClamp<int32_t>(menuY-1, 0, rows); menuY = mathClamp<int32_t>(menuY-1, 0, rows);
break; break;
case INPUT_BIND_ACCEPT: case INPUT_BIND_ACCEPT:
case INPUT_BIND_MOUSE_CLICK:
eventItemSelected.invoke(menuX, menuY); eventItemSelected.invoke(menuX, menuY);
break; break;
case INPUT_BIND_CANCEL: case INPUT_BIND_CANCEL:

View File

@ -22,10 +22,7 @@ namespace Dawn {
StateEvent<int32_t, int32_t> eventItemSelected; StateEvent<int32_t, int32_t> eventItemSelected;
StateEvent<> eventMenuCancel; StateEvent<> eventMenuCancel;
void moveRelative(int32_t x, int32_t y);
UIMenuController(SceneItem *item); UIMenuController(SceneItem *item);
void onStart() override;
void onStart();
}; };
} }

View File

@ -62,19 +62,32 @@ void UISimpleMenu::onStart() {
assertNotNull(canvas->camera); assertNotNull(canvas->camera);
if(!this->menu->active) return; if(!this->menu->active) return;
// Mouse in screen space.
auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y); auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
mouse *= 2.0f;
mouse -= glm::vec2(1, 1);
struct Ray3D ray;
ray.origin = canvas->camera->transform->getWorldPosition();
ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
switch(canvas->drawType) { switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE: case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
break; case UI_DRAW_TYPE_WORLD_ABSOLUTE: {
case UI_DRAW_TYPE_WORLD_ABSOLUTE: // Calculate ray
struct Ray3D ray;
switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
mouse *= 2.0f;
mouse -= glm::vec2(1, 1);
ray.origin = canvas->camera->transform->getWorldPosition();
ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
break;
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
RenderTarget *rt = canvas->camera->getRenderTarget();
mouse *= glm::vec2(rt->getWidth(), rt->getHeight());
ray.origin = glm::vec3(mouse, 5);
ray.direction = glm::vec3(0, 0, -10);
break;
}
// Find mouse item
auto itItems = menuItems.begin(); auto itItems = menuItems.begin();
while(itItems != menuItems.end()) { while(itItems != menuItems.end()) {
auto item = *itItems; auto item = *itItems;
@ -90,7 +103,7 @@ void UISimpleMenu::onStart() {
glm::vec3 normal; glm::vec3 normal;
float_t distance; float_t distance;
// TODO: Include Z axis. // TODO: Include Z axis for determining which item is hovered.
if(!raytestQuad( if(!raytestQuad(
ray, ray,
glm::vec2(0, 0), size, glm::vec2(0, 0), size,
@ -105,6 +118,11 @@ void UISimpleMenu::onStart() {
break; break;
} }
break; break;
}
default: {
assertUnreachable();
}
} }
}, getScene()->eventSceneUnpausedUpdate); }, getScene()->eventSceneUnpausedUpdate);
} }

View File

@ -17,7 +17,6 @@ namespace Dawn {
public: public:
UISimpleMenu(SceneItem *item); UISimpleMenu(SceneItem *item);
std::vector<SceneItemComponent*> getDependencies() override; std::vector<SceneItemComponent*> getDependencies() override;
void onStart() override; void onStart() override;
}; };

View File

@ -12,14 +12,19 @@ namespace Dawn {
StateEvent<> eventHoveredOn; StateEvent<> eventHoveredOn;
StateEvent<> eventHoveredOff; StateEvent<> eventHoveredOff;
StateEvent<> eventSelected; StateEvent<> eventSelected;
// May make these into either state events or make a new event. // May make these into either state events or make a new event.
int32_t menuX; int32_t menuX = 0;
int32_t menuY; int32_t menuY = 0;
UIComponent *uiComponent = nullptr; UIComponent *uiComponent = nullptr;
UISimpleMenuItem(SceneItem *item); UISimpleMenuItem(SceneItem *item);
/**
* Returns the UI component that this simple UI menu item uses to figure
* out if it is being hovered over currently or not.
*
* @return UI Component to use for highlighting / hovering.
*/
virtual UIComponent * getComponentForHighlighting(); virtual UIComponent * getComponentForHighlighting();
}; };
} }

View File

@ -24,7 +24,7 @@ namespace Dawn {
void stage() override { void stage() override {
camera = Camera::create(this); camera = Camera::create(this);
// camera->transform->lookAt(glm::vec3(0, 0, 8), glm::vec3(0, 0, 0)); // camera->transform->lookAt(glm::vec3(0, 0, 8), glm::vec3(0, 0, 0));
camera->transform->lookAt(glm::vec3(3, 3, 3), glm::vec3(0, 0, 0)); camera->transform->lookAt(glm::vec3(32, 32, 32), glm::vec3(0, 0, 0));
float_t s = 2.0f; float_t s = 2.0f;
camera->orthoTop = s; camera->orthoTop = s;
@ -59,8 +59,7 @@ namespace Dawn {
label->font = &this->game->assetManager.get<TrueTypeAsset>("truetype_bizudp")->font; label->font = &this->game->assetManager.get<TrueTypeAsset>("truetype_bizudp")->font;
label->text = "Item " + std::to_string(x) + ", " + std::to_string(y); label->text = "Item " + std::to_string(x) + ", " + std::to_string(y);
// label->fontSize = 36.0f; label->fontSize = 36.0f;
label->fontSize = 1.0f;
labelItem->transform.setParent(canvas->transform); labelItem->transform.setParent(canvas->transform);
label->alignment = glm::vec4(label->fontSize * 8 * x, label->fontSize * 1.5f * y, 350, 100); label->alignment = glm::vec4(label->fontSize * 8 * x, label->fontSize * 1.5f * y, 350, 100);
@ -69,7 +68,6 @@ namespace Dawn {
labelMenuItem->menuX = x; labelMenuItem->menuX = x;
labelMenuItem->menuY = y; labelMenuItem->menuY = y;
useEvent(std::bind([&](UISimpleMenuItem *itm){ useEvent(std::bind([&](UISimpleMenuItem *itm){
std::cout << "Hover on " << std::to_string(itm->menuX) << ", " << std::to_string(itm->menuY) << std::endl; std::cout << "Hover on " << std::to_string(itm->menuX) << ", " << std::to_string(itm->menuY) << std::endl;
}, labelMenuItem), labelMenuItem->eventHoveredOn); }, labelMenuItem), labelMenuItem->eventHoveredOn);