diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index 330351281..0cb3db31c 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -1001,7 +1001,7 @@ Describes a Sound object. - IsDisabled() : bool result -- Check if sound is disabled #### ColliderComponent -Describes a Sound object. +Describes a Collider object. - Shape : int -- Shape of the collider - Radius : float - Offset : Vector @@ -1012,6 +1012,97 @@ Describes a Sound object. - GetCapsule() : Capsule - GetSphere() : Sphere +#### ExpressionComponent +- FindExpressionID(string name) : int -- Find an expression within the ExpressionComponent by name +- SetWeight(int id, float weight) -- Set expression weight by ID. The ID can be a non-preset expression. Use FindExpressionID() to retrieve non-preset expression IDs +- SetPresetWeight(ExpressionPreset preset, float weight) -- Set a preset expression's weight. You can get access to preset values from ExpressionPreset table + +[outer] ExpressionPreset = { + Happy = 0, + Angry = 1, + Sad = 2, + Relaxed = 3, + Surprised = 4, + Aa = 5, + Ih = 6, + Ou = 7, + Ee = 8, + Oh = 9, + Blink = 10, + BlinkLeft = 11, + BlinkRight = 12, + LookUp = 13, + LookDown = 14, + LookLeft = 15, + LookRight = 16, + Neutral = 17, +} + + +#### HumanoidComponent +- GetBoneEntity(HumanoidBone bone) : int -- Get the entity that is mapped to the specified humanoid bone. Use HumanoidBone table to get access to humanoid bone values +- SetLookAtEnabled(bool value) -- Enable/disable automatic lookAt (for head and eyes movement) +- SetLookAt(Vector value) -- Set a target lookAt position (for head an eyes movement) + +[outer] HumanoidBone = { + Hips = 0, + Spine = 1, + Chest = 2, + UpperChest = 3, + Neck = 4, + Head = 5, + LeftEye = 6, + RightEye = 7, + Jaw = 8, + LeftUpperLeg = 9, + LeftLowerLeg = 10, + LeftFoot = 11, + LeftToes = 12, + RightUpperLeg = 13, + RightLowerLeg = 14, + RightFoot = 15, + RightToes = 16, + LeftShoulder = 17, + LeftUpperArm = 18, + LeftLowerArm = 19, + LeftHand = 20, + RightShoulder = 21, + RightUpperArm = 22, + RightLowerArm = 23, + RightHand = 24, + LeftThumbMetacarpal = 25, + LeftThumbProximal = 26, + LeftThumbDistal = 27, + LeftIndexProximal = 28, + LeftIndexIntermediate = 29, + LeftIndexDistal = 30, + LeftMiddleProximal = 31, + LeftMiddleIntermediate = 32, + LeftMiddleDistal = 33, + LeftRingProximal = 34, + LeftRingIntermediate = 35, + LeftRingDistal = 36, + LeftLittleProximal = 37, + LeftLittleIntermediate = 38, + LeftLittleDistal = 39, + RightThumbMetacarpal = 40, + RightThumbProximal = 41, + RightThumbDistal = 42, + RightIndexIntermediate = 43, + RightIndexDistal = 44, + RightIndexProximal = 45, + RightMiddleProximal = 46, + RightMiddleIntermediate = 47, + RightMiddleDistal = 48, + RightRingProximal = 49, + RightRingIntermediate = 50, + RightRingDistal = 51, + RightLittleProximal = 52, + RightLittleIntermediate = 53, + RightLittleDistal = 54, +} + + ## Canvas This is used to describe a drawable area - GetDPI() : float -- pixels per inch diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 5fab9897d..675099440 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -597,6 +597,8 @@ void EditorComponent::Update(float dt) CheckBonePickingEnabled(); UpdateTopMenuAnimation(); + save_text_alpha = std::max(0.0f, save_text_alpha - dt); + bool clear_selected = false; if (wi::input::Press(wi::input::KEYBOARD_BUTTON_ESCAPE)) { @@ -2438,6 +2440,20 @@ void EditorComponent::Compose(CommandList cmd) const renderPath->Compose(cmd); RenderPath2D::Compose(cmd); + + if (save_text_alpha > 0) + { + wi::font::Params params; + params.color = save_text_color; + params.shadowColor = wi::Color::Black(); + params.color.setA(uint8_t(std::min(1.0f, save_text_alpha) * 255)); + params.shadowColor.setA(params.color.getA()); + params.position = XMFLOAT3(GetLogicalWidth() * 0.5f, GetLogicalHeight() * 0.5f, 0); + params.h_align = wi::font::WIFALIGN_CENTER; + params.v_align = wi::font::WIFALIGN_CENTER; + params.size = 30; + wi::font::Draw("Scene saved: " + GetCurrentEditorScene().path, params, cmd); + } } void EditorComponent::ClearSelected() @@ -2840,6 +2856,8 @@ void EditorComponent::Save(const std::string& filename) RefreshSceneList(); wi::backlog::post("Scene " + std::to_string(current_scene) + " saved: " + GetCurrentEditorScene().path); + + save_text_alpha = 2; } void EditorComponent::SaveAs() { diff --git a/Editor/Editor.h b/Editor/Editor.h index 7516b3ca7..46140389e 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -112,6 +112,9 @@ public: void SaveAs(); bool deleting = false; + float save_text_alpha = 0; // seconds until save text disappears + wi::Color save_text_color = wi::Color::White(); + struct EditorScene { std::string path; diff --git a/Editor/OptionsWindow.cpp b/Editor/OptionsWindow.cpp index 38aab7462..0bf0b664e 100644 --- a/Editor/OptionsWindow.cpp +++ b/Editor/OptionsWindow.cpp @@ -568,6 +568,8 @@ void OptionsWindow::Create(EditorComponent* _editor) } editor->inactiveEntityColor.setA(150); + editor->save_text_color = theme.font.color; + }); AddWidget(&themeCombo); diff --git a/Editor/WeatherWindow.cpp b/Editor/WeatherWindow.cpp index 653a6ff65..55c496ff3 100644 --- a/Editor/WeatherWindow.cpp +++ b/Editor/WeatherWindow.cpp @@ -96,6 +96,16 @@ void WeatherWindow::Create(EditorComponent* _editor) colorComboBox.SetSize(XMFLOAT2(mod_wid - x + mod_x - hei - 1, hei)); primaryButton.SetSize(XMFLOAT2(mod_wid, hei)); + overrideFogColorCheckBox.Create("Override fog color: "); + overrideFogColorCheckBox.SetTooltip("If enabled, the fog color will be always taken from Horizon Color, even if the sky is realistic"); + overrideFogColorCheckBox.SetSize(XMFLOAT2(hei, hei)); + overrideFogColorCheckBox.SetPos(XMFLOAT2(x, y)); + overrideFogColorCheckBox.OnClick([&](wi::gui::EventArgs args) { + auto& weather = GetWeather(); + weather.SetOverrideFogColor(args.bValue); + }); + AddWidget(&overrideFogColorCheckBox); + heightFogCheckBox.Create("Height fog: "); heightFogCheckBox.SetSize(XMFLOAT2(hei, hei)); heightFogCheckBox.SetPos(XMFLOAT2(x, y)); @@ -683,6 +693,7 @@ void WeatherWindow::Update() volumetricCloudsWeatherMapButton.SetText(wi::helper::GetFileNameFromPath(weather.volumetricCloudsWeatherMapName)); } + overrideFogColorCheckBox.SetCheck(weather.IsOverrideFogColor()); heightFogCheckBox.SetCheck(weather.IsHeightFog()); fogStartSlider.SetValue(weather.fogStart); fogEndSlider.SetValue(weather.fogEnd); @@ -816,6 +827,7 @@ void WeatherWindow::ResizeLayout() add_fullwidth(skyButton); add_fullwidth(colorgradingButton); add_right(heightFogCheckBox); + overrideFogColorCheckBox.SetPos(XMFLOAT2(heightFogCheckBox.GetPos().x - 100, heightFogCheckBox.GetPos().y)); add(fogStartSlider); add(fogEndSlider); add(fogHeightStartSlider); diff --git a/Editor/WeatherWindow.h b/Editor/WeatherWindow.h index f0976f221..54f819da4 100644 --- a/Editor/WeatherWindow.h +++ b/Editor/WeatherWindow.h @@ -22,6 +22,7 @@ public: XMFLOAT3 default_sky_zenith = XMFLOAT3(0, 0, 0); wi::gui::Button primaryButton; + wi::gui::CheckBox overrideFogColorCheckBox; wi::gui::CheckBox heightFogCheckBox; wi::gui::Slider fogStartSlider; wi::gui::Slider fogEndSlider; diff --git a/Editor/main_Windows.cpp b/Editor/main_Windows.cpp index c7319f6d3..f3fe3aeaf 100644 --- a/Editor/main_Windows.cpp +++ b/Editor/main_Windows.cpp @@ -233,7 +233,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_SIZE: case WM_DPICHANGED: - if(editor.is_window_active) + if(editor.is_window_active && LOWORD(lParam) > 0 && HIWORD(lParam) > 0) editor.SetWindow(hWnd); break; case WM_HOTKEY: diff --git a/WickedEngine/shaders/ShaderInterop_Renderer.h b/WickedEngine/shaders/ShaderInterop_Renderer.h index 99ae5ef95..fc3df8806 100644 --- a/WickedEngine/shaders/ShaderInterop_Renderer.h +++ b/WickedEngine/shaders/ShaderInterop_Renderer.h @@ -663,6 +663,7 @@ static const uint OPTION_BIT_DISABLE_ALBEDO_MAPS = 1 << 11; static const uint OPTION_BIT_FORCE_DIFFUSE_LIGHTING = 1 << 12; static const uint OPTION_BIT_STATIC_SKY_HDR = 1 << 13; static const uint OPTION_BIT_VOLUMETRICCLOUDS_SHADOWS = 1 << 14; +static const uint OPTION_BIT_OVERRIDE_FOG_COLOR = 1 << 15; // ---------- Common Constant buffers: ----------------- diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index c3cc377b7..df0a66010 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -896,17 +896,15 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting) inline void ApplyFog(in float distance, float3 P, float3 V, inout float4 color) { const float fogAmount = GetFogAmount(distance, P, V); + + float3 fogColor = GetHorizonColor(); - if (GetFrame().options & OPTION_BIT_REALISTIC_SKY) + if ((GetFrame().options & OPTION_BIT_REALISTIC_SKY) && (GetFrame().options & OPTION_BIT_OVERRIDE_FOG_COLOR) == 0) { - const float3 skyLuminance = texture_skyluminancelut.SampleLevel(sampler_point_clamp, float2(0.5, 0.5), 0).rgb; - color.rgb = lerp(color.rgb, skyLuminance, fogAmount); - } - else - { - const float3 V = float3(0.0, -1.0, 0.0); - color.rgb = lerp(color.rgb, GetDynamicSkyColor(V, false, false, false, true), fogAmount); + fogColor = texture_skyluminancelut.SampleLevel(sampler_point_clamp, float2(0.5, 0.5), 0).rgb; } + + color.rgb = lerp(color.rgb, fogColor, fogAmount); } inline uint AlphaToCoverage(float alpha, float alphaTest, float4 svposition) diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index cd921b874..0678314e5 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3336,6 +3336,10 @@ void UpdatePerFrameData( { frameCB.options |= OPTION_BIT_REALISTIC_SKY; } + if (vis.scene->weather.IsOverrideFogColor()) + { + frameCB.options |= OPTION_BIT_OVERRIDE_FOG_COLOR; + } if (vis.scene->weather.IsHeightFog()) { frameCB.options |= OPTION_BIT_HEIGHT_FOG; diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index 89cc6e978..0c7cbd3f3 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -288,6 +288,121 @@ int SceneIntersectCapsule(lua_State* L) return 0; } + +static const std::string value_bindings = R"( +INVALID_ENTITY = 0 + +DIRECTIONAL = 0 +POINT = 1 +SPOT = 2 +SPHERE = 3 +DISC = 4 +RECTANGLE = 5 +TUBE = 6 + +STENCILREF_EMPTY = 0 +STENCILREF_DEFAULT = 1 +STENCILREF_CUSTOMSHADER = 2 +STENCILREF_OUTLINE = 3 +STENCILREF_CUSTOMSHADER_OUTLINE = 4 + +STENCILREF_SKIN = 3 +STENCILREF_SNOW = 4 + +FILTER_NONE = 0 +FILTER_OPAQUE = 1 << 0 +FILTER_TRANSPARENT = 1 << 1 +FILTER_WATER = 1 << 2 +FILTER_NAVIGATION_MESH = 1 << 3 +FILTER_OBJECT_ALL = FILTER_OPAQUE | FILTER_TRANSPARENT | FILTER_WATER | FILTER_NAVIGATION_MESH +FILTER_COLLIDER = 1 << 4 +FILTER_ALL = ~0 + +PICK_VOID = FILTER_NONE +PICK_OPAQUE = FILTER_OPAQUE +PICK_TRANSPARENT = FILTER_TRANSPARENT +PICK_WATER = FILTER_WATER + +ExpressionPreset = { + Happy = 0, + Angry = 1, + Sad = 2, + Relaxed = 3, + Surprised = 4, + Aa = 5, + Ih = 6, + Ou = 7, + Ee = 8, + Oh = 9, + Blink = 10, + BlinkLeft = 11, + BlinkRight = 12, + LookUp = 13, + LookDown = 14, + LookLeft = 15, + LookRight = 16, + Neutral = 17, +} + +HumanoidBone = { + Hips = 0, + Spine = 1, + Chest = 2, + UpperChest = 3, + Neck = 4, + Head = 5, + LeftEye = 6, + RightEye = 7, + Jaw = 8, + LeftUpperLeg = 9, + LeftLowerLeg = 10, + LeftFoot = 11, + LeftToes = 12, + RightUpperLeg = 13, + RightLowerLeg = 14, + RightFoot = 15, + RightToes = 16, + LeftShoulder = 17, + LeftUpperArm = 18, + LeftLowerArm = 19, + LeftHand = 20, + RightShoulder = 21, + RightUpperArm = 22, + RightLowerArm = 23, + RightHand = 24, + LeftThumbMetacarpal = 25, + LeftThumbProximal = 26, + LeftThumbDistal = 27, + LeftIndexProximal = 28, + LeftIndexIntermediate = 29, + LeftIndexDistal = 30, + LeftMiddleProximal = 31, + LeftMiddleIntermediate = 32, + LeftMiddleDistal = 33, + LeftRingProximal = 34, + LeftRingIntermediate = 35, + LeftRingDistal = 36, + LeftLittleProximal = 37, + LeftLittleIntermediate = 38, + LeftLittleDistal = 39, + RightThumbMetacarpal = 40, + RightThumbProximal = 41, + RightThumbDistal = 42, + RightIndexIntermediate = 43, + RightIndexDistal = 44, + RightIndexProximal = 45, + RightMiddleProximal = 46, + RightMiddleIntermediate = 47, + RightMiddleDistal = 48, + RightRingProximal = 49, + RightRingIntermediate = 50, + RightRingDistal = 51, + RightLittleProximal = 52, + RightLittleIntermediate = 53, + RightLittleDistal = 54, +} +)"; + void Bind() { static bool initialized = false; @@ -298,25 +413,6 @@ void Bind() lua_State* L = wi::lua::GetLuaState(); wi::lua::RegisterFunc("CreateEntity", CreateEntity_BindLua); - wi::lua::RunText("INVALID_ENTITY = 0"); - - wi::lua::RunText("DIRECTIONAL = 0"); - wi::lua::RunText("POINT = 1"); - wi::lua::RunText("SPOT = 2"); - wi::lua::RunText("SPHERE = 3"); - wi::lua::RunText("DISC = 4"); - wi::lua::RunText("RECTANGLE = 5"); - wi::lua::RunText("TUBE = 6"); - - wi::lua::RunText("STENCILREF_EMPTY = 0"); - wi::lua::RunText("STENCILREF_DEFAULT = 1"); - wi::lua::RunText("STENCILREF_CUSTOMSHADER = 2"); - wi::lua::RunText("STENCILREF_OUTLINE = 3"); - wi::lua::RunText("STENCILREF_CUSTOMSHADER_OUTLINE = 4"); - - - wi::lua::RunText("STENCILREF_SKIN = 3"); // deprecated - wi::lua::RunText("STENCILREF_SNOW = 4"); // deprecated wi::lua::RegisterFunc("GetCamera", GetCamera); wi::lua::RegisterFunc("GetScene", GetScene); @@ -325,21 +421,6 @@ void Bind() wi::lua::RegisterFunc("SceneIntersectSphere", SceneIntersectSphere); wi::lua::RegisterFunc("SceneIntersectCapsule", SceneIntersectCapsule); - wi::lua::RunText("FILTER_NONE = 0"); - wi::lua::RunText("FILTER_OPAQUE = 1 << 0"); - wi::lua::RunText("FILTER_TRANSPARENT = 1 << 1"); - wi::lua::RunText("FILTER_WATER = 1 << 2"); - wi::lua::RunText("FILTER_NAVIGATION_MESH = 1 << 3"); - wi::lua::RunText("FILTER_OBJECT_ALL = FILTER_OPAQUE | FILTER_TRANSPARENT | FILTER_WATER | FILTER_NAVIGATION_MESH"); - wi::lua::RunText("FILTER_COLLIDER = 1 << 4"); - wi::lua::RunText("FILTER_ALL = ~0"); - - // deprecated names: - wi::lua::RunText("PICK_VOID = FILTER_NONE"); - wi::lua::RunText("PICK_OPAQUE = FILTER_OPAQUE"); - wi::lua::RunText("PICK_TRANSPARENT = FILTER_TRANSPARENT"); - wi::lua::RunText("PICK_WATER = FILTER_WATER"); - Luna::Register(L); Luna::Register(L); Luna::Register(L); @@ -364,6 +445,10 @@ void Bind() Luna::Register(L); Luna::Register(L); Luna::Register(L); + Luna::Register(L); + Luna::Register(L); + + wi::lua::RunText(value_bindings); } } @@ -396,6 +481,8 @@ Luna::FunctionType Scene_BindLua::methods[] = { lunamethod(Scene_BindLua, Component_CreateWeather), lunamethod(Scene_BindLua, Component_CreateSound), lunamethod(Scene_BindLua, Component_CreateCollider), + lunamethod(Scene_BindLua, Component_CreateExpression), + lunamethod(Scene_BindLua, Component_CreateHumanoid), lunamethod(Scene_BindLua, Component_GetName), lunamethod(Scene_BindLua, Component_GetLayer), @@ -417,6 +504,8 @@ Luna::FunctionType Scene_BindLua::methods[] = { lunamethod(Scene_BindLua, Component_GetWeather), lunamethod(Scene_BindLua, Component_GetSound), lunamethod(Scene_BindLua, Component_GetCollider), + lunamethod(Scene_BindLua, Component_GetExpression), + lunamethod(Scene_BindLua, Component_GetHumanoid), lunamethod(Scene_BindLua, Component_GetNameArray), lunamethod(Scene_BindLua, Component_GetLayerArray), @@ -438,6 +527,8 @@ Luna::FunctionType Scene_BindLua::methods[] = { lunamethod(Scene_BindLua, Component_GetWeatherArray), lunamethod(Scene_BindLua, Component_GetSoundArray), lunamethod(Scene_BindLua, Component_GetColliderArray), + lunamethod(Scene_BindLua, Component_GetExpressionArray), + lunamethod(Scene_BindLua, Component_GetHumanoidArray), lunamethod(Scene_BindLua, Entity_GetNameArray), lunamethod(Scene_BindLua, Entity_GetLayerArray), @@ -459,6 +550,8 @@ Luna::FunctionType Scene_BindLua::methods[] = { lunamethod(Scene_BindLua, Entity_GetWeatherArray), lunamethod(Scene_BindLua, Entity_GetSoundArray), lunamethod(Scene_BindLua, Entity_GetColliderArray), + lunamethod(Scene_BindLua, Entity_GetExpressionArray), + lunamethod(Scene_BindLua, Entity_GetHumanoidArray), lunamethod(Scene_BindLua, Component_RemoveName), lunamethod(Scene_BindLua, Component_RemoveLayer), @@ -480,6 +573,8 @@ Luna::FunctionType Scene_BindLua::methods[] = { lunamethod(Scene_BindLua, Component_RemoveWeather), lunamethod(Scene_BindLua, Component_RemoveSound), lunamethod(Scene_BindLua, Component_RemoveCollider), + lunamethod(Scene_BindLua, Component_RemoveExpression), + lunamethod(Scene_BindLua, Component_RemoveHumanoid), lunamethod(Scene_BindLua, Component_Attach), lunamethod(Scene_BindLua, Component_Detach), @@ -938,6 +1033,40 @@ int Scene_BindLua::Component_CreateCollider(lua_State* L) } return 0; } +int Scene_BindLua::Component_CreateExpression(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + + ExpressionComponent& component = scene->expressions.Create(entity); + Luna::push(L, new ExpressionComponent_BindLua(&component)); + return 1; + } + else + { + wi::lua::SError(L, "Scene::Component_CreateExpression(Entity entity) not enough arguments!"); + } + return 0; +} +int Scene_BindLua::Component_CreateHumanoid(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + + HumanoidComponent& component = scene->humanoids.Create(entity); + Luna::push(L, new HumanoidComponent_BindLua(&component)); + return 1; + } + else + { + wi::lua::SError(L, "Scene::Component_CreateHumanoid(Entity entity) not enough arguments!"); + } + return 0; +} int Scene_BindLua::Component_GetName(lua_State* L) { @@ -1379,6 +1508,50 @@ int Scene_BindLua::Component_GetCollider(lua_State* L) } return 0; } +int Scene_BindLua::Component_GetExpression(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + + ExpressionComponent* component = scene->expressions.GetComponent(entity); + if (component == nullptr) + { + return 0; + } + + Luna::push(L, new ExpressionComponent_BindLua(component)); + return 1; + } + else + { + wi::lua::SError(L, "Scene::Component_GetExpression(Entity entity) not enough arguments!"); + } + return 0; +} +int Scene_BindLua::Component_GetHumanoid(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + + HumanoidComponent* component = scene->humanoids.GetComponent(entity); + if (component == nullptr) + { + return 0; + } + + Luna::push(L, new HumanoidComponent_BindLua(component)); + return 1; + } + else + { + wi::lua::SError(L, "Scene::Component_GetHumanoid(Entity entity) not enough arguments!"); + } + return 0; +} int Scene_BindLua::Component_GetNameArray(lua_State* L) { @@ -1569,9 +1742,9 @@ int Scene_BindLua::Component_GetForceFieldArray(lua_State* L) } int Scene_BindLua::Component_GetWeatherArray(lua_State* L) { - lua_createtable(L, (int)scene->forces.GetCount(), 0); + lua_createtable(L, (int)scene->weathers.GetCount(), 0); int newTable = lua_gettop(L); - for (size_t i = 0; i < scene->forces.GetCount(); ++i) + for (size_t i = 0; i < scene->weathers.GetCount(); ++i) { Luna::push(L, new WeatherComponent_BindLua(&scene->weathers[i])); lua_rawseti(L, newTable, lua_Integer(i + 1)); @@ -1580,9 +1753,9 @@ int Scene_BindLua::Component_GetWeatherArray(lua_State* L) } int Scene_BindLua::Component_GetSoundArray(lua_State* L) { - lua_createtable(L, (int)scene->forces.GetCount(), 0); + lua_createtable(L, (int)scene->sounds.GetCount(), 0); int newTable = lua_gettop(L); - for (size_t i = 0; i < scene->forces.GetCount(); ++i) + for (size_t i = 0; i < scene->sounds.GetCount(); ++i) { Luna::push(L, new SoundComponent_BindLua(&scene->sounds[i])); lua_rawseti(L, newTable, lua_Integer(i + 1)); @@ -1591,15 +1764,37 @@ int Scene_BindLua::Component_GetSoundArray(lua_State* L) } int Scene_BindLua::Component_GetColliderArray(lua_State* L) { - lua_createtable(L, (int)scene->forces.GetCount(), 0); + lua_createtable(L, (int)scene->colliders.GetCount(), 0); int newTable = lua_gettop(L); - for (size_t i = 0; i < scene->forces.GetCount(); ++i) + for (size_t i = 0; i < scene->colliders.GetCount(); ++i) { Luna::push(L, new ColliderComponent_BindLua(&scene->colliders[i])); lua_rawseti(L, newTable, lua_Integer(i + 1)); } return 1; } +int Scene_BindLua::Component_GetExpressionArray(lua_State* L) +{ + lua_createtable(L, (int)scene->expressions.GetCount(), 0); + int newTable = lua_gettop(L); + for (size_t i = 0; i < scene->expressions.GetCount(); ++i) + { + Luna::push(L, new ExpressionComponent_BindLua(&scene->expressions[i])); + lua_rawseti(L, newTable, lua_Integer(i + 1)); + } + return 1; +} +int Scene_BindLua::Component_GetHumanoidArray(lua_State* L) +{ + lua_createtable(L, (int)scene->humanoids.GetCount(), 0); + int newTable = lua_gettop(L); + for (size_t i = 0; i < scene->humanoids.GetCount(); ++i) + { + Luna::push(L, new HumanoidComponent_BindLua(&scene->humanoids[i])); + lua_rawseti(L, newTable, lua_Integer(i + 1)); + } + return 1; +} int Scene_BindLua::Entity_GetNameArray(lua_State* L) { @@ -1821,6 +2016,28 @@ int Scene_BindLua::Entity_GetColliderArray(lua_State* L) } return 1; } +int Scene_BindLua::Entity_GetExpressionArray(lua_State* L) +{ + lua_createtable(L, (int)scene->expressions.GetCount(), 0); + int newTable = lua_gettop(L); + for (size_t i = 0; i < scene->expressions.GetCount(); ++i) + { + wi::lua::SSetLongLong(L, scene->expressions.GetEntity(i)); + lua_rawseti(L, newTable, lua_Integer(i + 1)); + } + return 1; +} +int Scene_BindLua::Entity_GetHumanoidArray(lua_State* L) +{ + lua_createtable(L, (int)scene->humanoids.GetCount(), 0); + int newTable = lua_gettop(L); + for (size_t i = 0; i < scene->humanoids.GetCount(); ++i) + { + wi::lua::SSetLongLong(L, scene->humanoids.GetEntity(i)); + lua_rawseti(L, newTable, lua_Integer(i + 1)); + } + return 1; +} int Scene_BindLua::Component_RemoveName(lua_State* L) { @@ -2162,6 +2379,40 @@ int Scene_BindLua::Component_RemoveCollider(lua_State* L) } return 0; } +int Scene_BindLua::Component_RemoveExpression(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + if (scene->expressions.Contains(entity)) + { + scene->expressions.Remove(entity); + } + } + else + { + wi::lua::SError(L, "Scene::Component_RemoveExpression(Entity entity) not enough arguments!"); + } + return 0; +} +int Scene_BindLua::Component_RemoveHumanoid(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Entity entity = (Entity)wi::lua::SGetLongLong(L, 1); + if (scene->humanoids.Contains(entity)) + { + scene->humanoids.Remove(entity); + } + } + else + { + wi::lua::SError(L, "Scene::Component_RemoveExpression(Entity entity) not enough arguments!"); + } + return 0; +} int Scene_BindLua::Component_Attach(lua_State* L) { @@ -4857,4 +5108,169 @@ int ColliderComponent_BindLua::GetSphere(lua_State* L) return 1; } + + + + + + +const char ExpressionComponent_BindLua::className[] = "ExpressionComponent"; + +Luna::FunctionType ExpressionComponent_BindLua::methods[] = { + lunamethod(ExpressionComponent_BindLua, FindExpressionID), + lunamethod(ExpressionComponent_BindLua, SetWeight), + lunamethod(ExpressionComponent_BindLua, SetPresetWeight), + { NULL, NULL } +}; +Luna::PropertyType ExpressionComponent_BindLua::properties[] = { + { NULL, NULL } +}; + +int ExpressionComponent_BindLua::FindExpressionID(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + std::string find = wi::lua::SGetString(L, 1); + for (size_t i = 0; i < component->expressions.size(); ++i) + { + if (component->expressions[i].name.compare(find) == 0) + { + wi::lua::SSetInt(L, int(i)); + return 1; + } + } + } + else + { + wi::lua::SError(L, "FindExpressionID(string name) not enough arguments!"); + } + return 0; +} +int ExpressionComponent_BindLua::SetWeight(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 1) + { + int id = wi::lua::SGetInt(L, 1); + float weight = wi::lua::SGetFloat(L, 2); + if (id >= 0 && component->expressions.size() > id) + { + component->expressions[id].weight = weight; + component->expressions[id].SetDirty(true); + } + else + { + wi::lua::SError(L, "SetWeight(int id, float weight) id is out of bounds!"); + } + } + else + { + wi::lua::SError(L, "SetWeight(int id, float weight) not enough arguments!"); + } + return 0; +} +int ExpressionComponent_BindLua::SetPresetWeight(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 1) + { + ExpressionComponent::Preset preset = (ExpressionComponent::Preset)wi::lua::SGetInt(L, 1); + float weight = wi::lua::SGetFloat(L, 2); + int id = component->presets[size_t(preset)]; + if (id >= 0 && component->expressions.size() > id) + { + component->expressions[id].weight = weight; + component->expressions[id].SetDirty(true); + } + else + { + wi::lua::SError(L, "SetPresetWeight(ExpressionPreset preset, float weight) preset doesn't exist!"); + } + } + else + { + wi::lua::SError(L, "SetPresetWeight(ExpressionPreset preset, float weight) not enough arguments!"); + } + return 0; +} + + + + + + + +const char HumanoidComponent_BindLua::className[] = "HumanoidComponent"; + +Luna::FunctionType HumanoidComponent_BindLua::methods[] = { + lunamethod(HumanoidComponent_BindLua, GetBoneEntity), + lunamethod(HumanoidComponent_BindLua, SetLookAtEnabled), + lunamethod(HumanoidComponent_BindLua, SetLookAt), + { NULL, NULL } +}; +Luna::PropertyType HumanoidComponent_BindLua::properties[] = { + { NULL, NULL } +}; + +int HumanoidComponent_BindLua::GetBoneEntity(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + int humanoidBone = wi::lua::SGetInt(L, 1); + if (humanoidBone >= 0 && humanoidBone < arraysize(component->bones)) + { + wi::lua::SSetInt(L, (int)component->bones[humanoidBone]); + } + else + { + wi::lua::SError(L, "GetBoneEntity(HumanoidBone bone) invalid humanoid bone!"); + } + return 1; + } + else + { + wi::lua::SError(L, "GetBoneEntity(HumanoidBone bone) not enough arguments!"); + } + return 0; +} +int HumanoidComponent_BindLua::SetLookAtEnabled(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + bool value = wi::lua::SGetBool(L, 1); + component->SetLookAtEnabled(value); + } + else + { + wi::lua::SError(L, "SetLookAtEnabled(bool value) not enough arguments!"); + } + return 0; +} +int HumanoidComponent_BindLua::SetLookAt(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Vector_BindLua* vec = Luna::lightcheck(L, 1); + if (vec) + { + component->lookAt.x = vec->data.x; + component->lookAt.y = vec->data.y; + component->lookAt.z = vec->data.z; + } + else + { + wi::lua::SError(L, "SetLookAt(Vector value) argument is not a Vector!"); + } + } + else + { + wi::lua::SError(L, "SetLookAt(Vector value) not enough arguments!"); + } + return 0; +} + } diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h index 31a5abd6f..eb517c32a 100644 --- a/WickedEngine/wiScene_BindLua.h +++ b/WickedEngine/wiScene_BindLua.h @@ -63,6 +63,8 @@ namespace wi::lua::scene int Component_CreateWeather(lua_State* L); int Component_CreateSound(lua_State* L); int Component_CreateCollider(lua_State* L); + int Component_CreateExpression(lua_State* L); + int Component_CreateHumanoid(lua_State* L); int Component_GetName(lua_State* L); int Component_GetLayer(lua_State* L); @@ -84,6 +86,8 @@ namespace wi::lua::scene int Component_GetWeather(lua_State* L); int Component_GetSound(lua_State* L); int Component_GetCollider(lua_State* L); + int Component_GetExpression(lua_State* L); + int Component_GetHumanoid(lua_State* L); int Component_GetNameArray(lua_State* L); int Component_GetLayerArray(lua_State* L); @@ -105,6 +109,8 @@ namespace wi::lua::scene int Component_GetWeatherArray(lua_State* L); int Component_GetSoundArray(lua_State* L); int Component_GetColliderArray(lua_State* L); + int Component_GetExpressionArray(lua_State* L); + int Component_GetHumanoidArray(lua_State* L); int Entity_GetNameArray(lua_State* L); int Entity_GetLayerArray(lua_State* L); @@ -126,6 +132,8 @@ namespace wi::lua::scene int Entity_GetWeatherArray(lua_State* L); int Entity_GetSoundArray(lua_State* L); int Entity_GetColliderArray(lua_State* L); + int Entity_GetExpressionArray(lua_State* L); + int Entity_GetHumanoidArray(lua_State* L); int Component_RemoveName(lua_State* L); int Component_RemoveLayer(lua_State* L); @@ -147,6 +155,8 @@ namespace wi::lua::scene int Component_RemoveWeather(lua_State* L); int Component_RemoveSound(lua_State* L); int Component_RemoveCollider(lua_State* L); + int Component_RemoveExpression(lua_State* L); + int Component_RemoveHumanoid(lua_State* L); int Component_Attach(lua_State* L); int Component_Detach(lua_State* L); @@ -1529,5 +1539,51 @@ namespace wi::lua::scene int GetCapsule(lua_State* L); int GetSphere(lua_State* L); }; + + class ExpressionComponent_BindLua + { + private: + std::unique_ptr owning; + public: + wi::scene::ExpressionComponent* component = nullptr; + + static const char className[]; + static Luna::FunctionType methods[]; + static Luna::PropertyType properties[]; + + ExpressionComponent_BindLua(wi::scene::ExpressionComponent* component) :component(component) {} + ExpressionComponent_BindLua(lua_State* L) + { + owning = std::make_unique(); + component = owning.get(); + } + + int FindExpressionID(lua_State* L); + int SetWeight(lua_State* L); + int SetPresetWeight(lua_State* L); + }; + + class HumanoidComponent_BindLua + { + private: + std::unique_ptr owning; + public: + wi::scene::HumanoidComponent* component = nullptr; + + static const char className[]; + static Luna::FunctionType methods[]; + static Luna::PropertyType properties[]; + + HumanoidComponent_BindLua(wi::scene::HumanoidComponent* component) :component(component) {} + HumanoidComponent_BindLua(lua_State* L) + { + owning = std::make_unique(); + component = owning.get(); + } + + int GetBoneEntity(lua_State* L); + int SetLookAtEnabled(lua_State* L); + int SetLookAt(lua_State* L); + }; } diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index d0bb506c4..92310d26c 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -1228,6 +1228,7 @@ namespace wi::scene VOLUMETRIC_CLOUDS = 1 << 3, HEIGHT_FOG = 1 << 4, VOLUMETRIC_CLOUDS_SHADOWS = 1 << 5, + OVERRIDE_FOG_COLOR = 1 << 6, }; uint32_t _flags = EMPTY; @@ -1236,12 +1237,14 @@ namespace wi::scene inline bool IsVolumetricClouds() const { return _flags & VOLUMETRIC_CLOUDS; } inline bool IsHeightFog() const { return _flags & HEIGHT_FOG; } inline bool IsVolumetricCloudsShadows() const { return _flags & VOLUMETRIC_CLOUDS_SHADOWS; } + inline bool IsOverrideFogColor() const { return _flags & OVERRIDE_FOG_COLOR; } inline void SetOceanEnabled(bool value = true) { if (value) { _flags |= OCEAN_ENABLED; } else { _flags &= ~OCEAN_ENABLED; } } inline void SetRealisticSky(bool value = true) { if (value) { _flags |= REALISTIC_SKY; } else { _flags &= ~REALISTIC_SKY; } } inline void SetVolumetricClouds(bool value = true) { if (value) { _flags |= VOLUMETRIC_CLOUDS; } else { _flags &= ~VOLUMETRIC_CLOUDS; } } inline void SetHeightFog(bool value = true) { if (value) { _flags |= HEIGHT_FOG; } else { _flags &= ~HEIGHT_FOG; } } inline void SetVolumetricCloudsShadows(bool value = true) { if (value) { _flags |= VOLUMETRIC_CLOUDS_SHADOWS; } else { _flags &= ~VOLUMETRIC_CLOUDS_SHADOWS; } } + inline void SetOverrideFogColor(bool value = true) { if (value) { _flags |= OVERRIDE_FOG_COLOR; } else { _flags &= ~OVERRIDE_FOG_COLOR; } } XMFLOAT3 sunColor = XMFLOAT3(0, 0, 0); XMFLOAT3 sunDirection = XMFLOAT3(0, 1, 0); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 9280461b7..fafbb969d 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 = 46; + const int revision = 47; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);