diff --git a/Documentation/ScriptingAPI-Documentation.md b/Documentation/ScriptingAPI-Documentation.md index 5eaa3c460..1a4dc5ac8 100644 --- a/Documentation/ScriptingAPI-Documentation.md +++ b/Documentation/ScriptingAPI-Documentation.md @@ -112,7 +112,8 @@ You can use the Renderer with the following functions, all of which are in the g - GetScreenHeight() : float result - GetRenderWidth() : float result - GetRenderHeight(): float result -- GetCamera() : Camera? result +- GetCameras() : string result +- GetCamera(opt String name) : Camera result // If string is provided, it will search a camera by name, otherwise, returns the main camera - LoadModel(string fileName, opt string identifier, opt Matrix transform) : Model? result - LoadWorldInfo(string fileName) - FinishLoading() @@ -326,6 +327,8 @@ It inherits functions from Node. - Scale(Vector vector) - Rotate(Vector vectorRollPitchYaw) - Translate(Vector vector) +- Lerp(Transform a,b, float t) +- CatmullRom(Transform a,b,c,d, float t) - MatrixTransform(Matrix matrix) - GetMatrix() : Matrix result - ClearTransform() @@ -422,8 +425,12 @@ Main camera looking at the scene. It is a Transform. - [constructor]Camera() - SetFarPlane(float val) - SetNearPlane(float val) +- SetFOV(float val) - GetFarPlane() : float result - GetNearPlane() : float result +- GetFOV() : float result +- Lerp(Camera a,b, float t) +- CatmullRom(Camera a,b,c,d, float t) #### Model Collection of Objects, Armatures, Lights, Decals. Also a transform by itself diff --git a/Editor/CameraWindow.cpp b/Editor/CameraWindow.cpp index 762e8261c..70917a31d 100644 --- a/Editor/CameraWindow.cpp +++ b/Editor/CameraWindow.cpp @@ -17,7 +17,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) orbitalCamTarget = new Transform; cameraWindow = new wiWindow(GUI, "Camera Window"); - cameraWindow->SetSize(XMFLOAT2(400, 420)); + cameraWindow->SetSize(XMFLOAT2(600, 420)); GUI->AddWidget(cameraWindow); float x = 200; @@ -85,6 +85,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) proxyButton->SetPos(XMFLOAT2(x, y += inc * 2)); proxyButton->OnClick([&](wiEventArgs args) { Camera* cam = new Camera(*wiRenderer::getCamera()); + cam->name = "ProxyCam"; wiRenderer::Add(cam); @@ -92,6 +93,18 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) }); cameraWindow->AddWidget(proxyButton); + proxyNameField = new wiTextInputField("Proxy Name: "); + proxyNameField->SetSize(XMFLOAT2(140, 30)); + proxyNameField->SetPos(XMFLOAT2(x + 200, y)); + proxyNameField->OnInputAccepted([&](wiEventArgs args) { + if (proxy != nullptr) + { + proxy->name = args.sValue; + } + }); + cameraWindow->AddWidget(proxyNameField); + + followCheckBox = new wiCheckBox("Follow Proxy: "); followCheckBox->SetPos(XMFLOAT2(x, y += inc)); followCheckBox->SetCheck(false); @@ -130,11 +143,13 @@ void CameraWindow::SetProxy(Camera* camera) { followCheckBox->SetEnabled(true); followSlider->SetEnabled(true); + proxyNameField->SetValue(proxy->name); } else { followCheckBox->SetCheck(false); followCheckBox->SetEnabled(false); followSlider->SetEnabled(false); + proxyNameField->SetValue("Proxy Name: "); } } diff --git a/Editor/CameraWindow.h b/Editor/CameraWindow.h index eff8e0e5f..7a206fe97 100644 --- a/Editor/CameraWindow.h +++ b/Editor/CameraWindow.h @@ -6,6 +6,7 @@ class wiWindow; class wiLabel; class wiCheckBox; class wiSlider; +class wiTextInputField; class CameraWindow { @@ -32,6 +33,7 @@ public: wiCheckBox* fpsCheckBox; wiButton* proxyButton; + wiTextInputField* proxyNameField; wiCheckBox* followCheckBox; wiSlider* followSlider; }; diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 90ff04df1..4cab6203c 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -878,7 +878,7 @@ void EditorComponent::Update(float dt) if (cameraWnd->followCheckBox->IsEnabled() && cameraWnd->followCheckBox->GetCheck()) { cam->detach(); - cam->Lerp(cameraWnd->proxy, 1.0f - cameraWnd->followSlider->GetValue()); + cam->Lerp(cam, cameraWnd->proxy, 1.0f - cameraWnd->followSlider->GetValue()); } if (!wiBackLog::isActive() && !GetGUI().HasFocus()) diff --git a/Editor/startup.lua b/Editor/startup.lua index 5f9f88833..85a2655f1 100644 --- a/Editor/startup.lua +++ b/Editor/startup.lua @@ -28,6 +28,10 @@ -- end -- end) +local tt = 0.0 +local play = false +local rot = 0 + main.SetResolutionDisplay(true); runProcess(function() while true do @@ -64,6 +68,28 @@ runProcess(function() end end) end + + if(input.Press(VK_F8)) then + tt = 0.0 + play = true + end + if(play) then + local prox = {} + prox[0] = GetCamera("cam0") + prox[1] = GetCamera("cam1") + prox[2] = GetCamera("cam2") + prox[3] = GetCamera("cam3") + local cam = GetCamera() + + cam.CatmullRom(prox[(rot + 0) % 4], prox[(rot + 1) % 4], prox[(rot + 2) % 4], prox[(rot + 3) % 4], tt) + + tt = tt + 0.4 * 0.016 + if(tt >= 1.0) then + tt = 0.0 + rot = rot + 1 + end + end + update() end diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 545996cda..74ef10aae 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -4148,11 +4148,30 @@ void Camera::UpdateTransform() UpdateProps(); } -void Camera::Lerp(const Camera* target, float t) +void Camera::Lerp(const Camera* a, const Camera* b, float t) { - Transform::Lerp(target, t); + Transform::Lerp(a, b, t); + + fov = wiMath::Lerp(a->fov, b->fov, t); UpdateProps(); + UpdateProjection(); +} +void Camera::CatmullRom(const Camera* a, const Camera* b, const Camera* c, const Camera* d, float t) +{ + Transform::CatmullRom(a, b, c, d, t); + + XMVECTOR FOV = XMVectorCatmullRom( + XMVectorSet(a->fov, 0, 0, 0), + XMVectorSet(b->fov, 0, 0, 0), + XMVectorSet(c->fov, 0, 0, 0), + XMVectorSet(d->fov, 0, 0, 0), + t + ); + fov = XMVectorGetX(FOV); + + UpdateProps(); + UpdateProjection(); } void Camera::Serialize(wiArchive& archive) diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index 8775ead5e..583a63e2c 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -1077,7 +1077,8 @@ struct Camera:public Transform{ XMStoreFloat4x4(&this->InvProjection, InvP); } - void Lerp(const Camera* target, float t); + void Lerp(const Camera* a, const Camera* b, float t); + void CatmullRom(const Camera* a, const Camera* b, const Camera* c, const Camera* d, float t); XMVECTOR GetEye() const { diff --git a/WickedEngine/wiLoader_BindLua.cpp b/WickedEngine/wiLoader_BindLua.cpp index 55d43e733..d5cca21e8 100644 --- a/WickedEngine/wiLoader_BindLua.cpp +++ b/WickedEngine/wiLoader_BindLua.cpp @@ -106,6 +106,8 @@ Luna::FunctionType Transform_BindLua::methods[] = { lunamethod(Transform_BindLua, Scale), lunamethod(Transform_BindLua, Rotate), lunamethod(Transform_BindLua, Translate), + lunamethod(Transform_BindLua, Lerp), + lunamethod(Transform_BindLua, CatmullRom), lunamethod(Transform_BindLua, MatrixTransform), lunamethod(Transform_BindLua, GetMatrix), lunamethod(Transform_BindLua, ClearTransform), @@ -283,6 +285,86 @@ int Transform_BindLua::Translate(lua_State* L) } return 0; } +int Transform_BindLua::Lerp(lua_State* L) +{ + int argc = wiLua::SGetArgCount(L); + if (argc > 2) + { + Transform_BindLua* a = Luna::lightcheck(L, 1); + if (a != nullptr) + { + Transform_BindLua* b = Luna::lightcheck(L, 2); + + if (b != nullptr) + { + float t = wiLua::SGetFloat(L, 3); + this->transform->Lerp(a->transform, b->transform, t); + } + else + { + wiLua::SError(L, "Lerp(Transform a,b, float t) argument (b) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "Lerp(Transform a,b, float t) argument (a) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "Lerp(Transform a,b, float t) not enough arguments!"); + } + return 0; +} +int Transform_BindLua::CatmullRom(lua_State* L) +{ + int argc = wiLua::SGetArgCount(L); + if (argc > 4) + { + Transform_BindLua* a = Luna::lightcheck(L, 1); + if (a != nullptr) + { + Transform_BindLua* b = Luna::lightcheck(L, 2); + + if (b != nullptr) + { + Transform_BindLua* c = Luna::lightcheck(L, 3); + + if (c != nullptr) + { + Transform_BindLua* d = Luna::lightcheck(L, 4); + + if (d != nullptr) + { + float t = wiLua::SGetFloat(L, 5); + this->transform->CatmullRom(a->transform, b->transform, c->transform, d->transform, t); + } + else + { + wiLua::SError(L, "CatmullRom(Transform a,b,c,d, float t) argument (d) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Transform a,b,c,d, float t) argument (c) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Transform a,b,c,d, float t) argument (b) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Transform a,b,c,d, float t) argument (a) is not a Transform!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Transform a,b,c,d, float t) not enough arguments!"); + } + return 0; +} int Transform_BindLua::MatrixTransform(lua_State* L) { int argc = wiLua::SGetArgCount(L); @@ -491,6 +573,8 @@ Luna::FunctionType Object_BindLua::methods[] = { lunamethod(Transform_BindLua, Scale), lunamethod(Transform_BindLua, Rotate), lunamethod(Transform_BindLua, Translate), + lunamethod(Transform_BindLua, Lerp), + lunamethod(Transform_BindLua, CatmullRom), lunamethod(Transform_BindLua, MatrixTransform), lunamethod(Transform_BindLua, GetMatrix), lunamethod(Transform_BindLua, ClearTransform), @@ -732,6 +816,8 @@ Luna::FunctionType Armature_BindLua::methods[] = { lunamethod(Transform_BindLua, Scale), lunamethod(Transform_BindLua, Rotate), lunamethod(Transform_BindLua, Translate), + lunamethod(Transform_BindLua, Lerp), + lunamethod(Transform_BindLua, CatmullRom), lunamethod(Transform_BindLua, MatrixTransform), lunamethod(Transform_BindLua, GetMatrix), lunamethod(Transform_BindLua, ClearTransform), @@ -1100,6 +1186,8 @@ Luna::FunctionType Decal_BindLua::methods[] = { lunamethod(Transform_BindLua, Scale), lunamethod(Transform_BindLua, Rotate), lunamethod(Transform_BindLua, Translate), + lunamethod(Transform_BindLua, Lerp), + lunamethod(Transform_BindLua, CatmullRom), lunamethod(Transform_BindLua, MatrixTransform), lunamethod(Transform_BindLua, GetMatrix), lunamethod(Transform_BindLua, ClearTransform), @@ -1681,8 +1769,12 @@ Luna::FunctionType Camera_BindLua::methods[] = { lunamethod(Camera_BindLua, SetFarPlane), lunamethod(Camera_BindLua, SetNearPlane), + lunamethod(Camera_BindLua, SetFOV), lunamethod(Camera_BindLua, GetFarPlane), lunamethod(Camera_BindLua, GetNearPlane), + lunamethod(Camera_BindLua, GetFOV), + lunamethod(Camera_BindLua, Lerp), + lunamethod(Camera_BindLua, CatmullRom), { NULL, NULL } }; Luna::PropertyType Camera_BindLua::properties[] = { @@ -1732,6 +1824,20 @@ int Camera_BindLua::SetNearPlane(lua_State *L) } return 0; } +int Camera_BindLua::SetFOV(lua_State *L) +{ + int argc = wiLua::SGetArgCount(L); + if (argc > 0) + { + cam->fov = wiLua::SGetFloat(L, 1); + cam->UpdateProjection(); + } + else + { + wiLua::SError(L, "SetFOV(float val) not enough arguments!"); + } + return 0; +} int Camera_BindLua::GetFarPlane(lua_State *L) { wiLua::SSetFloat(L, cam->zFarP); @@ -1742,6 +1848,91 @@ int Camera_BindLua::GetNearPlane(lua_State *L) wiLua::SSetFloat(L, cam->zNearP); return 1; } +int Camera_BindLua::GetFOV(lua_State *L) +{ + wiLua::SSetFloat(L, cam->fov); + return 1; +} +int Camera_BindLua::Lerp(lua_State* L) +{ + int argc = wiLua::SGetArgCount(L); + if (argc > 2) + { + Camera_BindLua* a = Luna::lightcheck(L, 1); + if (a != nullptr) + { + Camera_BindLua* b = Luna::lightcheck(L, 2); + + if (b != nullptr) + { + float t = wiLua::SGetFloat(L, 3); + this->cam->Lerp(a->cam, b->cam, t); + } + else + { + wiLua::SError(L, "Lerp(Camera a,b, float t) argument (b) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "Lerp(Camera a,b, float t) argument (a) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "Lerp(Camera a,b, float t) not enough arguments!"); + } + return 0; +} +int Camera_BindLua::CatmullRom(lua_State* L) +{ + int argc = wiLua::SGetArgCount(L); + if (argc > 4) + { + Camera_BindLua* a = Luna::lightcheck(L, 1); + if (a != nullptr) + { + Camera_BindLua* b = Luna::lightcheck(L, 2); + + if (b != nullptr) + { + Camera_BindLua* c = Luna::lightcheck(L, 3); + + if (c != nullptr) + { + Camera_BindLua* d = Luna::lightcheck(L, 4); + + if (d != nullptr) + { + float t = wiLua::SGetFloat(L, 5); + this->cam->CatmullRom(a->cam, b->cam, c->cam, d->cam, t); + } + else + { + wiLua::SError(L, "CatmullRom(Camera a,b,c,d, float t) argument (d) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Camera a,b,c,d, float t) argument (c) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Camera a,b,c,d, float t) argument (b) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Camera a,b,c,d, float t) argument (a) is not a Camera!"); + } + } + else + { + wiLua::SError(L, "CatmullRom(Camera a,b,c,d, float t) not enough arguments!"); + } + return 0; +} void Camera_BindLua::Bind() { @@ -1773,6 +1964,8 @@ Luna::FunctionType Model_BindLua::methods[] = { lunamethod(Transform_BindLua, Scale), lunamethod(Transform_BindLua, Rotate), lunamethod(Transform_BindLua, Translate), + lunamethod(Transform_BindLua, Lerp), + lunamethod(Transform_BindLua, CatmullRom), lunamethod(Transform_BindLua, MatrixTransform), lunamethod(Transform_BindLua, GetMatrix), lunamethod(Transform_BindLua, ClearTransform), diff --git a/WickedEngine/wiLoader_BindLua.h b/WickedEngine/wiLoader_BindLua.h index bd6ab1278..678655ccc 100644 --- a/WickedEngine/wiLoader_BindLua.h +++ b/WickedEngine/wiLoader_BindLua.h @@ -47,6 +47,8 @@ public: int Scale(lua_State* L); int Rotate(lua_State* L); int Translate(lua_State* L); + int Lerp(lua_State* L); + int CatmullRom(lua_State* L); int MatrixTransform(lua_State* L); int GetMatrix(lua_State* L); int ClearTransform(lua_State* L); @@ -266,6 +268,10 @@ public: int SetFarPlane(lua_State* L); int GetNearPlane(lua_State* L); int SetNearPlane(lua_State* L); + int GetFOV(lua_State* L); + int SetFOV(lua_State* L); + int Lerp(lua_State* L); + int CatmullRom(lua_State* L); static void Bind(); }; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 79485128c..235649513 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -2865,6 +2865,21 @@ Object* wiRenderer::getObjectByName(const std::string& name) return nullptr; } +Camera* wiRenderer::getCameraByName(const std::string& name) +{ + for (Model* model : GetScene().models) + { + for (auto& x : model->cameras) + { + if (!x->name.compare(name)) + { + return x; + } + } + } + + return nullptr; +} Light* wiRenderer::getLightByName(const std::string& name) { for (Model* model : GetScene().models) diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 197688014..c94b89902 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -407,6 +407,7 @@ public: static Material* getMaterialByName(const std::string& get); HitSphere* getSphereByName(const std::string& get); static Object* getObjectByName(const std::string& name); + static Camera* getCameraByName(const std::string& name); static Light* getLightByName(const std::string& name); static void ReloadShaders(const std::string& path = ""); diff --git a/WickedEngine/wiRenderer_BindLua.cpp b/WickedEngine/wiRenderer_BindLua.cpp index 35568c8fc..523a046e7 100644 --- a/WickedEngine/wiRenderer_BindLua.cpp +++ b/WickedEngine/wiRenderer_BindLua.cpp @@ -246,9 +246,39 @@ namespace wiRenderer_BindLua } int GetCamera(lua_State* L) { + int argc = wiLua::SGetArgCount(L); + if (argc > 0) + { + string name = wiLua::SGetString(L, 1); + Camera* camera = wiRenderer::getCameraByName(name); + if (camera != nullptr) + { + Luna::push(L, new Camera_BindLua(camera)); + return 1; + } + else + { + wiLua::SError(L, "GetCamera(opt String name) name was provided but there was no corresponding camera found!"); + return 0; + } + } + Luna::push(L, new Camera_BindLua(wiRenderer::getCamera())); return 1; } + int GetCameras(lua_State* L) + { + stringstream ss(""); + for (auto& m : wiRenderer::GetScene().models) + { + for (auto& x : m->cameras) + { + ss << x->name << endl; + } + } + wiLua::SSetString(L, ss.str()); + return 1; + } int SetResolutionScale(lua_State* L) { @@ -704,6 +734,7 @@ namespace wiRenderer_BindLua wiLua::GetGlobal()->RegisterFunc("GetScreenWidth", GetScreenWidth); wiLua::GetGlobal()->RegisterFunc("GetScreenHeight", GetScreenHeight); wiLua::GetGlobal()->RegisterFunc("GetCamera", GetCamera); + wiLua::GetGlobal()->RegisterFunc("GetCameras", GetCameras); wiLua::GetGlobal()->RegisterFunc("SetResolutionScale", SetResolutionScale); wiLua::GetGlobal()->RegisterFunc("SetGamma", SetGamma); diff --git a/WickedEngine/wiTransform.cpp b/WickedEngine/wiTransform.cpp index a6faaf66e..a61e1dcd1 100644 --- a/WickedEngine/wiTransform.cpp +++ b/WickedEngine/wiTransform.cpp @@ -271,11 +271,41 @@ void Transform::Scale(const XMFLOAT3& value) { transform(XMFLOAT3(0, 0, 0), XMFLOAT4(0, 0, 0, 1), value); } -void Transform::Lerp(const Transform* target, float t) +void Transform::Lerp(const Transform* a, const Transform* b, float t) { - translation_rest = wiMath::Lerp(translation_rest, target->translation, t); - rotation_rest = wiMath::Slerp(rotation_rest, target->rotation, t); - scale_rest = wiMath::Lerp(scale_rest, target->scale, t); + translation_rest = wiMath::Lerp(a->translation, b->translation, t); + rotation_rest = wiMath::Slerp(a->rotation, b->rotation, t); + scale_rest = wiMath::Lerp(a->scale, b->scale, t); + UpdateTransform(); +} +void Transform::CatmullRom(const Transform* a, const Transform* b, const Transform* c, const Transform* d, float t) +{ + XMVECTOR T = XMVectorCatmullRom( + XMLoadFloat3(&a->translation), + XMLoadFloat3(&b->translation), + XMLoadFloat3(&c->translation), + XMLoadFloat3(&d->translation), + t + ); + XMVECTOR R = XMVectorCatmullRom( // not the best choice for quaternions, but it will do for now... + XMLoadFloat4(&a->rotation), + XMLoadFloat4(&b->rotation), + XMLoadFloat4(&c->rotation), + XMLoadFloat4(&d->rotation), + t + ); + XMVECTOR S = XMVectorCatmullRom( + XMLoadFloat3(&a->scale), + XMLoadFloat3(&b->scale), + XMLoadFloat3(&c->scale), + XMLoadFloat3(&d->scale), + t + ); + + XMStoreFloat3(&translation_rest, T); + XMStoreFloat4(&rotation_rest, R); + XMStoreFloat3(&scale_rest, S); + UpdateTransform(); } diff --git a/WickedEngine/wiTransform.h b/WickedEngine/wiTransform.h index bc418e739..585d1772e 100644 --- a/WickedEngine/wiTransform.h +++ b/WickedEngine/wiTransform.h @@ -70,7 +70,8 @@ struct Transform : public Node void RotateRollPitchYaw(const XMFLOAT3& value); void Rotate(const XMFLOAT4& quaternion); void Scale(const XMFLOAT3& value); - void Lerp(const Transform* target, float t); + void Lerp(const Transform* a, const Transform* b, float t); + void CatmullRom(const Transform* a, const Transform* b, const Transform* c, const Transform* d, float t); // Update this transform and children recursively virtual void UpdateTransform(); // Get the root of the tree diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 407dee572..637287deb 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 17; // minor bug fixes, alterations, refactors, updates - const int revision = 26; + const int revision = 27; long GetVersion()