Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions TombEngine/Game/Hud/DrawItems/DisplayItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,28 @@ namespace TEN::Hud
return true;
}

bool DisplayItem::HasScissor() const
{
return _hasScissor;
}

void DisplayItem::SetScissor(const TEN::Renderer::Structures::RendererRectangle& rect)
{
_hasScissor = true;
_scissorRect = rect;
}

void DisplayItem::ClearScissor()
{
_hasScissor = false;
_scissorRect = {};
}

const TEN::Renderer::Structures::RendererRectangle& DisplayItem::GetScissorRect() const
{
return _scissorRect;
}

void DisplayItem::StoreInterpolationData()
{
_prevPosition = _position;
Expand Down
8 changes: 8 additions & 0 deletions TombEngine/Game/Hud/DrawItems/DisplayItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Math/Constants.h"
#include "Objects/game_object_ids.h"
#include "Renderer/Structures/RendererRectangle.h"
#include "Specific/Structures/BitField.h"

using namespace TEN::Math;
Expand Down Expand Up @@ -34,6 +35,9 @@ namespace TEN::Hud
int _frameNumber = 0;
int _prevFrameNumber = 0;

bool _hasScissor = false;
TEN::Renderer::Structures::RendererRectangle _scissorRect = {};

Vector3 _prevPosition = Vector3::Zero;
EulerAngles _prevOrientation = EulerAngles::Identity;
Vector3 _prevScale = Vector3::Zero;
Expand Down Expand Up @@ -92,9 +96,13 @@ namespace TEN::Hud
// Inquirers

bool MeshExists(int meshIndex) const;
bool HasScissor() const;

// Utilities

void SetScissor(const TEN::Renderer::Structures::RendererRectangle& rect);
void ClearScissor();
const TEN::Renderer::Structures::RendererRectangle& GetScissorRect() const;
void StoreInterpolationData();
};
}
9 changes: 9 additions & 0 deletions TombEngine/Renderer/RendererDrawMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,11 @@ namespace TEN::Renderer
if (color.A() <= EPSILON)
return;

// Apply scissor rect if set.
bool hasScissor = item.HasScissor();
if (hasScissor)
SetScissor(item.GetScissorRect());

auto objectNumber = item.GetObjectID();
auto pos = item.GetInterpolatedPosition(alpha);
auto orient = item.GetInterpolatedOrientation(alpha);
Expand Down Expand Up @@ -1165,6 +1170,10 @@ namespace TEN::Renderer
}
}
}

// Reset scissor rect if it was set.
if (hasScissor)
ResetScissor();
}

void Renderer::RenderTitleImage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ namespace TEN::Scripting::DisplayArea
}

/// Add a display item to the area.
// Items can be View.DisplayString or View.DisplaySprite objects.
// Items can be View.DisplayString, View.DisplaySprite, or View.DisplayItem objects.
// Arguments are forwarded to the item's Draw() method.
// @function DisplayArea:AddItem
// @tparam object item A DisplayString or DisplaySprite to clip within this area.
// @tparam object item A DisplayString, DisplaySprite, or DisplayItem to clip within this area.
// @tparam[opt] table args Draw arguments forwarded to the item, e.g. { priority, alignMode, scaleMode, blendMode }.
void ScriptDisplayArea::AddItem(sol::object item, sol::optional<sol::table> args)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Scripting/Internal/TEN/Types/Rotation/Rotation.h"
#include "Scripting/Internal/TEN/Types/Vec2/Vec2.h"
#include "Scripting/Internal/TEN/Types/Vec3/Vec3.h"
#include "Scripting/Internal/TEN/View/DisplayAnchors/ScriptDisplayAnchors.h"
#include "Specific/configuration.h"

using namespace TEN::Effects::DisplaySprite;
Expand Down Expand Up @@ -64,6 +65,7 @@ namespace TEN::Scripting::DisplayItem

ScriptReserved_GetEndFrame, &ScriptDisplayItem::GetEndFrame,
ScriptReserved_GetBounds, &ScriptDisplayItem::GetBounds,
ScriptReserved_DisplayStringGetAnchors, &ScriptDisplayItem::GetAnchors,

ScriptReserved_DisplayItemSetAmbientLight, &ScriptDisplayItem::SetAmbientLight,
ScriptReserved_DisplayItemSetCamera, &ScriptDisplayItem::SetCameraPosition,
Expand Down Expand Up @@ -540,13 +542,73 @@ namespace TEN::Scripting::DisplayItem
return sol::nullopt;
}

/// Get the anchor points of the display item's projected bounding box.
// Projects the display item into 2D screen space and returns 9 anchor points
// (corners, edge midpoints, and center) as percent coordinates.
// @function DisplayItem:GetAnchors
// @treturn[1] View.DisplayAnchors An object containing the anchor points.
// @treturn[2] DisplayAnchors with default (zero) values if the display item does not exist or has no bounds.
// @usage
// local anchors = item:GetAnchors()
// print("Center: " .. tostring(anchors.CENTER))
ScriptDisplayAnchors ScriptDisplayItem::GetAnchors() const
{
ScriptDisplayAnchors anchors;

if (auto* item = TryGetItem())
{
auto bounds = item->GetBounds();
if (!bounds.has_value())
return anchors;

float screenWidth = (float)g_Configuration.ScreenWidth;
float screenHeight = (float)g_Configuration.ScreenHeight;

const auto& center = bounds->first;
const auto& size = bounds->second;

// Calculate half extents.
float halfW = size.x * 0.5f;
float halfH = size.y * 0.5f;

// Helper lambda for percent conversion with rounding.
auto toPercent = [&](float x, float y) -> Vec2
{
return Vec2(
std::round((x / screenWidth) * 10000.0f) / 100.0f,
std::round((y / screenHeight) * 10000.0f) / 100.0f);
};

// Populate anchors from axis-aligned bounding box.
anchors.TOP_LEFT = toPercent(center.x - halfW, center.y - halfH);
anchors.TOP_CENTER = toPercent(center.x, center.y - halfH);
anchors.TOP_RIGHT = toPercent(center.x + halfW, center.y - halfH);
anchors.CENTER_LEFT = toPercent(center.x - halfW, center.y);
anchors.CENTER = toPercent(center.x, center.y);
anchors.CENTER_RIGHT = toPercent(center.x + halfW, center.y);
anchors.BOTTOM_LEFT = toPercent(center.x - halfW, center.y + halfH);
anchors.BOTTOM_CENTER = toPercent(center.x, center.y + halfH);
anchors.BOTTOM_RIGHT = toPercent(center.x + halfW, center.y + halfH);
}

return anchors;
}

/// Draw the display item in display space for the current frame.
// @function DisplayItem:Draw
// @usage
// item:Draw()
void ScriptDisplayItem::Draw()
{
if (auto* item = TryGetItem())
{
item->SetVisible(true);

// Capture active scissor state (set by DisplayArea).
if (HasActiveDisplayScissor())
item->SetScissor(GetActiveDisplayScissor());
else
item->ClearScissor();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Scripting/Internal/TEN/Types/Vec2/Vec2.h"
#include "Scripting/Internal/TEN/Types/Vec3/Vec3.h"
#include "Scripting/Internal/TEN/Types/Rotation/Rotation.h"
#include "Scripting/Internal/TEN/View/DisplayAnchors/ScriptDisplayAnchors.h"

using namespace TEN::Scripting::Types;

Expand Down Expand Up @@ -64,6 +65,7 @@ namespace TEN::Scripting::DisplayItem
sol::optional <int> GetFrameNumber() const;
sol::optional <int> GetEndFrame() const;
sol::optional<std::pair<Vec2, Vec2>> GetBounds() const;
ScriptDisplayAnchors GetAnchors() const;

// Methods

Expand Down