From a261dbbcdae9fa3b3bae76c88f95ae5fe02987d9 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Sat, 28 Mar 2020 23:28:51 +0000 Subject: [PATCH] editor - paint tool updates #94; mesh updates; --- Editor/PaintToolWindow.cpp | 323 +++++++++++++++++++------------------ WickedEngine/wiScene.cpp | 50 +++--- WickedEngine/wiScene.h | 4 +- WickedEngine/wiVersion.cpp | 2 +- 4 files changed, 201 insertions(+), 178 deletions(-) diff --git a/Editor/PaintToolWindow.cpp b/Editor/PaintToolWindow.cpp index 532d6feed..6f4642983 100644 --- a/Editor/PaintToolWindow.cpp +++ b/Editor/PaintToolWindow.cpp @@ -9,7 +9,7 @@ using namespace wiGraphics; PaintToolWindow::PaintToolWindow(EditorComponent* editor) : editor(editor) { window = new wiWindow(&editor->GetGUI(), "Paint Tool Window"); - window->SetSize(XMFLOAT2(400, 580)); + window->SetSize(XMFLOAT2(400, 600)); editor->GetGUI().AddWidget(window); float x = 100; @@ -71,7 +71,7 @@ PaintToolWindow::PaintToolWindow(EditorComponent* editor) : editor(editor) y += step + 5; infoLabel = new wiLabel("Paint Tool is disabled."); - infoLabel->SetSize(XMFLOAT2(400 - 20, 80)); + infoLabel->SetSize(XMFLOAT2(400 - 20, 100)); infoLabel->SetPos(XMFLOAT2(10, y)); infoLabel->SetColor(wiColor::Transparent()); window->AddWidget(infoLabel); @@ -178,6 +178,7 @@ void PaintToolWindow::Update(float dt) const XMVECTOR MUL = XMVectorSet(0.5f, -0.5f, 1, 1); const XMVECTOR ADD = XMVectorSet(0.5f, 0.5f, 0, 0); const XMVECTOR SCREEN = XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 1, 1); + const XMVECTOR F = camera.GetAt(); switch (mode) { @@ -225,63 +226,65 @@ void PaintToolWindow::Update(float dt) rebuild = true; } - for (size_t j = 0; j < mesh->indices.size(); j += 3) + if (painting) { - const uint32_t triangle[] = { - mesh->indices[j + 0], - mesh->indices[j + 1], - mesh->indices[j + 2], - }; - const XMVECTOR P[arraysize(triangle)] = { - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), - }; - - if (painting) + for (size_t j = 0; j < mesh->vertex_positions.size(); ++j) { - XMVECTOR PT[arraysize(triangle)]; - for (int k = 0; k < arraysize(triangle); ++k) + XMVECTOR P, N; + if (armature == nullptr) { - PT[k] = XMVector3TransformCoord(P[k], VP); - PT[k] = PT[k] * MUL + ADD; - PT[k] = PT[k] * SCREEN; + P = XMLoadFloat3(&mesh->vertex_positions[j]); + N = XMLoadFloat3(&mesh->vertex_normals[j]); } - - bool culled = false; - if (!backfaces) + else { - const XMVECTOR N = XMVector3Normalize(XMVector3Cross(PT[1] - PT[0], PT[2] - PT[1])); - culled = XMVectorGetZ(N) > 0; + P = wiScene::SkinVertex(*mesh, *armature, (uint32_t)j, &N); } + P = XMVector3Transform(P, W); + N = XMVector3Normalize(XMVector3TransformNormal(N, W)); - if (!culled) + if (!backfaces && XMVectorGetX(XMVector3Dot(F, N)) > 0) + continue; + + P = XMVector3TransformCoord(P, VP); + P = P * MUL + ADD; + P = P * SCREEN; + + if (subset >= 0 && mesh->vertex_subsets[j] != subset) + continue; + + const float z = XMVectorGetZ(P); + const float dist = XMVectorGetX(XMVector2Length(C - P)); + if (z >= 0 && z <= 1 && dist <= radius) { - for (int k = 0; k < arraysize(triangle); ++k) - { - if (subset >= 0 && subset < (int)mesh->subsets.size()) - { - const MeshComponent::MeshSubset& sub = mesh->subsets[subset]; - if (sub.indexOffset > triangle[k] || sub.indexOffset + sub.indexCount < triangle[k]) - continue; - } - const float z = XMVectorGetZ(PT[k]); - const float dist = XMVectorGetX(XMVector2Length(C - PT[k])); - if (z >= 0 && z <= 1 && dist <= radius) - { - RecordHistory(true); - wiColor vcol = mesh->vertex_colors[triangle[k]]; - const float affection = amount * std::powf(1 - (dist / radius), falloff); - vcol = wiColor::lerp(vcol, color, affection); - mesh->vertex_colors[triangle[k]] = vcol.rgba; - rebuild = true; - } - } + RecordHistory(true); + wiColor vcol = mesh->vertex_colors[j]; + const float affection = amount * std::powf(1 - (dist / radius), falloff); + vcol = wiColor::lerp(vcol, color, affection); + mesh->vertex_colors[j] = vcol.rgba; + rebuild = true; } } + } - if (wireframe) + if (wireframe) + { + for (size_t j = 0; j < mesh->indices.size(); j += 3) { + const uint32_t triangle[] = { + mesh->indices[j + 0], + mesh->indices[j + 1], + mesh->indices[j + 2], + }; + if (subset >= 0 && (mesh->vertex_subsets[triangle[0]] != subset|| mesh->vertex_subsets[triangle[1]] != subset|| mesh->vertex_subsets[triangle[2]] != subset)) + continue; + + const XMVECTOR P[arraysize(triangle)] = { + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), + }; + wiRenderer::RenderableTriangle tri; XMStoreFloat3(&tri.positionA, P[0]); XMStoreFloat3(&tri.positionB, P[1]); @@ -320,66 +323,68 @@ void PaintToolWindow::Update(float dt) const XMMATRIX W = XMLoadFloat4x4(&transform->world); bool rebuild = false; - for (size_t j = 0; j < mesh->indices.size(); j += 3) + if (painting) { - const uint32_t triangle[] = { - mesh->indices[j + 0], - mesh->indices[j + 1], - mesh->indices[j + 2], - }; - const XMVECTOR P[arraysize(triangle)] = { - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), - }; - - if (painting) + for (size_t j = 0; j < mesh->vertex_positions.size(); ++j) { - XMVECTOR PT[arraysize(triangle)]; - for (int k = 0; k < arraysize(triangle); ++k) + XMVECTOR P, N; + if (armature == nullptr) { - PT[k] = XMVector3TransformCoord(P[k], VP); - PT[k] = PT[k] * MUL + ADD; - PT[k] = PT[k] * SCREEN; + P = XMLoadFloat3(&mesh->vertex_positions[j]); + N = XMLoadFloat3(&mesh->vertex_normals[j]); } - - bool culled = false; - if (!backfaces) + else { - const XMVECTOR N = XMVector3Normalize(XMVector3Cross(PT[1] - PT[0], PT[2] - PT[1])); - culled = XMVectorGetZ(N) > 0; + P = wiScene::SkinVertex(*mesh, *armature, (uint32_t)j, &N); } + P = XMVector3Transform(P, W); + N = XMVector3Normalize(XMVector3TransformNormal(N, W)); - if (!culled) + if (!backfaces && XMVectorGetX(XMVector3Dot(F, N)) > 0) + continue; + + P = XMVector3TransformCoord(P, VP); + P = P * MUL + ADD; + P = P * SCREEN; + + const float z = XMVectorGetZ(P); + const float dist = XMVectorGetX(XMVector2Length(C - P)); + if (z >= 0 && z <= 1 && dist <= radius) { - for (int k = 0; k < arraysize(triangle); ++k) + RecordHistory(true); + XMVECTOR PL = XMLoadFloat3(&mesh->vertex_positions[j]); + const XMVECTOR NL = XMLoadFloat3(&mesh->vertex_normals[j]); + const float affection = amount * std::powf(1 - (dist / radius), falloff); + switch (mode) { - const float z = XMVectorGetZ(PT[k]); - const float dist = XMVectorGetX(XMVector2Length(C - PT[k])); - if (z >= 0 && z <= 1 && dist <= radius) - { - RecordHistory(true); - XMVECTOR PL = XMLoadFloat3(&mesh->vertex_positions[triangle[k]]); - const XMVECTOR N = XMLoadFloat3(&mesh->vertex_normals[triangle[k]]); - const float affection = amount * std::powf(1 - (dist / radius), falloff); - switch (mode) - { - case MODE_SCULPTING_ADD: - PL += N * affection; - break; - case MODE_SCULPTING_SUBTRACT: - PL -= N * affection; - break; - } - XMStoreFloat3(&mesh->vertex_positions[triangle[k]], PL); - rebuild = true; - } + case MODE_SCULPTING_ADD: + PL += NL * affection; + break; + case MODE_SCULPTING_SUBTRACT: + PL -= NL * affection; + break; } + XMStoreFloat3(&mesh->vertex_positions[j], PL); + rebuild = true; } } + } - if (wireframe) + if (wireframe) + { + for (size_t j = 0; j < mesh->indices.size(); j += 3) { + const uint32_t triangle[] = { + mesh->indices[j + 0], + mesh->indices[j + 1], + mesh->indices[j + 2], + }; + const XMVECTOR P[arraysize(triangle)] = { + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), + }; + wiRenderer::RenderableTriangle tri; XMStoreFloat3(&tri.positionA, P[0]); XMStoreFloat3(&tri.positionB, P[1]); @@ -505,91 +510,101 @@ void PaintToolWindow::Update(float dt) const XMMATRIX W = XMLoadFloat4x4(&transform->world); - for (size_t j = 0; j < mesh->indices.size(); j += 3) + if (painting) { - const uint32_t triangle[] = { - mesh->indices[j + 0], - mesh->indices[j + 1], - mesh->indices[j + 2], - }; - const XMVECTOR P[arraysize(triangle)] = { - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), - XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), - }; - - if (painting) + for (size_t j = 0; j < mesh->vertex_positions.size(); ++j) { - XMVECTOR PT[arraysize(triangle)]; - for (int k = 0; k < arraysize(triangle); ++k) + XMVECTOR P, N; + if (armature == nullptr) { - PT[k] = XMVector3TransformCoord(P[k], VP); - PT[k] = PT[k] * MUL + ADD; - PT[k] = PT[k] * SCREEN; + P = XMLoadFloat3(&mesh->vertex_positions[j]); + N = XMLoadFloat3(&mesh->vertex_normals[j]); } - - bool culled = false; - if (!backfaces) + else { - const XMVECTOR N = XMVector3Normalize(XMVector3Cross(PT[1] - PT[0], PT[2] - PT[1])); - culled = XMVectorGetZ(N) > 0; + P = wiScene::SkinVertex(*mesh, *armature, (uint32_t)j, &N); } + P = XMVector3Transform(P, W); + N = XMVector3Normalize(XMVector3TransformNormal(N, W)); - if (!culled) + if (!backfaces && XMVectorGetX(XMVector3Dot(F, N)) > 0) + continue; + + P = XMVector3TransformCoord(P, VP); + P = P * MUL + ADD; + P = P * SCREEN; + + const float z = XMVectorGetZ(P); + const float dist = XMVectorGetX(XMVector2Length(C - P)); + if (z >= 0 && z <= 1 && dist <= radius) { - for (int k = 0; k < arraysize(triangle); ++k) + RecordHistory(true); + switch (mode) { - const float z = XMVectorGetZ(PT[k]); - const float dist = XMVectorGetX(XMVector2Length(C - PT[k])); - if (z >= 0 && z <= 1 && dist <= radius) + case MODE_HAIRPARTICLE_ADD_TRIANGLE: + hair->vertex_lengths[j] = 1.0f; + break; + case MODE_HAIRPARTICLE_REMOVE_TRIANGLE: + hair->vertex_lengths[j] = 0; + break; + case MODE_HAIRPARTICLE_LENGTH: + if (hair->vertex_lengths[j] > 0) // don't change distribution { - RecordHistory(true); - switch (mode) - { - case MODE_HAIRPARTICLE_ADD_TRIANGLE: - hair->vertex_lengths[triangle[k]] = 1.0f; - break; - case MODE_HAIRPARTICLE_REMOVE_TRIANGLE: - hair->vertex_lengths[triangle[k]] = 0; - break; - case MODE_HAIRPARTICLE_LENGTH: - const float affection = amount * std::powf(1 - (dist / radius), falloff); - hair->vertex_lengths[triangle[k]] = wiMath::Lerp(hair->vertex_lengths[triangle[k]], color_float.w, affection); - // don't let it "remove" the vertex by keeping its length above zero: - // (because if removed, distribution also changes which might be distracting) - hair->vertex_lengths[triangle[k]] = wiMath::Clamp(hair->vertex_lengths[triangle[k]], 1.0f / 255.0f, 1.0f); - break; - } - hair->_flags |= wiHairParticle::REBUILD_BUFFERS; + const float affection = amount * std::powf(1 - (dist / radius), falloff); + hair->vertex_lengths[j] = wiMath::Lerp(hair->vertex_lengths[j], color_float.w, affection); + // don't let it "remove" the vertex by keeping its length above zero: + // (because if removed, distribution also changes which might be distracting) + hair->vertex_lengths[j] = wiMath::Clamp(hair->vertex_lengths[j], 1.0f / 255.0f, 1.0f); } + break; } + hair->_flags |= wiHairParticle::REBUILD_BUFFERS; } } + } - if (wireframe) + if (wireframe) + { + for (size_t j = 0; j < mesh->indices.size(); j += 3) { + const uint32_t triangle[] = { + mesh->indices[j + 0], + mesh->indices[j + 1], + mesh->indices[j + 2], + }; + const XMVECTOR P[arraysize(triangle)] = { + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), + }; + wiRenderer::RenderableTriangle tri; XMStoreFloat3(&tri.positionA, P[0]); XMStoreFloat3(&tri.positionB, P[1]); XMStoreFloat3(&tri.positionC, P[2]); wiRenderer::DrawTriangle(tri, true); } - } - for (size_t j = 0; j < hair->indices.size() && wireframe; j += 3) - { - const uint32_t triangle[] = { - hair->indices[j + 0], - hair->indices[j + 1], - hair->indices[j + 2], - }; + for (size_t j = 0; j < hair->indices.size() && wireframe; j += 3) + { + const uint32_t triangle[] = { + hair->indices[j + 0], + hair->indices[j + 1], + hair->indices[j + 2], + }; + const XMVECTOR P[arraysize(triangle)] = { + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[0]]) : wiScene::SkinVertex(*mesh, *armature, triangle[0]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[1]]) : wiScene::SkinVertex(*mesh, *armature, triangle[1]), W), + XMVector3Transform(armature == nullptr ? XMLoadFloat3(&mesh->vertex_positions[triangle[2]]) : wiScene::SkinVertex(*mesh, *armature, triangle[2]), W), + }; - wiRenderer::RenderableTriangle tri; - XMStoreFloat3(&tri.positionA, XMVector3Transform(XMLoadFloat3(&mesh->vertex_positions[triangle[0]]), W)); - XMStoreFloat3(&tri.positionB, XMVector3Transform(XMLoadFloat3(&mesh->vertex_positions[triangle[1]]), W)); - XMStoreFloat3(&tri.positionC, XMVector3Transform(XMLoadFloat3(&mesh->vertex_positions[triangle[2]]), W)); - tri.colorA = tri.colorB = tri.colorC = XMFLOAT4(1, 0, 1, 0.9f); - wiRenderer::DrawTriangle(tri, false); + wiRenderer::RenderableTriangle tri; + XMStoreFloat3(&tri.positionA, P[0]); + XMStoreFloat3(&tri.positionB, P[1]); + XMStoreFloat3(&tri.positionC, P[2]); + tri.colorA = tri.colorB = tri.colorC = XMFLOAT4(1, 0, 1, 0.9f); + wiRenderer::DrawTriangle(tri, false); + } } } break; diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index be90f6927..6ac2035d0 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -347,7 +347,7 @@ namespace wiScene // vertexBuffer - POSITION + NORMAL + SUBSETINDEX: { - std::vector vertex_subsetindices(vertex_positions.size()); + vertex_subsets.resize(vertex_positions.size()); uint32_t subsetCounter = 0; for (auto& subset : subsets) @@ -355,7 +355,7 @@ namespace wiScene for (uint32_t i = 0; i < subset.indexCount; ++i) { uint32_t index = indices[subset.indexOffset + i]; - vertex_subsetindices[index] = subsetCounter; + vertex_subsets[index] = subsetCounter; } subsetCounter++; } @@ -366,7 +366,7 @@ namespace wiScene const XMFLOAT3& pos = vertex_positions[i]; XMFLOAT3& nor = vertex_normals.empty() ? XMFLOAT3(1, 1, 1) : vertex_normals[i]; XMStoreFloat3(&nor, XMVector3Normalize(XMLoadFloat3(&nor))); - uint32_t subsetIndex = vertex_subsetindices[i]; + uint32_t subsetIndex = vertex_subsets[i]; vertices[i].FromFULL(pos, nor, subsetIndex); _min = wiMath::Min(_min, pos); @@ -900,17 +900,6 @@ namespace wiScene { vertex_positions_simulation.resize(mesh.vertex_positions.size()); - std::vector vertex_subsetindices(mesh.vertex_positions.size()); - uint32_t subsetCounter = 0; - for (auto& subset : mesh.subsets) - { - for (uint32_t i = 0; i < subset.indexCount; ++i) - { - uint32_t index = mesh.indices[subset.indexOffset + i]; - vertex_subsetindices[index] = subsetCounter; - } - subsetCounter++; - } XMMATRIX W = XMLoadFloat4x4(&worldMatrix); XMFLOAT3 _min = XMFLOAT3(FLT_MAX, FLT_MAX, FLT_MAX); XMFLOAT3 _max = XMFLOAT3(-FLT_MAX, -FLT_MAX, -FLT_MAX); @@ -920,7 +909,7 @@ namespace wiScene XMStoreFloat3(&pos, XMVector3Transform(XMLoadFloat3(&pos), W)); XMFLOAT3 nor = mesh.vertex_normals.empty() ? XMFLOAT3(1, 1, 1) : mesh.vertex_normals[i]; XMStoreFloat3(&nor, XMVector3Normalize(XMVector3TransformNormal(XMLoadFloat3(&nor), W))); - uint32_t subsetIndex = vertex_subsetindices[i]; + uint32_t subsetIndex = mesh.vertex_subsets[i]; vertex_positions_simulation[i].FromFULL(pos, nor, subsetIndex); _min = wiMath::Min(_min, pos); _max = wiMath::Max(_max, pos); @@ -2430,18 +2419,35 @@ namespace wiScene } - XMVECTOR SkinVertex(const MeshComponent& mesh, const ArmatureComponent& armature, uint32_t index) + XMVECTOR SkinVertex(const MeshComponent& mesh, const ArmatureComponent& armature, uint32_t index, XMVECTOR* N) { XMVECTOR P = XMLoadFloat3(&mesh.vertex_positions[index]); const XMUINT4& ind = mesh.vertex_boneindices[index]; const XMFLOAT4& wei = mesh.vertex_boneweights[index]; - XMVECTOR skinned_pos; - skinned_pos = XMVector3Transform(P, armature.boneData[ind.x].Load()) * wei.x; - skinned_pos += XMVector3Transform(P, armature.boneData[ind.y].Load()) * wei.y; - skinned_pos += XMVector3Transform(P, armature.boneData[ind.z].Load()) * wei.z; - skinned_pos += XMVector3Transform(P, armature.boneData[ind.w].Load()) * wei.w; - P = skinned_pos; + const XMMATRIX M[] = { + armature.boneData[ind.x].Load(), + armature.boneData[ind.y].Load(), + armature.boneData[ind.z].Load(), + armature.boneData[ind.w].Load(), + }; + + XMVECTOR skinned; + skinned = XMVector3Transform(P, M[0]) * wei.x; + skinned += XMVector3Transform(P, M[1]) * wei.y; + skinned += XMVector3Transform(P, M[2]) * wei.z; + skinned += XMVector3Transform(P, M[3]) * wei.w; + P = skinned; + + if (N != nullptr) + { + *N = XMLoadFloat3(&mesh.vertex_normals[index]); + skinned = XMVector3TransformNormal(*N, M[0]) * wei.x; + skinned += XMVector3TransformNormal(*N, M[1]) * wei.y; + skinned += XMVector3TransformNormal(*N, M[2]) * wei.z; + skinned += XMVector3TransformNormal(*N, M[3]) * wei.w; + *N = XMVector3Normalize(skinned); + } return P; } diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index e58a4d8a3..6692892d9 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -283,6 +283,7 @@ namespace wiScene wiGraphics::GPUBuffer vertexBuffer_ATL; wiGraphics::GPUBuffer vertexBuffer_PRE; wiGraphics::GPUBuffer streamoutBuffer_POS; + std::vector vertex_subsets; inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } } @@ -1273,7 +1274,8 @@ namespace wiScene ); // Returns skinned vertex position in armature local space - XMVECTOR SkinVertex(const MeshComponent& mesh, const ArmatureComponent& armature, uint32_t index); + // N : normal (out, optional) + XMVECTOR SkinVertex(const MeshComponent& mesh, const ArmatureComponent& armature, uint32_t index, XMVECTOR* N = nullptr); // Helper that manages a global scene diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b3b769ed3..dd674bb7b 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 39; // minor bug fixes, alterations, refactors, updates - const int revision = 32; + const int revision = 33; long GetVersion()