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(vtxa);
|
||||||
flat.triangulated_data.push_back(vtxb);
|
flat.triangulated_data.push_back(vtxb);
|
||||||
flat.triangulated_data.push_back(vtxc);
|
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)
|
if (flat.material)
|
||||||
m_mesh.AddBatch(
|
m_mesh.AddBatch(
|
||||||
&flat.material->textures[MAT_TEX_DIFFUSE],
|
&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
|
* 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.
|
* "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;
|
const float E = 4.0f / 128.0f;
|
||||||
|
|
||||||
if (!material)
|
if (!wall.materials[mat_type])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sector.inverted)
|
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;
|
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
|
// Fix up the UVs so they keep the right scale
|
||||||
float tw = material ? texture_scale / material->textures[MAT_TEX_DIFFUSE].GetWidth() : 0.0f;
|
float tw = texture_scale / wall.materials[mat_type]->textures[MAT_TEX_DIFFUSE].GetWidth();
|
||||||
float th = material ? texture_scale / material->textures[MAT_TEX_DIFFUSE].GetHeight() : 0.0f;
|
float th = texture_scale / wall.materials[mat_type]->textures[MAT_TEX_DIFFUSE].GetHeight();
|
||||||
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
|
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
|
||||||
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
|
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
|
||||||
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
|
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
|
||||||
BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, §or, nullptr, &wall};
|
BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, (MaterialType)(mat_type + 2), §or, nullptr, &wall};
|
||||||
if (material)
|
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]);
|
||||||
m_mesh.AddBatch(&material->textures[MAT_TEX_DIFFUSE], {vtxa, vtxb, vtxc}, flip, std::make_any<BatchSectorInfo>(info), &material->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 a = {wall.start.x, 0.0f, wall.start.y};
|
||||||
Vec3 b = {wall.end.x, 0.0f, wall.end.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))
|
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)
|
// 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;
|
bool flip = wall.portal->floor.base_height < sector.floor.base_height;
|
||||||
if (flip && !FloatCmp(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;
|
flip = wall.portal->ceiling.base_height < sector.ceiling.base_height;
|
||||||
if (!flip && !FloatCmp(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;
|
wall.flags |= Wall::FLAG_JOINED;
|
||||||
}
|
}
|
||||||
|
@ -343,9 +342,9 @@ void Map::BuildWall(Sector& sector, Wall& wall)
|
||||||
if (!(wall.flags & Wall::FLAG_JOINED))
|
if (!(wall.flags & Wall::FLAG_JOINED))
|
||||||
{
|
{
|
||||||
bool flip = wall.portal->floor.base_height < sector.floor.base_height;
|
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;
|
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;
|
wall.flags |= Wall::FLAG_JOINED;
|
||||||
}
|
}
|
||||||
|
@ -775,7 +774,7 @@ void Map::Rebuild(NormalGenType gen_normals)
|
||||||
const auto& bu = std::any_cast<BatchSectorInfo>(b.userdata);
|
const auto& bu = std::any_cast<BatchSectorInfo>(b.userdata);
|
||||||
|
|
||||||
return a.texture->GetGLID() != b.texture->GetGLID() ||
|
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());
|
KP3D_LOG_INFO("Finalized mesh with {} batches", m_mesh.GetBatchesRef().size());
|
||||||
|
|
|
@ -18,6 +18,15 @@ enum WallTextureIndex
|
||||||
TEX_LOWER
|
TEX_LOWER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MaterialType
|
||||||
|
{
|
||||||
|
MAT_FLOOR_TEX,
|
||||||
|
MAT_CEILING_TEX,
|
||||||
|
MAT_UPPER_TEX,
|
||||||
|
MAT_MIDDLE_TEX,
|
||||||
|
MAT_LOWER_TEX
|
||||||
|
};
|
||||||
|
|
||||||
struct Sector;
|
struct Sector;
|
||||||
|
|
||||||
struct Wall
|
struct Wall
|
||||||
|
@ -117,6 +126,7 @@ struct BatchSectorInfo
|
||||||
BATCH_FLAT,
|
BATCH_FLAT,
|
||||||
BATCH_WALL
|
BATCH_WALL
|
||||||
} type;
|
} type;
|
||||||
|
MaterialType mat_type;
|
||||||
kp3d::Sector* sector = nullptr;
|
kp3d::Sector* sector = nullptr;
|
||||||
kp3d::Flat* flat = nullptr;
|
kp3d::Flat* flat = nullptr;
|
||||||
kp3d::Wall* wall = nullptr;
|
kp3d::Wall* wall = nullptr;
|
||||||
|
@ -132,7 +142,7 @@ public:
|
||||||
ErrCode SaveToFile(const std::string& path);
|
ErrCode SaveToFile(const std::string& path);
|
||||||
|
|
||||||
void BuildFlat(Sector& sector, Flat& flat, bool invert);
|
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 BuildWall(Sector& sector, Wall& wall);
|
||||||
void JoinSectors(Sector& sector);
|
void JoinSectors(Sector& sector);
|
||||||
void SanitizeSectors();
|
void SanitizeSectors();
|
||||||
|
|
|
@ -230,7 +230,7 @@ void Editor::UpdateModeNormal()
|
||||||
{
|
{
|
||||||
using namespace kp3d;
|
using namespace kp3d;
|
||||||
|
|
||||||
// Raycast through everything on the map
|
// Wall/flat selection
|
||||||
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT) && !editing_gizmo)
|
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT) && !editing_gizmo)
|
||||||
{
|
{
|
||||||
// editor_hovered_batch = nullptr;
|
// editor_hovered_batch = nullptr;
|
||||||
|
@ -293,6 +293,7 @@ void Editor::UpdateModeNormal()
|
||||||
catch (std::bad_any_cast& e)
|
catch (std::bad_any_cast& e)
|
||||||
{
|
{
|
||||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
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);
|
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)
|
if (editing_gizmo)
|
||||||
kp3d::editor_hovered_batch.clear();
|
kp3d::editor_hovered_batch.clear();
|
||||||
|
|
||||||
|
// Wall moving
|
||||||
if (!editor_hovered_batch.empty() && !editing_gizmo)
|
if (!editor_hovered_batch.empty() && !editing_gizmo)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -371,6 +426,7 @@ void Editor::UpdateModeNormal()
|
||||||
{
|
{
|
||||||
can_wall_update = false;
|
can_wall_update = false;
|
||||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
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::CheckboxFlags("Double-sided", (unsigned*)&info.wall->user_flags, kp3d::Wall::UFLAG_DOUBLESIDED);
|
||||||
|
|
||||||
ImGui::SeparatorText("Materials");
|
ImGui::SeparatorText("Materials");
|
||||||
RenderUIMaterialSelect("Middle", MAT_MIDDLE_TEX, &info.wall->materials[kp3d::TEX_FRONT]);
|
RenderUIMaterialSelect("Middle", kp3d::MAT_MIDDLE_TEX, &info.wall->materials[kp3d::TEX_FRONT]);
|
||||||
RenderUIMaterialSelect("Upper", MAT_UPPER_TEX, &info.wall->materials[kp3d::TEX_UPPER]);
|
RenderUIMaterialSelect("Upper", kp3d::MAT_UPPER_TEX, &info.wall->materials[kp3d::TEX_UPPER]);
|
||||||
RenderUIMaterialSelect("Lower", MAT_LOWER_TEX, &info.wall->materials[kp3d::TEX_LOWER]);
|
RenderUIMaterialSelect("Lower", kp3d::MAT_LOWER_TEX, &info.wall->materials[kp3d::TEX_LOWER]);
|
||||||
}
|
}
|
||||||
else if (info.sector)
|
else if (info.sector)
|
||||||
{
|
{
|
||||||
|
@ -527,13 +583,14 @@ void Editor::RenderUI()
|
||||||
if (changed)
|
if (changed)
|
||||||
RebuildMap();
|
RebuildMap();
|
||||||
ImGui::SeparatorText("Materials");
|
ImGui::SeparatorText("Materials");
|
||||||
RenderUIMaterialSelect("Floor", MAT_FLOOR_TEX, &info.sector->floor.material);
|
RenderUIMaterialSelect("Floor", kp3d::MAT_FLOOR_TEX, &info.sector->floor.material);
|
||||||
RenderUIMaterialSelect("Ceiling", MAT_CEILING_TEX, &info.sector->ceiling.material);
|
RenderUIMaterialSelect("Ceiling", kp3d::MAT_CEILING_TEX, &info.sector->ceiling.material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::bad_any_cast& e)
|
catch (std::bad_any_cast& e)
|
||||||
{
|
{
|
||||||
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
KP3D_LOG_ERROR("Bad any cast: {}", e.what());
|
||||||
|
kp3d::editor_hovered_batch.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -621,9 +678,9 @@ void Editor::RenderUIMaterialSelect(const char* name, int type, const kp3d::Mate
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case MAT_UPPER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_UPPER]);
|
case kp3d::MAT_UPPER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_UPPER]); break;
|
||||||
case MAT_LOWER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_LOWER]);
|
case kp3d::MAT_LOWER_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_LOWER]); break;
|
||||||
case MAT_MIDDLE_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_FRONT]);
|
case kp3d::MAT_MIDDLE_TEX: m_materials_to_update.push_back(&info.wall->materials[kp3d::TEX_FRONT]); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (info.flat)
|
else if (info.flat)
|
||||||
|
|
|
@ -14,15 +14,6 @@ enum EditMode
|
||||||
MODE_BUILD,
|
MODE_BUILD,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MaterialType
|
|
||||||
{
|
|
||||||
MAT_FLOOR_TEX,
|
|
||||||
MAT_CEILING_TEX,
|
|
||||||
MAT_UPPER_TEX,
|
|
||||||
MAT_LOWER_TEX,
|
|
||||||
MAT_MIDDLE_TEX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum WallPoint
|
enum WallPoint
|
||||||
{
|
{
|
||||||
WP_START,
|
WP_START,
|
||||||
|
|
Loading…
Reference in a new issue