diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md
index b3bdda712..894ef14bd 100644
--- a/Content/Documentation/ScriptingAPI-Documentation.md
+++ b/Content/Documentation/ScriptingAPI-Documentation.md
@@ -56,6 +56,7 @@ This is a reference and explanation of Lua scripting features in Wicked Engine.
3. [Sphere](#sphere)
4. [Capsule](#capsule)
12. [Input](#input)
+ 13. [Physics](#physics)
## Introduction and usage
Scripting in Wicked Engine is powered by Lua, meaning that the user can make use of the
@@ -525,8 +526,14 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_CreateLight(Entity entity) : LightComponent result -- attach a light component to an entity. The returned LightComponent is associated with the entity and can be manipulated
- Component_CreateObject(Entity entity) : ObjectComponent result -- attach an object component to an entity. The returned ObjectComponent is associated with the entity and can be manipulated
- Component_CreateInverseKinematics(Entity entity) : InverseKinematicsComponent result -- attach an IK component to an entity. The returned InverseKinematicsComponent is associated with the entity and can be manipulated
-- Component_CreateSpring(Entity entity) : SpringComponent result -- attach a spring component to an entity. The returned SpringKinematicsComponent is associated with the entity and can be manipulated
-- Component_CreateSpring(Entity entity) : ScriptComponent result -- attach a script component to an entity. The returned ScriptKinematicsComponent is associated with the entity and can be manipulated
+- Component_CreateSpring(Entity entity) : SpringComponent result -- attach a spring component to an entity. The returned SpringComponent is associated with the entity and can be manipulated
+- Component_CreateScript(Entity entity) : ScriptComponent result -- attach a script component to an entity. The returned ScriptComponent is associated with the entity and can be manipulated
+- Component_CreateRigidBodyPhysics(Entity entity) : RigidBodyPhysicsComponent result -- attach a RigidBodyPhysicsComponent to an entity. The returned RigidBodyPhysicsComponent is associated with the entity and can be manipulated
+- Component_CreateSoftBodyPhysics(Entity entity) : SoftBodyPhysicsComponent result -- attach a SoftBodyPhysicsComponent to an entity. The returned SoftBodyPhysicsComponent is associated with the entity and can be manipulated
+- Component_CreateForceField(Entity entity) : ForceFieldComponent result -- attach a ForceFieldComponent to an entity. The returned ForceFieldComponent is associated with the entity and can be manipulated
+- Component_CreateWeather(Entity entity) : WeatherComponent result -- attach a WeatherComponent to an entity. The returned WeatherComponent is associated with the entity and can be manipulated
+- Component_CreateSound(Entity entity) : SoundComponent result -- attach a SoundComponent to an entity. The returned SoundComponent is associated with the entity and can be manipulated
+- Component_CreateCollider(Entity entity) : ColliderComponent result -- attach a script to an entity. The returned ColliderComponent is associated with the entity and can be manipulated
- Component_GetName(Entity entity) : NameComponent? result -- query the name component of the entity (if exists)
- Component_GetLayer(Entity entity) : LayerComponent? result -- query the layer component of the entity (if exists)
@@ -539,7 +546,13 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_GetObject(Entity entity) : ObjectComponent? result -- query the object component of the entity (if exists)
- Component_GetInverseKinematics(Entity entity) : InverseKinematicsComponent? result -- query the IK component of the entity (if exists)
- Component_GetSpring(Entity entity) : SpringComponent? result -- query the spring component of the entity (if exists)
-- Component_GetSpring(Entity entity) : ScriptComponent? result -- query the script component of the entity (if exists)
+- Component_GetScript(Entity entity) : ScriptComponent? result -- query the script component of the entity (if exists)
+- Component_GetRigidBodyPhysics(Entity entity) : RigidBodyPhysicsComponent? result -- query the RigidBodyPhysicsComponent of the entity (if exists)
+- Component_GetSoftBodyPhysics(Entity entity) : SoftBodyPhysicsComponent? result -- query the SoftBodyPhysicsComponent of the entity (if exists)
+- Component_GetForceField(Entity entity) : ForceFieldComponent? result -- query the ForceFieldComponent of the entity (if exists)
+- Component_GetWeather(Entity entity) : WeatherComponent? result -- query the WeatherComponent of the entity (if exists)
+- Component_GetSound(Entity entity) : SoundComponent? result -- query the SoundComponent of the entity (if exists)
+- Component_GetCollider(Entity entity) : ColliderComponent? result -- query the ColliderComponent of the entity (if exists)
- Component_GetNameArray() : NameComponent[] result -- returns the array of all components of this type
- Component_GetLayerArray() : LayerComponent[] result -- returns the array of all components of this type
@@ -553,6 +566,12 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_GetInverseKinematicsArray() : InverseKinematicsComponent[] result -- returns the array of all components of this type
- Component_GetSpringArray() : SpringComponent[] result -- returns the array of all components of this type
- Component_GetScriptArray() : ScriptComponent[] result -- returns the array of all components of this type
+- Component_GetRigidBodyPhysicsArray() : RigidBodyPhysicsComponent[] result -- returns the array of all components of this type
+- Component_GetSoftBodyPhysicsArray() : SoftBodyPhysicsComponent[] result -- returns the array of all components of this type
+- Component_GetForceFieldArray() : ForceFieldComponent[] result -- returns the array of all components of this type
+- Component_GetWeatherArray() : WeatherComponent[] result -- returns the array of all components of this type
+- Component_GetSoundArray() : SoundComponent[] result -- returns the array of all components of this type
+- Component_GetColliderArray() : ColliderComponent[] result -- returns the array of all components of this type
- Entity_GetNameArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetLayerArray() : Entity[] result -- returns the array of all entities that have this component type
@@ -566,6 +585,12 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Entity_GetInverseKinematicsArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetSpringArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetScriptArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetRigidBodyPhysicsArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetSoftBodyPhysicsArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetForceFieldArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetWeatherArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetSoundArray() : Entity[] result -- returns the array of all entities that have this component type
+- Entity_GetColliderArray() : Entity[] result -- returns the array of all entities that have this component type
- Component_Attach(Entity entity,parent) -- attaches entity to parent (adds a hierarchy component to entity). From now on, entity will inherit certain properties from parent, such as transform (entity will move with parent) or layer (entity's layer will be a sublayer of parent's layer)
- Component_Detach(Entity entity) -- detaches entity from parent (if hierarchycomponent exists for it). Restores entity's original layer, and applies current transformation to entity
@@ -912,6 +937,7 @@ Describes a Weather
- VolumetricCloudParameters : VolumetricCloudParameters -- Returns a table to modify volumetric cloud parameters
- SkyMapName : string -- Resource name for sky texture
- ColorGradingMapName : string -- Resource name for color grading map
+- Gravity : Vector
@@ -948,6 +974,9 @@ Describes a Sound object.
- Offset : Vector
- Tail : Vector
+- SetCPUEnabled(bool value)
+- SetGPUEnabled(bool value)
+
## Canvas
This is used to describe a drawable area
- GetDPI() : float -- pixels per inch
@@ -1211,3 +1240,27 @@ Describes a touch contact point
- [outer]GAMEPAD_ANALOG_THUMBSTICK_R : int
- [outer]GAMEPAD_ANALOG_TRIGGER_L : int
- [outer]GAMEPAD_ANALOG_TRIGGER_R : int
+
+
+### Physics
+- [outer]physics : Physics -- use this global object to access physics functions
+- SetEnabled(bool value) -- Enable/disable the physics engine all together
+- IsEnabled() : bool
+- SetSimulationEnabled(bool value) -- Enable/disable the physics simulation. Physics engine state will be updated but not simulated
+- IsSimulationEnabeld() : bool
+- SetDebugDrawEnabled(bool value) -- Enable/disable debug drawing of physics objects
+- IsDebugDrawEnabled() : bool
+- SetAccuracy(int value) -- Set the accuracy of the simulation. This value corresponds to maximum simulation step count. Higher values will be slower but more accurate.
+- GetAccuracy() : int
+- SetLinearVelocity(RigidBodyPhysicsComponent component, Vector velocity) -- Set the linear velocity manually
+- SetAngularVelocity(RigidBodyPhysicsComponent component, Vector velocity) -- Set the angular velocity manually
+- ApplyForce(RigidBodyPhysicsComponent component, Vector force) -- Apply force at body center
+- ApplyForceAt(RigidBodyPhysicsComponent component, Vector force, Vector at) -- Apply force at body local position
+- ApplyImpulse(RigidBodyPhysicsComponent component, Vector impulse) -- Apply impulse at body center
+- ApplyImpulseAt(RigidBodyPhysicsComponent component, Vector impulse, Vector at) -- Apply impulse at body local position
+- ApplyTorque(RigidBodyPhysicsComponent component, Vector torque) -- Apply torque at body center
+- ApplyTorqueImpulse(RigidBodyPhysicsComponent component, Vector torque) -- Apply torque impulse at body center
+- SetActivationState(RigidBodyPhysicsComponent component, int state) -- Force set activation state to rigid body. Use a value ACTIVATION_STATE_ACTIVE or ACTIVATION_STATE_INACTIVE
+- SetActivationState(SoftBodyPhysicsComponent component, int state) -- Force set activation state to soft body. Use a value ACTIVATION_STATE_ACTIVE or ACTIVATION_STATE_INACTIVE
+- [outer]ACTIVATION_STATE_ACTIVE : int
+- [outer]ACTIVATION_STATE_INACTIVE : int
diff --git a/Editor/AnimationWindow.cpp b/Editor/AnimationWindow.cpp
index 86d40e854..196bb880d 100644
--- a/Editor/AnimationWindow.cpp
+++ b/Editor/AnimationWindow.cpp
@@ -9,7 +9,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create(ICON_ANIMATION " Animation", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
- SetSize(XMFLOAT2(520, 430));
+ SetSize(XMFLOAT2(520, 480));
closeButton.SetTooltip("Delete AnimationComponent");
OnClose([=](wi::gui::EventArgs args) {
@@ -31,6 +31,11 @@ void AnimationWindow::Create(EditorComponent* _editor)
float wid = 200;
float step = hei + 4;
+ infoLabel.Create("");
+ infoLabel.SetSize(XMFLOAT2(100, 50));
+ infoLabel.SetText("The animation window will stay open even if you select other entities until it is collapsed, so you can record other entities' data.");
+ AddWidget(&infoLabel);
+
modeComboBox.Create("Sampling: ");
modeComboBox.SetSize(XMFLOAT2(wid, hei));
modeComboBox.SetPos(XMFLOAT2(x, y));
@@ -64,7 +69,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
}
}
});
- modeComboBox.SetTooltip("Choose how animation data is interpreted between keyframes.\nNote that Cubic spline sampling requires spline animation data, otherwise, it will fall back to Linear!");
+ modeComboBox.SetTooltip("Choose how animation data is interpreted between keyframes.\nNote that Cubic spline sampling requires spline animation data, otherwise, it will fall back to Linear!\nCurrently spline animation data creation is not supported, but it can be imported from GLTF/VRM models.");
AddWidget(&modeComboBox);
loopedCheckBox.Create("Looped: ");
@@ -1140,6 +1145,7 @@ void AnimationWindow::ResizeLayout()
y += padding;
};
+ add_fullwidth(infoLabel);
add(modeComboBox);
loopedCheckBox.SetPos(XMFLOAT2(margin_left, y));
diff --git a/Editor/AnimationWindow.h b/Editor/AnimationWindow.h
index d7a49c004..b82cde5f7 100644
--- a/Editor/AnimationWindow.h
+++ b/Editor/AnimationWindow.h
@@ -12,6 +12,7 @@ public:
wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY;
void SetEntity(wi::ecs::Entity entity);
+ wi::gui::Label infoLabel;
wi::gui::ComboBox modeComboBox;
wi::gui::CheckBox loopedCheckBox;
wi::gui::Button playButton;
diff --git a/Editor/ArmatureWindow.cpp b/Editor/ArmatureWindow.cpp
index 79a06884a..7e71b884b 100644
--- a/Editor/ArmatureWindow.cpp
+++ b/Editor/ArmatureWindow.cpp
@@ -10,7 +10,7 @@ void ArmatureWindow::Create(EditorComponent* _editor)
editor = _editor;
wi::gui::Window::Create(ICON_ARMATURE " Armature", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
- SetSize(XMFLOAT2(670, 300));
+ SetSize(XMFLOAT2(670, 350));
closeButton.SetTooltip("Delete ArmatureComponent");
OnClose([=](wi::gui::EventArgs args) {
@@ -32,6 +32,11 @@ void ArmatureWindow::Create(EditorComponent* _editor)
float step = hei + 2;
float wid = 220;
+ infoLabel.Create("");
+ infoLabel.SetSize(XMFLOAT2(100, 50));
+ infoLabel.SetText("This window will stay open even if you select other entities until it is collapsed, so you can select other bone entities.");
+ AddWidget(&infoLabel);
+
resetPoseButton.Create("Reset Pose");
resetPoseButton.SetSize(XMFLOAT2(wid, hei));
resetPoseButton.OnClick([=](wi::gui::EventArgs args) {
@@ -192,6 +197,7 @@ void ArmatureWindow::ResizeLayout()
y += padding;
};
+ add_fullwidth(infoLabel);
add_fullwidth(resetPoseButton);
y += jump;
diff --git a/Editor/ArmatureWindow.h b/Editor/ArmatureWindow.h
index d43c651d6..574cd5682 100644
--- a/Editor/ArmatureWindow.h
+++ b/Editor/ArmatureWindow.h
@@ -13,6 +13,7 @@ public:
void SetEntity(wi::ecs::Entity entity);
void RefreshBoneList();
+ wi::gui::Label infoLabel;
wi::gui::Button resetPoseButton;
wi::gui::TreeList boneList;
diff --git a/Editor/ColliderWindow.cpp b/Editor/ColliderWindow.cpp
index f701415d7..52791accb 100644
--- a/Editor/ColliderWindow.cpp
+++ b/Editor/ColliderWindow.cpp
@@ -10,7 +10,7 @@ void ColliderWindow::Create(EditorComponent* _editor)
editor = _editor;
wi::gui::Window::Create(ICON_COLLIDER " Collider", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
- SetSize(XMFLOAT2(670, 280));
+ SetSize(XMFLOAT2(670, 340));
closeButton.SetTooltip("Delete ColliderComponent");
OnClose([=](wi::gui::EventArgs args) {
@@ -32,6 +32,37 @@ void ColliderWindow::Create(EditorComponent* _editor)
float step = hei + 2;
float wid = 220;
+ infoLabel.Create("");
+ infoLabel.SetText("Colliders are used for simple fake physics, without using the physics engine. They are only used in specific CPU/GPU systems.");
+ infoLabel.SetSize(XMFLOAT2(100, 50));
+ AddWidget(&infoLabel);
+
+ cpuCheckBox.Create("CPU: ");
+ cpuCheckBox.SetTooltip("Enable for use on the CPU. CPU usage includes: springs.");
+ cpuCheckBox.SetSize(XMFLOAT2(hei, hei));
+ cpuCheckBox.OnClick([=](wi::gui::EventArgs args) {
+ wi::scene::Scene& scene = editor->GetCurrentScene();
+ ColliderComponent* collider = scene.colliders.GetComponent(entity);
+ if (collider == nullptr)
+ return;
+
+ collider->SetCPUEnabled(args.bValue);
+ });
+ AddWidget(&cpuCheckBox);
+
+ gpuCheckBox.Create("GPU: ");
+ gpuCheckBox.SetTooltip("Enable for use on the GPU. GPU usage includes: emitter and hair particle systems.\nNote that GPU can support only a limited amount of colliders.");
+ gpuCheckBox.SetSize(XMFLOAT2(hei, hei));
+ gpuCheckBox.OnClick([=](wi::gui::EventArgs args) {
+ wi::scene::Scene& scene = editor->GetCurrentScene();
+ ColliderComponent* collider = scene.colliders.GetComponent(entity);
+ if (collider == nullptr)
+ return;
+
+ collider->SetGPUEnabled(args.bValue);
+ });
+ AddWidget(&gpuCheckBox);
+
shapeCombo.Create("Shape: ");
shapeCombo.SetSize(XMFLOAT2(wid, hei));
shapeCombo.SetPos(XMFLOAT2(x, y));
@@ -167,6 +198,8 @@ void ColliderWindow::SetEntity(Entity entity)
if (collider != nullptr)
{
+ cpuCheckBox.SetCheck(collider->IsCPUEnabled());
+ gpuCheckBox.SetCheck(collider->IsGPUEnabled());
shapeCombo.SetSelectedByUserdataWithoutCallback((uint64_t)collider->shape);
radiusSlider.SetValue(collider->radius);
offsetX.SetValue(collider->offset.x);
@@ -215,6 +248,9 @@ void ColliderWindow::ResizeLayout()
y += padding;
};
+ add_fullwidth(infoLabel);
+ add_right(cpuCheckBox);
+ gpuCheckBox.SetPos(XMFLOAT2(cpuCheckBox.GetPos().x - 100, cpuCheckBox.GetPos().y));
add(shapeCombo);
add(radiusSlider);
diff --git a/Editor/ColliderWindow.h b/Editor/ColliderWindow.h
index ec2993ad4..1c1b38975 100644
--- a/Editor/ColliderWindow.h
+++ b/Editor/ColliderWindow.h
@@ -12,6 +12,9 @@ public:
wi::ecs::Entity entity = wi::ecs::INVALID_ENTITY;
void SetEntity(wi::ecs::Entity entity);
+ wi::gui::Label infoLabel;
+ wi::gui::CheckBox cpuCheckBox;
+ wi::gui::CheckBox gpuCheckBox;
wi::gui::ComboBox shapeCombo;
wi::gui::Slider radiusSlider;
wi::gui::Slider offsetX;
diff --git a/Editor/OptionsWindow.cpp b/Editor/OptionsWindow.cpp
index 31b0fd7e8..5b7293ea1 100644
--- a/Editor/OptionsWindow.cpp
+++ b/Editor/OptionsWindow.cpp
@@ -313,6 +313,7 @@ void OptionsWindow::Create(EditorComponent* _editor)
filterCombo.AddItem("Inverse Kinematics " ICON_IK, (uint64_t)Filter::IK);
filterCombo.AddItem("Camera " ICON_CAMERA, (uint64_t)Filter::Camera);
filterCombo.AddItem("Armature " ICON_ARMATURE, (uint64_t)Filter::Armature);
+ filterCombo.AddItem("Collider " ICON_COLLIDER, (uint64_t)Filter::Collider);
filterCombo.AddItem("Script " ICON_SCRIPT, (uint64_t)Filter::Script);
filterCombo.AddItem("Expression " ICON_EXPRESSION, (uint64_t)Filter::Expression);
filterCombo.AddItem("Terrain " ICON_TERRAIN, (uint64_t)Filter::Terrain);
diff --git a/Editor/TerrainWindow.cpp b/Editor/TerrainWindow.cpp
index ce71dba82..56d07f140 100644
--- a/Editor/TerrainWindow.cpp
+++ b/Editor/TerrainWindow.cpp
@@ -864,6 +864,7 @@ void TerrainWindow::SetupAssets()
wi::scene::LoadModel(props_scene, "terrain/props.wiscene");
// Tree prop:
+ if(props_scene.Entity_FindByName("tree_mesh") != INVALID_ENTITY)
{
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
prop.min_count_per_chunk = 0;
@@ -898,6 +899,7 @@ void TerrainWindow::SetupAssets()
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
}
// Rock prop:
+ if (props_scene.Entity_FindByName("rock_mesh") != INVALID_ENTITY)
{
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
prop.min_count_per_chunk = 0;
@@ -932,6 +934,7 @@ void TerrainWindow::SetupAssets()
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
}
// Bush prop:
+ if (props_scene.Entity_FindByName("bush_mesh") != INVALID_ENTITY)
{
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
prop.min_count_per_chunk = 0;
diff --git a/Editor/WeatherWindow.cpp b/Editor/WeatherWindow.cpp
index 09409e7a0..653a6ff65 100644
--- a/Editor/WeatherWindow.cpp
+++ b/Editor/WeatherWindow.cpp
@@ -137,6 +137,15 @@ void WeatherWindow::Create(EditorComponent* _editor)
});
AddWidget(&fogHeightEndSlider);
+ gravitySlider.Create(-20, 20, -10, 10000, "Gravity: ");
+ gravitySlider.SetTooltip("Set the gravity factor on Y (vertical) axis for physics.");
+ gravitySlider.SetSize(XMFLOAT2(wid, hei));
+ gravitySlider.SetPos(XMFLOAT2(x, y += step));
+ gravitySlider.OnSlide([&](wi::gui::EventArgs args) {
+ GetWeather().gravity.y = args.fValue;
+ });
+ AddWidget(&gravitySlider);
+
windSpeedSlider.Create(0.0f, 4.0f, 1.0f, 10000, "Wind Speed: ");
windSpeedSlider.SetSize(XMFLOAT2(wid, hei));
windSpeedSlider.SetPos(XMFLOAT2(x, y += step));
@@ -679,6 +688,7 @@ void WeatherWindow::Update()
fogEndSlider.SetValue(weather.fogEnd);
fogHeightStartSlider.SetValue(weather.fogHeightStart);
fogHeightEndSlider.SetValue(weather.fogHeightEnd);
+ gravitySlider.SetValue(weather.gravity.y);
windSpeedSlider.SetValue(weather.windSpeed);
windWaveSizeSlider.SetValue(weather.windWaveSize);
windRandomnessSlider.SetValue(weather.windRandomness);
@@ -810,6 +820,7 @@ void WeatherWindow::ResizeLayout()
add(fogEndSlider);
add(fogHeightStartSlider);
add(fogHeightEndSlider);
+ add(gravitySlider);
add(windSpeedSlider);
add(windMagnitudeSlider);
add(windDirectionSlider);
diff --git a/Editor/WeatherWindow.h b/Editor/WeatherWindow.h
index 5d9bef0a5..f0976f221 100644
--- a/Editor/WeatherWindow.h
+++ b/Editor/WeatherWindow.h
@@ -27,6 +27,7 @@ public:
wi::gui::Slider fogEndSlider;
wi::gui::Slider fogHeightStartSlider;
wi::gui::Slider fogHeightEndSlider;
+ wi::gui::Slider gravitySlider;
wi::gui::Slider windSpeedSlider;
wi::gui::Slider windMagnitudeSlider;
wi::gui::Slider windDirectionSlider;
diff --git a/Editor/startup.lua b/Editor/startup.lua
index 6bed754da..956c0bdd5 100644
--- a/Editor/startup.lua
+++ b/Editor/startup.lua
@@ -1,4 +1,5 @@
SetProfilerEnabled(false)
+physics.SetAccuracy(1)
-- You can set custom scaling for 2D screen elements here (GUI, sprites, fonts):
--local canvas = application.GetCanvas()
diff --git a/WickedEngine/CMakeLists.txt b/WickedEngine/CMakeLists.txt
index 62401fdcf..9d895116a 100644
--- a/WickedEngine/CMakeLists.txt
+++ b/WickedEngine/CMakeLists.txt
@@ -99,6 +99,7 @@ set(HEADER_FILES
wiNoise.h
wiOcean.h
wiPhysics.h
+ wiPhysics_BindLua.h
wiPlatform.h
wiPrimitive.h
wiPrimitive_BindLua.h
@@ -188,6 +189,7 @@ add_library(${TARGET_NAME} ${WICKED_LIBRARY_TYPE}
wiNetwork_UWP.cpp
wiOcean.cpp
wiPhysics_Bullet.cpp
+ wiPhysics_BindLua.cpp
wiProfiler.cpp
wiRandom.cpp
wiRawInput.cpp
diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems b/WickedEngine/WickedEngine_SOURCE.vcxitems
index fa69ada83..94ead5be3 100644
--- a/WickedEngine/WickedEngine_SOURCE.vcxitems
+++ b/WickedEngine/WickedEngine_SOURCE.vcxitems
@@ -231,6 +231,7 @@
+
@@ -502,6 +503,7 @@
+
diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
index 8f18614f2..9bb7ee471 100644
--- a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
+++ b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
@@ -1086,6 +1086,9 @@
ENGINE\System
+
+ ENGINE\Scripting\LuaBindings
+
@@ -1829,6 +1832,9 @@
ENGINE\System
+
+ ENGINE\Scripting\LuaBindings
+
diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp
index 5238f8e8d..4fcf52d7d 100644
--- a/WickedEngine/wiLua.cpp
+++ b/WickedEngine/wiLua.cpp
@@ -20,6 +20,7 @@
#include "wiBacklog_BindLua.h"
#include "wiNetwork_BindLua.h"
#include "wiPrimitive_BindLua.h"
+#include "wiPhysics_BindLua.h"
#include "wiTimer.h"
#include "wiVector.h"
@@ -41,7 +42,11 @@ namespace wi::lua
}
}
};
- LuaInternal luainternal;
+ LuaInternal& lua_internal()
+ {
+ static LuaInternal luainternal;
+ return luainternal;
+ }
uint32_t GeneratePID()
{
@@ -135,8 +140,8 @@ namespace wi::lua
{
wi::Timer timer;
- luainternal.m_luaState = luaL_newstate();
- luaL_openlibs(luainternal.m_luaState);
+ lua_internal().m_luaState = luaL_newstate();
+ luaL_openlibs(lua_internal().m_luaState);
RegisterFunc("dofile", Internal_DoFile);
RunText(wiLua_Globals);
@@ -160,49 +165,50 @@ namespace wi::lua
backlog::Bind();
Network_BindLua::Bind();
primitive::Bind();
+ Physics_BindLua::Bind();
wi::backlog::post("wi::lua Initialized (" + std::to_string((int)std::round(timer.elapsed())) + " ms)");
}
lua_State* GetLuaState()
{
- return luainternal.m_luaState;
+ return lua_internal().m_luaState;
}
bool Success()
{
- return luainternal.m_status == 0;
+ return lua_internal().m_status == 0;
}
bool Failed()
{
- return luainternal.m_status != 0;
+ return lua_internal().m_status != 0;
}
std::string GetErrorMsg()
{
if (Failed()) {
- std::string retVal = lua_tostring(luainternal.m_luaState, -1);
+ std::string retVal = lua_tostring(lua_internal().m_luaState, -1);
return retVal;
}
return std::string("");
}
std::string PopErrorMsg()
{
- std::string retVal = lua_tostring(luainternal.m_luaState, -1);
- lua_pop(luainternal.m_luaState, 1); // remove error message
+ std::string retVal = lua_tostring(lua_internal().m_luaState, -1);
+ lua_pop(lua_internal().m_luaState, 1); // remove error message
return retVal;
}
void PostErrorMsg()
{
if (Failed())
{
- const char* str = lua_tostring(luainternal.m_luaState, -1);
+ const char* str = lua_tostring(lua_internal().m_luaState, -1);
if (str == nullptr)
return;
std::string ss;
ss += WILUA_ERROR_PREFIX;
ss += str;
wi::backlog::post(ss, wi::backlog::LogLevel::Error);
- lua_pop(luainternal.m_luaState, 1); // remove error message
+ lua_pop(lua_internal().m_luaState, 1); // remove error message
}
}
bool RunFile(const std::string& filename)
@@ -218,7 +224,7 @@ namespace wi::lua
}
bool RunScript()
{
- luainternal.m_status = lua_pcall(luainternal.m_luaState, 0, LUA_MULTRET, 0);
+ lua_internal().m_status = lua_pcall(lua_internal().m_luaState, 0, LUA_MULTRET, 0);
if (Failed())
{
PostErrorMsg();
@@ -228,7 +234,7 @@ namespace wi::lua
}
bool RunText(const std::string& script)
{
- luainternal.m_status = luaL_loadstring(luainternal.m_luaState, script.c_str());
+ lua_internal().m_status = luaL_loadstring(lua_internal().m_luaState, script.c_str());
if (Success())
{
return RunScript();
@@ -239,7 +245,7 @@ namespace wi::lua
}
bool RegisterFunc(const std::string& name, lua_CFunction function)
{
- lua_register(luainternal.m_luaState, name.c_str(), function);
+ lua_register(lua_internal().m_luaState, name.c_str(), function);
PostErrorMsg();
@@ -247,11 +253,11 @@ namespace wi::lua
}
void RegisterLibrary(const std::string& tableName, const luaL_Reg* functions)
{
- if (luaL_newmetatable(luainternal.m_luaState, tableName.c_str()) != 0)
+ if (luaL_newmetatable(lua_internal().m_luaState, tableName.c_str()) != 0)
{
//table is not yet present
- lua_pushvalue(luainternal.m_luaState, -1);
- lua_setfield(luainternal.m_luaState, -2, "__index"); // Object.__index = Object
+ lua_pushvalue(lua_internal().m_luaState, -1);
+ lua_setfield(lua_internal().m_luaState, -2, "__index"); // Object.__index = Object
AddFuncArray(functions);
}
}
@@ -260,37 +266,37 @@ namespace wi::lua
RegisterLibrary(tableName, nullptr);
// does this call need to be checked? eg. userData == nullptr?
- void** userData = static_cast(lua_newuserdata(luainternal.m_luaState, sizeof(void*)));
+ void** userData = static_cast(lua_newuserdata(lua_internal().m_luaState, sizeof(void*)));
*(userData) = object;
- luaL_setmetatable(luainternal.m_luaState, tableName.c_str());
- lua_setglobal(luainternal.m_luaState, name.c_str());
+ luaL_setmetatable(lua_internal().m_luaState, tableName.c_str());
+ lua_setglobal(lua_internal().m_luaState, name.c_str());
return true;
}
void AddFunc(const std::string& name, lua_CFunction function)
{
- lua_pushcfunction(luainternal.m_luaState, function);
- lua_setfield(luainternal.m_luaState, -2, name.c_str());
+ lua_pushcfunction(lua_internal().m_luaState, function);
+ lua_setfield(lua_internal().m_luaState, -2, name.c_str());
}
void AddFuncArray(const luaL_Reg* functions)
{
if (functions != nullptr)
{
- luaL_setfuncs(luainternal.m_luaState, functions, 0);
+ luaL_setfuncs(lua_internal().m_luaState, functions, 0);
}
}
void AddInt(const std::string& name, int data)
{
- lua_pushinteger(luainternal.m_luaState, data);
- lua_setfield(luainternal.m_luaState, -2, name.c_str());
+ lua_pushinteger(lua_internal().m_luaState, data);
+ lua_setfield(lua_internal().m_luaState, -2, name.c_str());
}
void SetDeltaTime(double dt)
{
- lua_getglobal(luainternal.m_luaState, "setDeltaTime");
- SSetDouble(luainternal.m_luaState, dt);
- lua_call(luainternal.m_luaState, 1, 0);
+ lua_getglobal(lua_internal().m_luaState, "setDeltaTime");
+ SSetDouble(lua_internal().m_luaState, dt);
+ lua_call(lua_internal().m_luaState, 1, 0);
}
inline void SignalHelper(lua_State* L, const char* str)
@@ -301,19 +307,19 @@ namespace wi::lua
}
void FixedUpdate()
{
- SignalHelper(luainternal.m_luaState, "wickedengine_fixed_update_tick");
+ SignalHelper(lua_internal().m_luaState, "wickedengine_fixed_update_tick");
}
void Update()
{
- SignalHelper(luainternal.m_luaState, "wickedengine_update_tick");
+ SignalHelper(lua_internal().m_luaState, "wickedengine_update_tick");
}
void Render()
{
- SignalHelper(luainternal.m_luaState, "wickedengine_render_tick");
+ SignalHelper(lua_internal().m_luaState, "wickedengine_render_tick");
}
void Signal(const std::string& name)
{
- SignalHelper(luainternal.m_luaState, name.c_str());
+ SignalHelper(lua_internal().m_luaState, name.c_str());
}
void KillProcesses()
diff --git a/WickedEngine/wiPhysics.h b/WickedEngine/wiPhysics.h
index 7602a0883..c618bf09c 100644
--- a/WickedEngine/wiPhysics.h
+++ b/WickedEngine/wiPhysics.h
@@ -17,14 +17,13 @@ namespace wi::physics
void SetSimulationEnabled(bool value);
bool IsSimulationEnabled();
- // Enable/disable debug drawing of physics object
+ // Enable/disable debug drawing of physics objects
void SetDebugDrawEnabled(bool value);
bool IsDebugDrawEnabled();
// Set the accuracy of the simulation
// This value corresponds to maximum simulation step count
// Higher values will be slower but more accurate
- // Default is 10
void SetAccuracy(int value);
int GetAccuracy();
@@ -35,6 +34,17 @@ namespace wi::physics
float dt
);
+ // Set linear velocity to rigid body
+ void SetLinearVelocity(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& velocity
+ );
+ // Set angular velocity to rigid body
+ void SetAngularVelocity(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& velocity
+ );
+
// Apply force at body center
void ApplyForce(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
@@ -63,4 +73,22 @@ namespace wi::physics
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& torque
);
+ void ApplyTorqueImpulse(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& torque
+ );
+
+ enum class ActivationState
+ {
+ Active,
+ Inactive,
+ };
+ void SetActivationState(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ ActivationState state
+ );
+ void SetActivationState(
+ wi::scene::SoftBodyPhysicsComponent& physicscomponent,
+ ActivationState state
+ );
}
diff --git a/WickedEngine/wiPhysics_BindLua.cpp b/WickedEngine/wiPhysics_BindLua.cpp
new file mode 100644
index 000000000..09c1e9b5d
--- /dev/null
+++ b/WickedEngine/wiPhysics_BindLua.cpp
@@ -0,0 +1,367 @@
+#include "wiPhysics_BindLua.h"
+#include "wiPhysics.h"
+#include "wiScene_BindLua.h"
+#include "wiMath_BindLua.h"
+
+namespace wi::lua
+{
+ const char Physics_BindLua::className[] = "Physics";
+
+ Luna::FunctionType Physics_BindLua::methods[] = {
+ lunamethod(Physics_BindLua, SetEnabled),
+ lunamethod(Physics_BindLua, IsEnabled),
+ lunamethod(Physics_BindLua, SetSimulationEnabled),
+ lunamethod(Physics_BindLua, IsSimulationEnabled),
+ lunamethod(Physics_BindLua, SetDebugDrawEnabled),
+ lunamethod(Physics_BindLua, IsDebugDrawEnabled),
+ lunamethod(Physics_BindLua, SetAccuracy),
+ lunamethod(Physics_BindLua, GetAccuracy),
+ lunamethod(Physics_BindLua, SetLinearVelocity),
+ lunamethod(Physics_BindLua, SetAngularVelocity),
+ lunamethod(Physics_BindLua, ApplyForceAt),
+ lunamethod(Physics_BindLua, ApplyForce),
+ lunamethod(Physics_BindLua, ApplyForceAt),
+ lunamethod(Physics_BindLua, ApplyImpulse),
+ lunamethod(Physics_BindLua, ApplyImpulseAt),
+ lunamethod(Physics_BindLua, ApplyTorque),
+ lunamethod(Physics_BindLua, ApplyTorqueImpulse),
+ lunamethod(Physics_BindLua, SetActivationState),
+ { NULL, NULL }
+ };
+ Luna::PropertyType Physics_BindLua::properties[] = {
+ { NULL, NULL }
+ };
+
+
+ int Physics_BindLua::SetEnabled(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ wi::physics::SetEnabled(wi::lua::SGetBool(L, 1));
+ }
+ else
+ wi::lua::SError(L, "SetEnabled(bool value) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::IsEnabled(lua_State* L)
+ {
+ wi::lua::SSetBool(L, wi::physics::IsEnabled());
+ return 1;
+ }
+ int Physics_BindLua::SetSimulationEnabled(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ wi::physics::SetSimulationEnabled(wi::lua::SGetBool(L, 1));
+ }
+ else
+ wi::lua::SError(L, "SetSimulationEnabled(bool value) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::IsSimulationEnabled(lua_State* L)
+ {
+ wi::lua::SSetBool(L, wi::physics::IsSimulationEnabled());
+ return 1;
+ }
+ int Physics_BindLua::SetDebugDrawEnabled(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ wi::physics::SetDebugDrawEnabled(wi::lua::SGetBool(L, 1));
+ }
+ else
+ wi::lua::SError(L, "SetDebugDrawEnabled(bool value) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::IsDebugDrawEnabled(lua_State* L)
+ {
+ wi::lua::SSetBool(L, wi::physics::IsDebugDrawEnabled());
+ return 1;
+ }
+ int Physics_BindLua::SetAccuracy(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ wi::physics::SetAccuracy(wi::lua::SGetInt(L, 1));
+ }
+ else
+ wi::lua::SError(L, "SetAccuracy(int value) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::GetAccuracy(lua_State* L)
+ {
+ wi::lua::SSetInt(L, wi::physics::GetAccuracy());
+ return 1;
+ }
+
+ int Physics_BindLua::SetLinearVelocity(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "SetLinearVelocity(RigidBodyPhysicsComponent component, Vector velocity) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "SetLinearVelocity(RigidBodyPhysicsComponent component, Vector velocity) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::SetLinearVelocity(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "SetLinearVelocity(RigidBodyPhysicsComponent component, Vector velocity) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::SetAngularVelocity(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "SetAngularVelocity(RigidBodyPhysicsComponent component, Vector velocity) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "SetAngularVelocity(RigidBodyPhysicsComponent component, Vector velocity) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::SetAngularVelocity(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "SetAngularVelocity(RigidBodyPhysicsComponent component, Vector velocity) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyForce(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyForce(RigidBodyPhysicsComponent component, Vector force) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyForce(RigidBodyPhysicsComponent component, Vector force) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyForce(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyForce(RigidBodyPhysicsComponent component, Vector force) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyForceAt(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 2)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyForceAt(RigidBodyPhysicsComponent component, Vector force, Vector at) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyForceAt(RigidBodyPhysicsComponent component, Vector force, Vector at) second argument is not a Vector!");
+ return 0;
+ }
+ Vector_BindLua* vec2 = Luna::lightcheck(L, 3);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyForceAt(RigidBodyPhysicsComponent component, Vector force, Vector at) third argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyForceAt(
+ *component->component,
+ *(XMFLOAT3*)vec,
+ *(XMFLOAT3*)vec2
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyForceAt(RigidBodyPhysicsComponent component, Vector force, Vector at) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyImpulse(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyImpulse(RigidBodyPhysicsComponent component, Vector impulse) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyImpulse(RigidBodyPhysicsComponent component, Vector impulse) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyImpulse(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyImpulse(RigidBodyPhysicsComponent component, Vector impulse) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyImpulseAt(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 2)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyImpulseAt(RigidBodyPhysicsComponent component, Vector impulse, Vector at) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyImpulseAt(RigidBodyPhysicsComponent component, Vector impulse, Vector at) second argument is not a Vector!");
+ return 0;
+ }
+ Vector_BindLua* vec2 = Luna::lightcheck(L, 3);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyImpulseAt(RigidBodyPhysicsComponent component, Vector impulse, Vector at) third argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyImpulseAt(
+ *component->component,
+ *(XMFLOAT3*)vec,
+ *(XMFLOAT3*)vec2
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyImpulseAt(RigidBodyPhysicsComponent component, Vector impulse, Vector at) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyTorque(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyTorque(RigidBodyPhysicsComponent component, Vector torque) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyTorque(RigidBodyPhysicsComponent component, Vector torque) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyTorque(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyTorque(RigidBodyPhysicsComponent component, Vector torque) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::ApplyTorqueImpulse(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* component = Luna::lightcheck(L, 1);
+ if (component == nullptr)
+ {
+ wi::lua::SError(L, "ApplyTorqueImpulse(RigidBodyPhysicsComponent component, Vector torque) first argument is not a RigidBodyPhysicsComponent!");
+ return 0;
+ }
+ Vector_BindLua* vec = Luna::lightcheck(L, 2);
+ if (vec == nullptr)
+ {
+ wi::lua::SError(L, "ApplyTorqueImpulse(RigidBodyPhysicsComponent component, Vector torque) second argument is not a Vector!");
+ return 0;
+ }
+ wi::physics::ApplyTorqueImpulse(
+ *component->component,
+ *(XMFLOAT3*)vec
+ );
+ }
+ else
+ wi::lua::SError(L, "ApplyTorqueImpulse(RigidBodyPhysicsComponent component, Vector torque) not enough arguments!");
+ return 0;
+ }
+ int Physics_BindLua::SetActivationState(lua_State* L)
+ {
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ scene::RigidBodyPhysicsComponent_BindLua* rigid = Luna::lightcheck(L, 1);
+ if (rigid == nullptr)
+ {
+ scene::SoftBodyPhysicsComponent_BindLua* soft = Luna::lightcheck(L, 1);
+ if (soft == nullptr)
+ {
+ wi::lua::SError(L, "SetActivationState(RigidBodyPhysicsComponent | SoftBodyPhysicsComponent component, int state) first argument is not a RigidBodyPhysicsComponent or SoftBodyPhysicsComponent!");
+ return 0;
+ }
+ wi::physics::SetActivationState(
+ *soft->component,
+ (wi::physics::ActivationState)wi::lua::SGetInt(L, 2)
+ );
+ return 0;
+ }
+ wi::physics::SetActivationState(
+ *rigid->component,
+ (wi::physics::ActivationState)wi::lua::SGetInt(L, 2)
+ );
+ }
+ else
+ wi::lua::SError(L, "SetActivationState(RigidBodyPhysicsComponent | SoftBodyPhysicsComponent component, int state) not enough arguments!");
+ return 0;
+ }
+
+ void Physics_BindLua::Bind()
+ {
+ static bool initialized = false;
+ if (!initialized)
+ {
+ initialized = true;
+ Luna::Register(wi::lua::GetLuaState());
+
+ wi::lua::RunText("physics = Physics()");
+
+ wi::lua::RunText("ACTIVATION_STATE_ACTIVE = 0");
+ wi::lua::RunText("ACTIVATION_STATE_INACTIVE = 1");
+ }
+ }
+}
diff --git a/WickedEngine/wiPhysics_BindLua.h b/WickedEngine/wiPhysics_BindLua.h
new file mode 100644
index 000000000..c87d7a27f
--- /dev/null
+++ b/WickedEngine/wiPhysics_BindLua.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "wiLua.h"
+#include "wiLuna.h"
+#include "wiPhysics.h"
+
+namespace wi::lua
+{
+ class Physics_BindLua
+ {
+ public:
+ static const char className[];
+ static Luna::FunctionType methods[];
+ static Luna::PropertyType properties[];
+
+ Physics_BindLua(lua_State* L) {}
+
+ int SetEnabled(lua_State* L);
+ int IsEnabled(lua_State* L);
+ int SetSimulationEnabled(lua_State* L);
+ int IsSimulationEnabled(lua_State* L);
+ int SetDebugDrawEnabled(lua_State* L);
+ int IsDebugDrawEnabled(lua_State* L);
+ int SetAccuracy(lua_State* L);
+ int GetAccuracy(lua_State* L);
+
+ int SetLinearVelocity(lua_State* L);
+ int SetAngularVelocity(lua_State* L);
+ int ApplyForce(lua_State* L);
+ int ApplyForceAt(lua_State* L);
+ int ApplyImpulse(lua_State* L);
+ int ApplyImpulseAt(lua_State* L);
+ int ApplyTorque(lua_State* L);
+ int ApplyTorqueImpulse(lua_State* L);
+ int SetActivationState(lua_State* L);
+
+ static void Bind();
+ };
+}
diff --git a/WickedEngine/wiPhysics_Bullet.cpp b/WickedEngine/wiPhysics_Bullet.cpp
index 19c2c9fcf..6e7a2408f 100644
--- a/WickedEngine/wiPhysics_Bullet.cpp
+++ b/WickedEngine/wiPhysics_Bullet.cpp
@@ -25,11 +25,11 @@ namespace wi::physics
bool ENABLED = true;
bool SIMULATION_ENABLED = true;
bool DEBUGDRAW_ENABLED = false;
- int ACCURACY = 10;
+ int ACCURACY = 1;
int softbodyIterationCount = 5;
std::mutex physicsLock;
- class DebugDraw : public btIDebugDraw
+ class DebugDraw final : public btIDebugDraw
{
void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override
{
@@ -72,7 +72,6 @@ namespace wi::physics
struct PhysicsScene
{
- btVector3 gravity = btVector3(0, -10, 0);
btSoftBodyRigidBodyCollisionConfiguration collisionConfiguration;
btDbvtBroadphase overlappingPairCache;
btSequentialImpulseConstraintSolver solver;
@@ -85,10 +84,13 @@ namespace wi::physics
{
auto physics_scene = std::make_shared();
- physics_scene->dynamicsWorld.getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER;
- physics_scene->dynamicsWorld.getDispatchInfo().m_enableSatConvex = true;
- physics_scene->dynamicsWorld.getSolverInfo().m_splitImpulse = true;
- physics_scene->dynamicsWorld.setGravity(physics_scene->gravity);
+ btContactSolverInfo& solverInfo = physics_scene->dynamicsWorld.getSolverInfo();
+ solverInfo.m_solverMode |= SOLVER_RANDMIZE_ORDER;
+ solverInfo.m_splitImpulse = true;
+
+ btDispatcherInfo& dispatcherInfo = physics_scene->dynamicsWorld.getDispatchInfo();
+ dispatcherInfo.m_enableSatConvex = true;
+
physics_scene->dynamicsWorld.setDebugDrawer(&debugDraw);
btSoftBodyWorldInfo& softWorldInfo = physics_scene->dynamicsWorld.getWorldInfo();
@@ -96,7 +98,6 @@ namespace wi::physics
softWorldInfo.water_density = 0;
softWorldInfo.water_offset = 0;
softWorldInfo.water_normal = btVector3(0, 0, 0);
- softWorldInfo.m_gravity.setValue(physics_scene->gravity.x(), physics_scene->gravity.y(), physics_scene->gravity.z());
softWorldInfo.m_sparsesdf.Initialize();
scene.physics_scene = physics_scene;
@@ -304,10 +305,6 @@ namespace wi::physics
{
physicsobject.rigidBody->setActivationState(DISABLE_DEACTIVATION);
}
- if (physicscomponent.shape == RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH)
- {
- physicsobject.rigidBody->setActivationState(DISABLE_DEACTIVATION);
- }
physicsobject.physics_scene = scene.physics_scene;
GetPhysicsScene(scene).dynamicsWorld.addRigidBody(physicsobject.rigidBody.get());
@@ -485,6 +482,7 @@ namespace wi::physics
auto range = wi::profiler::BeginRangeCPU("Physics");
btSoftRigidDynamicsWorld& dynamicsWorld = GetPhysicsScene(scene).dynamicsWorld;
+ dynamicsWorld.setGravity(btVector3(scene.weather.gravity.x, scene.weather.gravity.y, scene.weather.gravity.z));
btVector3 wind = btVector3(scene.weather.windDirection.x, scene.weather.windDirection.y, scene.weather.windDirection.z);
@@ -512,17 +510,6 @@ namespace wi::physics
{
btRigidBody* rigidbody = GetRigidBody(physicscomponent).rigidBody.get();
- int activationState = rigidbody->getActivationState();
- if (physicscomponent.IsDisableDeactivation())
- {
- activationState |= DISABLE_DEACTIVATION;
- }
- else
- {
- activationState &= ~DISABLE_DEACTIVATION;
- }
- rigidbody->setActivationState(activationState);
-
rigidbody->setDamping(
physicscomponent.damping_linear,
physicscomponent.damping_angular
@@ -586,6 +573,7 @@ namespace wi::physics
if (physicscomponent.physicsobject != nullptr)
{
btSoftBody* softbody = GetSoftBody(physicscomponent).softBody.get();
+ softbody->getWorldInfo()->m_gravity = dynamicsWorld.getGravity();
softbody->m_cfg.kDF = physicscomponent.friction;
softbody->setWindVelocity(wind);
@@ -787,6 +775,27 @@ namespace wi::physics
+ void SetLinearVelocity(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& velocity
+ )
+ {
+ if (physicscomponent.physicsobject != nullptr)
+ {
+ GetRigidBody(physicscomponent).rigidBody->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+ }
+ }
+ void SetAngularVelocity(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& velocity
+ )
+ {
+ if (physicscomponent.physicsobject != nullptr)
+ {
+ GetRigidBody(physicscomponent).rigidBody->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+ }
+ }
+
void ApplyForce(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& force
@@ -841,4 +850,48 @@ namespace wi::physics
GetRigidBody(physicscomponent).rigidBody->applyTorque(btVector3(torque.x, torque.y, torque.z));
}
}
+ void ApplyTorqueImpulse(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ const XMFLOAT3& torque
+ )
+ {
+ if (physicscomponent.physicsobject != nullptr)
+ {
+ GetRigidBody(physicscomponent).rigidBody->applyTorqueImpulse(btVector3(torque.x, torque.y, torque.z));
+ }
+ }
+
+ constexpr int to_internal(ActivationState state)
+ {
+ switch (state)
+ {
+ default:
+ case wi::physics::ActivationState::Active:
+ return ACTIVE_TAG;
+ case wi::physics::ActivationState::Inactive:
+ return DISABLE_SIMULATION;
+ }
+ }
+ void SetActivationState(
+ wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+ ActivationState state
+ )
+ {
+ if (physicscomponent.physicsobject != nullptr)
+ {
+ //GetRigidBody(physicscomponent).rigidBody->setActivationState(to_internal(state));
+ GetRigidBody(physicscomponent).rigidBody->forceActivationState(to_internal(state));
+ }
+ }
+ void SetActivationState(
+ wi::scene::SoftBodyPhysicsComponent& physicscomponent,
+ ActivationState state
+ )
+ {
+ if (physicscomponent.physicsobject != nullptr)
+ {
+ //GetSoftBody(physicscomponent).softBody->setActivationState(to_internal(state));
+ GetSoftBody(physicscomponent).softBody->forceActivationState(to_internal(state));
+ }
+ }
}
diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp
index cee02cce7..5798ed6d4 100644
--- a/WickedEngine/wiRenderer.cpp
+++ b/WickedEngine/wiRenderer.cpp
@@ -3269,7 +3269,7 @@ void UpdatePerFrameData(
frameCB.lightarray_offset = frameCB.envprobearray_offset + frameCB.envprobearray_count;
frameCB.lightarray_count = (uint)vis.visibleLights.size();
frameCB.forcefieldarray_offset = frameCB.lightarray_offset + frameCB.lightarray_count;
- frameCB.forcefieldarray_count = uint(vis.scene->forces.GetCount() + vis.scene->colliders.GetCount());
+ frameCB.forcefieldarray_count = uint(vis.scene->forces.GetCount() + vis.scene->colliders_gpu.size());
frameCB.envprobe_mipcount = 0;
frameCB.envprobe_mipcount_rcp = 1.0f;
@@ -3734,7 +3734,7 @@ void UpdateRenderData(
}
// Write colliders into entity array:
- for (size_t i = 0; i < vis.scene->colliders.GetCount(); ++i)
+ for (size_t i = 0; i < vis.scene->colliders_gpu.size(); ++i)
{
if (entityCounter == SHADER_ENTITY_COUNT)
{
@@ -3744,16 +3744,8 @@ void UpdateRenderData(
}
ShaderEntity shaderentity = {};
- const ColliderComponent& collider = vis.scene->colliders[i];
-
- shaderentity.layerMask = ~0u;
-
- Entity entity = vis.scene->colliders.GetEntity(i);
- const LayerComponent* layer = vis.scene->layers.GetComponent(entity);
- if (layer != nullptr)
- {
- shaderentity.layerMask = layer->layerMask;
- }
+ const ColliderComponent& collider = vis.scene->colliders_gpu[i];
+ shaderentity.layerMask = collider.layerMask;
switch (collider.shape)
{
diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp
index 9fa2407f8..a4e0ad99d 100644
--- a/WickedEngine/wiScene.cpp
+++ b/WickedEngine/wiScene.cpp
@@ -2151,6 +2151,9 @@ namespace wi::scene
}
void Scene::RunColliderUpdateSystem(wi::jobsystem::context& ctx)
{
+ colliders_cpu.clear();
+ colliders_gpu.clear();
+
for (size_t i = 0; i < colliders.GetCount(); ++i)
{
ColliderComponent& collider = colliders[i];
@@ -2189,6 +2192,21 @@ namespace wi::scene
PLANE = XMMatrixInverse(nullptr, PLANE);
XMStoreFloat4x4(&collider.planeProjection, PLANE);
}
+
+ const LayerComponent* layer = layers.GetComponent(entity);
+ if (layer != nullptr)
+ {
+ collider.layerMask = layer->layerMask;
+ }
+
+ if (collider.IsCPUEnabled())
+ {
+ colliders_cpu.push_back(collider);
+ }
+ if (collider.IsGPUEnabled())
+ {
+ colliders_gpu.push_back(collider);
+ }
}
}
void Scene::RunSpringUpdateSystem(wi::jobsystem::context& ctx)
@@ -2321,9 +2339,9 @@ namespace wi::scene
XMFLOAT3 scale = transform.GetScale();
const float hitRadius = spring.hitRadius * std::max(scale.x, std::max(scale.y, scale.z));
- for (size_t collider_index = 0; collider_index < colliders.GetCount(); ++collider_index)
+ for (size_t collider_index = 0; collider_index < colliders_cpu.size(); ++collider_index)
{
- const ColliderComponent& collider = colliders[collider_index];
+ const ColliderComponent& collider = colliders_cpu[collider_index];
wi::primitive::Sphere tail_sphere;
XMStoreFloat3(&tail_sphere.center, tail_next); // tail_sphere center can change within loop!
diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h
index 68a614888..2ab4878cb 100644
--- a/WickedEngine/wiScene.h
+++ b/WickedEngine/wiScene.h
@@ -45,11 +45,11 @@ namespace wi::scene
wi::ecs::ComponentManager& animation_datas = componentLibrary.Register("wi::scene::Scene::animation_datas");
wi::ecs::ComponentManager& emitters = componentLibrary.Register("wi::scene::Scene::emitters");
wi::ecs::ComponentManager& hairs = componentLibrary.Register("wi::scene::Scene::hairs");
- wi::ecs::ComponentManager& weathers = componentLibrary.Register("wi::scene::Scene::weathers");
+ wi::ecs::ComponentManager& weathers = componentLibrary.Register("wi::scene::Scene::weathers", 1); // version = 1
wi::ecs::ComponentManager& sounds = componentLibrary.Register("wi::scene::Scene::sounds");
wi::ecs::ComponentManager& inverse_kinematics = componentLibrary.Register("wi::scene::Scene::inverse_kinematics");
wi::ecs::ComponentManager& springs = componentLibrary.Register("wi::scene::Scene::springs", 1); // version = 1
- wi::ecs::ComponentManager& colliders = componentLibrary.Register("wi::scene::Scene::colliders", 1); // version = 1
+ wi::ecs::ComponentManager& colliders = componentLibrary.Register("wi::scene::Scene::colliders", 2); // version = 2
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", 1); // version = 1
@@ -178,6 +178,10 @@ namespace wi::scene
mutable std::atomic_bool lightmap_refresh_needed{ false };
wi::vector transforms_temp;
+ // CPU/GPU Colliders:
+ wi::vector colliders_cpu;
+ wi::vector colliders_gpu;
+
// Ocean GPU state:
wi::Ocean ocean;
void OceanRegenerate() { ocean.Create(weather.oceanParameters); }
diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp
index 5e3f4924f..d0c1c7604 100644
--- a/WickedEngine/wiScene_BindLua.cpp
+++ b/WickedEngine/wiScene_BindLua.cpp
@@ -4376,6 +4376,7 @@ Luna::PropertyType WeatherComponent_BindLua::propertie
lunaproperty(WeatherComponent_BindLua, cloud_shadow_scale),
lunaproperty(WeatherComponent_BindLua, cloud_shadow_speed),
lunaproperty(WeatherComponent_BindLua, windDirection),
+ lunaproperty(WeatherComponent_BindLua, gravity),
lunaproperty(WeatherComponent_BindLua, windRandomness),
lunaproperty(WeatherComponent_BindLua, windWaveSize),
lunaproperty(WeatherComponent_BindLua, windSpeed),
@@ -4642,6 +4643,8 @@ int SoundComponent_BindLua::SetDisable3D(lua_State* L)
const char ColliderComponent_BindLua::className[] = "ColliderComponent";
Luna::FunctionType ColliderComponent_BindLua::methods[] = {
+ lunamethod(ColliderComponent_BindLua, SetCPUEnabled),
+ lunamethod(ColliderComponent_BindLua, SetGPUEnabled),
{ NULL, NULL }
};
Luna::PropertyType ColliderComponent_BindLua::properties[] = {
@@ -4666,4 +4669,31 @@ ColliderComponent_BindLua::~ColliderComponent_BindLua()
}
}
+int ColliderComponent_BindLua::SetCPUEnabled(lua_State* L)
+{
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ component->SetCPUEnabled(wi::lua::SGetBool(L, 1));
+ }
+ else
+ {
+ wi::lua::SError(L, "SetCPUEnabled(bool value) not enough arguments!");
+ }
+ return 0;
+}
+int ColliderComponent_BindLua::SetGPUEnabled(lua_State* L)
+{
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 0)
+ {
+ component->SetGPUEnabled(wi::lua::SGetBool(L, 1));
+ }
+ else
+ {
+ wi::lua::SError(L, "SetGPUEnabled(bool value) not enough arguments!");
+ }
+ return 0;
+}
+
}
diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h
index 0c541ff8a..572729cb4 100644
--- a/WickedEngine/wiScene_BindLua.h
+++ b/WickedEngine/wiScene_BindLua.h
@@ -1184,6 +1184,7 @@ namespace wi::lua::scene
windWaveSize = FloatProperty(&component->windWaveSize);
windSpeed = FloatProperty(&component->windSpeed);
stars = FloatProperty(&component->stars);
+ gravity = VectorProperty(&component->gravity);
OceanParameters = Weather_OceanParams_Property(&component->oceanParameters);
AtmosphereParameters = Weather_AtmosphereParams_Property(&component->atmosphereParameters);
@@ -1216,6 +1217,7 @@ namespace wi::lua::scene
FloatProperty cloud_shadow_scale;
FloatProperty cloud_shadow_speed;
VectorProperty windDirection;
+ VectorProperty gravity;
FloatProperty windRandomness;
FloatProperty windWaveSize;
FloatProperty windSpeed;
@@ -1239,6 +1241,7 @@ namespace wi::lua::scene
PropertyFunction(cloud_shadow_scale)
PropertyFunction(cloud_shadow_speed)
PropertyFunction(windDirection)
+ PropertyFunction(gravity)
PropertyFunction(windRandomness)
PropertyFunction(windWaveSize)
PropertyFunction(windSpeed)
@@ -1336,7 +1339,7 @@ namespace wi::lua::scene
ColliderComponent_BindLua(wi::scene::ColliderComponent* component) :component(component) { BuildBindings(); }
ColliderComponent_BindLua(lua_State* L);
~ColliderComponent_BindLua();
-
+
IntProperty Shape;
FloatProperty Radius;
VectorProperty Offset;
@@ -1346,6 +1349,9 @@ namespace wi::lua::scene
PropertyFunction(Radius)
PropertyFunction(Offset)
PropertyFunction(Tail)
+
+ int SetCPUEnabled(lua_State* L);
+ int SetGPUEnabled(lua_State* L);
};
}
diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h
index b3e76958d..1df78c124 100644
--- a/WickedEngine/wiScene_Components.h
+++ b/WickedEngine/wiScene_Components.h
@@ -1257,6 +1257,7 @@ namespace wi::scene
float windWaveSize = 1;
float windSpeed = 1;
float stars = 0.5f;
+ XMFLOAT3 gravity = XMFLOAT3(0, -10, 0);
wi::Ocean::OceanParameters oceanParameters;
AtmosphereParameters atmosphereParameters;
@@ -1366,8 +1367,16 @@ namespace wi::scene
enum FLAGS
{
EMPTY = 0,
+ CPU = 1 << 0,
+ GPU = 1 << 1,
};
- uint32_t _flags = EMPTY;
+ uint32_t _flags = CPU;
+
+ constexpr void SetCPUEnabled(bool value = true) { if (value) { _flags |= CPU; } else { _flags &= ~CPU; } }
+ constexpr void SetGPUEnabled(bool value = true) { if (value) { _flags |= GPU; } else { _flags &= ~GPU; } }
+
+ constexpr bool IsCPUEnabled() const { return _flags & CPU; }
+ constexpr bool IsGPUEnabled() const { return _flags & GPU; }
enum class Shape
{
@@ -1387,6 +1396,7 @@ namespace wi::scene
XMFLOAT3 planeOrigin = {};
XMFLOAT3 planeNormal = {};
XMFLOAT4X4 planeProjection = wi::math::IDENTITY_MATRIX;
+ uint32_t layerMask = ~0u;
void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri);
};
diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp
index 151d225e7..f80334899 100644
--- a/WickedEngine/wiScene_Serializers.cpp
+++ b/WickedEngine/wiScene_Serializers.cpp
@@ -1241,6 +1241,11 @@ namespace wi::scene
volumetricCloudsWeatherMap = wi::resourcemanager::Load(volumetricCloudsWeatherMapName, wi::resourcemanager::Flags::IMPORT_RETAIN_FILEDATA);
}
}
+
+ if (seri.GetVersion() >= 1)
+ {
+ archive >> gravity;
+ }
}
else
{
@@ -1388,6 +1393,11 @@ namespace wi::scene
{
archive << volumetricCloudsWeatherMapName;
}
+
+ if (seri.GetVersion() >= 1)
+ {
+ archive << gravity;
+ }
}
}
void SoundComponent::Serialize(wi::Archive& archive, EntitySerializer& seri)
@@ -1486,6 +1496,12 @@ namespace wi::scene
archive >> radius;
archive >> offset;
archive >> tail;
+
+ if (seri.GetVersion() < 2)
+ {
+ SetCPUEnabled(true);
+ SetGPUEnabled(true);
+ }
}
else
{
diff --git a/WickedEngine/wiTerrain.cpp b/WickedEngine/wiTerrain.cpp
index c3350db7f..58831b637 100644
--- a/WickedEngine/wiTerrain.cpp
+++ b/WickedEngine/wiTerrain.cpp
@@ -4,6 +4,7 @@
#include "wiRenderer.h"
#include "wiHelper.h"
#include "wiScene.h"
+#include "wiPhysics.h"
using namespace wi::ecs;
using namespace wi::scene;
@@ -397,21 +398,27 @@ namespace wi::terrain
RigidBodyPhysicsComponent* rigidbody = scene->rigidbodies.GetComponent(chunk_data.entity);
if (IsPhysicsEnabled())
{
- const int lod_required = std::max(0, dist - 1);
+ const ObjectComponent* object = scene->objects.GetComponent(chunk_data.entity);
+ const int lod_required = object == nullptr ? 0 : object->lod;
if (rigidbody != nullptr)
{
- if (dist < physics_generation)
+ if (rigidbody->mesh_lod != lod_required)
{
- if (rigidbody->mesh_lod != lod_required)
- {
- rigidbody->mesh_lod = lod_required;
- rigidbody->physicsobject = {}; // will be recreated
- }
+ rigidbody->mesh_lod = lod_required;
+ rigidbody->physicsobject = {}; // will be recreated
}
else
{
- scene->rigidbodies.Remove(chunk_data.entity);
+ if (dist < physics_generation)
+ {
+ wi::physics::SetActivationState(*rigidbody, wi::physics::ActivationState::Active);
+ }
+ else
+ {
+ //scene->rigidbodies.Remove(chunk_data.entity);
+ wi::physics::SetActivationState(*rigidbody, wi::physics::ActivationState::Inactive);
+ }
}
}
else
@@ -420,7 +427,7 @@ namespace wi::terrain
{
RigidBodyPhysicsComponent& newrigidbody = scene->rigidbodies.Create(chunk_data.entity);
newrigidbody.shape = RigidBodyPhysicsComponent::TRIANGLE_MESH;
- newrigidbody.SetDisableDeactivation(true);
+ //newrigidbody.SetDisableDeactivation(true);
newrigidbody.SetKinematic(true);
newrigidbody.mesh_lod = lod_required;
}
@@ -753,6 +760,8 @@ namespace wi::terrain
for (const auto& prop : props)
{
+ if (prop.data.empty())
+ continue;
std::uniform_int_distribution gen_distr(
uint32_t(prop.min_count_per_chunk * chunk_data.prop_density_current),
uint32_t(prop.max_count_per_chunk * chunk_data.prop_density_current)
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index 2f7a1ae5c..c7fdcf9c0 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 = 36;
+ const int revision = 37;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);