1
0
mirror of synced 2025-03-01 15:40:26 +01:00

fix: Textures, uv coordinates and light source not updating properly. (#1872)

### Problem description
The only time textures would update was through the file picker. Once UV
coordinates were used, disabling them didn't have any effect because the
vertex array didn't invalidate the corresponding buffer array. When
`shouldUpdate` is true, the light source needs to know as well,
otherwise it will set the location at 0,0.

### Implementation description

Textures were fixed by creating a member variable that holds the file
name of the texture used in the last model rendering.

Instead of invalidating buffer arrays it is much simpler to define a
default UV coordinate set for the case when no UV is specified. if a
texture is not present then the values of UV will not be used. If there
is a texture it must be a minimum of 1 pixel in size. So we choose the
UV coordinates so that every vertex gets assigned the color at the 0,0
coordinate of the texture.

When `shouldUpdate` is on, we also turn `shouldUpdateLightSource` on.

Also included are some formatting changes that are purely aesthetic.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
paxcut 2024-11-24 03:18:19 -07:00 committed by GitHub
parent 80084f5c5a
commit 4b3bf2f358
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -96,6 +96,8 @@ namespace hex::plugin::visualizers {
ImGuiExt::Texture s_texture; ImGuiExt::Texture s_texture;
std::fs::path s_texturePath; std::fs::path s_texturePath;
std::fs::path s_texturePathOld;
u32 s_vertexCount; u32 s_vertexCount;
const auto isIndexInRange = [](auto index) { const auto isIndexInRange = [](auto index) {
@ -112,30 +114,30 @@ namespace hex::plugin::visualizers {
indices.resize(vertexCount * 6); indices.resize(vertexCount * 6);
for (u32 i = 0; i < vertexCount; i += 1) { for (u32 i = 0; i < vertexCount; i += 1) {
indices[i * 6] = vertexIndices[3 * i]; indices[ i * 6 ] = vertexIndices[ 3 * i ];
indices[(i * 6) + 1] = vertexIndices[(3 * i) + 1]; indices[(i * 6) + 1] = vertexIndices[(3 * i) + 1];
indices[(i * 6) + 2] = vertexIndices[(3 * i) + 1]; indices[(i * 6) + 2] = vertexIndices[(3 * i) + 1];
indices[(i * 6) + 3] = vertexIndices[(3 * i) + 2]; indices[(i * 6) + 3] = vertexIndices[(3 * i) + 2];
indices[(i * 6) + 4] = vertexIndices[(3 * i) + 2]; indices[(i * 6) + 4] = vertexIndices[(3 * i) + 2];
indices[(i * 6) + 5] = vertexIndices[3 * i]; indices[(i * 6) + 5] = vertexIndices[ 3 * i ];
} }
vertexIndices.resize(indices.size()); vertexIndices.resize(indices.size());
for (u32 i = 0; i < indices.size(); ++i) for (u32 i = 0; i < indices.size(); i += 1) {
vertexIndices[i] = indices[i]; vertexIndices[i] = indices[i];
}
} }
float getBoundingBox(const std::vector<float> &vertices) { float getBoundingBox(const std::vector<float> &vertices) {
gl::Vector<float, 4> minWorld(std::numeric_limits<float>::infinity()), maxWorld(-std::numeric_limits<float>::infinity()); gl::Vector<float, 4> minWorld(std::numeric_limits<float>::infinity()), maxWorld(-std::numeric_limits<float>::infinity());
for (u32 i = 0; i < vertices.size(); i += 3) { for (u32 i = 0; i < vertices.size(); i += 3) {
minWorld[0] = std::min(vertices[i], minWorld[0]); minWorld[0] = std::min(vertices[i ], minWorld[0]);
minWorld[1] = std::min(vertices[i + 1], minWorld[1]); minWorld[1] = std::min(vertices[i + 1], minWorld[1]);
minWorld[2] = std::min(vertices[i + 2], minWorld[2]); minWorld[2] = std::min(vertices[i + 2], minWorld[2]);
maxWorld[0] = std::max(vertices[i], maxWorld[0]); maxWorld[0] = std::max(vertices[i ], maxWorld[0]);
maxWorld[1] = std::max(vertices[i + 1], maxWorld[1]); maxWorld[1] = std::max(vertices[i + 1], maxWorld[1]);
maxWorld[2] = std::max(vertices[i + 2], maxWorld[2]); maxWorld[2] = std::max(vertices[i + 2], maxWorld[2]);
} }
@ -174,7 +176,7 @@ namespace hex::plugin::visualizers {
float alpha = float((color >> 24) & 0xFF) / 255.0F; float alpha = float((color >> 24) & 0xFF) / 255.0F;
for (u32 i = 0; i < colors.size(); i += 4) { for (u32 i = 0; i < colors.size(); i += 4) {
colors[i] = red; colors[i ] = red;
colors[i + 1] = green; colors[i + 1] = green;
colors[i + 2] = blue; colors[i + 2] = blue;
colors[i + 3] = alpha; colors[i + 3] = alpha;
@ -184,12 +186,12 @@ namespace hex::plugin::visualizers {
void setNormals(const std::vector<float> &vertices, std::vector<float> &normals) { void setNormals(const std::vector<float> &vertices, std::vector<float> &normals) {
for (u32 i = 0; i < normals.size(); i += 9) { for (u32 i = 0; i < normals.size(); i += 9) {
auto v1 = gl::Vector<float, 3>({vertices[i], vertices[i + 1], vertices[i + 2]}); auto v1 = gl::Vector<float, 3>({vertices[i ], vertices[i + 1], vertices[i + 2]});
auto v2 = gl::Vector<float, 3>({vertices[i + 3], vertices[i + 4], vertices[i + 5]}); auto v2 = gl::Vector<float, 3>({vertices[i + 3], vertices[i + 4], vertices[i + 5]});
auto v3 = gl::Vector<float, 3>({vertices[i + 6], vertices[i + 7], vertices[i + 8]}); auto v3 = gl::Vector<float, 3>({vertices[i + 6], vertices[i + 7], vertices[i + 8]});
auto normal = ((v2 - v1).cross(v3 - v1)); auto normal = ((v2 - v1).cross(v3 - v1));
normals[i] += normal[0]; normals[i ] += normal[0];
normals[i + 1] += normal[1]; normals[i + 1] += normal[1];
normals[i + 2] += normal[2]; normals[i + 2] += normal[2];
normals[i + 3] += normal[0]; normals[i + 3] += normal[0];
@ -202,7 +204,7 @@ namespace hex::plugin::visualizers {
for (u32 i = 0; i < normals.size(); i += 3) { for (u32 i = 0; i < normals.size(); i += 3) {
auto normal = gl::Vector<float, 3>({normals[i], normals[i + 1], normals[i + 2]}); auto normal = gl::Vector<float, 3>({normals[i], normals[i + 1], normals[i + 2]});
normal.normalize(); normal.normalize();
normals[i] = normal[0]; normals[i ] = normal[0];
normals[i + 1] = normal[1]; normals[i + 1] = normal[1];
normals[i + 2] = normal[2]; normals[i + 2] = normal[2];
} }
@ -210,28 +212,27 @@ namespace hex::plugin::visualizers {
void setNormalsWithIndices(const std::vector<float> &vertices, std::vector<float> &normals, const std::vector<u32> &indices) { void setNormalsWithIndices(const std::vector<float> &vertices, std::vector<float> &normals, const std::vector<u32> &indices) {
for (u32 i = 0; i < indices.size(); i += 3) { for (u32 i = 0; i < indices.size(); i += 3) {
auto idx = indices[i]; auto idx = indices[i ];
auto idx1 = indices[i + 1]; auto idx1 = indices[i + 1];
auto idx2 = indices[i + 2]; auto idx2 = indices[i + 2];
auto v1 = gl::Vector<float, 3>({vertices[3 * idx], vertices[(3 * idx) + 1], vertices[(3 * idx) + 2]}); auto v1 = gl::Vector<float, 3>({vertices[3 * idx ], vertices[(3 * idx ) + 1], vertices[(3 * idx ) + 2]});
auto v2 = gl::Vector<float, 3>( auto v2 = gl::Vector<float, 3>({vertices[3 * idx1], vertices[(3 * idx1) + 1], vertices[(3 * idx1) + 2]});
{vertices[3 * idx1], vertices[(3 * idx1) + 1], vertices[(3 * idx1) + 2]}); auto v3 = gl::Vector<float, 3>({vertices[3 * idx2], vertices[(3 * idx2) + 1], vertices[(3 * idx2) + 2]});
auto v3 = gl::Vector<float, 3>(
{vertices[3 * idx2], vertices[(3 * idx2) + 1], vertices[(3 * idx2) + 2]});
auto weighted = ((v2 - v1).cross(v3 - v1)); auto weighted = ((v2 - v1).cross(v3 - v1));
normals[3 * idx] += weighted[0]; normals[ 3 * idx ] += weighted[0];
normals[(3 * idx) + 1] += weighted[1]; normals[(3 * idx) + 1] += weighted[1];
normals[(3 * idx) + 2] += weighted[2]; normals[(3 * idx) + 2] += weighted[2];
normals[(3 * idx1)] += weighted[0]; normals[(3 * idx1) ] += weighted[0];
normals[(3 * idx1) + 1] += weighted[1]; normals[(3 * idx1) + 1] += weighted[1];
normals[(3 * idx1) + 2] += weighted[2]; normals[(3 * idx1) + 2] += weighted[2];
normals[(3 * idx2)] += weighted[0]; normals[(3 * idx2) ] += weighted[0];
normals[(3 * idx2) + 1] += weighted[1]; normals[(3 * idx2) + 1] += weighted[1];
normals[(3 * idx2) + 2] += weighted[2]; normals[(3 * idx2) + 2] += weighted[2];
} }
for (u32 i = 0; i < normals.size(); i += 3) { for (u32 i = 0; i < normals.size(); i += 3) {
auto normal = gl::Vector<float, 3>({normals[i], normals[i + 1], normals[i + 2]}); auto normal = gl::Vector<float, 3>({normals[i], normals[i + 1], normals[i + 2]});
@ -323,20 +324,20 @@ namespace hex::plugin::visualizers {
scaling = std::max(scaling, 0.01F); scaling = std::max(scaling, 0.01F);
processKeyEvent(ImGuiKey_Keypad4, translation[0], -0.1F, accel); processKeyEvent(ImGuiKey_Keypad4, translation[0], -0.1F, accel);
processKeyEvent(ImGuiKey_Keypad6, translation[0], 0.1F, accel); processKeyEvent(ImGuiKey_Keypad6, translation[0], 0.1F, accel);
processKeyEvent(ImGuiKey_Keypad8, translation[1], 0.1F, accel); processKeyEvent(ImGuiKey_Keypad8, translation[1], 0.1F, accel);
processKeyEvent(ImGuiKey_Keypad2, translation[1], -0.1F, accel); processKeyEvent(ImGuiKey_Keypad2, translation[1], -0.1F, accel);
processKeyEvent(ImGuiKey_Keypad1, translation[2], 0.1F, accel); processKeyEvent(ImGuiKey_Keypad1, translation[2], 0.1F, accel);
processKeyEvent(ImGuiKey_Keypad7, translation[2], -0.1F, accel); processKeyEvent(ImGuiKey_Keypad7, translation[2], -0.1F, accel);
processKeyEvent(ImGuiKey_Keypad9, nearLimit, -0.01F, accel); processKeyEvent(ImGuiKey_Keypad9, nearLimit, -0.01F, accel);
processKeyEvent(ImGuiKey_Keypad3, nearLimit, 0.01F, accel); processKeyEvent(ImGuiKey_Keypad3, nearLimit, 0.01F, accel);
if (ImHexApi::System::isDebugBuild()) { if (ImHexApi::System::isDebugBuild()) {
processKeyEvent(ImGuiKey_KeypadDivide, farLimit, -1.0F, accel); processKeyEvent(ImGuiKey_KeypadDivide, farLimit, -1.0F, accel);
processKeyEvent(ImGuiKey_KeypadMultiply, farLimit, 1.0F, accel); processKeyEvent(ImGuiKey_KeypadMultiply, farLimit, 1.0F, accel);
} }
processKeyEvent(ImGuiKey_KeypadAdd, rotation[2], -0.075F, accel); processKeyEvent(ImGuiKey_KeypadAdd, rotation[2], -0.075F, accel);
processKeyEvent(ImGuiKey_KeypadSubtract, rotation[2], 0.075F, accel); processKeyEvent(ImGuiKey_KeypadSubtract, rotation[2], 0.075F, accel);
rotation[2] = std::fmod(rotation[2], 2 * std::numbers::pi_v<float>); rotation[2] = std::fmod(rotation[2], 2 * std::numbers::pi_v<float>);
} }
@ -397,7 +398,6 @@ namespace hex::plugin::visualizers {
else else
throw std::runtime_error(errorMessage); throw std::runtime_error(errorMessage);
vertexArray.addBuffer(0, buffers.vertices); vertexArray.addBuffer(0, buffers.vertices);
vertexArray.addBuffer(1, buffers.colors, 4); vertexArray.addBuffer(1, buffers.colors, 4);
vertexArray.addBuffer(2, buffers.normals); vertexArray.addBuffer(2, buffers.normals);
@ -482,17 +482,17 @@ namespace hex::plugin::visualizers {
axes.updateRow(1, axes.getRow(1) * (1.0F / axes(1, 3))); axes.updateRow(1, axes.getRow(1) * (1.0F / axes(1, 3)));
axes.updateRow(2, axes.getRow(2) * (1.0F / axes(2, 3))); axes.updateRow(2, axes.getRow(2) * (1.0F / axes(2, 3)));
auto axesPosx = (axes.getColumn(0) + 1.0F) * (textureWidth / 2.0F); auto axesPositionX = (axes.getColumn(0) + 1.0F) * (textureWidth / 2.0F);
auto axesPosy = (axes.getColumn(1) + 1.0F) * (-textureHeight / 2.0F) + textureHeight; auto axesPositionY = (axes.getColumn(1) + 1.0F) * (-textureHeight / 2.0F) + textureHeight;
ImDrawList *drawList = ImGui::GetWindowDrawList(); ImDrawList *drawList = ImGui::GetWindowDrawList();
if (showX) if (showX)
drawList->AddText(ImVec2(axesPosx[0], axesPosy[0]) + screenPos, IM_COL32(255, 0, 0, 255), "X"); drawList->AddText(ImVec2(axesPositionX[0], axesPositionY[0]) + screenPos, IM_COL32(255, 0, 0, 255), "X");
if (showY) if (showY)
drawList->AddText(ImVec2(axesPosx[1], axesPosy[1]) + screenPos, IM_COL32(0, 255, 0, 255), "Y"); drawList->AddText(ImVec2(axesPositionX[1], axesPositionY[1]) + screenPos, IM_COL32(0, 255, 0, 255), "Y");
if (showZ) if (showZ)
drawList->AddText(ImVec2(axesPosx[2], axesPosy[2]) + screenPos, IM_COL32(0, 0, 255, 255), "Z"); drawList->AddText(ImVec2(axesPositionX[2], axesPositionY[2]) + screenPos, IM_COL32(0, 0, 255, 255), "Z");
} }
if (ImHexApi::System::isDebugBuild()) { if (ImHexApi::System::isDebugBuild()) {
@ -634,6 +634,7 @@ namespace hex::plugin::visualizers {
static Buffers<T> buffers; static Buffers<T> buffers;
static LineBuffers<T> lineBuffers; static LineBuffers<T> lineBuffers;
if (s_shouldReset) { if (s_shouldReset) {
s_shouldReset = false; s_shouldReset = false;
s_shouldUpdateLightSource = true; s_shouldUpdateLightSource = true;
@ -781,13 +782,13 @@ namespace hex::plugin::visualizers {
shader.bind(); shader.bind();
shader.setUniform("modelScale", scaledModel); shader.setUniform("modelScale", scaledModel);
shader.setUniform("modelMatrix", model); shader.setUniform("modelMatrix", model);
shader.setUniform("viewMatrix", view); shader.setUniform("viewMatrix", view);
shader.setUniform("projectionMatrix",projection); shader.setUniform("projectionMatrix", projection);
shader.setUniform("lightPosition", s_lightPosition); shader.setUniform("lightPosition", s_lightPosition);
shader.setUniform("lightBrightness", s_lightBrightness); shader.setUniform("lightBrightness", s_lightBrightness);
shader.setUniform("lightColor", s_lightColor); shader.setUniform("lightColor", s_lightColor);
vertexArray.bind(); vertexArray.bind();
if (s_shouldUpdateTexture) { if (s_shouldUpdateTexture) {