Skip to content

Commit

Permalink
[PRE-PORTAL] Just backup before major changes in rendering pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
DronCode committed Dec 25, 2023
1 parent 32f5af9 commit 4c32758
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 13 deletions.
6 changes: 4 additions & 2 deletions Assets/g1/ZROOM.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
"parent": "ZTreeGroup",
"properties": [
{
"name": "property_6C",
"name": "iNeighboursCount",
"__comment__": "I'm not sure about that. 6C and 84 sometimes same",
"offset": 108,
"typename": "PRPOpCode.Int32"
},
{
"name": "property_84",
"name": "iExitsCount",
"__comment__": "I'm not sure about that. 6C and 84 sometimes same",
"offset": 132,
"typename": "PRPOpCode.Int8"
},
Expand Down
22 changes: 22 additions & 0 deletions BMEdit/Editor/Include/Widgets/SceneRenderWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ namespace widgets
void invalidateRenderList();

void buildRoomCache();
void resetLastRoom();
void updateCameraRoomAttachment();

private:
// Data
Expand Down Expand Up @@ -156,11 +158,31 @@ namespace widgets

struct RoomDef
{
enum class ELocation : int {
eUNDEFINED = 0,
eOUTSIDE = 1,
eINSIDE = 2,
eBOTH = 3,
};

/**
* @brief Weak pointer to entity which represent room
*/
gamelib::scene::SceneObject::Ref rRoom {};

/**
* @brief World space bounding box which cover whole room. Typically it's been built from collision box, but sometimes it could be a expanded bbox (expanded by children objects)
*/
gamelib::BoundingBox vBoundingBox {};

/**
* @brief Type of room location. Seee ELocation.json for details
*/
ELocation eLocation { ELocation::eUNDEFINED };
};

std::list<RoomDef> m_rooms {};
const RoomDef* m_pLastRoom { nullptr };

private:
void computeRoomBoundingBox(RoomDef& d);
Expand Down
120 changes: 110 additions & 10 deletions BMEdit/Editor/Source/Widgets/SceneRenderWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ namespace widgets
invalidateRenderList();
resetViewMode();
resetRenderMode();
resetLastRoom();
}
}

Expand All @@ -376,6 +377,7 @@ namespace widgets
m_pLevel = nullptr;
m_bFirstMouseQuery = true;
invalidateRenderList();
resetLastRoom();
resetViewMode();
resetRenderMode();
repaint();
Expand Down Expand Up @@ -1003,28 +1005,60 @@ namespace widgets
}
else
{
// Need to update room before
updateCameraRoomAttachment();

if (!m_pLastRoom)
return; // Do nothing

std::list<RoomDef> acceptedRooms {};

// Render static
// SEE 0047B190 (ZViewSpace::CheckExitsInRoom) for details. Current solution is piece of crap
for (const auto& sRoomDef : m_rooms)
{
const bool bCameraInsideRoom = sRoomDef.vBoundingBox.contains(m_camera.getPosition());
bool bAcceptedAnything = false;

if (bCameraInsideRoom || m_camera.canSeeObject(sRoomDef.vBoundingBox.min, sRoomDef.vBoundingBox.max))
if (auto eRoomLoc = m_pLastRoom->eLocation; eRoomLoc == RoomDef::ELocation::eBOTH || eRoomLoc == RoomDef::ELocation::eUNDEFINED)
{
if (auto pRoom = sRoomDef.rRoom.lock())
// Render if we've inside or can see
if (sRoomDef.vBoundingBox.contains(m_camera.getPosition()) || m_camera.canSeeObject(sRoomDef.vBoundingBox.min, sRoomDef.vBoundingBox.max))
{
if (bCameraInsideRoom)
// Allowed to render
if (auto pRoom = sRoomDef.rRoom.lock())
{
// Store new room name
stats.currentRoom = QString::fromStdString(pRoom->getName());
collectRenderEntriesIntoRenderList(pRoom.get(), entries, stats, bIgnoreVisibility);
bAcceptedAnything = true;
}

collectRenderEntriesIntoRenderList(pRoom.get(), entries, stats, bIgnoreVisibility);
}
}
else
{
const bool bBothInside = eRoomLoc == RoomDef::ELocation::eINSIDE && sRoomDef.eLocation == RoomDef::ELocation::eINSIDE;
const bool bBothOutside = eRoomLoc == RoomDef::ELocation::eOUTSIDE && sRoomDef.eLocation == RoomDef::ELocation::eOUTSIDE;

acceptedRooms.emplace_back(sRoomDef);
if (bBothInside || bBothOutside)
{
// Allowed to render
if (auto pRoom = sRoomDef.rRoom.lock())
{
collectRenderEntriesIntoRenderList(pRoom.get(), entries, stats, bIgnoreVisibility);
bAcceptedAnything = true;
}
}
}

// TODO: Here we need to check if we skipped this room we need to check all gates and if we able to see room through gate - include it too
// if (!bAcceptedAnything)
}

if (auto pRoom = m_pLastRoom->rRoom.lock())
{
stats.currentRoom = QString::fromStdString(pRoom->getName());
}
else
{
stats.currentRoom = {};
}

// Render dynamic
Expand Down Expand Up @@ -1075,7 +1109,7 @@ namespace widgets
}

// Don't draw invisible things
if (bInvisible && !bIgnoreVisibility)
if (bInvisible)
return;

if (g_bannedObjectIds.contains(std::string_view{geom->getName()}))
Expand Down Expand Up @@ -1531,6 +1565,8 @@ namespace widgets
{
auto& room = m_rooms.emplace_back();
room.rRoom = pObject;
room.eLocation = RoomDef::ELocation::eUNDEFINED;

// ZBackdrop always has maximum possible size to see it from any point of the world
constexpr float kMinPoint = std::numeric_limits<float>::min();
constexpr float kMaxPoint = std::numeric_limits<float>::max();
Expand Down Expand Up @@ -1558,6 +1594,17 @@ namespace widgets
auto& room = m_rooms.emplace_back();
room.rRoom = pObject;

//room.eLocation
const auto iLocation = pObject->getProperties().getObject<std::int32_t>("Location", 0);
if (iLocation >= 0 && iLocation <= 3)
{
room.eLocation = static_cast<RoomDef::ELocation>(iLocation);
}
else
{
assert(false && "Unknown room type, room will be ignored in optimisations loop");
}

// Compute room dimensions
computeRoomBoundingBox(room);

Expand All @@ -1569,4 +1616,57 @@ namespace widgets
});
}
}

void SceneRenderWidget::resetLastRoom()
{
m_pLastRoom = nullptr;
}

void SceneRenderWidget::updateCameraRoomAttachment()
{
if (!m_pLevel || m_rooms.empty())
{
m_pLastRoom = nullptr;
return;
}

// First of all check that we out of our current room
if (m_pLastRoom)
{
if (m_pLastRoom->vBoundingBox.contains(m_camera.getPosition()))
return; // Do nothing

// Reject current room
m_pLastRoom = nullptr;
}

std::list<const RoomDef*> foundInRooms {};
for (const auto& sRoom : m_rooms)
{
if (sRoom.vBoundingBox.contains(m_camera.getPosition()))
{
foundInRooms.emplace_back(&sRoom);
}
}

if (foundInRooms.empty())
return; // Out of rooms

// Then need to sort found rooms list. Firstly we need to have eINSIDE rooms
foundInRooms.sort([this](const RoomDef* a, const RoomDef* b) {
if (a->eLocation == b->eLocation)
{
const float d1 = glm::distance(m_camera.getPosition(), a->vBoundingBox.getCenter());
const float d2 = glm::distance(m_camera.getPosition(), b->vBoundingBox.getCenter());

return d1 < d2;
}

return static_cast<int>(a->eLocation) > static_cast<int>(b->eLocation);
});

// Now, use first found room
// NOTE: Maybe we've better to check that top room is preferable for us? Idk
m_pLastRoom = (*foundInRooms.begin());
}
}
4 changes: 4 additions & 0 deletions BMEdit/Editor/UI/Source/BMEditMainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ void BMEditMainWindow::onLevelLoadSuccess()

// Load controllers index
ui->geomControllers->switchToDefaults();
ui->geomControllers->resetGeom();

// Export action
ui->menuExport->setEnabled(true);
Expand All @@ -289,6 +290,7 @@ void BMEditMainWindow::onLevelLoadFailed(const QString &reason)
QMessageBox::warning(this, QString("Failed to load level"), QString("Error occurred during level load process:\n%1").arg(reason));
m_operationCommentLabel->setText(QString("Failed to open level '%1'").arg(reason));
m_operationProgress->setValue(0);
//TODO: Need to reset global state properly!
}

void BMEditMainWindow::onLevelLoadProgressChanged(int totalPercentsProgress, const QString &currentOperationTag)
Expand Down Expand Up @@ -330,6 +332,7 @@ void BMEditMainWindow::onSelectedSceneObject(const gamelib::scene::SceneObject*
ui->sceneObjectName->setText(QString::fromStdString(selectedSceneObject->getName()));
ui->sceneObjectTypeCombo->setEnabled(true);
ui->sceneObjectTypeCombo->setCurrentText(QString::fromStdString(selectedSceneObject->getType()->getName()));
ui->geomInstanceId->setText(QString("%1").arg(selectedSceneObject->getGeomInfo().getInstanceId()));

ui->sceneGLView->setSelectedObject(const_cast<gamelib::scene::SceneObject*>(selectedSceneObject));

Expand All @@ -350,6 +353,7 @@ void BMEditMainWindow::onDeselectedSceneObject()

ui->sceneObjectTypeCombo->setEnabled(false);
ui->sceneObjectName->clear();
ui->geomInstanceId->setText("0");
ui->geomControllers->resetGeom();

m_sceneObjectPropertiesModel->resetGeom();
Expand Down
23 changes: 22 additions & 1 deletion BMEdit/Editor/UI/UI/BMEditMainWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@
<attribute name="title">
<string>Properties</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
Expand Down Expand Up @@ -269,6 +269,27 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="geomInstanceIdLabel">
<property name="text">
<string>Instance ID:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="geomInstanceId">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
Expand Down

0 comments on commit 4c32758

Please sign in to comment.