Physics updates, lua bindings (#554)

* physics updates, lua bindings

* velocity setters

* fix softbody gravity

* gui things

* colliders cpu and gpu separation

* terrain prop check for missing assets

* lua internal put in function
This commit is contained in:
Turánszki János
2022-09-04 16:34:50 +02:00
committed by GitHub
parent c359395cea
commit 03fe5dcce8
29 changed files with 802 additions and 92 deletions
@@ -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
</br>
@@ -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
+8 -2
View File
@@ -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));
+1
View File
@@ -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;
+7 -1
View File
@@ -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;
+1
View File
@@ -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;
+37 -1
View File
@@ -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);
+3
View File
@@ -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;
+1
View File
@@ -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);
+3
View File
@@ -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;
+11
View File
@@ -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);
+1
View File
@@ -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;
+1
View File
@@ -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()
+2
View File
@@ -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
@@ -231,6 +231,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)CommonInclude.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiConfig.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiNoise.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiPhysics_BindLua.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)wiRenderPath3D_PathTracing.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\liberation_sans.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\D3D12MemAlloc.h" />
@@ -502,6 +503,7 @@
<ClCompile Include="$(MSBuildThisFileDirectory)BULLET\LinearMath\btSerializer.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)BULLET\LinearMath\btVector3.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiConfig.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiPhysics_BindLua.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)wiRenderPath3D_PathTracing.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\D3D12MemAlloc.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" />
@@ -1086,6 +1086,9 @@
<ClInclude Include="$(MSBuildThisFileDirectory)wiScene_Components.h">
<Filter>ENGINE\System</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)wiPhysics_BindLua.h">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)LUA\lapi.c">
@@ -1829,6 +1832,9 @@
<ClCompile Include="$(MSBuildThisFileDirectory)wiScene_Components.cpp">
<Filter>ENGINE\System</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)wiPhysics_BindLua.cpp">
<Filter>ENGINE\Scripting\LuaBindings</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="$(MSBuildThisFileDirectory)ArchiveVersionHistory.txt" />
+38 -32
View File
@@ -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<void**>(lua_newuserdata(luainternal.m_luaState, sizeof(void*)));
void** userData = static_cast<void**>(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()
+30 -2
View File
@@ -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
);
}
+367
View File
@@ -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<Physics_BindLua>::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<Physics_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::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<Vector_BindLua>::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<scene::RigidBodyPhysicsComponent_BindLua>::lightcheck(L, 1);
if (rigid == nullptr)
{
scene::SoftBodyPhysicsComponent_BindLua* soft = Luna<scene::SoftBodyPhysicsComponent_BindLua>::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<Physics_BindLua>::Register(wi::lua::GetLuaState());
wi::lua::RunText("physics = Physics()");
wi::lua::RunText("ACTIVATION_STATE_ACTIVE = 0");
wi::lua::RunText("ACTIVATION_STATE_INACTIVE = 1");
}
}
}
+38
View File
@@ -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<Physics_BindLua>::FunctionType methods[];
static Luna<Physics_BindLua>::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();
};
}
+76 -23
View File
@@ -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<PhysicsScene>();
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));
}
}
}
+4 -12
View File
@@ -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)
{
+20 -2
View File
@@ -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!
+6 -2
View File
@@ -45,11 +45,11 @@ namespace wi::scene
wi::ecs::ComponentManager<AnimationDataComponent>& animation_datas = componentLibrary.Register<AnimationDataComponent>("wi::scene::Scene::animation_datas");
wi::ecs::ComponentManager<EmittedParticleSystem>& emitters = componentLibrary.Register<EmittedParticleSystem>("wi::scene::Scene::emitters");
wi::ecs::ComponentManager<HairParticleSystem>& hairs = componentLibrary.Register<HairParticleSystem>("wi::scene::Scene::hairs");
wi::ecs::ComponentManager<WeatherComponent>& weathers = componentLibrary.Register<WeatherComponent>("wi::scene::Scene::weathers");
wi::ecs::ComponentManager<WeatherComponent>& weathers = componentLibrary.Register<WeatherComponent>("wi::scene::Scene::weathers", 1); // version = 1
wi::ecs::ComponentManager<SoundComponent>& sounds = componentLibrary.Register<SoundComponent>("wi::scene::Scene::sounds");
wi::ecs::ComponentManager<InverseKinematicsComponent>& inverse_kinematics = componentLibrary.Register<InverseKinematicsComponent>("wi::scene::Scene::inverse_kinematics");
wi::ecs::ComponentManager<SpringComponent>& springs = componentLibrary.Register<SpringComponent>("wi::scene::Scene::springs", 1); // version = 1
wi::ecs::ComponentManager<ColliderComponent>& colliders = componentLibrary.Register<ColliderComponent>("wi::scene::Scene::colliders", 1); // version = 1
wi::ecs::ComponentManager<ColliderComponent>& colliders = componentLibrary.Register<ColliderComponent>("wi::scene::Scene::colliders", 2); // version = 2
wi::ecs::ComponentManager<ScriptComponent>& scripts = componentLibrary.Register<ScriptComponent>("wi::scene::Scene::scripts");
wi::ecs::ComponentManager<ExpressionComponent>& expressions = componentLibrary.Register<ExpressionComponent>("wi::scene::Scene::expressions");
wi::ecs::ComponentManager<wi::terrain::Terrain>& terrains = componentLibrary.Register<wi::terrain::Terrain>("wi::scene::Scene::terrains", 1); // version = 1
@@ -178,6 +178,10 @@ namespace wi::scene
mutable std::atomic_bool lightmap_refresh_needed{ false };
wi::vector<TransformComponent> transforms_temp;
// CPU/GPU Colliders:
wi::vector<ColliderComponent> colliders_cpu;
wi::vector<ColliderComponent> colliders_gpu;
// Ocean GPU state:
wi::Ocean ocean;
void OceanRegenerate() { ocean.Create(weather.oceanParameters); }
+30
View File
@@ -4376,6 +4376,7 @@ Luna<WeatherComponent_BindLua>::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<ColliderComponent_BindLua>::FunctionType ColliderComponent_BindLua::methods[] = {
lunamethod(ColliderComponent_BindLua, SetCPUEnabled),
lunamethod(ColliderComponent_BindLua, SetGPUEnabled),
{ NULL, NULL }
};
Luna<ColliderComponent_BindLua>::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;
}
}
+7 -1
View File
@@ -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);
};
}
+11 -1
View File
@@ -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);
};
+16
View File
@@ -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
{
+18 -9
View File
@@ -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<uint32_t> 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)
+1 -1
View File
@@ -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);