Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
turanszkij committed Feb 24, 2024
1 parent 8a1174e commit 19d88ab
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 57 deletions.
2 changes: 1 addition & 1 deletion Content/Documentation/ScriptingAPI-Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ The scene holds components. Entity handles can be used to retrieve associated co

- RetargetAnimation(Entity dst, src, bool bake_data) : Entity entity -- Retargets an animation from a Humanoid to an other Humanoid such that the new animation will play back on the destination humanoid. dst : destination humanoid that the animation will be fit onto src : the animation to copy, it should already target humanoid bones. bake_data : if true, the retargeted data will be baked into a new animation data. If false, it will reuse the source animation data without creating a new one and retargeting will be applied at runtime on every Update. Returns entity ID of the new animation or INVALID_ENTITY if retargeting was not successful

- VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, bool subtract = false) -- voxelizes a single object into the voxel grid. Subtract parameter controls whether the voxels are added (true) or removed (false). This returns immediately after voxelization is finished.
- VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, bool subtract = false, opt int lod = 0) -- voxelizes a single object into the voxel grid. Subtract parameter controls whether the voxels are added (true) or removed (false). Lod argument selects object's level of detail

#### NameComponent
Holds a string that can more easily identify an entity to humans than an entity ID.
Expand Down
1 change: 1 addition & 0 deletions Editor/IconDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#define ICON_VOXELGRID ICON_FA_TABLE_CELLS
#define ICON_CLEARVOXELS ICON_FA_TRASH_CAN
#define ICON_VOXELIZE ICON_FA_WAVE_SQUARE
#define ICON_VOXELBOUNDS ICON_FA_VECTOR_SQUARE

#define ICON_SAVE ICON_FA_FLOPPY_DISK
#define ICON_OPEN ICON_FA_FOLDER_OPEN
Expand Down
4 changes: 2 additions & 2 deletions Editor/OptionsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ void OptionsWindow::Create(EditorComponent* _editor)
case NEW_VOXELGRID:
{
pick.entity = CreateEntity();
scene.voxel_grids.Create(pick.entity).init(32, 32, 32);
scene.transforms.Create(pick.entity);
scene.voxel_grids.Create(pick.entity).init(64, 64, 64);
scene.transforms.Create(pick.entity).Scale(XMFLOAT3(0.25f, 0.25f, 0.25f));
scene.names.Create(pick.entity) = "voxelgrid";
}
break;
Expand Down
84 changes: 60 additions & 24 deletions Editor/VoxelGridWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create(ICON_VOXELGRID " VoxelGrid", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
SetSize(XMFLOAT2(520, 300));
SetSize(XMFLOAT2(520, 400));

closeButton.SetTooltip("Delete VoxelGrid");
OnClose([=](wi::gui::EventArgs args) {
Expand Down Expand Up @@ -42,7 +42,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(uint32_t(args.iValue), voxelgrid->resolution.y, voxelgrid->resolution.z);
voxelgrid->init(uint32_t(std::max(1, args.iValue)), voxelgrid->resolution.y, voxelgrid->resolution.z);
});
AddWidget(&dimXInput);

Expand All @@ -54,7 +54,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(voxelgrid->resolution.x, uint32_t(args.iValue), voxelgrid->resolution.z);
voxelgrid->init(voxelgrid->resolution.x, uint32_t(std::max(1, args.iValue)), voxelgrid->resolution.z);
});
AddWidget(&dimYInput);

Expand All @@ -66,7 +66,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->init(voxelgrid->resolution.x, voxelgrid->resolution.y, uint32_t(args.iValue));
voxelgrid->init(voxelgrid->resolution.x, voxelgrid->resolution.y, uint32_t(std::max(1, args.iValue)));
});
AddWidget(&dimZInput);

Expand All @@ -81,35 +81,68 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
});
AddWidget(&clearButton);

generateWholeButton.Create("Generate full grid " ICON_VOXELIZE);
generateWholeButton.SetTooltip("Generate navigation grid including all meshes.");
generateWholeButton.SetSize(XMFLOAT2(100, hei));
generateWholeButton.OnClick([=](wi::gui::EventArgs args) {
voxelizeObjectsButton.Create("Voxelize objects " ICON_VOXELIZE);
voxelizeObjectsButton.SetTooltip("Generate navigation grid including all meshes.");
voxelizeObjectsButton.SetSize(XMFLOAT2(100, hei));
voxelizeObjectsButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
wi::jobsystem::context ctx;
voxelgrid->cleardata();
scene.VoxelizeWholeScene(ctx, *voxelgrid);
wi::jobsystem::Wait(ctx);
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_OBJECT_ALL);
});
AddWidget(&generateWholeButton);
AddWidget(&voxelizeObjectsButton);

generateNavigationButton.Create("Generate navigation grid " ICON_VOXELIZE);
generateNavigationButton.SetTooltip("Generate navigation grid including all navmeshes (object tagged as navmesh).");
generateNavigationButton.SetSize(XMFLOAT2(100, hei));
generateNavigationButton.OnClick([=](wi::gui::EventArgs args) {
voxelizeNavigationButton.Create("Voxelize navigation " ICON_VOXELIZE);
voxelizeNavigationButton.SetTooltip("Generate navigation grid including all navmeshes (object tagged as navmesh).");
voxelizeNavigationButton.SetSize(XMFLOAT2(100, hei));
voxelizeNavigationButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
wi::jobsystem::context ctx;
voxelgrid->cleardata();
scene.VoxelizeNavigation(ctx, *voxelgrid);
wi::jobsystem::Wait(ctx);
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_NAVIGATION_MESH);
});
AddWidget(&voxelizeNavigationButton);

voxelizeCollidersButton.Create("Voxelize CPU colliders " ICON_VOXELIZE);
voxelizeCollidersButton.SetTooltip("Generate navigation grid including all CPU colliders.");
voxelizeCollidersButton.SetSize(XMFLOAT2(100, hei));
voxelizeCollidersButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
scene.VoxelizeScene(*voxelgrid, subtractCheckBox.GetCheck(), wi::enums::FILTER_COLLIDER);
});
AddWidget(&generateNavigationButton);
AddWidget(&voxelizeCollidersButton);

fitToSceneButton.Create("Fit bounds to scene " ICON_VOXELBOUNDS);
fitToSceneButton.SetTooltip("Fit the bounds of the voxel grid onto the whole scene.");
fitToSceneButton.SetSize(XMFLOAT2(100, hei));
fitToSceneButton.OnClick([=](wi::gui::EventArgs args) {
Scene& scene = editor->GetCurrentScene();
if (scene.bounds.getArea() < 0)
return;
wi::VoxelGrid* voxelgrid = scene.voxel_grids.GetComponent(entity);
if (voxelgrid == nullptr)
return;
voxelgrid->from_aabb(scene.bounds);
TransformComponent* transform = scene.transforms.GetComponent(entity);
if (transform != nullptr)
{
// feed back to transform component if it exists:
transform->translation_local = voxelgrid->center;
transform->scale_local = voxelgrid->voxelSize;
transform->SetDirty();
}
});
AddWidget(&fitToSceneButton);

subtractCheckBox.Create("Subtraction mode: ");
subtractCheckBox.SetTooltip("If enabled, voxelization will be subtractive, so it will remove voxels instead of add.");
subtractCheckBox.SetSize(XMFLOAT2(hei, hei));
AddWidget(&subtractCheckBox);

debugAllCheckBox.Create("Debug draw all: ");
debugAllCheckBox.SetTooltip("Draw all voxel grids, whether they are selected or not.");
Expand Down Expand Up @@ -197,7 +230,10 @@ void VoxelGridWindow::ResizeLayout()
y += padding;

add_fullwidth(clearButton);
add_fullwidth(generateWholeButton);
add_fullwidth(generateNavigationButton);
add_fullwidth(voxelizeObjectsButton);
add_fullwidth(voxelizeCollidersButton);
add_fullwidth(voxelizeNavigationButton);
add_fullwidth(fitToSceneButton);
add_right(subtractCheckBox);
add_right(debugAllCheckBox);
}
7 changes: 5 additions & 2 deletions Editor/VoxelGridWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ class VoxelGridWindow : public wi::gui::Window
wi::gui::TextInputField dimYInput;
wi::gui::TextInputField dimZInput;
wi::gui::Button clearButton;
wi::gui::Button generateWholeButton;
wi::gui::Button generateNavigationButton;
wi::gui::Button voxelizeObjectsButton;
wi::gui::Button voxelizeNavigationButton;
wi::gui::Button voxelizeCollidersButton;
wi::gui::Button fitToSceneButton;
wi::gui::CheckBox subtractCheckBox;
wi::gui::CheckBox debugAllCheckBox;

void ResizeLayout() override;
Expand Down
82 changes: 64 additions & 18 deletions WickedEngine/wiScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5750,7 +5750,7 @@ namespace wi::scene
return result;
}

void Scene::VoxelizeObject(size_t objectIndex, wi::VoxelGrid& grid, bool subtract)
void Scene::VoxelizeObject(size_t objectIndex, wi::VoxelGrid& grid, bool subtract, uint32_t lod)
{
if (objectIndex >= objects.GetCount() || objectIndex >= aabb_objects.size())
return;
Expand All @@ -5766,7 +5766,7 @@ namespace wi::scene

uint32_t first_subset = 0;
uint32_t last_subset = 0;
mesh->GetLODSubsetRange(0, first_subset, last_subset);
mesh->GetLODSubsetRange(lod, first_subset, last_subset);
for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex)
{
const MeshComponent::MeshSubset& subset = mesh->subsets[subsetIndex];
Expand Down Expand Up @@ -5816,28 +5816,74 @@ namespace wi::scene
}
}
}
void Scene::VoxelizeNavigation(wi::jobsystem::context& ctx, wi::VoxelGrid& voxelgrid)

void Scene::VoxelizeScene(wi::VoxelGrid& voxelgrid, bool subtract, wi::enums::FILTER filterMask, uint32_t layerMask, uint32_t lod)
{
for (size_t i = 0; i < objects.GetCount(); ++i)
wi::jobsystem::context ctx;
if ((filterMask & FILTER_COLLIDER))
{
const ObjectComponent& object = objects[i];
if ((object.GetFilterMask() & FILTER::FILTER_NAVIGATION_MESH) == 0)
continue;
for (size_t i = 0; i < collider_count_cpu; ++i)
{
const ColliderComponent& collider = colliders_cpu[i];

wi::jobsystem::Execute(ctx, [this, i, &voxelgrid](wi::jobsystem::JobArgs args) {
VoxelizeObject(i, voxelgrid);
});
if ((collider.layerMask & layerMask) == 0)
continue;

switch (collider.shape)
{
default:
case ColliderComponent::Shape::Sphere:
{
Sphere sphere = collider.sphere;
// TODO: fix heap allocating lambda capture!
wi::jobsystem::Execute(ctx, [&voxelgrid, subtract, sphere](wi::jobsystem::JobArgs args) {
voxelgrid.inject_sphere(sphere, subtract);
});
}
break;
case ColliderComponent::Shape::Capsule:
{
AABB aabb = collider.capsule.getAABB();
// TODO: fix heap allocating lambda capture!
wi::jobsystem::Execute(ctx, [&voxelgrid, subtract, aabb](wi::jobsystem::JobArgs args) {
voxelgrid.inject_aabb(aabb, subtract);
});
}
break;
case ColliderComponent::Shape::Plane:
{
XMMATRIX planeMatrix = XMMatrixInverse(nullptr, XMLoadFloat4x4(&collider.plane.projection));
XMVECTOR P0 = XMVector3Transform(XMVectorSet(-1, 0, -1, 1), planeMatrix);
XMVECTOR P1 = XMVector3Transform(XMVectorSet(1, 0, -1, 1), planeMatrix);
XMVECTOR P2 = XMVector3Transform(XMVectorSet(1, 0, 1, 1), planeMatrix);
XMVECTOR P3 = XMVector3Transform(XMVectorSet(-1, 0, 1, 1), planeMatrix);
// TODO: fix heap allocating lambda capture!
wi::jobsystem::Execute(ctx, [&voxelgrid, subtract, P0, P1, P2, P3](wi::jobsystem::JobArgs args) {
voxelgrid.inject_triangle(P0, P1, P2, subtract);
voxelgrid.inject_triangle(P0, P2, P3, subtract);
});
}
break;
}
}
}
}
void Scene::VoxelizeWholeScene(wi::jobsystem::context& ctx, wi::VoxelGrid& voxelgrid)
{
for (size_t i = 0; i < objects.GetCount(); ++i)
if (filterMask & FILTER_OBJECT_ALL)
{
const ObjectComponent& object = objects[i];
wi::jobsystem::Execute(ctx, [this, i, &voxelgrid](wi::jobsystem::JobArgs args) {
VoxelizeObject(i, voxelgrid);
});
for (size_t i = 0; i < objects.GetCount(); ++i)
{
const ObjectComponent& object = objects[i];
if ((filterMask & object.GetFilterMask()) == 0)
continue;
const AABB& aabb = aabb_objects[i];
if ((layerMask & aabb.layerMask) == 0)
continue;
// TODO: fix heap allocating lambda capture!
wi::jobsystem::Execute(ctx, [this, &voxelgrid, subtract, lod, i](wi::jobsystem::JobArgs args) {
VoxelizeObject(i, voxelgrid, subtract, lod);
});
}
}
wi::jobsystem::Wait(ctx);
}

XMFLOAT3 Scene::GetPositionOnSurface(wi::ecs::Entity objectEntity, int vertexID0, int vertexID1, int vertexID2, const XMFLOAT2& bary) const
Expand Down
9 changes: 3 additions & 6 deletions WickedEngine/wiScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,10 @@ namespace wi::scene

// All triangles of the object will be injected into the voxel grid
// subtract: if false (default), voxels will be added, if true then voxels will be removed
void VoxelizeObject(size_t objectIndex, wi::VoxelGrid& grid, bool subtract = false);
void VoxelizeObject(size_t objectIndex, wi::VoxelGrid& grid, bool subtract = false, uint32_t lod = 0);

// Voxelize all navigation meshes into a voxel grid
void VoxelizeNavigation(wi::jobsystem::context& ctx, wi::VoxelGrid& voxelgrid);

// Voxelize all meshes into a voxel grid
void VoxelizeWholeScene(wi::jobsystem::context& ctx, wi::VoxelGrid& voxelgrid);
// Voxelize all meshes that match the filters into a voxel grid
void VoxelizeScene(wi::VoxelGrid& voxelgrid, bool subtract = false, wi::enums::FILTER filterMask = wi::enums::FILTER_ALL, uint32_t layerMask = ~0, uint32_t lod = 0);

// Get the current position on the surface of an object, tracked by the triangle barycentrics
XMFLOAT3 GetPositionOnSurface(wi::ecs::Entity objectEntity, int vertexID0, int vertexID1, int vertexID2, const XMFLOAT2& bary) const;
Expand Down
11 changes: 8 additions & 3 deletions WickedEngine/wiScene_BindLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2947,22 +2947,27 @@ int Scene_BindLua::VoxelizeObject(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc < 2)
{
wi::lua::SError(L, "VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, opt bool subtract = false) not enough arguments!");
wi::lua::SError(L, "VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, opt bool subtract = false, opt int lod = 0) not enough arguments!");
return 0;
}
size_t objectIndex = (size_t)wi::lua::SGetInt(L, 1);
VoxelGrid_BindLua* voxelgrid = Luna<VoxelGrid_BindLua>::lightcheck(L, 2);
if (voxelgrid == nullptr)
{
wi::lua::SError(L, "VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, opt bool subtract = false) second argument is not a VoxelGrid!");
wi::lua::SError(L, "VoxelizeObject(int objectIndex, VoxelGrid voxelgrid, opt bool subtract = false, opt int lod = 0) second argument is not a VoxelGrid!");
return 0;
}
bool subtract = false;
uint32_t lod = 0;
if (argc > 2)
{
subtract = wi::lua::SGetBool(L, 3);
if (argc > 3)
{
lod = (uint32_t)wi::lua::SGetInt(L, 4);
}
}
scene->VoxelizeObject(objectIndex, voxelgrid->voxelgrid, subtract);
scene->VoxelizeObject(objectIndex, voxelgrid->voxelgrid, subtract, lod);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion WickedEngine/wiVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 381;
const int revision = 382;

const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

Expand Down
1 change: 1 addition & 0 deletions features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Expressions
Humanoid rig
Animation retargeting
Video decoding: H264
3D voxel path finding

GLTF 2.0 - KHR extensions supported:
KHR_materials_unlit
Expand Down

0 comments on commit 19d88ab

Please sign in to comment.