Skip to content

Commit

Permalink
[jak2] fully implement collide mesh renderer (#3010)
Browse files Browse the repository at this point in the history
Fixes #2983
  • Loading branch information
ManDude authored Sep 22, 2023
1 parent fe491c2 commit 61c4fc4
Show file tree
Hide file tree
Showing 31 changed files with 501 additions and 200 deletions.
2 changes: 1 addition & 1 deletion decompiler/config/jak2/all-types.gc
Original file line number Diff line number Diff line change
Expand Up @@ -14939,7 +14939,7 @@
(deadly 1)
(endlessfall 2)
(burn 3)
(deadlup 4)
(deadlyup 4)
(burnup 5)
(melt 6)
(slide 7)
Expand Down
30 changes: 20 additions & 10 deletions decompiler/level_extractor/extract_collide_frags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,24 +325,34 @@ void handle_collide_fragment(const TypedRef& collide_fragment,
4 * (max_pat + 1));

for (const auto& p : polys) {
math::Vector4f verts_in[3];
for (int vi = 0; vi < 3; vi++) {
int v = p.vert_index[vi];
auto& vert_out = out->emplace_back();
vert_out.flags = 0;
math::Vector4f pt(u32(verts.at(v * 3)) * 16 + bbox_min.data[0],
u32(verts.at(v * 3 + 1)) * 16 + bbox_min.data[1],
u32(verts.at(v * 3 + 2)) * 16 + bbox_min.data[2], 1.f);
verts_in[vi] = {u32(verts.at(v * 3)) * 16 + bbox_min.data[0],
u32(verts.at(v * 3 + 1)) * 16 + bbox_min.data[1],
u32(verts.at(v * 3 + 2)) * 16 + bbox_min.data[2], 1.f};
if (matrix) {
pt = transform_tie(*matrix, pt);
verts_in[vi] = transform_tie(*matrix, verts_in[vi]);
}
vert_out.x = pt.x();
vert_out.y = pt.y();
vert_out.z = pt.z();
}

math::Vector3f v10 = verts_in[1].xyz() - verts_in[0].xyz();
math::Vector3f v20 = verts_in[2].xyz() - verts_in[0].xyz();
auto normal = (v10.cross(v20).normalized() * INT16_MAX).cast<s16>();
for (int i = 0; i < 3; i++) {
auto& vert_out = out->emplace_back();
vert_out.x = verts_in[i].x();
vert_out.y = verts_in[i].y();
vert_out.z = verts_in[i].z();
vert_out.nx = normal.x();
vert_out.ny = normal.y();
vert_out.nz = normal.z();
vert_out.flags = 0; // todo
vert_out.pad = 0;
vert_out.pad2 = 0;
vert_out.pat = pats.at(p.pat);
}
};
}
}

void extract_collide_frags(const level_tools::CollideHash& chash,
Expand Down
35 changes: 26 additions & 9 deletions game/graphics/gfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ u32 sync_path() {
return 0;
}

bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) {
int arr_idx = mask_id / 32;
int arr_ofs = mask_id % 32;

Expand All @@ -142,15 +142,20 @@ bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int
case GfxGlobalSettings::CollisionRendererMode::Material:
return (g_global_settings.collision_material_mask[arr_idx] >> arr_ofs) & 1;
case GfxGlobalSettings::CollisionRendererMode::Skip:
ASSERT(arr_idx == 0);
return (g_global_settings.collision_skip_mask >> arr_ofs) & 1;
if (mask_id == -1) {
return g_global_settings.collision_skip_nomask_allowed;
} else {
return g_global_settings.collision_skip_mask & mask_id;
}
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
return g_global_settings.collision_skip_hide_mask & mask_id;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
return false;
}
}

void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) {
int arr_idx = mask_id / 32;
int arr_ofs = mask_id % 32;

Expand All @@ -165,16 +170,22 @@ void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int
g_global_settings.collision_material_mask[arr_idx] |= 1 << arr_ofs;
break;
case GfxGlobalSettings::CollisionRendererMode::Skip:
ASSERT(arr_idx == 0);
g_global_settings.collision_skip_mask |= 1 << arr_ofs;
if (mask_id == -1) {
g_global_settings.collision_skip_nomask_allowed = true;
} else {
g_global_settings.collision_skip_mask |= mask_id;
}
break;
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
g_global_settings.collision_skip_hide_mask |= mask_id;
break;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
break;
}
}

void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) {
void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) {
int arr_idx = mask_id / 32;
int arr_ofs = mask_id % 32;

Expand All @@ -189,8 +200,14 @@ void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, i
g_global_settings.collision_material_mask[arr_idx] &= ~(1 << arr_ofs);
break;
case GfxGlobalSettings::CollisionRendererMode::Skip:
ASSERT(arr_idx == 0);
g_global_settings.collision_skip_mask &= ~(1 << arr_ofs);
if (mask_id == -1) {
g_global_settings.collision_skip_nomask_allowed = false;
} else {
g_global_settings.collision_skip_mask &= ~mask_id;
}
break;
case GfxGlobalSettings::CollisionRendererMode::SkipHide:
g_global_settings.collision_skip_hide_mask &= ~mask_id;
break;
default:
lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id);
Expand Down
19 changes: 11 additions & 8 deletions game/graphics/gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,16 @@ struct GfxRendererModule {
std::function<void(const u8*, int, u32)> texture_upload_now;
std::function<void(u32, u32, u32)> texture_relocate;
std::function<void(const std::vector<std::string>&)> set_levels;
std::function<void(const std::vector<std::string>&)> set_active_levels;
std::function<void(float)> set_pmode_alp;
GfxPipeline pipeline;
const char* name;
};

// runtime settings
static constexpr int PAT_MOD_COUNT = 3;
static constexpr int PAT_EVT_COUNT = 7;
static constexpr int PAT_MAT_COUNT = 23;
static constexpr int PAT_MOD_COUNT = 4;
static constexpr int PAT_EVT_COUNT = 15;
static constexpr int PAT_MAT_COUNT = 29;
struct GfxGlobalSettings {
bool debug = true; // graphics debugging

Expand Down Expand Up @@ -93,11 +94,13 @@ struct GfxGlobalSettings {
bool collision_wireframe = true;

// matching enum in kernel-defs.gc !!
enum CollisionRendererMode { None, Mode, Event, Material, Skip } collision_mode = Mode;
enum CollisionRendererMode { None, Mode, Event, Material, Skip, SkipHide } collision_mode = Mode;
std::array<u32, (PAT_MOD_COUNT + 31) / 32> collision_mode_mask = {UINT32_MAX};
std::array<u32, (PAT_EVT_COUNT + 31) / 32> collision_event_mask = {UINT32_MAX};
std::array<u32, (PAT_MAT_COUNT + 31) / 32> collision_material_mask = {UINT32_MAX};
u32 collision_skip_mask = UINT32_MAX;
u32 collision_skip_mask = 0;
u32 collision_skip_hide_mask = 0;
bool collision_skip_nomask_allowed = true;
};

namespace Gfx {
Expand All @@ -118,9 +121,9 @@ u32 sync_path();

// matching enum in kernel-defs.gc !!
enum class RendererTreeType { NONE = 0, TFRAG3 = 1, TIE3 = 2, INVALID };
bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id);
void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id);
void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id);
bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id);
void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id);
void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id);
void CollisionRendererSetMode(GfxGlobalSettings::CollisionRendererMode mode);

} // namespace Gfx
114 changes: 99 additions & 15 deletions game/graphics/opengl_renderer/CollideMeshRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "CollideMeshRenderer.h"

#include <vector>

#include "game/graphics/gfx.h"
#include "game/graphics/opengl_renderer/background/background_common.h"

float material_colors_jak1[23 * 3] = {
const static std::vector<float> material_colors_jak1 = {
1.0f, 0.7f, 1.0f, // 0, stone
0.1f, 2.0f, 2.0f, // 1, ice
0.75f, 0.25f, 0.1f, // 2, quicksand
Expand All @@ -29,7 +31,7 @@ float material_colors_jak1[23 * 3] = {
1.0f, 1.0f, 1.0f, // 22, neutral
};

float event_colors_jak1[7 * 3] = {
const static std::vector<float> event_colors_jak1 = {
1.0f, 1.0f, 1.0f, // 0, none
0.2f, 1.0f, 1.0f, // 1, deadly
0.1f, 1.0f, 0.1f, // 2, endlessfall
Expand All @@ -39,12 +41,69 @@ float event_colors_jak1[7 * 3] = {
1.0f, 0.1f, 0.1f, // 6, melt
};

float mode_colors_jak1[3 * 3] = {
const static std::vector<float> mode_colors_jak1 = {
1.25f, 0.1f, 0.1f, // 0, ground
0.1f, 0.1f, 1.0f, // 1, wall
1.0f, 0.1f, 1.0f, // 2, obstacle
};

const static std::vector<float> material_colors_jak2 = {
1.0f, 0.1f, 1.0f, // 0, unknown
0.1f, 2.0f, 2.0f, // 1, ice
0.75f, 0.25f, 0.1f, // 2, quicksand
0.1f, 0.25f, 0.75f, // 3, waterbottom
0.5f, 0.15f, 0.1f, // 4, tar
2.0f, 1.5f, 0.5f, // 5, sand
1.5f, 0.75f, 0.1f, // 6, wood
0.1f, 1.35f, 0.1f, // 7, grass
1.7f, 1.3f, 0.1f, // 8, pcmetal
1.8f, 1.8f, 1.8f, // 9, snow
1.5f, 0.2f, 1.0f, // 10, deepsnow
1.2f, 0.5f, 0.3f, // 11, hotcoals
1.4f, 0.1f, 0.1f, // 12, lava
0.8f, 0.3f, 0.1f, // 13, crwood
1.0f, 0.4f, 1.0f, // 14, gravel
1.5f, 0.5f, 0.15f, // 15, dirt
0.7f, 0.7f, 1.0f, // 16, metal
0.1f, 0.1f, 1.2f, // 17, straw
0.75f, 1.75f, 0.75f, // 18, tube
0.4f, 0.1f, 0.8f, // 19, swamp
0.1f, 0.4f, 0.8f, // 20, stopproj
1.9f, 0.1f, 1.9f, // 21, rotate
1.0f, 1.0f, 1.0f, // 22, neutral
1.0f, 0.7f, 1.0f, // 23, stone
0.8f, 1.2f, 1.2f, // 24, crmetal
0.7f, 0.0f, 0.0f, // 25, carpet
0.1f, 0.9f, 0.1f, // 26, grmetal
1.4f, 0.7f, 0.1f, // 27, shmetal
0.5f, 0.5f, 0.0f, // 28, hdwood
};

const static std::vector<float> event_colors_jak2 = {
1.0f, 1.0f, 1.0f, // 0, none
0.5f, 1.0f, 1.0f, // 1, deadly
0.1f, 1.0f, 0.1f, // 2, endlessfall
1.0f, 1.0f, 0.1f, // 3, burn
0.1f, 0.1f, 1.0f, // 4, deadlyup
1.0f, 0.1f, 0.5f, // 5, burnup
1.0f, 0.1f, 0.1f, // 6, melt
0.1f, 0.7f, 0.7f, // 7, slide
1.0f, 0.2f, 1.0f, // 8, lip
0.5f, 0.2f, 1.0f, // 9, lipramp
0.1f, 0.5f, 1.0f, // 10, shock
0.5f, 0.6f, 1.0f, // 11, shockup
0.5f, 0.6f, 0.5f, // 12, hide
0.5f, 1.0f, 0.5f, // 13, rail
0.7f, 0.7f, 0.7f, // 14, slippery
};

const static std::vector<float> mode_colors_jak2 = {
1.25f, 0.1f, 0.1f, // 0, ground
0.1f, 0.1f, 1.0f, // 1, wall
1.0f, 0.1f, 1.0f, // 2, obstacle
1.0f, 1.0f, 0.1f, // 3, halfpipe
};

CollideMeshRenderer::CollideMeshRenderer(GameVersion version) {
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_ubo);
Expand All @@ -62,37 +121,54 @@ CollideMeshRenderer::~CollideMeshRenderer() {
}

void CollideMeshRenderer::init_pat_colors(GameVersion version) {
for (int i = 0; i < 0x8; ++i) {
for (int i = 0; i < 4; ++i) {
m_colors.pat_mode_colors[i].x() = -1.f;
m_colors.pat_mode_colors[i].y() = -1.f;
m_colors.pat_mode_colors[i].z() = -1.f;
}
for (int i = 0; i < 0x40; ++i) {
for (int i = 0; i < 32; ++i) {
m_colors.pat_material_colors[i].x() = -1.f;
m_colors.pat_material_colors[i].y() = -1.f;
m_colors.pat_material_colors[i].z() = -1.f;
}
for (int i = 0; i < 0x40; ++i) {
for (int i = 0; i < 32; ++i) {
m_colors.pat_event_colors[i].x() = -1.f;
m_colors.pat_event_colors[i].y() = -1.f;
m_colors.pat_event_colors[i].z() = -1.f;
}

const std::vector<float>* material_colors = nullptr;
const std::vector<float>* event_colors = nullptr;
const std::vector<float>* mode_colors = nullptr;

switch (version) {
case GameVersion::Jak1:
for (int i = 0; i < 23 * 3; ++i) {
m_colors.pat_material_colors[i / 3].data()[i % 3] = material_colors_jak1[i];
}
for (int i = 0; i < 7 * 3; ++i) {
m_colors.pat_event_colors[i / 3].data()[i % 3] = event_colors_jak1[i];
}
for (int i = 0; i < 3 * 3; ++i) {
m_colors.pat_mode_colors[i / 3].data()[i % 3] = mode_colors_jak1[i];
}
material_colors = &material_colors_jak1;
event_colors = &event_colors_jak1;
mode_colors = &mode_colors_jak1;
break;
case GameVersion::Jak2:
material_colors = &material_colors_jak2;
event_colors = &event_colors_jak2;
mode_colors = &mode_colors_jak2;
break;
}

if (material_colors) {
for (size_t i = 0; i < material_colors->size(); ++i) {
m_colors.pat_material_colors[i / 3].data()[i % 3] = material_colors->at(i);
}
}
if (event_colors) {
for (size_t i = 0; i < event_colors->size(); ++i) {
m_colors.pat_event_colors[i / 3].data()[i % 3] = event_colors->at(i);
}
}
if (mode_colors) {
for (size_t i = 0; i < mode_colors->size(); ++i) {
m_colors.pat_mode_colors[i / 3].data()[i % 3] = mode_colors->at(i);
}
}
}

void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfilerNode& prof) {
Expand Down Expand Up @@ -161,6 +237,8 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler
(void*)offsetof(tfrag3::CollisionMesh::Vertex, pat) // offset (0)
);
glUniform1i(glGetUniformLocation(shader, "wireframe"), 0);
glUniform1i(glGetUniformLocation(shader, "wireframe_enabled"),
Gfx::g_global_settings.collision_wireframe);
glUniform1uiv(glGetUniformLocation(shader, "collision_mode_mask"),
Gfx::g_global_settings.collision_mode_mask.size(),
Gfx::g_global_settings.collision_mode_mask.data());
Expand All @@ -172,6 +250,10 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler
Gfx::g_global_settings.collision_material_mask.data());
glUniform1ui(glGetUniformLocation(shader, "collision_skip_mask"),
Gfx::g_global_settings.collision_skip_mask);
glUniform1ui(glGetUniformLocation(shader, "collision_skip_hide_mask"),
Gfx::g_global_settings.collision_skip_hide_mask);
glUniform1ui(glGetUniformLocation(shader, "collision_skip_nomask_allowed"),
Gfx::g_global_settings.collision_skip_nomask_allowed);
glUniform1i(glGetUniformLocation(shader, "mode"), Gfx::g_global_settings.collision_mode);
glDrawArrays(GL_TRIANGLES, 0, lev->level->collision.vertices.size());

Expand All @@ -188,5 +270,7 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler

prof.add_draw_call();
prof.add_tri(lev->level->collision.vertices.size() / 3);

last_render_time = current_time;
}
}
9 changes: 6 additions & 3 deletions game/graphics/opengl_renderer/CollideMeshRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include "game/graphics/opengl_renderer/BucketRenderer.h"

struct PatColors {
math::Vector4f pat_mode_colors[0x8];
math::Vector4f pat_material_colors[0x40];
math::Vector4f pat_event_colors[0x40];
math::Vector4f pat_mode_colors[4];
math::Vector4f pat_material_colors[32];
math::Vector4f pat_event_colors[32];
};

class CollideMeshRenderer {
Expand All @@ -15,6 +15,9 @@ class CollideMeshRenderer {
void render(SharedRenderState* render_state, ScopedProfilerNode& prof);
~CollideMeshRenderer();

int current_time = 0;
int last_render_time = 0;

private:
void init_pat_colors(GameVersion version);

Expand Down
Loading

0 comments on commit 61c4fc4

Please sign in to comment.