diff --git a/Editor/ComponentsWindow.cpp b/Editor/ComponentsWindow.cpp
index 4820f2086..c01bc7522 100644
--- a/Editor/ComponentsWindow.cpp
+++ b/Editor/ComponentsWindow.cpp
@@ -66,8 +66,8 @@ void ComponentsWindow::Create(EditorComponent* _editor)
newComponentCombo.AddItem("Force Field " ICON_FORCE, 13);
newComponentCombo.AddItem("Animation " ICON_ANIMATION, 14);
newComponentCombo.AddItem("Script " ICON_SCRIPT, 15);
- newComponentCombo.AddItem("Rigid Body " ICON_RIGIDBODY, 16);
- newComponentCombo.AddItem("Soft Body " ICON_SOFTBODY, 17);
+ newComponentCombo.AddItem("Rigid Body Physics " ICON_RIGIDBODY, 16);
+ newComponentCombo.AddItem("Soft Body Physics " ICON_SOFTBODY, 17);
newComponentCombo.AddItem("Collider " ICON_COLLIDER, 18);
newComponentCombo.AddItem("Camera " ICON_CAMERA, 20);
newComponentCombo.AddItem("Object " ICON_OBJECT, 21);
diff --git a/Editor/Editor_SOURCE.vcxitems b/Editor/Editor_SOURCE.vcxitems
index 8dbe8f2e2..8c12175ac 100644
--- a/Editor/Editor_SOURCE.vcxitems
+++ b/Editor/Editor_SOURCE.vcxitems
@@ -192,15 +192,7 @@
true
true
-
- true
- true
-
-
- true
- true
-
-
+
true
true
@@ -244,33 +236,6 @@
-
- true
- true
-
-
- true
- true
-
-
- true
- true
-
-
- true
- true
-
-
- true
- true
-
-
- true
- true
-
-
- true
- true
-
+
\ No newline at end of file
diff --git a/Editor/Editor_SOURCE.vcxitems.filters b/Editor/Editor_SOURCE.vcxitems.filters
index d76dbcbcf..1784e052e 100644
--- a/Editor/Editor_SOURCE.vcxitems.filters
+++ b/Editor/Editor_SOURCE.vcxitems.filters
@@ -135,16 +135,10 @@
-
- terrain
-
-
- terrain
-
-
- terrain
-
+
+ terrain
+
@@ -184,25 +178,7 @@
-
- terrain
-
-
- terrain
-
-
- terrain
-
-
- terrain
-
-
- terrain
-
-
- terrain
-
-
+
terrain
diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp
index ea84fef74..56bc2e174 100644
--- a/Editor/ObjectWindow.cpp
+++ b/Editor/ObjectWindow.cpp
@@ -369,6 +369,19 @@ void ObjectWindow::Create(EditorComponent* _editor)
});
AddWidget(&lodSlider);
+ drawdistanceSlider.Create(0, 1000, 1, 10000, "Draw Distance: ");
+ drawdistanceSlider.SetTooltip("Specify the draw distance of the object");
+ drawdistanceSlider.SetSize(XMFLOAT2(wid, hei));
+ drawdistanceSlider.SetPos(XMFLOAT2(x, y += step));
+ drawdistanceSlider.OnSlide([&](wi::gui::EventArgs args) {
+ ObjectComponent* object = editor->GetCurrentScene().objects.GetComponent(entity);
+ if (object != nullptr)
+ {
+ object->draw_distance = args.fValue;
+ }
+ });
+ AddWidget(&drawdistanceSlider);
+
y += step;
@@ -597,6 +610,7 @@ void ObjectWindow::SetEntity(Entity entity)
cascadeMaskSlider.SetValue((float)object->cascadeMask);
ditherSlider.SetValue(object->GetTransparency());
lodSlider.SetValue(object->lod_distance_multiplier);
+ drawdistanceSlider.SetValue(object->draw_distance);
switch (colorComboBox.GetSelected())
{
@@ -667,6 +681,7 @@ void ObjectWindow::ResizeLayout()
add(ditherSlider);
add(cascadeMaskSlider);
add(lodSlider);
+ add(drawdistanceSlider);
add(colorComboBox);
add_fullwidth(colorPicker);
add(lightmapResolutionSlider);
diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h
index 712f08a50..bf3124671 100644
--- a/Editor/ObjectWindow.h
+++ b/Editor/ObjectWindow.h
@@ -18,6 +18,7 @@ public:
wi::gui::Slider ditherSlider;
wi::gui::Slider cascadeMaskSlider;
wi::gui::Slider lodSlider;
+ wi::gui::Slider drawdistanceSlider;
wi::gui::ComboBox colorComboBox;
wi::gui::ColorPicker colorPicker;
diff --git a/Editor/RigidBodyWindow.cpp b/Editor/RigidBodyWindow.cpp
index 2cabd0328..3db6fe075 100644
--- a/Editor/RigidBodyWindow.cpp
+++ b/Editor/RigidBodyWindow.cpp
@@ -332,32 +332,7 @@ void RigidBodyWindow::SetEntity(Entity entity)
kinematicCheckBox.SetCheck(physicsComponent->IsKinematic());
disabledeactivationCheckBox.SetCheck(physicsComponent->IsDisableDeactivation());
- if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::BOX)
- {
- collisionShapeComboBox.SetSelected(1);
- }
- else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::SPHERE)
- {
- collisionShapeComboBox.SetSelected(2);
- }
- else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CAPSULE)
- {
- collisionShapeComboBox.SetSelected(3);
- }
- else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL)
- {
- collisionShapeComboBox.SetSelected(4);
- }
- else if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH)
- {
- collisionShapeComboBox.SetSelected(5);
- }
- }
- else
- {
- collisionShapeComboBox.SetSelected(0);
- kinematicCheckBox.SetCheck(false);
- disabledeactivationCheckBox.SetCheck(false);
+ collisionShapeComboBox.SetSelectedByUserdata((uint64_t)physicsComponent->shape);
}
}
diff --git a/Editor/TerrainWindow.cpp b/Editor/TerrainWindow.cpp
index d7a2f7ffa..ce71dba82 100644
--- a/Editor/TerrainWindow.cpp
+++ b/Editor/TerrainWindow.cpp
@@ -296,6 +296,29 @@ void TerrainWindow::Create(EditorComponent* _editor)
float hei = 20;
float wid = 120;
+ auto generate_callback = [&]() {
+
+ terrain->SetCenterToCamEnabled(centerToCamCheckBox.GetCheck());
+ terrain->SetRemovalEnabled(removalCheckBox.GetCheck());
+ terrain->SetGrassEnabled(grassCheckBox.GetCheck());
+ terrain->lod_multiplier = lodSlider.GetValue();
+ terrain->texlod = texlodSlider.GetValue();
+ terrain->generation = (int)generationSlider.GetValue();
+ terrain->prop_generation = (int)propGenerationSlider.GetValue();
+ terrain->physics_generation = (int)physicsGenerationSlider.GetValue();
+ terrain->prop_density = propDensitySlider.GetValue();
+ terrain->grass_density = grassDensitySlider.GetValue();
+ terrain->chunk_scale = scaleSlider.GetValue();
+ terrain->seed = (uint32_t)seedSlider.GetValue();
+ terrain->bottomLevel = bottomLevelSlider.GetValue();
+ terrain->topLevel = topLevelSlider.GetValue();
+ terrain->region1 = region1Slider.GetValue();
+ terrain->region2 = region2Slider.GetValue();
+ terrain->region3 = region3Slider.GetValue();
+
+ terrain->SetGenerationStarted(false);
+ };
+
centerToCamCheckBox.Create("Center to Cam: ");
centerToCamCheckBox.SetTooltip("Automatically generate chunks around camera. This sets the center chunk to camera position.");
centerToCamCheckBox.SetSize(XMFLOAT2(hei, hei));
@@ -326,6 +349,17 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&grassCheckBox);
+ physicsCheckBox.Create("Physics: ");
+ physicsCheckBox.SetTooltip("Specify whether physics is enabled for newly generated terrain chunks.");
+ physicsCheckBox.SetSize(XMFLOAT2(hei, hei));
+ physicsCheckBox.SetPos(XMFLOAT2(x, y += step));
+ physicsCheckBox.SetCheck(true);
+ physicsCheckBox.OnClick([=](wi::gui::EventArgs args) {
+ terrain->SetPhysicsEnabled(args.bValue);
+ generate_callback();
+ });
+ AddWidget(&physicsCheckBox);
+
lodSlider.Create(0.0001f, 0.01f, 0.005f, 10000, "Mesh LOD Distance: ");
lodSlider.SetTooltip("Set the LOD (Level Of Detail) distance multiplier.\nLow values increase LOD detail in distance");
lodSlider.SetSize(XMFLOAT2(wid, hei));
@@ -365,14 +399,23 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&generationSlider);
- propSlider.Create(0, 16, 10, 16, "Prop Distance: ");
- propSlider.SetTooltip("How far out props will be generated (value is in number of chunks)");
- propSlider.SetSize(XMFLOAT2(wid, hei));
- propSlider.SetPos(XMFLOAT2(x, y += step));
- propSlider.OnSlide([this](wi::gui::EventArgs args) {
+ propGenerationSlider.Create(0, 16, 10, 16, "Prop Distance: ");
+ propGenerationSlider.SetTooltip("How far out props will be generated (value is in number of chunks)");
+ propGenerationSlider.SetSize(XMFLOAT2(wid, hei));
+ propGenerationSlider.SetPos(XMFLOAT2(x, y += step));
+ propGenerationSlider.OnSlide([this](wi::gui::EventArgs args) {
terrain->prop_generation = args.iValue;
});
- AddWidget(&propSlider);
+ AddWidget(&propGenerationSlider);
+
+ physicsGenerationSlider.Create(0, 16, 3, 16, "Physics Distance: ");
+ physicsGenerationSlider.SetTooltip("How far out physics meshes will be generated (value is in number of chunks)");
+ physicsGenerationSlider.SetSize(XMFLOAT2(wid, hei));
+ physicsGenerationSlider.SetPos(XMFLOAT2(x, y += step));
+ physicsGenerationSlider.OnSlide([this](wi::gui::EventArgs args) {
+ terrain->physics_generation = args.iValue;
+ });
+ AddWidget(&physicsGenerationSlider);
propDensitySlider.Create(0, 10, 1, 1000, "Prop Density: ");
propDensitySlider.SetTooltip("Modifies overall prop density.");
@@ -392,28 +435,6 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&grassDensitySlider);
- auto generate_callback = [&]() {
-
- terrain->SetCenterToCamEnabled(centerToCamCheckBox.GetCheck());
- terrain->SetRemovalEnabled(removalCheckBox.GetCheck());
- terrain->SetGrassEnabled(grassCheckBox.GetCheck());
- terrain->lod_multiplier = lodSlider.GetValue();
- terrain->texlod = texlodSlider.GetValue();
- terrain->generation = (int)generationSlider.GetValue();
- terrain->prop_generation = (int)propSlider.GetValue();
- terrain->prop_density = propDensitySlider.GetValue();
- terrain->grass_density = grassDensitySlider.GetValue();
- terrain->chunk_scale = scaleSlider.GetValue();
- terrain->seed = (uint32_t)seedSlider.GetValue();
- terrain->bottomLevel = bottomLevelSlider.GetValue();
- terrain->topLevel = topLevelSlider.GetValue();
- terrain->region1 = region1Slider.GetValue();
- terrain->region2 = region2Slider.GetValue();
- terrain->region3 = region3Slider.GetValue();
-
- terrain->SetGenerationStarted(false);
- };
-
presetCombo.Create("Preset: ");
presetCombo.SetTooltip("Select a terrain preset");
presetCombo.SetSize(XMFLOAT2(wid, hei));
@@ -747,10 +768,12 @@ void TerrainWindow::SetEntity(Entity entity)
centerToCamCheckBox.SetCheck(terrain->IsCenterToCamEnabled());
removalCheckBox.SetCheck(terrain->IsRemovalEnabled());
grassCheckBox.SetCheck(terrain->IsGrassEnabled());
+ physicsCheckBox.SetCheck(terrain->IsPhysicsEnabled());
lodSlider.SetValue(terrain->lod_multiplier);
texlodSlider.SetValue(terrain->texlod);
generationSlider.SetValue((float)terrain->generation);
- propSlider.SetValue((float)terrain->prop_generation);
+ propGenerationSlider.SetValue((float)terrain->prop_generation);
+ physicsGenerationSlider.SetValue((float)terrain->physics_generation);
propDensitySlider.SetValue(terrain->prop_density);
scaleSlider.SetValue(terrain->chunk_scale);
seedSlider.SetValue((float)terrain->seed);
@@ -836,12 +859,13 @@ void TerrainWindow::SetupAssets()
terrain_preset.material_LowAltitude.CreateRenderData();
terrain_preset.material_HighAltitude.CreateRenderData();
terrain_preset.material_GrassParticle.CreateRenderData();
+
+ Scene props_scene;
+ wi::scene::LoadModel(props_scene, "terrain/props.wiscene");
+
// Tree prop:
{
- Scene props_scene;
- wi::scene::LoadModel(props_scene, "terrain/tree.wiscene");
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
- prop.name = "tree";
prop.min_count_per_chunk = 0;
prop.max_count_per_chunk = 10;
prop.region = 0;
@@ -853,25 +877,29 @@ void TerrainWindow::SetupAssets()
prop.max_size = 8.0f;
prop.min_y_offset = -0.5f;
prop.max_y_offset = -0.5f;
- prop.mesh_entity = props_scene.Entity_FindByName("tree_mesh");
- props_scene.impostors.Create(prop.mesh_entity).swapInDistance = 200;
+ Entity mesh_entity = props_scene.Entity_FindByName("tree_mesh");
+ props_scene.impostors.Create(mesh_entity).swapInDistance = 200;
Entity object_entity = props_scene.Entity_FindByName("tree_object");
ObjectComponent* object = props_scene.objects.GetComponent(object_entity);
if (object != nullptr)
{
- prop.object = *object;
- prop.object.lod_distance_multiplier = 0.05f;
+ object->lod_distance_multiplier = 0.05f;
//prop.object.cascadeMask = 1; // they won't be rendered into the largest shadow cascade
}
+ wi::Archive archive;
+ EntitySerializer seri;
+ props_scene.Entity_Serialize(
+ archive,
+ seri,
+ object_entity,
+ wi::scene::Scene::EntitySerializeFlags::RECURSIVE | wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES
+ );
+ archive.WriteData(prop.data);
props_scene.Entity_Remove(object_entity); // The objects will be placed by terrain generator, we don't need the default object that the scene has anymore
- editor->GetCurrentScene().Merge(props_scene);
}
// Rock prop:
{
- Scene props_scene;
- wi::scene::LoadModel(props_scene, "terrain/rock.wiscene");
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
- prop.name = "rock";
prop.min_count_per_chunk = 0;
prop.max_count_per_chunk = 8;
prop.region = 0;
@@ -883,25 +911,29 @@ void TerrainWindow::SetupAssets()
prop.max_size = 4.0f;
prop.min_y_offset = -2;
prop.max_y_offset = 0.5f;
- prop.mesh_entity = props_scene.Entity_FindByName("rock_mesh");
+ Entity mesh_entity = props_scene.Entity_FindByName("rock_mesh");
Entity object_entity = props_scene.Entity_FindByName("rock_object");
ObjectComponent* object = props_scene.objects.GetComponent(object_entity);
if (object != nullptr)
{
- prop.object = *object;
- prop.object.lod_distance_multiplier = 0.02f;
- prop.object.cascadeMask = 1; // they won't be rendered into the largest shadow cascade
- prop.object.draw_distance = 400;
+ object->lod_distance_multiplier = 0.02f;
+ object->cascadeMask = 1; // they won't be rendered into the largest shadow cascade
+ object->draw_distance = 400;
}
+ wi::Archive archive;
+ EntitySerializer seri;
+ props_scene.Entity_Serialize(
+ archive,
+ seri,
+ object_entity,
+ wi::scene::Scene::EntitySerializeFlags::RECURSIVE | wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES
+ );
+ archive.WriteData(prop.data);
props_scene.Entity_Remove(object_entity); // The objects will be placed by terrain generator, we don't need the default object that the scene has anymore
- editor->GetCurrentScene().Merge(props_scene);
}
// Bush prop:
{
- Scene props_scene;
- wi::scene::LoadModel(props_scene, "terrain/bush.wiscene");
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
- prop.name = "bush";
prop.min_count_per_chunk = 0;
prop.max_count_per_chunk = 10;
prop.region = 0;
@@ -913,20 +945,29 @@ void TerrainWindow::SetupAssets()
prop.max_size = 1.5f;
prop.min_y_offset = -1;
prop.max_y_offset = 0;
- prop.mesh_entity = props_scene.Entity_FindByName("bush_mesh");
+ Entity mesh_entity = props_scene.Entity_FindByName("bush_mesh");
Entity object_entity = props_scene.Entity_FindByName("bush_object");
ObjectComponent* object = props_scene.objects.GetComponent(object_entity);
if (object != nullptr)
{
- prop.object = *object;
- prop.object.lod_distance_multiplier = 0.05f;
- prop.object.cascadeMask = 1; // they won't be rendered into the largest shadow cascade
- prop.object.draw_distance = 200;
+ object->lod_distance_multiplier = 0.05f;
+ object->cascadeMask = 1; // they won't be rendered into the largest shadow cascade
+ object->draw_distance = 200;
}
+ wi::Archive archive;
+ EntitySerializer seri;
+ props_scene.Entity_Serialize(
+ archive,
+ seri,
+ object_entity,
+ wi::scene::Scene::EntitySerializeFlags::RECURSIVE | wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES
+ );
+ archive.WriteData(prop.data);
props_scene.Entity_Remove(object_entity); // The objects will be placed by terrain generator, we don't need the default object that the scene has anymore
- editor->GetCurrentScene().Merge(props_scene);
}
+ editor->GetCurrentScene().Merge(props_scene);
+
terrain = &terrain_preset;
presetCombo.SetSelected(0);
}
@@ -984,13 +1025,15 @@ void TerrainWindow::ResizeLayout()
widget.SetEnabled(true);
};
- add_checkbox(centerToCamCheckBox);
add_checkbox(removalCheckBox);
+ centerToCamCheckBox.SetPos(XMFLOAT2(removalCheckBox.GetPos().x - 100, removalCheckBox.GetPos().y));
add_checkbox(grassCheckBox);
+ physicsCheckBox.SetPos(XMFLOAT2(grassCheckBox.GetPos().x - 100, grassCheckBox.GetPos().y));
add(lodSlider);
add(texlodSlider);
add(generationSlider);
- add(propSlider);
+ add(propGenerationSlider);
+ add(physicsGenerationSlider);
add(propDensitySlider);
add(grassDensitySlider);
add(presetCombo);
diff --git a/Editor/TerrainWindow.h b/Editor/TerrainWindow.h
index 2673370a8..c885e9dcf 100644
--- a/Editor/TerrainWindow.h
+++ b/Editor/TerrainWindow.h
@@ -55,10 +55,12 @@ public:
wi::gui::CheckBox centerToCamCheckBox;
wi::gui::CheckBox removalCheckBox;
wi::gui::CheckBox grassCheckBox;
+ wi::gui::CheckBox physicsCheckBox;
wi::gui::Slider lodSlider;
wi::gui::Slider texlodSlider;
wi::gui::Slider generationSlider;
- wi::gui::Slider propSlider;
+ wi::gui::Slider propGenerationSlider;
+ wi::gui::Slider physicsGenerationSlider;
wi::gui::Slider propDensitySlider;
wi::gui::Slider grassDensitySlider;
wi::gui::ComboBox presetCombo;
diff --git a/Editor/terrain/base-LICENSE.txt b/Editor/terrain/base-LICENSE.txt
deleted file mode 100644
index 1b06d2c64..000000000
--- a/Editor/terrain/base-LICENSE.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-ambientCG (ambientCG.com)
-CC0 1.0 Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
-Grass001 by ambientCG
-https://ambientcg.com/a/Grass001
\ No newline at end of file
diff --git a/Editor/terrain/bush-LICENSE.txt b/Editor/terrain/bush-LICENSE.txt
deleted file mode 100644
index 666fa1848..000000000
--- a/Editor/terrain/bush-LICENSE.txt
+++ /dev/null
@@ -1 +0,0 @@
-https://www.cgtrader.com/free-3d-models/plant/bush/mediteranean-bush
\ No newline at end of file
diff --git a/Editor/terrain/bush.wiscene b/Editor/terrain/bush.wiscene
deleted file mode 100644
index 97b337498..000000000
Binary files a/Editor/terrain/bush.wiscene and /dev/null differ
diff --git a/Editor/terrain/high_altitude-LICENSE.txt b/Editor/terrain/high_altitude-LICENSE.txt
deleted file mode 100644
index 1490a7370..000000000
--- a/Editor/terrain/high_altitude-LICENSE.txt
+++ /dev/null
@@ -1 +0,0 @@
-https://www.sharetextures.com/textures/ground/snow_ground_3/
\ No newline at end of file
diff --git a/Editor/terrain/licenses.txt b/Editor/terrain/licenses.txt
new file mode 100644
index 000000000..8cbade39e
--- /dev/null
+++ b/Editor/terrain/licenses.txt
@@ -0,0 +1,26 @@
+Bush:
+https://www.cgtrader.com/free-3d-models/plant/bush/mediteranean-bush
+
+Rock:
+https://www.cgtrader.com/free-3d-models/plant/other/rocks-56c7a2d1-2e36-4b17-8d79-2a69ab29d860
+
+Tree:
+https://free3d.com/3d-model/tree02-35663.html
+
+Grass texture:
+ambientCG (ambientCG.com)
+CC0 1.0 Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
+Grass001 by ambientCG
+https://ambientcg.com/a/Grass001
+
+Snow texture:
+https://www.sharetextures.com/textures/ground/snow_ground_3/
+
+Sand texture:
+https://www.cgbookcase.com/textures/sandy-gravel-01/?source=3dassets.one
+
+Stone texture:
+ambientCG (ambientCG.com)
+CC0 1.0 Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
+Rock048 by ambientCG
+https://ambientcg.com/a/Rock048
diff --git a/Editor/terrain/low_altitude-LICENSE.txt b/Editor/terrain/low_altitude-LICENSE.txt
deleted file mode 100644
index a755f4192..000000000
--- a/Editor/terrain/low_altitude-LICENSE.txt
+++ /dev/null
@@ -1 +0,0 @@
-https://www.cgbookcase.com/textures/sandy-gravel-01/?source=3dassets.one
\ No newline at end of file
diff --git a/Editor/terrain/tree.wiscene b/Editor/terrain/props.wiscene
similarity index 58%
rename from Editor/terrain/tree.wiscene
rename to Editor/terrain/props.wiscene
index 14f267114..9de676b49 100644
Binary files a/Editor/terrain/tree.wiscene and b/Editor/terrain/props.wiscene differ
diff --git a/Editor/terrain/rock-LICENSE.txt b/Editor/terrain/rock-LICENSE.txt
deleted file mode 100644
index 5189c99e3..000000000
--- a/Editor/terrain/rock-LICENSE.txt
+++ /dev/null
@@ -1 +0,0 @@
-https://www.cgtrader.com/free-3d-models/plant/other/rocks-56c7a2d1-2e36-4b17-8d79-2a69ab29d860
\ No newline at end of file
diff --git a/Editor/terrain/rock.wiscene b/Editor/terrain/rock.wiscene
deleted file mode 100644
index d193ebbe1..000000000
Binary files a/Editor/terrain/rock.wiscene and /dev/null differ
diff --git a/Editor/terrain/slope-LICENSE.txt b/Editor/terrain/slope-LICENSE.txt
deleted file mode 100644
index 42892115e..000000000
--- a/Editor/terrain/slope-LICENSE.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-ambientCG (ambientCG.com)
-CC0 1.0 Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
-Rock048 by ambientCG
-https://ambientcg.com/a/Rock048
\ No newline at end of file
diff --git a/Editor/terrain/tree-LICENSE.txt b/Editor/terrain/tree-LICENSE.txt
deleted file mode 100644
index bbc15ae1e..000000000
--- a/Editor/terrain/tree-LICENSE.txt
+++ /dev/null
@@ -1 +0,0 @@
-https://free3d.com/3d-model/tree02-35663.html
\ No newline at end of file
diff --git a/WickedEngine/wiArchive.h b/WickedEngine/wiArchive.h
index 9f6589b77..6f2248b16 100644
--- a/WickedEngine/wiArchive.h
+++ b/WickedEngine/wiArchive.h
@@ -42,7 +42,9 @@ namespace wi
Archive& operator=(const Archive&) = default;
Archive& operator=(Archive&&) = default;
+ void WriteData(wi::vector& dest) const { dest.resize(pos); std::memcpy(dest.data(), data_ptr, pos); }
const uint8_t* GetData() const { return data_ptr; }
+ size_t GetPos() const { return pos; }
constexpr uint64_t GetVersion() const { return version; }
constexpr bool IsReadMode() const { return readMode; }
// This can set the archive into either read or write mode, and it will reset it's position
diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp
index df458b261..9fa2407f8 100644
--- a/WickedEngine/wiScene.cpp
+++ b/WickedEngine/wiScene.cpp
@@ -2742,6 +2742,8 @@ namespace wi::scene
for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex)
{
const MeshComponent::MeshSubset& subset = mesh.subsets[subsetIndex];
+ if (materials.GetCount() <= subset.materialIndex)
+ continue;
const MaterialComponent& material = materials[subset.materialIndex];
const uint32_t geometry_index = subsetIndex - first_subset;
diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h
index 9ea38c056..68a614888 100644
--- a/WickedEngine/wiScene.h
+++ b/WickedEngine/wiScene.h
@@ -30,7 +30,7 @@ namespace wi::scene
wi::ecs::ComponentManager& impostors = componentLibrary.Register("wi::scene::Scene::impostors");
wi::ecs::ComponentManager& objects = componentLibrary.Register("wi::scene::Scene::objects");
wi::ecs::ComponentManager& aabb_objects = componentLibrary.Register("wi::scene::Scene::aabb_objects");
- wi::ecs::ComponentManager& rigidbodies = componentLibrary.Register("wi::scene::Scene::rigidbodies");
+ wi::ecs::ComponentManager& rigidbodies = componentLibrary.Register("wi::scene::Scene::rigidbodies", 1); // version = 1
wi::ecs::ComponentManager& softbodies = componentLibrary.Register("wi::scene::Scene::softbodies");
wi::ecs::ComponentManager& armatures = componentLibrary.Register("wi::scene::Scene::armatures");
wi::ecs::ComponentManager& lights = componentLibrary.Register("wi::scene::Scene::lights");
@@ -52,7 +52,7 @@ namespace wi::scene
wi::ecs::ComponentManager& colliders = componentLibrary.Register("wi::scene::Scene::colliders", 1); // version = 1
wi::ecs::ComponentManager& scripts = componentLibrary.Register("wi::scene::Scene::scripts");
wi::ecs::ComponentManager& expressions = componentLibrary.Register("wi::scene::Scene::expressions");
- wi::ecs::ComponentManager& terrains = componentLibrary.Register("wi::scene::Scene::terrains");
+ wi::ecs::ComponentManager& terrains = componentLibrary.Register("wi::scene::Scene::terrains", 1); // version = 1
// Non-serialized attributes:
float dt = 0;
diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp
index 52d570c2a..5e3f4924f 100644
--- a/WickedEngine/wiScene_BindLua.cpp
+++ b/WickedEngine/wiScene_BindLua.cpp
@@ -2709,7 +2709,7 @@ int MaterialComponent_BindLua::SetTexture(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc >= 2)
{
- uint32_t textureindex = wi::lua::SGetLongLong(L, 1);
+ uint32_t textureindex = (uint32_t)wi::lua::SGetLongLong(L, 1);
std::string resourcename = wi::lua::SGetString(L, 2);
if(textureindex < MaterialComponent::TEXTURESLOT_COUNT)
@@ -2736,7 +2736,7 @@ int MaterialComponent_BindLua::GetTexture(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc > 0)
{
- uint32_t textureindex = wi::lua::SGetLongLong(L, 1);
+ uint32_t textureindex = (uint32_t)wi::lua::SGetLongLong(L, 1);
if(textureindex < MaterialComponent::TEXTURESLOT_COUNT)
{
@@ -2760,8 +2760,8 @@ int MaterialComponent_BindLua::SetTextureUVSet(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc >= 2)
{
- uint32_t textureindex = wi::lua::SGetLongLong(L, 1);
- uint32_t uvset = wi::lua::SGetLongLong(L, 2);
+ uint32_t textureindex = (uint32_t)wi::lua::SGetLongLong(L, 1);
+ uint32_t uvset = (uint32_t)wi::lua::SGetLongLong(L, 2);
if(textureindex < MaterialComponent::TEXTURESLOT_COUNT)
{
@@ -2786,7 +2786,7 @@ int MaterialComponent_BindLua::GetTextureUVSet(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc > 0)
{
- uint32_t textureindex = wi::lua::SGetLongLong(L, 1);
+ uint32_t textureindex = (uint32_t)wi::lua::SGetLongLong(L, 1);
if(textureindex < MaterialComponent::TEXTURESLOT_COUNT)
{
@@ -2849,8 +2849,8 @@ int MeshComponent_BindLua::SetMeshSubsetMaterialID(lua_State* L)
int argc = wi::lua::SGetArgCount(L);
if (argc >= 2)
{
- size_t subsetindex = wi::lua::SGetLongLong(L, 1);
- uint32_t uvset = wi::lua::SGetLongLong(L, 2);
+ size_t subsetindex = (uint32_t)wi::lua::SGetLongLong(L, 1);
+ uint32_t uvset = (uint32_t)wi::lua::SGetLongLong(L, 2);
if(subsetindex < component->subsets.size())
{
diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp
index 08a09be7a..151d225e7 100644
--- a/WickedEngine/wiScene_Serializers.cpp
+++ b/WickedEngine/wiScene_Serializers.cpp
@@ -624,6 +624,11 @@ namespace wi::scene
archive >> capsule.height;
archive >> capsule.radius;
}
+
+ if (seri.GetVersion() >= 1)
+ {
+ archive >> mesh_lod;
+ }
}
else
{
@@ -646,6 +651,11 @@ namespace wi::scene
archive << capsule.height;
archive << capsule.radius;
}
+
+ if (seri.GetVersion() >= 1)
+ {
+ archive << mesh_lod;
+ }
}
}
void SoftBodyPhysicsComponent::Serialize(wi::Archive& archive, EntitySerializer& seri)
diff --git a/WickedEngine/wiTerrain.cpp b/WickedEngine/wiTerrain.cpp
index 4f1b16ecb..c3350db7f 100644
--- a/WickedEngine/wiTerrain.cpp
+++ b/WickedEngine/wiTerrain.cpp
@@ -168,7 +168,7 @@ namespace wi::terrain
{
wi::scene::Scene scene; // The background generation thread can safely add things to this, it will be merged into the main scene when it is safe to do so
wi::jobsystem::context workload;
- std::atomic_bool cancelled;
+ std::atomic_bool cancelled{ false };
};
Terrain::Terrain()
@@ -282,6 +282,12 @@ namespace wi::terrain
return;
}
+ WeatherComponent* weather_component = scene->weathers.GetComponent(terrainEntity);
+ if (weather_component != nullptr)
+ {
+ weather = *weather_component; // feedback default weather
+ }
+
// What was generated, will be merged in to the main scene
scene->Merge(generator->scene);
@@ -388,6 +394,46 @@ namespace wi::terrain
}
}
+ RigidBodyPhysicsComponent* rigidbody = scene->rigidbodies.GetComponent(chunk_data.entity);
+ if (IsPhysicsEnabled())
+ {
+ const int lod_required = std::max(0, dist - 1);
+
+ if (rigidbody != nullptr)
+ {
+ if (dist < physics_generation)
+ {
+ if (rigidbody->mesh_lod != lod_required)
+ {
+ rigidbody->mesh_lod = lod_required;
+ rigidbody->physicsobject = {}; // will be recreated
+ }
+ }
+ else
+ {
+ scene->rigidbodies.Remove(chunk_data.entity);
+ }
+ }
+ else
+ {
+ if (dist < physics_generation)
+ {
+ RigidBodyPhysicsComponent& newrigidbody = scene->rigidbodies.Create(chunk_data.entity);
+ newrigidbody.shape = RigidBodyPhysicsComponent::TRIANGLE_MESH;
+ newrigidbody.SetDisableDeactivation(true);
+ newrigidbody.SetKinematic(true);
+ newrigidbody.mesh_lod = lod_required;
+ }
+ }
+ }
+ else
+ {
+ if (rigidbody != nullptr)
+ {
+ scene->rigidbodies.Remove(chunk_data.entity);
+ }
+ }
+
// Collect virtual texture update requests:
if (max_texture_resolution > 0)
{
@@ -705,7 +751,7 @@ namespace wi::terrain
std::mt19937 prop_rand;
prop_rand.seed((uint32_t)chunk.compute_hash() ^ seed);
- for (auto& prop : props)
+ for (const auto& prop : props)
{
std::uniform_int_distribution gen_distr(
uint32_t(prop.min_count_per_chunk * chunk_data.prop_density_current),
@@ -748,22 +794,51 @@ namespace wi::terrain
const float chance = std::pow(((float*)®ion)[prop.region], prop.region_power) * noise;
if (chance > prop.threshold)
{
- Entity entity = generator->scene.Entity_CreateObject(prop.name + std::to_string(i));
- ObjectComponent* object = generator->scene.objects.GetComponent(entity);
- *object = prop.object;
+ wi::Archive archive = wi::Archive(prop.data.data());
+ EntitySerializer seri;
+ wi::scene::Scene::EntitySerializeFlags flags = wi::scene::Scene::EntitySerializeFlags::RECURSIVE;
+ if (serializer_state.empty())
+ {
+ // This means the terrain was not serialized, but prop assets provided in this session, so we can keep references to them:
+ flags |= wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES;
+ }
+ else
+ {
+ // This means that terrain was serialized, so we have to resolve prop source asset dependencies:
+ seri.remap = serializer_state;
+ }
+ Entity entity = generator->scene.Entity_Serialize(
+ archive,
+ seri,
+ INVALID_ENTITY,
+ flags
+ );
+ NameComponent* name = generator->scene.names.GetComponent(entity);
+ if (name != nullptr)
+ {
+ name->name += std::to_string(i);
+ }
TransformComponent* transform = generator->scene.transforms.GetComponent(entity);
- XMFLOAT3 offset = vertex_pos;
- offset.y += wi::math::Lerp(prop.min_y_offset, prop.max_y_offset, float_distr(prop_rand));
- transform->Translate(offset);
+ if (transform == nullptr)
+ {
+ transform = &generator->scene.transforms.Create(entity);
+ }
+ transform->translation_local = vertex_pos;
+ transform->translation_local.y += wi::math::Lerp(prop.min_y_offset, prop.max_y_offset, float_distr(prop_rand));
const float scaling = wi::math::Lerp(prop.min_size, prop.max_size, float_distr(prop_rand));
transform->Scale(XMFLOAT3(scaling, scaling, scaling));
transform->RotateRollPitchYaw(XMFLOAT3(0, XM_2PI * float_distr(prop_rand), 0));
+ transform->SetDirty();
transform->UpdateTransform();
generator->scene.Component_Attach(entity, chunk_data.props_entity, true);
generated_something = true;
}
}
}
+ if (!IsPhysicsEnabled())
+ {
+ generator->scene.rigidbodies.Clear();
+ }
}
}
}
@@ -850,7 +925,7 @@ namespace wi::terrain
case MaterialComponent::BASECOLORMAP:
case MaterialComponent::SURFACEMAP:
case MaterialComponent::NORMALMAP:
- if (tex.name.empty() && tex.GetGPUResource() != nullptr)
+ if (!tex.name.empty() && tex.GetGPUResource() != nullptr)
{
wi::vector filedata;
if (wi::helper::saveTextureToMemory(tex.resource.GetTexture(), filedata))
@@ -943,15 +1018,46 @@ namespace wi::terrain
archive >> center_chunk.x;
archive >> center_chunk.z;
+ if (seri.GetVersion() >= 1)
+ {
+ archive >> physics_generation;
+ }
+
size_t count = 0;
archive >> count;
props.resize(count);
for (size_t i = 0; i < props.size(); ++i)
{
Prop& prop = props[i];
- archive >> prop.name;
- SerializeEntity(archive, prop.mesh_entity, seri);
- prop.object.Serialize(archive, seri);
+ if (seri.GetVersion() >= 1)
+ {
+ archive >> prop.data;
+ }
+ else
+ {
+ // Back compat reading of terrain version 0:
+ std::string name;
+ Entity mesh_entity;
+ ObjectComponent object;
+ archive >> name;
+ SerializeEntity(archive, mesh_entity, seri);
+ object.Serialize(archive, seri);
+ Scene tmp_scene;
+ Entity object_entity = CreateEntity();
+ tmp_scene.names.Create(object_entity) = name;
+ tmp_scene.objects.Create(object_entity) = object;
+ tmp_scene.aabb_objects.Create(object_entity);
+ tmp_scene.transforms.Create(object_entity);
+ wi::Archive archive;
+ EntitySerializer seri;
+ tmp_scene.Entity_Serialize(
+ archive,
+ seri,
+ object_entity,
+ wi::scene::Scene::EntitySerializeFlags::RECURSIVE | wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES
+ );
+ archive.WriteData(prop.data);
+ }
archive >> prop.min_count_per_chunk;
archive >> prop.max_count_per_chunk;
archive >> prop.region;
@@ -1036,6 +1142,8 @@ namespace wi::terrain
archive >> modifier->weight;
archive >> modifier->frequency;
}
+
+ serializer_state = seri.remap;
}
else
{
@@ -1059,13 +1167,16 @@ namespace wi::terrain
archive << center_chunk.x;
archive << center_chunk.z;
+ if (seri.GetVersion() >= 1)
+ {
+ archive << physics_generation;
+ }
+
archive << props.size();
for (size_t i = 0; i < props.size(); ++i)
{
Prop& prop = props[i];
- archive << prop.name;
- SerializeEntity(archive, prop.mesh_entity, seri);
- prop.object.Serialize(archive, seri);
+ archive << prop.data;
archive << prop.min_count_per_chunk;
archive << prop.max_count_per_chunk;
archive << prop.region;
diff --git a/WickedEngine/wiTerrain.h b/WickedEngine/wiTerrain.h
index f15292f07..94ff73ed1 100644
--- a/WickedEngine/wiTerrain.h
+++ b/WickedEngine/wiTerrain.h
@@ -64,9 +64,7 @@ namespace wi::terrain
struct Prop
{
- std::string name = "prop";
- wi::ecs::Entity mesh_entity = wi::ecs::INVALID_ENTITY;
- wi::scene::ObjectComponent object;
+ wi::vector data; // serialized component data storage
int min_count_per_chunk = 0; // a chunk will try to generate min this many props of this type
int max_count_per_chunk = 10; // a chunk will try to generate max this many props of this type
int region = 0; // region selection in range [0,3] (0: base/grass, 1: slopes, 2: low altitude (bottom level-0), 3: high altitude (0-top level))
@@ -92,6 +90,7 @@ namespace wi::terrain
REMOVAL = 1 << 1,
GRASS = 1 << 2,
GENERATION_STARTED = 1 << 4,
+ PHYSICS = 1 << 5,
};
uint32_t _flags = CENTER_TO_CAM | REMOVAL | GRASS;
@@ -108,6 +107,7 @@ namespace wi::terrain
Chunk center_chunk = {};
wi::noise::Perlin perlin_noise;
wi::vector props;
+ wi::unordered_map serializer_state;
// For generating scene on a background thread:
std::shared_ptr generator;
@@ -125,16 +125,19 @@ namespace wi::terrain
constexpr bool IsRemovalEnabled() const { return _flags & REMOVAL; }
constexpr bool IsGrassEnabled() const { return _flags & GRASS; }
constexpr bool IsGenerationStarted() const { return _flags & GENERATION_STARTED; }
+ constexpr bool IsPhysicsEnabled() const { return _flags & PHYSICS; }
constexpr void SetCenterToCamEnabled(bool value) { if (value) { _flags |= CENTER_TO_CAM; } else { _flags &= ~CENTER_TO_CAM; } }
constexpr void SetRemovalEnabled(bool value) { if (value) { _flags |= REMOVAL; } else { _flags &= ~REMOVAL; } }
constexpr void SetGrassEnabled(bool value) { if (value) { _flags |= GRASS; } else { _flags &= ~GRASS; } }
constexpr void SetGenerationStarted(bool value) { if (value) { _flags |= GENERATION_STARTED; } else { _flags &= ~GENERATION_STARTED; } }
+ constexpr void SetPhysicsEnabled(bool value) { if (value) { _flags |= PHYSICS; } else { _flags &= ~PHYSICS; } }
float lod_multiplier = 0.005f;
float texlod = 0.01f;
int generation = 12;
int prop_generation = 10;
+ int physics_generation = 3;
float prop_density = 1;
float grass_density = 1;
float chunk_scale = 1;
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index ad8d285d6..2f7a1ae5c 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -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 = 35;
+ const int revision = 36;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
@@ -114,6 +114,7 @@ Patreon supporters
- Delhills
- NI NI
- Sherief
+- ktopoet
)";
return credits;