Add ability to make new walls
This commit is contained in:
parent
e051973022
commit
e5a7498ef3
5 changed files with 1070 additions and 320 deletions
1267
Data/sandbox-log.txt
1267
Data/sandbox-log.txt
File diff suppressed because it is too large
Load diff
|
@ -199,7 +199,7 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
|
|||
flat.triangulated_data.push_back(vtxa);
|
||||
flat.triangulated_data.push_back(vtxb);
|
||||
flat.triangulated_data.push_back(vtxc);
|
||||
BatchSectorInfo info = {BatchSectorInfo::BATCH_FLAT, §or, &flat, nullptr};
|
||||
BatchSectorInfo info = {BatchSectorInfo::BATCH_FLAT, flat.floor ? MAT_FLOOR_TEX : MAT_CEILING_TEX, §or, &flat, nullptr};
|
||||
if (flat.material)
|
||||
m_mesh.AddBatch(
|
||||
&flat.material->textures[MAT_TEX_DIFFUSE],
|
||||
|
@ -217,11 +217,11 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
|
|||
* To do this we perform a similar approach to BuildFlat, but because the walls aren't strictly along one axis we have to
|
||||
* "flatten" them to perform the math to triangulate them. This is done by projecting the 3D points to 2D.
|
||||
*/
|
||||
void Map::BuildQuad(Sector& sector, Wall& wall, Flat& flat_topr, Flat& flat_bottomr, const Material* material, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset)
|
||||
void Map::BuildQuad(Sector& sector, Wall& wall, Flat& flat_topr, Flat& flat_bottomr, WallTextureIndex mat_type, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset)
|
||||
{
|
||||
const float E = 4.0f / 128.0f;
|
||||
|
||||
if (!material)
|
||||
if (!wall.materials[mat_type])
|
||||
return;
|
||||
|
||||
if (sector.inverted)
|
||||
|
@ -302,14 +302,13 @@ void Map::BuildQuad(Sector& sector, Wall& wall, Flat& flat_topr, Flat& flat_bott
|
|||
Vec3 fvc = Vec3(c.x, c.y, 0.0f).Rotated({0, 1, 0}, -ToDegrees(angle)); fvc.x += pos_a.x; fvc.z += pos_a.z;
|
||||
|
||||
// Fix up the UVs so they keep the right scale
|
||||
float tw = material ? texture_scale / material->textures[MAT_TEX_DIFFUSE].GetWidth() : 0.0f;
|
||||
float th = material ? texture_scale / material->textures[MAT_TEX_DIFFUSE].GetHeight() : 0.0f;
|
||||
float tw = texture_scale / wall.materials[mat_type]->textures[MAT_TEX_DIFFUSE].GetWidth();
|
||||
float th = texture_scale / wall.materials[mat_type]->textures[MAT_TEX_DIFFUSE].GetHeight();
|
||||
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
|
||||
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
|
||||
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
|
||||
BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, §or, nullptr, &wall};
|
||||
if (material)
|
||||
m_mesh.AddBatch(&material->textures[MAT_TEX_DIFFUSE], {vtxa, vtxb, vtxc}, flip, std::make_any<BatchSectorInfo>(info), &material->textures[MAT_TEX_NORMAL]);
|
||||
BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, (MaterialType)(mat_type + 2), §or, nullptr, &wall};
|
||||
m_mesh.AddBatch(&wall.materials[mat_type]->textures[MAT_TEX_DIFFUSE], {vtxa, vtxb, vtxc}, flip, std::make_any<BatchSectorInfo>(info), &wall.materials[mat_type]->textures[MAT_TEX_NORMAL]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +320,7 @@ void Map::BuildWall(Sector& sector, Wall& wall)
|
|||
{
|
||||
Vec3 a = {wall.start.x, 0.0f, wall.start.y};
|
||||
Vec3 b = {wall.end.x, 0.0f, wall.end.y};
|
||||
BuildQuad(sector, wall, sector.floor, sector.ceiling, wall.materials[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]);
|
||||
BuildQuad(sector, wall, sector.floor, sector.ceiling, TEX_FRONT, a, b, false, false, false, wall.uv_offset[TEX_FRONT]);
|
||||
|
||||
if (!(wall.flags & Wall::FLAG_SUBSECTOR_OPENING))
|
||||
{
|
||||
|
@ -330,10 +329,10 @@ void Map::BuildWall(Sector& sector, Wall& wall)
|
|||
// Build upper and lower walls for sectors connected to other sectors (or sectors within sectors)
|
||||
bool flip = wall.portal->floor.base_height < sector.floor.base_height;
|
||||
if (flip && !FloatCmp(wall.portal->floor.base_height, sector.floor.base_height))
|
||||
BuildQuad(sector, wall, sector.floor, wall.portal->floor, wall.materials[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
|
||||
BuildQuad(sector, wall, sector.floor, wall.portal->floor, TEX_LOWER, a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
|
||||
flip = wall.portal->ceiling.base_height < sector.ceiling.base_height;
|
||||
if (!flip && !FloatCmp(wall.portal->ceiling.base_height, sector.ceiling.base_height))
|
||||
BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, wall.materials[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
|
||||
BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, TEX_UPPER, a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
|
||||
|
||||
wall.flags |= Wall::FLAG_JOINED;
|
||||
}
|
||||
|
@ -343,9 +342,9 @@ void Map::BuildWall(Sector& sector, Wall& wall)
|
|||
if (!(wall.flags & Wall::FLAG_JOINED))
|
||||
{
|
||||
bool flip = wall.portal->floor.base_height < sector.floor.base_height;
|
||||
BuildQuad(sector, wall, sector.floor, wall.portal->floor, wall.materials[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
|
||||
BuildQuad(sector, wall, sector.floor, wall.portal->floor, TEX_LOWER, a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
|
||||
flip = wall.portal->ceiling.base_height < sector.ceiling.base_height;
|
||||
BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, wall.materials[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
|
||||
BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, TEX_UPPER, a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
|
||||
|
||||
wall.flags |= Wall::FLAG_JOINED;
|
||||
}
|
||||
|
@ -775,7 +774,7 @@ void Map::Rebuild(NormalGenType gen_normals)
|
|||
const auto& bu = std::any_cast<BatchSectorInfo>(b.userdata);
|
||||
|
||||
return a.texture->GetGLID() != b.texture->GetGLID() ||
|
||||
(au.sector != bu.sector || au.flat != bu.flat || au.wall != bu.wall);
|
||||
(au.sector != bu.sector || au.flat != bu.flat || au.wall != bu.wall || au.mat_type != bu.mat_type);
|
||||
}
|
||||
);
|
||||
KP3D_LOG_INFO("Finalized mesh with {} batches", m_mesh.GetBatchesRef().size());
|
||||
|
|
|
@ -18,6 +18,15 @@ enum WallTextureIndex
|
|||
TEX_LOWER
|
||||
};
|
||||
|
||||
enum MaterialType
|
||||
{
|
||||
MAT_FLOOR_TEX,
|
||||
MAT_CEILING_TEX,
|
||||
MAT_UPPER_TEX,
|
||||
MAT_MIDDLE_TEX,
|
||||
MAT_LOWER_TEX
|
||||
};
|
||||
|
||||
struct Sector;
|
||||
|
||||
struct Wall
|
||||
|
@ -117,6 +126,7 @@ struct BatchSectorInfo
|
|||
BATCH_FLAT,
|
||||
BATCH_WALL
|
||||
} type;
|
||||
MaterialType mat_type;
|
||||
kp3d::Sector* sector = nullptr;
|
||||
kp3d::Flat* flat = nullptr;
|
||||
kp3d::Wall* wall = nullptr;
|
||||
|
@ -132,7 +142,7 @@ public:
|
|||
ErrCode SaveToFile(const std::string& path);
|
||||
|
||||
void BuildFlat(Sector& sector, Flat& flat, bool invert);
|
||||
void BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, const Material* material, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset);
|
||||
void BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, WallTextureIndex mat_type, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset);
|
||||
void BuildWall(Sector& sector, Wall& wall);
|
||||
void JoinSectors(Sector& sector);
|
||||
void SanitizeSectors();
|
||||
|
|
|
@ -230,7 +230,7 @@ void Editor::UpdateModeNormal()
|
|||
{
|
||||
using namespace kp3d;
|
||||
|
||||
// Raycast through everything on the map
|
||||
// Wall/flat selection
|
||||
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT) && !editing_gizmo)
|
||||
{
|
||||
// editor_hovered_batch = nullptr;
|
||||
|
@ -293,6 +293,7 @@ void Editor::UpdateModeNormal()
|
|||
catch (std::bad_any_cast& e)
|
||||
{
|
||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,9 +303,63 @@ void Editor::UpdateModeNormal()
|
|||
sandbox->MouseButtonReset(kp3d::MOUSE_BUTTON_LEFT);
|
||||
}
|
||||
|
||||
// Wall split
|
||||
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_RIGHT) && !editing_gizmo)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto& info = std::any_cast<kp3d::BatchSectorInfo>(kp3d::editor_hovered_batch[0]->userdata);
|
||||
if (info.wall)
|
||||
{
|
||||
int wall_idx = -1;
|
||||
for (const auto& sp : sandbox->map.sectors)
|
||||
{
|
||||
for (int i = 0; i < sp->walls.size(); i++)
|
||||
{
|
||||
Wall& wall = sp->walls[i];
|
||||
if (&wall == info.wall)
|
||||
wall_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
XYf in_between = {
|
||||
(info.wall->start.x + info.wall->end.x) * 0.5f,
|
||||
(info.wall->start.y + info.wall->end.y) * 0.5f
|
||||
};
|
||||
XYf old_end = info.wall->end;
|
||||
info.wall->end = in_between;
|
||||
kp3d::Wall new_wall = *info.wall;
|
||||
new_wall.start = in_between;
|
||||
new_wall.end = old_end;
|
||||
kp3d::InsertLine(info.sector->walls, wall_idx + 1, new_wall);
|
||||
RebuildMap();
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
}
|
||||
}
|
||||
catch (std::bad_any_cast& e)
|
||||
{
|
||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
}
|
||||
sandbox->MouseButtonReset(kp3d::MOUSE_BUTTON_RIGHT);
|
||||
}
|
||||
|
||||
// Wall/sector remove
|
||||
if (sandbox->IsKeyDown(kp3d::KEY_DELETE))
|
||||
{
|
||||
sandbox->KeyReset(kp3d::KEY_DELETE);
|
||||
}
|
||||
|
||||
// UV adjust
|
||||
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (editing_gizmo)
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
|
||||
// Wall moving
|
||||
if (!editor_hovered_batch.empty() && !editing_gizmo)
|
||||
{
|
||||
try
|
||||
|
@ -371,6 +426,7 @@ void Editor::UpdateModeNormal()
|
|||
{
|
||||
can_wall_update = false;
|
||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,9 +561,9 @@ void Editor::RenderUI()
|
|||
ImGui::CheckboxFlags("Double-sided", (unsigned*)&info.wall->user_flags, kp3d::Wall::UFLAG_DOUBLESIDED);
|
||||
|
||||
ImGui::SeparatorText("Materials");
|
||||
RenderUIMaterialSelect("Middle", MAT_MIDDLE_TEX, &info.wall->materials[kp3d::TEX_FRONT]);
|
||||
RenderUIMaterialSelect("Upper", MAT_UPPER_TEX, &info.wall->materials[kp3d::TEX_UPPER]);
|
||||
RenderUIMaterialSelect("Lower", MAT_LOWER_TEX, &info.wall->materials[kp3d::TEX_LOWER]);
|
||||
RenderUIMaterialSelect("Middle", kp3d::MAT_MIDDLE_TEX, &info.wall->materials[kp3d::TEX_FRONT]);
|
||||
RenderUIMaterialSelect("Upper", kp3d::MAT_UPPER_TEX, &info.wall->materials[kp3d::TEX_UPPER]);
|
||||
RenderUIMaterialSelect("Lower", kp3d::MAT_LOWER_TEX, &info.wall->materials[kp3d::TEX_LOWER]);
|
||||
}
|
||||
else if (info.sector)
|
||||
{
|
||||
|
@ -527,13 +583,14 @@ void Editor::RenderUI()
|
|||
if (changed)
|
||||
RebuildMap();
|
||||
ImGui::SeparatorText("Materials");
|
||||
RenderUIMaterialSelect("Floor", MAT_FLOOR_TEX, &info.sector->floor.material);
|
||||
RenderUIMaterialSelect("Ceiling", MAT_CEILING_TEX, &info.sector->ceiling.material);
|
||||
RenderUIMaterialSelect("Floor", kp3d::MAT_FLOOR_TEX, &info.sector->floor.material);
|
||||
RenderUIMaterialSelect("Ceiling", kp3d::MAT_CEILING_TEX, &info.sector->ceiling.material);
|
||||
}
|
||||
}
|
||||
catch (std::bad_any_cast& e)
|
||||
{
|
||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
||||
kp3d::editor_hovered_batch.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -621,9 +678,9 @@ void Editor::RenderUIMaterialSelect(const char* name, int type, const kp3d::Mate
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case MAT_UPPER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_UPPER]);
|
||||
case MAT_LOWER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_LOWER]);
|
||||
case MAT_MIDDLE_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_FRONT]);
|
||||
case kp3d::MAT_UPPER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_UPPER]); break;
|
||||
case kp3d::MAT_LOWER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_LOWER]); break;
|
||||
case kp3d::MAT_MIDDLE_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_FRONT]); break;
|
||||
}
|
||||
}
|
||||
else if (info.flat)
|
||||
|
|
|
@ -14,15 +14,6 @@ enum EditMode
|
|||
MODE_BUILD,
|
||||
};
|
||||
|
||||
enum MaterialType
|
||||
{
|
||||
MAT_FLOOR_TEX,
|
||||
MAT_CEILING_TEX,
|
||||
MAT_UPPER_TEX,
|
||||
MAT_LOWER_TEX,
|
||||
MAT_MIDDLE_TEX
|
||||
};
|
||||
|
||||
enum WallPoint
|
||||
{
|
||||
WP_START,
|
||||
|
|
Loading…
Reference in a new issue