2023.3
This commit is contained in:
parent
134983b861
commit
b8941ef04e
187 changed files with 13593 additions and 8418 deletions
|
@ -147,7 +147,7 @@ void HelloTexturedCubeGame::BaseGame_DrawView(CGI::RcViewDesc viewDesc)
|
|||
renderer.GetFramebufferHandle_AutoWithDepth(renderer->GetSwapChainBufferIndex()),
|
||||
{ Vector4(0), Vector4(1) });
|
||||
|
||||
Scene::RCamera camera = GetDefaultCamera();
|
||||
World::RCamera camera = GetDefaultCamera();
|
||||
camera.SetAspectRatio(renderer.GetCurrentViewAspectRatio());
|
||||
camera.Update();
|
||||
Transform3 matW = Transform3::rotationZYX(_rotation);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
@ -12,6 +12,7 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
|
@ -72,7 +73,7 @@ struct VERTEX_CONSTANT_BUFFER_DX11
|
|||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
@ -97,14 +98,14 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
|||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader, NULL, 0);
|
||||
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader, NULL, 0);
|
||||
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(NULL, NULL, 0);
|
||||
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
|
||||
// Setup blend state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
|
@ -126,7 +127,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
|
@ -135,12 +136,12 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0)
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
|
@ -148,7 +149,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0)
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
|
@ -326,13 +327,13 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D* pTexture = NULL;
|
||||
ID3D11Texture2D* pTexture = nullptr;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = pixels;
|
||||
subResource.SysMemPitch = desc.Width * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
IM_ASSERT(pTexture != NULL);
|
||||
IM_ASSERT(pTexture != nullptr);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
|
@ -410,9 +411,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||
}";
|
||||
|
||||
ID3DBlob* vertexShaderBlob;
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL)))
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK)
|
||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false;
|
||||
|
@ -440,7 +441,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer);
|
||||
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,9 +464,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||
}";
|
||||
|
||||
ID3DBlob* pixelShaderBlob;
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL)))
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK)
|
||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||
{
|
||||
pixelShaderBlob->Release();
|
||||
return false;
|
||||
|
@ -525,23 +526,23 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
|||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; }
|
||||
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; }
|
||||
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; }
|
||||
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; }
|
||||
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; }
|
||||
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; }
|
||||
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; }
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||
|
@ -550,9 +551,9 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
||||
IDXGIFactory* pFactory = NULL;
|
||||
IDXGIDevice* pDXGIDevice = nullptr;
|
||||
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||
IDXGIFactory* pFactory = nullptr;
|
||||
|
||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||
|
@ -573,22 +574,22 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
|
@ -20,6 +20,7 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
|
||||
|
@ -49,14 +50,7 @@
|
|||
#endif
|
||||
|
||||
// DirectX data
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
{
|
||||
ID3D12Resource* IndexBuffer;
|
||||
ID3D12Resource* VertexBuffer;
|
||||
int IndexBufferSize;
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
struct ImGui_ImplDX12_RenderBuffers;
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ID3D12Device* pd3dDevice;
|
||||
|
@ -66,26 +60,36 @@ struct ImGui_ImplDX12_Data
|
|||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
|
||||
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||
UINT numFramesInFlight;
|
||||
UINT frameIndex;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER_DX12
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Buffers used during the rendering of a frame
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
{
|
||||
ID3D12Resource* IndexBuffer;
|
||||
ID3D12Resource* VertexBuffer;
|
||||
int IndexBufferSize;
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER_DX12
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
|
@ -149,7 +153,7 @@ static inline void SafeRelease(T*& res)
|
|||
{
|
||||
if (res)
|
||||
res->Release();
|
||||
res = NULL;
|
||||
res = nullptr;
|
||||
}
|
||||
|
||||
// Render function
|
||||
|
@ -166,7 +170,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
SafeRelease(fr->VertexBuffer);
|
||||
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
|
@ -186,10 +190,10 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
|
||||
return;
|
||||
}
|
||||
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
if (fr->IndexBuffer == nullptr || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
SafeRelease(fr->IndexBuffer);
|
||||
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
|
@ -209,7 +213,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
desc.SampleDesc.Count = 1;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
|
||||
if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -248,7 +252,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
|
@ -310,9 +314,9 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
ID3D12Resource* pTexture = NULL;
|
||||
ID3D12Resource* pTexture = nullptr;
|
||||
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, NULL, IID_PPV_ARGS(&pTexture));
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
||||
|
||||
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT uploadSize = height * uploadPitch;
|
||||
|
@ -332,12 +336,12 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
||||
ID3D12Resource* uploadBuffer = NULL;
|
||||
ID3D12Resource* uploadBuffer = nullptr;
|
||||
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&uploadBuffer));
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
void* mapped = NULL;
|
||||
void* mapped = nullptr;
|
||||
D3D12_RANGE range = { 0, uploadSize };
|
||||
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
@ -367,31 +371,31 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
|
||||
ID3D12Fence* fence = NULL;
|
||||
ID3D12Fence* fence = nullptr;
|
||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
HANDLE event = CreateEvent(0, 0, 0, 0);
|
||||
IM_ASSERT(event != NULL);
|
||||
IM_ASSERT(event != nullptr);
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = NULL;
|
||||
ID3D12CommandQueue* cmdQueue = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandAllocator* cmdAlloc = NULL;
|
||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12GraphicsCommandList* cmdList = NULL;
|
||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList));
|
||||
ID3D12GraphicsCommandList* cmdList = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL);
|
||||
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
|
||||
cmdList->ResourceBarrier(1, &barrier);
|
||||
|
||||
hr = cmdList->Close();
|
||||
|
@ -496,7 +500,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
// Load d3d12.dll and D3D12SerializeRootSignature() function address dynamically to facilitate using with D3D12On7.
|
||||
// See if any version of d3d12.dll is already loaded in the process. If so, give preference to that.
|
||||
static HINSTANCE d3d12_dll = ::GetModuleHandleA("d3d12.dll");
|
||||
if (d3d12_dll == NULL)
|
||||
if (d3d12_dll == nullptr)
|
||||
{
|
||||
// Attempt to load d3d12.dll from local directories. This will only succeed if
|
||||
// (1) the current OS is Windows 7, and
|
||||
|
@ -504,23 +508,23 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
// See https://github.com/ocornut/imgui/pull/3696 for details.
|
||||
const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample
|
||||
for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++)
|
||||
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != NULL)
|
||||
if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != nullptr)
|
||||
break;
|
||||
|
||||
// If failed, we are on Windows >= 10.
|
||||
if (d3d12_dll == NULL)
|
||||
if (d3d12_dll == nullptr)
|
||||
d3d12_dll = ::LoadLibraryA("d3d12.dll");
|
||||
|
||||
if (d3d12_dll == NULL)
|
||||
if (d3d12_dll == nullptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
|
||||
if (D3D12SerializeRootSignatureFn == NULL)
|
||||
if (D3D12SerializeRootSignatureFn == nullptr)
|
||||
return false;
|
||||
|
||||
ID3DBlob* blob = NULL;
|
||||
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK)
|
||||
ID3DBlob* blob = nullptr;
|
||||
if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, nullptr) != S_OK)
|
||||
return false;
|
||||
|
||||
bd->pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&bd->pRootSignature));
|
||||
|
@ -529,7 +533,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
// If you would like to use this DX12 sample code but remove this dependency you can:
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and assign them to psoDesc.VS/PS [preferred solution]
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
|
||||
|
@ -577,8 +581,8 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
return output;\
|
||||
}";
|
||||
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vertexShaderBlob, NULL)))
|
||||
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() };
|
||||
|
||||
// Create the input layout
|
||||
|
@ -609,10 +613,10 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||
return out_col; \
|
||||
}";
|
||||
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &pixelShaderBlob, NULL)))
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
}
|
||||
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
|
||||
}
|
||||
|
@ -675,12 +679,12 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
|||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(NULL); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
|
@ -694,7 +698,7 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
||||
|
@ -708,15 +712,15 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
IM_UNUSED(cbv_srv_heap); // Unused in master branch (will be used by multi-viewports)
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
for (int i = 0; i < num_frames_in_flight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = NULL;
|
||||
fr->VertexBuffer = NULL;
|
||||
fr->IndexBuffer = nullptr;
|
||||
fr->VertexBuffer = nullptr;
|
||||
fr->IndexBufferSize = 10000;
|
||||
fr->VertexBufferSize = 5000;
|
||||
}
|
||||
|
@ -727,20 +731,21 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||
void ImGui_ImplDX12_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Clean up windows and device objects
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX12_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX12_Init()?");
|
||||
|
||||
if (!bd->pPipelineState)
|
||||
ImGui_ImplDX12_CreateDeviceObjects();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_dx12.cpp file for details.
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
|
@ -30,6 +30,10 @@
|
|||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-10-04: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738).
|
||||
// 2022-01-20: Vulkan: Added support for ImTextureID as VkDescriptorSet. User need to call ImGui_ImplVulkan_AddTexture(). Building for 32-bit targets requires '#define ImTextureID ImU64'. (#914).
|
||||
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.
|
||||
|
@ -114,7 +118,7 @@ struct ImGui_ImplVulkan_Data
|
|||
VkDeviceMemory UploadBufferMemory;
|
||||
VkBuffer UploadBuffer;
|
||||
|
||||
// Render buffers
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
|
@ -190,6 +194,7 @@ static bool g_FunctionsLoaded = true;
|
|||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetBufferMemoryRequirements) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetImageMemoryRequirements) \
|
||||
|
@ -326,7 +331,7 @@ static uint32_t __glsl_shader_frag_spv[] =
|
|||
// FIXME: multi-context support is not tested and probably dysfunctional in this backend.
|
||||
static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
|
||||
|
@ -445,7 +450,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
|
||||
// Allocate array to store enough vertex/index buffers
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == NULL)
|
||||
if (wrb->FrameRenderBuffers == nullptr)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
wrb->Count = v->ImageCount;
|
||||
|
@ -467,8 +472,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = NULL;
|
||||
ImDrawIdx* idx_dst = NULL;
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst));
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst));
|
||||
|
@ -511,7 +516,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
|
@ -550,7 +555,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet);
|
||||
desc_set[0] = bd->FontDescriptorSet;
|
||||
}
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, NULL);
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, nullptr);
|
||||
|
||||
// Draw
|
||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
|
@ -563,7 +568,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||
// Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called.
|
||||
// Our last values will leak into user/application rendering IF:
|
||||
// - Your app uses a pipeline with VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR dynamic state
|
||||
// - And you forgot to call vkCmdSetViewport() and vkCmdSetScissor() yourself to explicitely set that state.
|
||||
// - And you forgot to call vkCmdSetViewport() and vkCmdSetScissor() yourself to explicitly set that state.
|
||||
// If you use VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR you are responsible for setting the values before rendering.
|
||||
// In theory we should aim to backup/restore those values but I am not sure this is possible.
|
||||
// We perform a call to vkCmdSetScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644)
|
||||
|
@ -655,7 +660,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
|||
|
||||
// Upload to Buffer:
|
||||
{
|
||||
char* map = NULL;
|
||||
char* map = nullptr;
|
||||
err = vkMapMemory(v->Device, bd->UploadBufferMemory, 0, upload_size, 0, (void**)(&map));
|
||||
check_vk_result(err);
|
||||
memcpy(map, pixels, upload_size);
|
||||
|
@ -681,7 +686,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
|||
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_barrier[0].subresourceRange.levelCount = 1;
|
||||
copy_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier);
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -703,7 +708,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
|||
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
use_barrier[0].subresourceRange.levelCount = 1;
|
||||
use_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier);
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
|
@ -736,72 +741,6 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca
|
|||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreateFontSampler(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (bd->FontSampler)
|
||||
return;
|
||||
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
VkSamplerCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
info.magFilter = VK_FILTER_LINEAR;
|
||||
info.minFilter = VK_FILTER_LINEAR;
|
||||
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
info.minLod = -1000;
|
||||
info.maxLod = 1000;
|
||||
info.maxAnisotropy = 1.0f;
|
||||
VkResult err = vkCreateSampler(device, &info, allocator, &bd->FontSampler);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreateDescriptorSetLayout(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (bd->DescriptorSetLayout)
|
||||
return;
|
||||
|
||||
ImGui_ImplVulkan_CreateFontSampler(device, allocator);
|
||||
VkSampler sampler[1] = { bd->FontSampler };
|
||||
VkDescriptorSetLayoutBinding binding[1] = {};
|
||||
binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
binding[0].descriptorCount = 1;
|
||||
binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
binding[0].pImmutableSamplers = sampler;
|
||||
VkDescriptorSetLayoutCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
info.bindingCount = 1;
|
||||
info.pBindings = binding;
|
||||
VkResult err = vkCreateDescriptorSetLayout(device, &info, allocator, &bd->DescriptorSetLayout);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreatePipelineLayout(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (bd->PipelineLayout)
|
||||
return;
|
||||
|
||||
// Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix
|
||||
ImGui_ImplVulkan_CreateDescriptorSetLayout(device, allocator);
|
||||
VkPushConstantRange push_constants[1] = {};
|
||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
push_constants[0].offset = sizeof(float) * 0;
|
||||
push_constants[0].size = sizeof(float) * 4;
|
||||
VkDescriptorSetLayout set_layout[1] = { bd->DescriptorSetLayout };
|
||||
VkPipelineLayoutCreateInfo layout_info = {};
|
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = set_layout;
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = push_constants;
|
||||
VkResult err = vkCreatePipelineLayout(device, &layout_info, allocator, &bd->PipelineLayout);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
|
@ -886,8 +825,6 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
|
|||
dynamic_state.dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states);
|
||||
dynamic_state.pDynamicStates = dynamic_states;
|
||||
|
||||
ImGui_ImplVulkan_CreatePipelineLayout(device, allocator);
|
||||
|
||||
VkGraphicsPipelineCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.flags = bd->PipelineCreateFlags;
|
||||
|
@ -916,6 +853,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||
|
||||
if (!bd->FontSampler)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
VkSamplerCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
info.magFilter = VK_FILTER_LINEAR;
|
||||
|
@ -933,12 +871,10 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||
|
||||
if (!bd->DescriptorSetLayout)
|
||||
{
|
||||
VkSampler sampler[1] = {bd->FontSampler};
|
||||
VkDescriptorSetLayoutBinding binding[1] = {};
|
||||
binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
binding[0].descriptorCount = 1;
|
||||
binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
binding[0].pImmutableSamplers = sampler;
|
||||
VkDescriptorSetLayoutCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
info.bindingCount = 1;
|
||||
|
@ -1013,7 +949,7 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
|
|||
#ifdef VK_NO_PROTOTYPES
|
||||
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
||||
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
|
||||
if (func == NULL) \
|
||||
if (func == nullptr) \
|
||||
return false;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
|
||||
#undef IMGUI_VULKAN_FUNC_LOAD
|
||||
|
@ -1030,7 +966,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
|||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplVulkan_Data* bd = IM_NEW(ImGui_ImplVulkan_Data)();
|
||||
|
@ -1059,19 +995,19 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
|||
void ImGui_ImplVulkan_Shutdown()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_NewFrame()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplVulkan_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplVulkan_Init()?");
|
||||
IM_UNUSED(bd);
|
||||
}
|
||||
|
||||
|
@ -1120,11 +1056,18 @@ VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image
|
|||
write_desc[0].descriptorCount = 1;
|
||||
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
write_desc[0].pImageInfo = desc_image;
|
||||
vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL);
|
||||
vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, nullptr);
|
||||
}
|
||||
return descriptor_set;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
|
||||
|
@ -1144,7 +1087,7 @@ VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image
|
|||
VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
|
||||
{
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
IM_ASSERT(request_formats != NULL);
|
||||
IM_ASSERT(request_formats != nullptr);
|
||||
IM_ASSERT(request_formats_count > 0);
|
||||
|
||||
// Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
|
||||
|
@ -1152,7 +1095,7 @@ VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physic
|
|||
// Additionally several new color spaces were introduced with Vulkan Spec v1.0.40,
|
||||
// hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used.
|
||||
uint32_t avail_count;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, NULL);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, nullptr);
|
||||
ImVector<VkSurfaceFormatKHR> avail_format;
|
||||
avail_format.resize((int)avail_count);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, avail_format.Data);
|
||||
|
@ -1189,12 +1132,12 @@ VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physic
|
|||
VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count)
|
||||
{
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
IM_ASSERT(request_modes != NULL);
|
||||
IM_ASSERT(request_modes != nullptr);
|
||||
IM_ASSERT(request_modes_count > 0);
|
||||
|
||||
// Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
|
||||
uint32_t avail_count = 0;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, NULL);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, nullptr);
|
||||
ImVector<VkPresentModeKHR> avail_modes;
|
||||
avail_modes.resize((int)avail_count);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, avail_modes.Data);
|
||||
|
@ -1286,8 +1229,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
}
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = NULL;
|
||||
wd->FrameSemaphores = NULL;
|
||||
wd->Frames = nullptr;
|
||||
wd->FrameSemaphores = nullptr;
|
||||
wd->ImageCount = 0;
|
||||
if (wd->RenderPass)
|
||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||
|
@ -1334,7 +1277,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
}
|
||||
err = vkCreateSwapchainKHR(device, &info, allocator, &wd->Swapchain);
|
||||
check_vk_result(err);
|
||||
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, NULL);
|
||||
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, nullptr);
|
||||
check_vk_result(err);
|
||||
VkImage backbuffers[16] = {};
|
||||
IM_ASSERT(wd->ImageCount >= min_image_count);
|
||||
|
@ -1342,7 +1285,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
|
||||
check_vk_result(err);
|
||||
|
||||
IM_ASSERT(wd->Frames == NULL);
|
||||
IM_ASSERT(wd->Frames == nullptr);
|
||||
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
|
||||
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->ImageCount);
|
||||
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
|
||||
|
@ -1457,8 +1400,8 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
|
|||
}
|
||||
IM_FREE(wd->Frames);
|
||||
IM_FREE(wd->FrameSemaphores);
|
||||
wd->Frames = NULL;
|
||||
wd->FrameSemaphores = NULL;
|
||||
wd->Frames = nullptr;
|
||||
wd->FrameSemaphores = nullptr;
|
||||
vkDestroyPipeline(device, wd->Pipeline, allocator);
|
||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
||||
|
@ -1502,7 +1445,7 @@ void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVul
|
|||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = NULL;
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
|
@ -72,12 +72,14 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
|
|||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = NULL);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
|
@ -86,8 +88,8 @@ IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*l
|
|||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the upcoming multi-viewport feature will need them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
|
|
|
@ -57,15 +57,20 @@ public:
|
|||
CMP_BOOL TextureTool::FeedbackProc(CMP_FLOAT progress, CMP_DWORD_PTR pUser1, CMP_DWORD_PTR pUser2)
|
||||
{
|
||||
const int edge = static_cast<int>(progress * 0.5f + 0.5f);
|
||||
std::wcout << _T("\rCompressing [");
|
||||
wchar_t buffer[80];
|
||||
wcscpy(buffer, _T("\rCompressing ["));
|
||||
size_t offset = wcslen(buffer);
|
||||
VERUS_FOR(i, 50)
|
||||
{
|
||||
if (i < edge)
|
||||
std::wcout << _T("=");
|
||||
buffer[i + offset] = _T('=');
|
||||
else
|
||||
std::wcout << _T(" ");
|
||||
buffer[i + offset] = _T(' ');
|
||||
}
|
||||
std::wcout << _T("] ") << std::setw(3) << static_cast<int>(progress + 0.5f) << _T("%") << std::flush;
|
||||
buffer[offset + 50] = 0;
|
||||
wsprintf(buffer + wcslen(buffer), _T("] %3d%%"), static_cast<int>(progress + 0.5f));
|
||||
wprintf(buffer);
|
||||
fflush(stdout);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>C:\Compressonator_4.2.5185\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\libogg-1.3.5\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.22.0-bin\include;C:\Home\Middleware\OpenXR-SDK-release-1.0.25\include;C:\Home\Middleware\SDL2-2.0.22\include;C:\VulkanSDK\1.3.216.0\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Compressonator_4.2.5185\lib\VS2017\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.5\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.22.0-bin\libs\Win64;C:\Home\Middleware\OpenXR-SDK-release-1.0.25\lib;C:\Home\Middleware\SDL2-2.0.22\lib\x64;C:\VulkanSDK\1.3.216.0\Lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>C:\Compressonator_4.3.206\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\libogg-1.3.5\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.22.0-bin\include;C:\Home\Middleware\OpenXR-SDK-release-1.0.25\include;C:\Home\Middleware\SDL2-2.0.22\include;C:\VulkanSDK\1.3.239.0\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Compressonator_4.3.206\lib\VS2019\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.5\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.22.0-bin\libs\Win64;C:\Home\Middleware\OpenXR-SDK-release-1.0.25\lib;C:\Home\Middleware\SDL2-2.0.22\lib\x64;C:\VulkanSDK\1.3.239.0\Lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
|
|
|
@ -222,8 +222,8 @@
|
|||
<ClInclude Include="src\Global\SyntaxHighlight.h" />
|
||||
<ClInclude Include="src\Global\Typedef.h" />
|
||||
<ClInclude Include="src\IO\StreamPtr.h" />
|
||||
<ClInclude Include="src\IO\Vwx.h" />
|
||||
<ClInclude Include="src\IO\Xml.h" />
|
||||
<ClInclude Include="src\IO\Xxx.h" />
|
||||
<ClInclude Include="src\Math\Bounds.h" />
|
||||
<ClInclude Include="src\Math\Frustum.h" />
|
||||
<ClInclude Include="src\Math\Math.h" />
|
||||
|
@ -250,40 +250,11 @@
|
|||
<ClInclude Include="src\Physics\Spring.h" />
|
||||
<ClInclude Include="src\Physics\UserPtr.h" />
|
||||
<ClInclude Include="src\Physics\Vehicle.h" />
|
||||
<ClInclude Include="src\Scene\Atmosphere.h" />
|
||||
<ClInclude Include="src\Scene\BaseMesh.h" />
|
||||
<ClInclude Include="src\Scene\Camera.h" />
|
||||
<ClInclude Include="src\Scene\CameraOrbit.h" />
|
||||
<ClInclude Include="src\Scene\CubeMapBaker.h" />
|
||||
<ClInclude Include="src\Scene\EditorTerrain.h" />
|
||||
<ClInclude Include="src\Scene\Forest.h" />
|
||||
<ClInclude Include="src\Scene\Grass.h" />
|
||||
<ClInclude Include="src\Scene\Helpers.h" />
|
||||
<ClInclude Include="src\Scene\LightMapBaker.h" />
|
||||
<ClInclude Include="src\Scene\MaterialManager.h" />
|
||||
<ClInclude Include="src\Scene\Mesh.h" />
|
||||
<ClInclude Include="src\Scene\Scatter.h" />
|
||||
<ClInclude Include="src\Scene\Scene.h" />
|
||||
<ClInclude Include="src\Scene\SceneManager.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Block.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Emitter.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Light.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Model.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Prefab.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneNode.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneNodes.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneParticles.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Site.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Trigger.h" />
|
||||
<ClInclude Include="src\Scene\SceneNodes\Types.h" />
|
||||
<ClInclude Include="src\Scene\ShadowMapBaker.h" />
|
||||
<ClInclude Include="src\Scene\Terrain.h" />
|
||||
<ClInclude Include="src\Scene\Water.h" />
|
||||
<ClInclude Include="src\Security\CipherRC4.h" />
|
||||
<ClInclude Include="src\Security\Security.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imconfig.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_impl_sdl.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_impl_sdl2.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_internal.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imstb_rectpack.h" />
|
||||
<ClInclude Include="src\ThirdParty\imgui\imstb_textedit.h" />
|
||||
|
@ -316,6 +287,41 @@
|
|||
<ClInclude Include="src\ThirdParty\zlib-1.2.12\zlib.h" />
|
||||
<ClInclude Include="src\ThirdParty\zlib-1.2.12\zutil.h" />
|
||||
<ClInclude Include="src\verus.h" />
|
||||
<ClInclude Include="src\World\Atmosphere.h" />
|
||||
<ClInclude Include="src\World\CubeMapBaker.h" />
|
||||
<ClInclude Include="src\World\EditorOverlays.h" />
|
||||
<ClInclude Include="src\World\EditorTerrain.h" />
|
||||
<ClInclude Include="src\World\Forest.h" />
|
||||
<ClInclude Include="src\World\Grass.h" />
|
||||
<ClInclude Include="src\World\LightMapBaker.h" />
|
||||
<ClInclude Include="src\World\BaseMesh.h" />
|
||||
<ClInclude Include="src\World\Camera.h" />
|
||||
<ClInclude Include="src\World\Scatter.h" />
|
||||
<ClInclude Include="src\World\ShadowMapBaker.h" />
|
||||
<ClInclude Include="src\World\Terrain.h" />
|
||||
<ClInclude Include="src\World\Water.h" />
|
||||
<ClInclude Include="src\World\World.h" />
|
||||
<ClInclude Include="src\World\WorldManager.h" />
|
||||
<ClInclude Include="src\World\MaterialManager.h" />
|
||||
<ClInclude Include="src\World\Mesh.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\BlockNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\ControlPointNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\EmitterNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\InstanceNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\LightNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\ModelNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\ParticlesNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\PathNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\PhysicsNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\PrefabNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\ShakerNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\SoundNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\TerrainNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\Types.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\BaseNode.h" />
|
||||
<ClInclude Include="src\World\WorldNodes\WorldNodes.h" />
|
||||
<ClInclude Include="src\World\OrbitingCamera.h" />
|
||||
<ClInclude Include="src\World\WorldUtils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\AI\AI.cpp" />
|
||||
|
@ -422,8 +428,8 @@
|
|||
<ClCompile Include="src\IO\IO.cpp" />
|
||||
<ClCompile Include="src\IO\Json.cpp" />
|
||||
<ClCompile Include="src\IO\Dictionary.cpp" />
|
||||
<ClCompile Include="src\IO\Vwx.cpp" />
|
||||
<ClCompile Include="src\IO\Xml.cpp" />
|
||||
<ClCompile Include="src\IO\Xxx.cpp" />
|
||||
<ClCompile Include="src\Math\Bounds.cpp" />
|
||||
<ClCompile Include="src\Math\Frustum.cpp" />
|
||||
<ClCompile Include="src\Math\Math.cpp" />
|
||||
|
@ -451,34 +457,6 @@
|
|||
<ClCompile Include="src\Physics\Physics.cpp" />
|
||||
<ClCompile Include="src\Physics\Spring.cpp" />
|
||||
<ClCompile Include="src\Physics\Vehicle.cpp" />
|
||||
<ClCompile Include="src\Scene\Atmosphere.cpp" />
|
||||
<ClCompile Include="src\Scene\BaseMesh.cpp" />
|
||||
<ClCompile Include="src\Scene\Camera.cpp" />
|
||||
<ClCompile Include="src\Scene\CameraOrbit.cpp" />
|
||||
<ClCompile Include="src\Scene\CubeMapBaker.cpp" />
|
||||
<ClCompile Include="src\Scene\EditorTerrain.cpp" />
|
||||
<ClCompile Include="src\Scene\Forest.cpp" />
|
||||
<ClCompile Include="src\Scene\Grass.cpp" />
|
||||
<ClCompile Include="src\Scene\Helpers.cpp" />
|
||||
<ClCompile Include="src\Scene\LightMapBaker.cpp" />
|
||||
<ClCompile Include="src\Scene\MaterialManager.cpp" />
|
||||
<ClCompile Include="src\Scene\Mesh.cpp" />
|
||||
<ClCompile Include="src\Scene\Scatter.cpp" />
|
||||
<ClCompile Include="src\Scene\Scene.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneManager.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Block.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Emitter.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Light.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Model.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Prefab.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneNode.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneNodes.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneParticles.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Site.cpp" />
|
||||
<ClCompile Include="src\Scene\SceneNodes\Trigger.cpp" />
|
||||
<ClCompile Include="src\Scene\ShadowMapBaker.cpp" />
|
||||
<ClCompile Include="src\Scene\Terrain.cpp" />
|
||||
<ClCompile Include="src\Scene\Water.cpp" />
|
||||
<ClCompile Include="src\ThirdParty\fast_atof.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
|
@ -495,7 +473,7 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ThirdParty\imgui\imgui_impl_sdl.cpp">
|
||||
<ClCompile Include="src\ThirdParty\imgui\imgui_impl_sdl2.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -641,6 +619,40 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Atmosphere.cpp" />
|
||||
<ClCompile Include="src\World\CubeMapBaker.cpp" />
|
||||
<ClCompile Include="src\World\EditorOverlays.cpp" />
|
||||
<ClCompile Include="src\World\EditorTerrain.cpp" />
|
||||
<ClCompile Include="src\World\Forest.cpp" />
|
||||
<ClCompile Include="src\World\Grass.cpp" />
|
||||
<ClCompile Include="src\World\LightMapBaker.cpp" />
|
||||
<ClCompile Include="src\World\BaseMesh.cpp" />
|
||||
<ClCompile Include="src\World\Camera.cpp" />
|
||||
<ClCompile Include="src\World\Scatter.cpp" />
|
||||
<ClCompile Include="src\World\ShadowMapBaker.cpp" />
|
||||
<ClCompile Include="src\World\Terrain.cpp" />
|
||||
<ClCompile Include="src\World\Water.cpp" />
|
||||
<ClCompile Include="src\World\World.cpp" />
|
||||
<ClCompile Include="src\World\WorldManager.cpp" />
|
||||
<ClCompile Include="src\World\MaterialManager.cpp" />
|
||||
<ClCompile Include="src\World\Mesh.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\BlockNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\ControlPointNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\EmitterNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\InstanceNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\LightNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\ModelNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\ParticlesNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\PathNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\PhysicsNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\BaseNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\PrefabNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\ShakerNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\SoundNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\TerrainNode.cpp" />
|
||||
<ClCompile Include="src\World\WorldNodes\WorldNodes.cpp" />
|
||||
<ClCompile Include="src\World\OrbitingCamera.cpp" />
|
||||
<ClCompile Include="src\World\WorldUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="src\Shaders\DS_Mesh.hlsl">
|
||||
|
|
|
@ -52,9 +52,6 @@
|
|||
<Filter Include="src\ThirdParty\libb64">
|
||||
<UniqueIdentifier>{2c793d5f-0a67-4166-8490-3ef154bdb4fc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\Scene">
|
||||
<UniqueIdentifier>{28848bdf-d48d-40a2-92a2-6946c609e14e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\AI">
|
||||
<UniqueIdentifier>{6c75fda0-ca2a-4925-9260-1d069a48b1b7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -85,9 +82,6 @@
|
|||
<Filter Include="src\Effects">
|
||||
<UniqueIdentifier>{5ea015f8-8b97-4159-ad67-d71abdba3c91}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\Scene\SceneNodes">
|
||||
<UniqueIdentifier>{07af1a9e-5cdc-4264-811b-d958ec70a709}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\ThirdParty\tinygltf-2.5.0">
|
||||
<UniqueIdentifier>{54a71e7f-5bcd-480d-990e-0d5e79d7ded9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -106,6 +100,12 @@
|
|||
<Filter Include="src\ThirdParty\zlib-1.2.12">
|
||||
<UniqueIdentifier>{8b9c1325-e416-4e6f-8277-1d5e18f9122f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\World">
|
||||
<UniqueIdentifier>{aa98d856-89ce-4d9d-af82-94b6f935fc27}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\World\WorldNodes">
|
||||
<UniqueIdentifier>{3b005273-c21c-493a-a7e2-c5e41cbbc66a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\CGI\BaseGeometry.h">
|
||||
|
@ -312,12 +312,6 @@
|
|||
<ClInclude Include="src\Global\Timer.h">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Camera.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Scene.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Math\Frustum.h">
|
||||
<Filter>src\Math</Filter>
|
||||
</ClInclude>
|
||||
|
@ -339,12 +333,6 @@
|
|||
<ClInclude Include="src\AI\Turret.h">
|
||||
<Filter>src\AI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\BaseMesh.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Mesh.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\IO\StreamPtr.h">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClInclude>
|
||||
|
@ -420,12 +408,6 @@
|
|||
<ClInclude Include="src\ThirdParty\json.hpp">
|
||||
<Filter>src\ThirdParty</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Terrain.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Atmosphere.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Physics\Bullet.h">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClInclude>
|
||||
|
@ -444,21 +426,9 @@
|
|||
<ClInclude Include="src\Math\Quadtree.h">
|
||||
<Filter>src\Math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\MaterialManager.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneManager.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Physics\UserPtr.h">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\EditorTerrain.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Helpers.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\DebugDraw.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
|
@ -468,9 +438,6 @@
|
|||
<ClInclude Include="src\IO\Dictionary.h">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\ShadowMapBaker.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Physics\BulletDebugDraw.h">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClInclude>
|
||||
|
@ -480,9 +447,6 @@
|
|||
<ClInclude Include="src\Physics\KinematicCharacterController.h">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\CameraOrbit.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Input\DragController.h">
|
||||
<Filter>src\Input</Filter>
|
||||
</ClInclude>
|
||||
|
@ -498,18 +462,9 @@
|
|||
<ClInclude Include="src\CGI\Scheduled.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\IO\Xxx.h">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Grass.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\TextureRAM.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Water.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Global\Cooldown.h">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClInclude>
|
||||
|
@ -585,30 +540,6 @@
|
|||
<ClInclude Include="src\Effects\Bloom.h">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Forest.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\Scatter.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Block.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Light.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Model.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneNode.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneNodes.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Types.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Effects\Particles.h">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClInclude>
|
||||
|
@ -621,18 +552,6 @@
|
|||
<ClInclude Include="src\Global\LocalPtr.h">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Site.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Prefab.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Emitter.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\SceneParticles.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Anim\Shaker.h">
|
||||
<Filter>src\Anim</Filter>
|
||||
</ClInclude>
|
||||
|
@ -672,9 +591,6 @@
|
|||
<ClInclude Include="src\Effects\Ssr.h">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\CubeMapBaker.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Game\QuestSystem.h">
|
||||
<Filter>src\Game</Filter>
|
||||
</ClInclude>
|
||||
|
@ -687,7 +603,7 @@
|
|||
<ClInclude Include="src\ThirdParty\imgui\imgui.h">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_impl_sdl.h">
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_impl_sdl2.h">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ThirdParty\imgui\imgui_internal.h">
|
||||
|
@ -702,9 +618,6 @@
|
|||
<ClInclude Include="src\ThirdParty\imgui\imstb_truetype.h">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\SceneNodes\Trigger.h">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\App\UndoManager.h">
|
||||
<Filter>src\App</Filter>
|
||||
</ClInclude>
|
||||
|
@ -741,9 +654,6 @@
|
|||
<ClInclude Include="src\Global\Interval.h">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Scene\LightMapBaker.h">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\CGI\DeferredShading.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
|
@ -792,6 +702,114 @@
|
|||
<ClInclude Include="src\CGI\BaseExtReality.h">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\World.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldManager.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\BlockNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\LightNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\ModelNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\BaseNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\WorldNodes.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\Types.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Camera.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\BaseMesh.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\MaterialManager.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Mesh.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\OrbitingCamera.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\PhysicsNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\EditorOverlays.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\EmitterNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\ParticlesNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\SoundNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\IO\Vwx.h">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\TerrainNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\PrefabNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\InstanceNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\CubeMapBaker.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\LightMapBaker.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\ShadowMapBaker.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Water.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Atmosphere.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Forest.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Scatter.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\EditorTerrain.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Terrain.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\Grass.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldUtils.h">
|
||||
<Filter>src\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\ShakerNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\ControlPointNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\World\WorldNodes\PathNode.h">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\CGI\BaseGeometry.cpp">
|
||||
|
@ -905,12 +923,6 @@
|
|||
<ClCompile Include="src\Global\Timer.cpp">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Camera.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Scene.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Math\Frustum.cpp">
|
||||
<Filter>src\Math</Filter>
|
||||
</ClCompile>
|
||||
|
@ -932,12 +944,6 @@
|
|||
<ClCompile Include="src\AI\Turret.cpp">
|
||||
<Filter>src\AI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\BaseMesh.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Mesh.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Math\TangentSpaceTools.cpp">
|
||||
<Filter>src\Math</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1004,12 +1010,6 @@
|
|||
<ClCompile Include="src\Game\Spirit.cpp">
|
||||
<Filter>src\Game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Terrain.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Atmosphere.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Physics\Bullet.cpp">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1025,18 +1025,6 @@
|
|||
<ClCompile Include="src\Math\Quadtree.cpp">
|
||||
<Filter>src\Math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\MaterialManager.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneManager.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\EditorTerrain.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Helpers.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\DebugDraw.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1046,9 +1034,6 @@
|
|||
<ClCompile Include="src\IO\Dictionary.cpp">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\ShadowMapBaker.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Physics\BulletDebugDraw.cpp">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1058,9 +1043,6 @@
|
|||
<ClCompile Include="src\Physics\KinematicCharacterController.cpp">
|
||||
<Filter>src\Physics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\CameraOrbit.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Input\DragController.cpp">
|
||||
<Filter>src\Input</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1085,18 +1067,9 @@
|
|||
<ClCompile Include="src\CGI\Scheduled.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IO\Xxx.cpp">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Grass.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\TextureRAM.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Water.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Global\Cooldown.cpp">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1166,42 +1139,9 @@
|
|||
<ClCompile Include="src\Effects\Bloom.cpp">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Forest.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\Scatter.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Block.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Light.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Model.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneNode.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneNodes.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Effects\Particles.cpp">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Site.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Prefab.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Emitter.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\SceneParticles.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Anim\Shaker.cpp">
|
||||
<Filter>src\Anim</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1232,9 +1172,6 @@
|
|||
<ClCompile Include="src\Effects\Ssr.cpp">
|
||||
<Filter>src\Effects</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\CubeMapBaker.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Game\QuestSystem.cpp">
|
||||
<Filter>src\Game</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1250,7 +1187,7 @@
|
|||
<ClCompile Include="src\ThirdParty\imgui\imgui_draw.cpp">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ThirdParty\imgui\imgui_impl_sdl.cpp">
|
||||
<ClCompile Include="src\ThirdParty\imgui\imgui_impl_sdl2.cpp">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ThirdParty\imgui\imgui_tables.cpp">
|
||||
|
@ -1259,9 +1196,6 @@
|
|||
<ClCompile Include="src\ThirdParty\imgui\imgui_widgets.cpp">
|
||||
<Filter>src\ThirdParty\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\SceneNodes\Trigger.cpp">
|
||||
<Filter>src\Scene\SceneNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\App\UndoManager.cpp">
|
||||
<Filter>src\App</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1301,9 +1235,6 @@
|
|||
<ClCompile Include="src\Global\Range.cpp">
|
||||
<Filter>src\Global</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Scene\LightMapBaker.cpp">
|
||||
<Filter>src\Scene</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\CGI\DeferredShading.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1361,6 +1292,111 @@
|
|||
<ClCompile Include="src\CGI\BaseExtReality.cpp">
|
||||
<Filter>src\CGI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\World.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldManager.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\BlockNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\LightNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\ModelNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\BaseNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\WorldNodes.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Camera.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\BaseMesh.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\MaterialManager.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Mesh.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\OrbitingCamera.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\PhysicsNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\EditorOverlays.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\EmitterNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\ParticlesNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\SoundNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\IO\Vwx.cpp">
|
||||
<Filter>src\IO</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\TerrainNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\PrefabNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\InstanceNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\CubeMapBaker.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\LightMapBaker.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\ShadowMapBaker.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Water.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Atmosphere.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Forest.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Scatter.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\EditorTerrain.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Terrain.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\Grass.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldUtils.cpp">
|
||||
<Filter>src\World</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\ShakerNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\ControlPointNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\World\WorldNodes\PathNode.cpp">
|
||||
<Filter>src\World\WorldNodes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="src\Shaders\Lib.hlsl">
|
||||
|
|
|
@ -32,8 +32,8 @@ namespace verus
|
|||
const T d = _target - _actual;
|
||||
if (angle)
|
||||
{
|
||||
VERUS_RT_ASSERT(_target >= T(-VERUS_PI) && _target < T(VERUS_PI));
|
||||
VERUS_RT_ASSERT(_actual >= T(-VERUS_PI) && _actual < T(VERUS_PI));
|
||||
VERUS_RT_ASSERT(_target >= T(-4) && _target < T(4));
|
||||
VERUS_RT_ASSERT(_actual >= T(-4) && _actual < T(4));
|
||||
if (d > T(VERUS_PI))
|
||||
_actual += VERUS_2PI;
|
||||
else if (d < T(-VERUS_PI))
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
using namespace verus;
|
||||
using namespace verus::Anim;
|
||||
|
||||
const float Motion::Bone::s_magicValueForCircle = 0.825f * 0.7071f * 4; // Octagon vertices will form a perfect circle.
|
||||
|
||||
// Motion::Bone::Rotation:
|
||||
|
||||
Motion::Bone::Rotation::Rotation()
|
||||
|
@ -24,6 +22,8 @@ Motion::Bone::Rotation::Rotation(RcVector3 euler)
|
|||
|
||||
// Motion::Bone:
|
||||
|
||||
const float Motion::Bone::s_magicValueForCircle = 0.825f * 0.7071f * 4; // Octagon vertices will form a perfect circle.
|
||||
|
||||
Motion::Bone::Bone(PMotion pMotion) :
|
||||
_pMotion(pMotion)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@ using namespace verus::Anim;
|
|||
|
||||
void Shaker::Load(CSZ url)
|
||||
{
|
||||
_url = url;
|
||||
|
||||
Vector<BYTE> v;
|
||||
IO::FileSystem::LoadResource(url, v);
|
||||
|
||||
|
@ -29,7 +31,7 @@ void Shaker::Load(CSZ url)
|
|||
const float val = v[chunkOffset + i] * (1 / 128.f) - 1;
|
||||
_vData[i] = val;
|
||||
}
|
||||
if (!_loop)
|
||||
if (!_looping)
|
||||
_offset = static_cast<float>(chunkSize);
|
||||
}
|
||||
|
||||
|
@ -39,7 +41,7 @@ void Shaker::Update()
|
|||
_offset += dt * _speed;
|
||||
if (_offset >= _vData.size())
|
||||
{
|
||||
if (_loop)
|
||||
if (_looping)
|
||||
{
|
||||
_offset = fmod(_offset, static_cast<float>(_vData.size()));
|
||||
}
|
||||
|
@ -68,9 +70,3 @@ float Shaker::Get()
|
|||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
void Shaker::SetScaleBias(float s, float b)
|
||||
{
|
||||
_scale = s;
|
||||
_bias = b;
|
||||
}
|
||||
|
|
|
@ -9,24 +9,40 @@ namespace verus
|
|||
// Works well for camera's shaking effects.
|
||||
class Shaker
|
||||
{
|
||||
String _url;
|
||||
Vector<float> _vData;
|
||||
float _speed = 0;
|
||||
float _offset = 0;
|
||||
float _value = 0;
|
||||
float _scale = 1;
|
||||
float _bias = 0;
|
||||
bool _loop = false;
|
||||
bool _looping = false;
|
||||
|
||||
public:
|
||||
Shaker(float speed = 400, bool loop = true) : _speed(speed), _loop(loop) {}
|
||||
Shaker(float speed = 400, bool looping = true) : _speed(speed), _looping(looping) {}
|
||||
|
||||
bool IsLoaded() const { return !_vData.empty(); }
|
||||
void Load(CSZ url);
|
||||
Str GetURL() const { return _C(_url); }
|
||||
|
||||
void Update();
|
||||
|
||||
void Reset() { _offset = 0; }
|
||||
void Randomize();
|
||||
// Returns the current value in the range [-1 to 1].
|
||||
float Get();
|
||||
void SetScaleBias(float s, float b);
|
||||
|
||||
float GetSpeed() const { return _speed; }
|
||||
void SetSpeed(float speed) { _speed = speed; }
|
||||
|
||||
float GetScale() const { return _scale; }
|
||||
void SetScale(float scale) { _scale = scale; }
|
||||
|
||||
float GetBias() const { return _bias; }
|
||||
void SetBias(float bias) { _bias = bias; }
|
||||
|
||||
bool IsLooping() const { return _looping; }
|
||||
void SetLooping(float looping) { _looping = looping; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Shaker);
|
||||
}
|
||||
|
|
|
@ -137,9 +137,11 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
|
|||
for (auto& kv : _mapBones)
|
||||
{
|
||||
RBone bone = kv.second;
|
||||
if (bone._pBody)
|
||||
if (bone._pRigidBody)
|
||||
{
|
||||
bone._matFinal = _matRagdollToWorldInv * Transform3(bone._pBody->getWorldTransform()) * bone._matToActorSpace;
|
||||
btTransform btr;
|
||||
bone._pRigidBody->getMotionState()->getWorldTransform(btr);
|
||||
bone._matFinal = _matRagdollToWorldInv * Transform3(btr) * bone._matToActorSpace;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -149,9 +151,11 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
|
|||
PBone pParent = FindBone(_C(bone._parentName));
|
||||
while (pParent)
|
||||
{
|
||||
if (pParent->_pBody)
|
||||
if (pParent->_pRigidBody)
|
||||
{
|
||||
bone._matFinal = _matRagdollToWorldInv * Transform3(pParent->_pBody->getWorldTransform()) * pParent->_matToActorSpace;
|
||||
btTransform btr;
|
||||
pParent->_pRigidBody->getMotionState()->getWorldTransform(btr);
|
||||
bone._matFinal = _matRagdollToWorldInv * Transform3(btr) * pParent->_matToActorSpace;
|
||||
break;
|
||||
}
|
||||
pParent = FindBone(_C(pParent->_parentName));
|
||||
|
@ -553,16 +557,16 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
|
|||
pParent->_matToActorSpace = VMath::inverse(matBody);
|
||||
matBody = _matRagdollToWorld * pParent->_matFinal * matBody;
|
||||
|
||||
Physics::Group group = Physics::Group::general, mask = Physics::Group::all;
|
||||
Physics::Group group = Physics::Group::ragdoll, mask = Physics::Group::all;
|
||||
if (pParent->_noCollision)
|
||||
group = mask = Physics::Group::none;
|
||||
const btTransform tr = matBody.Bullet();
|
||||
pParent->_pBody = bullet.AddNewRigidBody(pParent->_mass, tr, pParent->_pShape, group, mask);
|
||||
pParent->_pBody->setFriction(pParent->_friction);
|
||||
pParent->_pBody->setRestitution(Physics::Bullet::GetRestitution(Physics::Material::leather) * 0.5f);
|
||||
pParent->_pBody->setDamping(dampL, dampA);
|
||||
pParent->_pBody->setDeactivationTime(daTime);
|
||||
pParent->_pBody->setSleepingThresholds(sleepL, sleepA);
|
||||
pParent->_pRigidBody = bullet.AddNewRigidBody(pParent->_mass, tr, pParent->_pShape, +group, +mask);
|
||||
pParent->_pRigidBody->setFriction(pParent->_friction);
|
||||
pParent->_pRigidBody->setRestitution(Physics::Bullet::GetRestitution(Physics::Material::leather) * 0.5f);
|
||||
pParent->_pRigidBody->setDamping(dampL, dampA);
|
||||
pParent->_pRigidBody->setDeactivationTime(daTime);
|
||||
pParent->_pRigidBody->setSleepingThresholds(sleepL, sleepA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,16 +608,16 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
|
|||
pBone->_matToActorSpace = VMath::inverse(matBody);
|
||||
matBody = _matRagdollToWorld * pBone->_matFinal * matBody;
|
||||
|
||||
Physics::Group group = Physics::Group::general, mask = Physics::Group::all;
|
||||
Physics::Group group = Physics::Group::ragdoll, mask = Physics::Group::all;
|
||||
if (pBone->_noCollision)
|
||||
group = mask = Physics::Group::none;
|
||||
const btTransform tr = matBody.Bullet();
|
||||
pBone->_pBody = bullet.AddNewRigidBody(pBone->_mass, tr, pBone->_pShape, group, mask);
|
||||
pBone->_pBody->setFriction(pBone->_friction);
|
||||
pBone->_pBody->setRestitution(Physics::Bullet::GetRestitution(Physics::Material::leather) * 0.5f);
|
||||
pBone->_pBody->setDamping(dampL, dampA);
|
||||
pBone->_pBody->setDeactivationTime(daTime);
|
||||
pBone->_pBody->setSleepingThresholds(sleepL, sleepA);
|
||||
pBone->_pRigidBody = bullet.AddNewRigidBody(pBone->_mass, tr, pBone->_pShape, +group, +mask);
|
||||
pBone->_pRigidBody->setFriction(pBone->_friction);
|
||||
pBone->_pRigidBody->setRestitution(Physics::Bullet::GetRestitution(Physics::Material::leather) * 0.5f);
|
||||
pBone->_pRigidBody->setDamping(dampL, dampA);
|
||||
pBone->_pRigidBody->setDeactivationTime(daTime);
|
||||
pBone->_pRigidBody->setSleepingThresholds(sleepL, sleepA);
|
||||
|
||||
isLeaf = true;
|
||||
}
|
||||
|
@ -630,7 +634,7 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
|
|||
|
||||
if (pBone->_hinge)
|
||||
{
|
||||
btHingeConstraint* pHingeC = new btHingeConstraint(*pBone->_pBody, *pParent->_pBody, localA, localB);
|
||||
btHingeConstraint* pHingeC = new btHingeConstraint(*pBone->_pRigidBody, *pParent->_pRigidBody, localA, localB);
|
||||
if (!pBone->_cLimits.IsZero())
|
||||
pHingeC->setLimit(pBone->_cLimits.getX(), pBone->_cLimits.getY());
|
||||
else
|
||||
|
@ -640,7 +644,7 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
|
|||
}
|
||||
else
|
||||
{
|
||||
btConeTwistConstraint* pConeC = new btConeTwistConstraint(*pBone->_pBody, *pParent->_pBody, localA, localB);
|
||||
btConeTwistConstraint* pConeC = new btConeTwistConstraint(*pBone->_pRigidBody, *pParent->_pRigidBody, localA, localB);
|
||||
if (!pBone->_cLimits.IsZero())
|
||||
pConeC->setLimit(pBone->_cLimits.getX(), pBone->_cLimits.getY(), pBone->_cLimits.getZ(), 0.9f);
|
||||
else
|
||||
|
@ -652,8 +656,8 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
|
|||
}
|
||||
}
|
||||
|
||||
if (pBone->_name == bone && pBone->_pBody)
|
||||
pBone->_pBody->applyCentralImpulse(impulse.Bullet());
|
||||
if (pBone->_name == bone && pBone->_pRigidBody)
|
||||
pBone->_pRigidBody->applyCentralImpulse(impulse.Bullet());
|
||||
}
|
||||
|
||||
_ragdollMode = true;
|
||||
|
@ -677,12 +681,12 @@ void Skeleton::EndRagdoll()
|
|||
for (auto& kv : _mapBones)
|
||||
{
|
||||
RBone bone = kv.second;
|
||||
if (bone._pBody)
|
||||
if (bone._pRigidBody)
|
||||
{
|
||||
bullet.GetWorld()->removeRigidBody(bone._pBody);
|
||||
delete bone._pBody->getMotionState();
|
||||
delete bone._pBody;
|
||||
bone._pBody = nullptr;
|
||||
bullet.GetWorld()->removeRigidBody(bone._pRigidBody);
|
||||
delete bone._pRigidBody->getMotionState();
|
||||
delete bone._pRigidBody;
|
||||
bone._pRigidBody = nullptr;
|
||||
}
|
||||
if (bone._pShape)
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace verus
|
|||
String _name;
|
||||
String _parentName;
|
||||
btCollisionShape* _pShape = nullptr;
|
||||
btRigidBody* _pBody = nullptr;
|
||||
btRigidBody* _pRigidBody = nullptr;
|
||||
btTypedConstraint* _pConstraint = nullptr;
|
||||
float _width = 0;
|
||||
float _length = 0;
|
||||
|
|
|
@ -82,7 +82,7 @@ void Warp::DrawLines() const
|
|||
|
||||
void Warp::DrawZones() const
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
VERUS_QREF_EO;
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
for (const auto& zone : _vZones)
|
||||
|
@ -94,7 +94,7 @@ void Warp::DrawZones() const
|
|||
case 'g': color = VERUS_COLOR_RGBA(0, 255, 0, 255); break;
|
||||
case 'b': color = VERUS_COLOR_RGBA(0, 0, 255, 255); break;
|
||||
}
|
||||
helpers.DrawSphere(zone._pos, zone._radius, color, renderer.GetCommandBuffer());
|
||||
eo.DrawSphere(zone._pos, zone._radius, color, renderer.GetCommandBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,12 +54,12 @@ void UndoManager::Redo()
|
|||
|
||||
bool UndoManager::CanUndo() const
|
||||
{
|
||||
return _nextUndo < _vCommands.size() && _vCommands[_nextUndo]->HasRedo();
|
||||
return _nextUndo < _vCommands.size() && _vCommands[_nextUndo]->IsValid() && _vCommands[_nextUndo]->HasRedo();
|
||||
}
|
||||
|
||||
bool UndoManager::CanRedo() const
|
||||
{
|
||||
return _nextUndo && _vCommands[_nextUndo - 1]->HasRedo();
|
||||
return _nextUndo && _vCommands[_nextUndo - 1]->IsValid() && _vCommands[_nextUndo - 1]->HasRedo();
|
||||
}
|
||||
|
||||
UndoManager::PCommand UndoManager::BeginChange(PCommand pCommand)
|
||||
|
|
|
@ -25,12 +25,12 @@ void Sound::Init(RcDesc desc)
|
|||
_url = desc._url;
|
||||
_refCount = 1;
|
||||
if (desc._is3D) SetFlag(SoundFlags::is3D);
|
||||
if (desc._loop) SetFlag(SoundFlags::loop);
|
||||
if (desc._looping) SetFlag(SoundFlags::looping);
|
||||
if (desc._randomOffset) SetFlag(SoundFlags::randOff);
|
||||
if (desc._keepPcmBuffer) SetFlag(SoundFlags::keepPcmBuffer);
|
||||
_gain = desc._gain;
|
||||
_pitch = desc._pitch;
|
||||
_referenceDistance = desc._referenceDistance;
|
||||
if (desc._randomOffset) SetFlag(SoundFlags::randOff);
|
||||
if (desc._keepPcmBuffer) SetFlag(SoundFlags::keepPcmBuffer);
|
||||
|
||||
IO::Async::I().Load(desc._url, this);
|
||||
}
|
||||
|
@ -51,6 +51,25 @@ bool Sound::Done()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Sound::Update()
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
VERUS_UPDATE_ONCE_CHECK;
|
||||
|
||||
VERUS_FOR(i, VERUS_COUNT_OF(_sources))
|
||||
_sources[i].Update();
|
||||
}
|
||||
|
||||
void Sound::UpdateHRTF()
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
const bool is3D = IsFlagSet(SoundFlags::is3D);
|
||||
VERUS_FOR(i, VERUS_COUNT_OF(_sources))
|
||||
_sources[i].UpdateHRTF(is3D);
|
||||
}
|
||||
|
||||
void Sound::Async_WhenLoaded(CSZ url, RcBlob blob)
|
||||
{
|
||||
VERUS_RT_ASSERT(_url == url);
|
||||
|
@ -94,25 +113,6 @@ void Sound::Async_WhenLoaded(CSZ url, RcBlob blob)
|
|||
SetFlag(SoundFlags::loaded);
|
||||
}
|
||||
|
||||
void Sound::Update()
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
VERUS_UPDATE_ONCE_CHECK;
|
||||
|
||||
VERUS_FOR(i, VERUS_COUNT_OF(_sources))
|
||||
_sources[i].Update();
|
||||
}
|
||||
|
||||
void Sound::UpdateHRTF()
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
const bool is3D = IsFlagSet(SoundFlags::is3D);
|
||||
VERUS_FOR(i, VERUS_COUNT_OF(_sources))
|
||||
_sources[i].UpdateHRTF(is3D);
|
||||
}
|
||||
|
||||
SourcePtr Sound::NewSource(PSourcePtr pID, Source::RcDesc desc)
|
||||
{
|
||||
SourcePtr source;
|
||||
|
@ -138,10 +138,10 @@ SourcePtr Sound::NewSource(PSourcePtr pID, Source::RcDesc desc)
|
|||
alSource3f(sid, AL_VELOCITY, 0, 0, 0);
|
||||
alSourcef(sid, AL_ROLLOFF_FACTOR, 0);
|
||||
}
|
||||
alSourcef(sid, AL_PITCH, _pitch.GetRandomValue() * desc._pitch);
|
||||
alSourcei(sid, AL_LOOPING, IsFlagSet(SoundFlags::loop) ? 1 : 0);
|
||||
alSourcef(sid, AL_PITCH, Math::Clamp<float>(_pitch.GetRandomValue() * desc._pitch, 0.5f, 2));
|
||||
alSourcei(sid, AL_LOOPING, IsFlagSet(SoundFlags::looping) ? 1 : 0);
|
||||
alSourcei(sid, AL_BUFFER, _buffer);
|
||||
alSourcef(sid, AL_GAIN, _gain.GetRandomValue() * desc._gain);
|
||||
alSourcef(sid, AL_GAIN, Math::Clamp<float>(_gain.GetRandomValue() * desc._gain, 0, 1));
|
||||
|
||||
if (desc._secOffset < 0)
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ void SoundPwn::Done()
|
|||
{
|
||||
if (_p)
|
||||
{
|
||||
AudioSystem::I().DeleteSound(_C(_p->GetUrl()));
|
||||
AudioSystem::I().DeleteSound(_C(_p->GetURL()));
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace verus
|
|||
{
|
||||
loaded = (ObjectFlags::user << 0),
|
||||
is3D = (ObjectFlags::user << 1),
|
||||
loop = (ObjectFlags::user << 2),
|
||||
looping = (ObjectFlags::user << 2),
|
||||
randOff = (ObjectFlags::user << 3),
|
||||
keepPcmBuffer = (ObjectFlags::user << 4),
|
||||
user = (ObjectFlags::user << 5)
|
||||
|
@ -24,14 +24,15 @@ namespace verus
|
|||
String _url;
|
||||
Vector<BYTE> _vPcmBuffer;
|
||||
ALuint _buffer = 0;
|
||||
int _next = 0;
|
||||
int _refCount = 0;
|
||||
int _next = 0;
|
||||
Interval _gain = 1;
|
||||
Interval _pitch = 1;
|
||||
float _length = 0;
|
||||
float _referenceDistance = 4;
|
||||
float _length = 0;
|
||||
|
||||
public:
|
||||
// Note that this structure contains some default values for new sources, which can be changed per source.
|
||||
struct Desc
|
||||
{
|
||||
CSZ _url = nullptr;
|
||||
|
@ -39,16 +40,16 @@ namespace verus
|
|||
Interval _pitch = 1;
|
||||
float _referenceDistance = 4;
|
||||
bool _is3D = false;
|
||||
bool _loop = false;
|
||||
bool _looping = false;
|
||||
bool _randomOffset = false;
|
||||
bool _keepPcmBuffer = false;
|
||||
|
||||
Desc(CSZ url) : _url(url) {}
|
||||
Desc& Set3D(bool b = true) { _is3D = b; return *this; }
|
||||
Desc& SetLoop(bool b = true) { _loop = b; return *this; }
|
||||
Desc& SetLooping(bool b = true) { _looping = b; return *this; }
|
||||
Desc& SetRandomOffset(bool b = true) { _randomOffset = b; return *this; }
|
||||
Desc& SetGain(Interval gain) { _gain = gain; return *this; }
|
||||
Desc& SetPitch(Interval pitch) { _pitch = pitch; return *this; }
|
||||
Desc& SetRandomOffset(bool b = true) { _randomOffset = b; return *this; }
|
||||
Desc& SetReferenceDistance(float rd) { _referenceDistance = rd; return *this; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
@ -56,18 +57,21 @@ namespace verus
|
|||
Sound();
|
||||
~Sound();
|
||||
|
||||
void AddRef() { _refCount++; }
|
||||
int GetRefCount() const { return _refCount; }
|
||||
|
||||
void Init(RcDesc desc);
|
||||
bool Done();
|
||||
|
||||
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
|
||||
bool IsLoaded() const { return IsFlagSet(SoundFlags::loaded); }
|
||||
void AddRef() { _refCount++; }
|
||||
|
||||
Str GetUrl() const { return _C(_url); }
|
||||
|
||||
void Update();
|
||||
void UpdateHRTF();
|
||||
|
||||
// <Resources>
|
||||
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
|
||||
bool IsLoaded() const { return IsFlagSet(SoundFlags::loaded); }
|
||||
Str GetURL() const { return _C(_url); }
|
||||
// </Resources>
|
||||
|
||||
SourcePtr NewSource(PSourcePtr pID = nullptr, Source::RcDesc desc = Source::Desc());
|
||||
|
||||
Interval GetGain() const { return _gain; }
|
||||
|
|
|
@ -110,13 +110,19 @@ void Source::MoveTo(RcPoint3 pos, RcVector3 dir, RcVector3 vel)
|
|||
void Source::SetGain(float gain)
|
||||
{
|
||||
if (_pSound && _pSound->IsLoaded())
|
||||
alSourcef(_sid, AL_GAIN, gain * _pSound->GetGain().GetRandomValue());
|
||||
alSourcef(_sid, AL_GAIN, Math::Clamp<float>(gain * _pSound->GetGain().GetRandomValue(), 0, 1));
|
||||
}
|
||||
|
||||
void Source::SetPitch(float pitch)
|
||||
{
|
||||
if (_pSound && _pSound->IsLoaded())
|
||||
alSourcef(_sid, AL_PITCH, pitch * _pSound->GetPitch().GetRandomValue());
|
||||
alSourcef(_sid, AL_PITCH, Math::Clamp<float>(pitch * _pSound->GetPitch().GetRandomValue(), 0.5f, 2));
|
||||
}
|
||||
|
||||
void Source::SetLooping(bool loop)
|
||||
{
|
||||
if (_pSound && _pSound->IsLoaded())
|
||||
alSourcei(_sid, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
// SourcePtr:
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace verus
|
|||
|
||||
void SetGain(float gain);
|
||||
void SetPitch(float pitch);
|
||||
void SetLooping(bool loop);
|
||||
};
|
||||
VERUS_TYPEDEFS(Source);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void DebugDraw::Done()
|
|||
|
||||
void DebugDraw::Begin(Type type, PcTransform3 pMat, bool zEnable)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
|
@ -92,8 +92,8 @@ void DebugDraw::Begin(Type type, PcTransform3 pMat, bool zEnable)
|
|||
}
|
||||
|
||||
Matrix4 matWVP;
|
||||
if (sm.GetPassCamera())
|
||||
matWVP = sm.GetPassCamera()->GetMatrixVP();
|
||||
if (wm.GetPassCamera())
|
||||
matWVP = wm.GetPassCamera()->GetMatrixVP();
|
||||
else
|
||||
matWVP = Matrix4::identity();
|
||||
s_ubDebugDraw._matWVP = pMat ? Matrix4(matWVP * *pMat).UniformBufferFormat() : matWVP.UniformBufferFormat();
|
||||
|
|
|
@ -469,8 +469,8 @@ void DeferredShading::OnSwapChainResized(bool init, bool done)
|
|||
|
||||
bool DeferredShading::IsLoaded()
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
Scene::RDeferredLights dl = helpers.GetDeferredLights();
|
||||
VERUS_QREF_WU;
|
||||
World::RDeferredLights dl = wu.GetDeferredLights();
|
||||
return
|
||||
dl.Get(LightType::dir).IsLoaded() &&
|
||||
dl.Get(LightType::omni).IsLoaded() &&
|
||||
|
@ -479,8 +479,8 @@ bool DeferredShading::IsLoaded()
|
|||
|
||||
void DeferredShading::ResetInstanceCount()
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
Scene::RDeferredLights dl = helpers.GetDeferredLights();
|
||||
VERUS_QREF_WU;
|
||||
World::RDeferredLights dl = wu.GetDeferredLights();
|
||||
dl.Get(LightType::dir).ResetInstanceCount();
|
||||
dl.Get(LightType::omni).ResetInstanceCount();
|
||||
dl.Get(LightType::spot).ResetInstanceCount();
|
||||
|
@ -599,13 +599,13 @@ bool DeferredShading::BeginLightingPass(bool ambient, bool terrainOcclusion)
|
|||
if (ambient)
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
s_ubAmbientVS._matW = Math::QuadMatrix().UniformBufferFormat();
|
||||
s_ubAmbientVS._matV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
s_ubAmbientVS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubAmbientFS._matInvV = sm.GetPassCamera()->GetMatrixInvV().UniformBufferFormat();
|
||||
s_ubAmbientFS._matInvP = sm.GetPassCamera()->GetMatrixInvP().UniformBufferFormat();
|
||||
s_ubAmbientFS._matInvV = wm.GetPassCamera()->GetMatrixInvV().UniformBufferFormat();
|
||||
s_ubAmbientFS._matInvP = wm.GetPassCamera()->GetMatrixInvP().UniformBufferFormat();
|
||||
s_ubAmbientFS._ambientColorY0 = float4(atmo.GetAmbientColorY0().GLM(), 0);
|
||||
s_ubAmbientFS._ambientColorY1 = float4(atmo.GetAmbientColorY1().GLM(), 0);
|
||||
s_ubAmbientFS._invMapSide_minOcclusion.x = 1.f / _terrainMapSide;
|
||||
|
@ -628,8 +628,8 @@ bool DeferredShading::BeginLightingPass(bool ambient, bool terrainOcclusion)
|
|||
{
|
||||
_async_initPipe = true;
|
||||
|
||||
VERUS_QREF_HELPERS;
|
||||
Scene::RDeferredLights dl = helpers.GetDeferredLights();
|
||||
VERUS_QREF_WU;
|
||||
World::RDeferredLights dl = wu.GetDeferredLights();
|
||||
|
||||
{
|
||||
PipelineDesc pipeDesc(dl.Get(LightType::dir).GetGeometry(), _shader[SHADER_LIGHT], "#InstancedDir", _rph, 1);
|
||||
|
@ -690,7 +690,7 @@ void DeferredShading::EndLightingPass()
|
|||
void DeferredShading::BeginComposeAndForwardRendering(bool underwaterMask)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_WATER;
|
||||
VERUS_RT_ASSERT(renderer.GetFrameCount() == _frame);
|
||||
|
@ -707,7 +707,7 @@ void DeferredShading::BeginComposeAndForwardRendering(bool underwaterMask)
|
|||
_tex[TEX_GBUFFER_3]->GetClearValue()
|
||||
});
|
||||
|
||||
const Matrix4 matInvVP = VMath::inverse(sm.GetPassCamera()->GetMatrixVP());
|
||||
const Matrix4 matInvVP = VMath::inverse(wm.GetPassCamera()->GetMatrixVP());
|
||||
|
||||
s_ubComposeVS._matW = Math::QuadMatrix().UniformBufferFormat();
|
||||
s_ubComposeVS._matV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
|
@ -717,7 +717,7 @@ void DeferredShading::BeginComposeAndForwardRendering(bool underwaterMask)
|
|||
s_ubComposeFS._exposure_underwaterMask.y = underwaterMask ? 1.f : 0.f;
|
||||
s_ubComposeFS._backgroundColor = _backgroundColor.GLM();
|
||||
s_ubComposeFS._fogColor = Vector4(atmo.GetFogColor(), atmo.GetFogDensity()).GLM();
|
||||
s_ubComposeFS._zNearFarEx = sm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubComposeFS._zNearFarEx = wm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubComposeFS._waterDiffColorShallow = float4(water.GetDiffuseColorShallow().GLM(), water.GetFogDensity());
|
||||
s_ubComposeFS._waterDiffColorDeep = float4(water.GetDiffuseColorDeep().GLM(), water.IsUnderwater() ? 1.f : 0.f);
|
||||
|
||||
|
@ -802,13 +802,13 @@ bool DeferredShading::IsLightUrl(CSZ url)
|
|||
void DeferredShading::OnNewLightType(CommandBufferPtr cb, LightType type, bool wireframe)
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
s_ubPerFrame._matToUV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
s_ubPerFrame._matV = sm.GetPassCamera()->GetMatrixV().UniformBufferFormat();
|
||||
s_ubPerFrame._matInvV = sm.GetPassCamera()->GetMatrixInvV().UniformBufferFormat();
|
||||
s_ubPerFrame._matVP = sm.GetPassCamera()->GetMatrixVP().UniformBufferFormat();
|
||||
s_ubPerFrame._matInvP = sm.GetPassCamera()->GetMatrixInvP().UniformBufferFormat();
|
||||
s_ubPerFrame._matV = wm.GetPassCamera()->GetMatrixV().UniformBufferFormat();
|
||||
s_ubPerFrame._matInvV = wm.GetPassCamera()->GetMatrixInvV().UniformBufferFormat();
|
||||
s_ubPerFrame._matVP = wm.GetPassCamera()->GetMatrixVP().UniformBufferFormat();
|
||||
s_ubPerFrame._matInvP = wm.GetPassCamera()->GetMatrixInvP().UniformBufferFormat();
|
||||
s_ubPerFrame._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
|
||||
switch (type)
|
||||
|
@ -851,10 +851,10 @@ void DeferredShading::BindDescriptorsPerMeshVS(CommandBufferPtr cb)
|
|||
|
||||
void DeferredShading::Load()
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
Scene::RDeferredLights dl = helpers.GetDeferredLights();
|
||||
VERUS_QREF_WU;
|
||||
World::RDeferredLights dl = wu.GetDeferredLights();
|
||||
|
||||
Scene::Mesh::Desc meshDesc;
|
||||
World::Mesh::Desc meshDesc;
|
||||
meshDesc._instanceCapacity = 10000;
|
||||
|
||||
meshDesc._url = "[Models]:DS/Dir.x3d";
|
||||
|
|
|
@ -242,10 +242,10 @@ void Renderer::Done()
|
|||
_commandBuffer.Done();
|
||||
|
||||
Effects::Particles::DoneStatic();
|
||||
Scene::Forest::DoneStatic();
|
||||
Scene::Grass::DoneStatic();
|
||||
Scene::Terrain::DoneStatic();
|
||||
Scene::Mesh::DoneStatic();
|
||||
World::Forest::DoneStatic();
|
||||
World::Grass::DoneStatic();
|
||||
World::Terrain::DoneStatic();
|
||||
World::Mesh::DoneStatic();
|
||||
GUI::Font::DoneStatic();
|
||||
|
||||
_pBaseRenderer->ReleaseMe();
|
||||
|
@ -279,7 +279,7 @@ void Renderer::Update()
|
|||
const float alpha = Math::Max(0.001f, floatColor[3]);
|
||||
const float actual = gray.r;
|
||||
const float expScale = Math::Clamp(_exposure[1] * (1 / 16.f), 0.f, 1.f);
|
||||
const float target = -0.2f + 0.6f * expScale * expScale; // Dark scene exposure compensation.
|
||||
const float target = -0.1f + 0.5f * expScale * expScale; // Dark scene exposure compensation.
|
||||
const float important = (actual - 0.5f * (1 - alpha)) / alpha;
|
||||
const float delta = target - important;
|
||||
const float speed = (delta * delta) * ((delta > 0) ? 5.f : 15.f);
|
||||
|
@ -406,8 +406,8 @@ bool Renderer::OnWindowSizeChanged(int w, int h)
|
|||
OnScreenSwapChainResized(true, true);
|
||||
if (_ds.IsInitialized())
|
||||
_ds.OnSwapChainResized(true, true);
|
||||
if (Scene::Water::IsValidSingleton())
|
||||
Scene::Water::I().OnSwapChainResized();
|
||||
if (World::Water::IsValidSingleton())
|
||||
World::Water::I().OnSwapChainResized();
|
||||
if (Effects::Bloom::IsValidSingleton())
|
||||
Effects::Bloom::I().OnSwapChainResized();
|
||||
if (Effects::Ssao::IsValidSingleton())
|
||||
|
@ -704,6 +704,12 @@ void Renderer::ImGuiUpdateStyle()
|
|||
colors[ImGuiCol_PlotHistogram] = disabledColor;
|
||||
colors[ImGuiCol_PlotHistogramHovered] = satColorB;
|
||||
|
||||
colors[ImGuiCol_TableHeaderBg] = borderColor;
|
||||
colors[ImGuiCol_TableBorderStrong] = borderColor;
|
||||
colors[ImGuiCol_TableBorderLight] = borderColor;
|
||||
colors[ImGuiCol_TableRowBg] = frameBgColor;
|
||||
colors[ImGuiCol_TableRowBgAlt] = frameBgColor;
|
||||
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||
colors[ImGuiCol_DragDropTarget] = satColorB;
|
||||
colors[ImGuiCol_NavHighlight] = satColorB;
|
||||
|
|
|
@ -129,7 +129,7 @@ void Bloom::Generate()
|
|||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
if (!settings._postProcessBloom)
|
||||
return;
|
||||
|
@ -176,10 +176,10 @@ void Bloom::Generate()
|
|||
cb->BeginRenderPass(_rphLightShafts, _fbh, { _tex[TEX_PING]->GetClearValue() },
|
||||
CGI::ViewportScissorFlags::setAllForCurrentViewScaled | CGI::ViewportScissorFlags::applyHalfScale);
|
||||
|
||||
s_ubBloomLightShaftsFS._matInvVP = Matrix4(VMath::inverse(sm.GetPassCamera()->GetMatrixVP())).UniformBufferFormat();
|
||||
s_ubBloomLightShaftsFS._matInvVP = Matrix4(VMath::inverse(wm.GetPassCamera()->GetMatrixVP())).UniformBufferFormat();
|
||||
s_ubBloomLightShaftsFS._dirToSun = float4(atmo.GetDirToSun().GLM(), 0);
|
||||
s_ubBloomLightShaftsFS._sunColor = float4(atmo.GetSunColor().GLM(), 0);
|
||||
s_ubBloomLightShaftsFS._eyePos = float4(sm.GetPassCamera()->GetEyePosition().GLM(), 0);
|
||||
s_ubBloomLightShaftsFS._eyePos = float4(wm.GetPassCamera()->GetEyePosition().GLM(), 0);
|
||||
s_ubBloomLightShaftsFS._maxDist_sunGloss_wideStrength_sunStrength.x = _maxDist;
|
||||
s_ubBloomLightShaftsFS._maxDist_sunGloss_wideStrength_sunStrength.y = _sunGloss;
|
||||
s_ubBloomLightShaftsFS._maxDist_sunGloss_wideStrength_sunStrength.z = _wideStrength;
|
||||
|
|
|
@ -40,8 +40,8 @@ namespace verus
|
|||
float _colorBias = 1.4f;
|
||||
float _maxDist = 20;
|
||||
float _sunGloss = 128;
|
||||
float _wideStrength = 0.2f;
|
||||
float _sunStrength = 0.3f;
|
||||
float _wideStrength = 0.15f;
|
||||
float _sunStrength = 0.35f;
|
||||
bool _blur = true;
|
||||
bool _blurLightShafts = true;
|
||||
bool _editMode = false;
|
||||
|
|
|
@ -349,7 +349,7 @@ void Blur::GenerateForDepthOfField()
|
|||
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
const float radius = 0.02f;
|
||||
const Matrix3 matR = Matrix3::rotationZ(Math::ToRadians(45));
|
||||
|
@ -394,7 +394,7 @@ void Blur::GenerateForDepthOfField()
|
|||
s_ubBlurVS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubBlurFS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
UpdateUniformBuffer(radius, 0, renderer.GetCurrentViewWidth(), samplesPerPixel, maxSamples);
|
||||
s_ubExtraBlurFS._zNearFarEx = sm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubExtraBlurFS._zNearFarEx = wm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubExtraBlurFS._textureSize = cb->GetViewportSize().GLM();
|
||||
s_ubExtraBlurFS._focusDist_blurStrength.x = _dofFocusDist;
|
||||
s_ubExtraBlurFS._focusDist_blurStrength.y = _dofBlurStrength;
|
||||
|
@ -505,7 +505,7 @@ void Blur::GenerateForAntiAliasing()
|
|||
{
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
|
||||
|
@ -516,7 +516,7 @@ void Blur::GenerateForAntiAliasing()
|
|||
s_ubBlurVS._matV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
s_ubBlurVS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubBlurFS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubExtraBlurFS._zNearFarEx = sm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubExtraBlurFS._zNearFarEx = wm.GetPassCamera()->GetZNearFarEx().GLM();
|
||||
s_ubExtraBlurFS._textureSize = cb->GetViewportSize().GLM();
|
||||
|
||||
cb->BindPipeline(_pipe[settings._postProcessAntiAliasing ? PIPE_AA : PIPE_AA_OFF]);
|
||||
|
@ -535,7 +535,7 @@ void Blur::GenerateForMotionBlur()
|
|||
{
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
|
||||
|
@ -546,9 +546,9 @@ void Blur::GenerateForMotionBlur()
|
|||
s_ubBlurVS._matV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
s_ubBlurVS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubBlurFS._tcViewScaleBias = cb->GetViewScaleBias().GLM();
|
||||
s_ubExtraBlurFS._matInvVP = Matrix4(VMath::inverse(sm.GetViewCamera()->GetMatrixVP())).UniformBufferFormat();
|
||||
s_ubExtraBlurFS._matPrevVP = sm.GetViewCamera()->GetMatrixPrevVP().UniformBufferFormat();
|
||||
s_ubExtraBlurFS._zNearFarEx = sm.GetViewCamera()->GetZNearFarEx().GLM();
|
||||
s_ubExtraBlurFS._matInvVP = Matrix4(VMath::inverse(wm.GetViewCamera()->GetMatrixVP())).UniformBufferFormat();
|
||||
s_ubExtraBlurFS._matPrevVP = wm.GetViewCamera()->GetMatrixPrevVP().UniformBufferFormat();
|
||||
s_ubExtraBlurFS._zNearFarEx = wm.GetViewCamera()->GetZNearFarEx().GLM();
|
||||
|
||||
cb->BindPipeline(_pipe[settings._postProcessMotionBlur ? PIPE_MOTION_BLUR : PIPE_MOTION_BLUR_OFF]);
|
||||
_shader->BeginBindDescriptors();
|
||||
|
|
|
@ -248,7 +248,7 @@ void Particles::Update()
|
|||
VERUS_QREF_TIMER;
|
||||
|
||||
Vector3 wind = Vector3(0);
|
||||
if (Scene::Atmosphere::IsValidSingleton())
|
||||
if (World::Atmosphere::IsValidSingleton())
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
wind = atmo.GetWindVelocity();
|
||||
|
@ -293,8 +293,8 @@ void Particles::Update()
|
|||
}
|
||||
else // Billboards:
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
Scene::PCamera pHeadCamera = sm.GetHeadCamera();
|
||||
VERUS_QREF_WM;
|
||||
World::PCamera pHeadCamera = wm.GetHeadCamera();
|
||||
Vector3 normal = pHeadCamera->GetFrontDirection();
|
||||
Vector3 up(0, 1, 0);
|
||||
switch (_billboardType)
|
||||
|
@ -371,7 +371,7 @@ void Particles::Draw()
|
|||
VERUS_UPDATE_ONCE_CHECK_DRAW;
|
||||
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
VERUS_QREF_ATMO;
|
||||
|
||||
if (!_drawCount || !_csh.IsSet())
|
||||
|
@ -386,8 +386,8 @@ void Particles::Draw()
|
|||
brightness = gray.x * abs(brightness);
|
||||
}
|
||||
|
||||
s_ubParticlesVS._matP = sm.GetPassCamera()->GetMatrixP().UniformBufferFormat();
|
||||
s_ubParticlesVS._matWVP = sm.GetPassCamera()->GetMatrixVP().UniformBufferFormat();
|
||||
s_ubParticlesVS._matP = wm.GetPassCamera()->GetMatrixP().UniformBufferFormat();
|
||||
s_ubParticlesVS._matWVP = wm.GetPassCamera()->GetMatrixVP().UniformBufferFormat();
|
||||
s_ubParticlesVS._viewportSize = cb->GetViewportSize().GLM();
|
||||
s_ubParticlesVS._brightness.x = brightness;
|
||||
s_ubParticlesFS._tilesetSize = _tilesetSize.GLM();
|
||||
|
@ -539,7 +539,7 @@ int Particles::Add(RcPoint3 pos, RcVector3 dir, float scale, PcVector4 pUserColo
|
|||
VERUS_QREF_TIMER;
|
||||
|
||||
Vector3 wind = Vector3(0);
|
||||
if (Scene::Atmosphere::IsValidSingleton())
|
||||
if (World::Atmosphere::IsValidSingleton())
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
wind = atmo.GetWindVelocity();
|
||||
|
@ -626,7 +626,7 @@ bool Particles::TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point
|
|||
bool hit = false;
|
||||
|
||||
Vector3 wind = Vector3(0);
|
||||
if (Scene::Atmosphere::IsValidSingleton())
|
||||
if (World::Atmosphere::IsValidSingleton())
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
wind = atmo.GetWindVelocity();
|
||||
|
@ -648,8 +648,8 @@ bool Particles::TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point
|
|||
}
|
||||
else
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
if (sm.RayCastingTest(particle._prevPosition, particle._position, nullptr, &point, &normal))
|
||||
VERUS_QREF_WM;
|
||||
if (wm.RayTestEx(particle._prevPosition, particle._position, nullptr, &point, &normal, nullptr, Physics::Bullet::I().GetMainMask()))
|
||||
{
|
||||
hit = true;
|
||||
particle._inContact = normal.getY() > 0.7071f;
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace verus
|
|||
void Update(); // Call this after adding particles!
|
||||
void Draw();
|
||||
|
||||
Str GetUrl() const { return _C(_url); }
|
||||
Str GetURL() const { return _C(_url); }
|
||||
int GetTilesetX() const { return _tilesetX; }
|
||||
int GetTilesetY() const { return _tilesetY; }
|
||||
int GetCapacity() const { return _capacity; }
|
||||
|
|
|
@ -109,7 +109,7 @@ void Ssao::Generate()
|
|||
{
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
if (!settings._postProcessSSAO)
|
||||
return;
|
||||
|
@ -127,7 +127,7 @@ void Ssao::Generate()
|
|||
|
||||
cb->BeginRenderPass(_rph, _fbh, { renderer.GetDS().GetGBuffer(3)->GetClearValue() });
|
||||
|
||||
Scene::RCamera passCamera = *sm.GetPassCamera();
|
||||
World::RCamera passCamera = *wm.GetPassCamera();
|
||||
|
||||
s_ubSsaoVS._matW = Math::QuadMatrix().UniformBufferFormat();
|
||||
s_ubSsaoVS._matV = Math::ToUVMatrix().UniformBufferFormat();
|
||||
|
|
|
@ -116,7 +116,7 @@ void Ssr::Generate()
|
|||
{
|
||||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
if (!_csh.IsSet())
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ void Ssr::Generate()
|
|||
cb->PipelineImageMemoryBarrier(renderer.GetTexDepthStencil(), CGI::ImageLayout::depthStencilAttachment, CGI::ImageLayout::depthStencilReadOnly, 0);
|
||||
cb->BeginRenderPass(_rph, _fbh, { renderer.GetDS().GetLightAccSpecularTexture()->GetClearValue() });
|
||||
|
||||
Scene::RCamera passCamera = *sm.GetPassCamera();
|
||||
World::RCamera passCamera = *wm.GetPassCamera();
|
||||
|
||||
const Matrix4 matPTex = Matrix4(Math::ToUVMatrix()) * passCamera.GetMatrixP();
|
||||
|
||||
|
|
|
@ -317,13 +317,13 @@ void BaseConvert::Mesh::Compress()
|
|||
VERUS_FOR(i, _vertCount)
|
||||
aabb.Include(_vUberVerts[i]._pos);
|
||||
extents = aabb.GetExtents();
|
||||
Scene::BaseMesh::ComputeDeq(_posScale, _posBias, extents, aabb._mn);
|
||||
World::BaseMesh::ComputeDeq(_posScale, _posBias, extents, aabb._mn);
|
||||
_vZipPos.reserve(_vertCount);
|
||||
VERUS_FOR(i, _vertCount)
|
||||
{
|
||||
Mesh::Vec3Short pos;
|
||||
glm::vec3 v(_vUberVerts[i]._pos);
|
||||
Scene::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
World::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
pos._x = short(v.x);
|
||||
pos._y = short(v.y);
|
||||
pos._z = short(v.z);
|
||||
|
@ -336,7 +336,7 @@ void BaseConvert::Mesh::Compress()
|
|||
VERUS_FOR(i, _vertCount)
|
||||
aabb.Include(glm::vec3(_vUberVerts[i]._tc0, 0));
|
||||
extents = aabb.GetExtents();
|
||||
Scene::BaseMesh::ComputeDeq(scale, bias, extents, aabb._mn);
|
||||
World::BaseMesh::ComputeDeq(scale, bias, extents, aabb._mn);
|
||||
_tc0Scale = glm::vec2(scale);
|
||||
_tc0Bias = glm::vec2(bias);
|
||||
_vZipTc0.reserve(_vertCount);
|
||||
|
@ -344,7 +344,7 @@ void BaseConvert::Mesh::Compress()
|
|||
{
|
||||
Mesh::Vec2Short tc;
|
||||
glm::vec3 v(_vUberVerts[i]._tc0, 0);
|
||||
Scene::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
World::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
tc._u = short(v.x);
|
||||
tc._v = short(v.y);
|
||||
_vZipTc0.push_back(tc);
|
||||
|
@ -369,7 +369,7 @@ void BaseConvert::Mesh::Compress()
|
|||
aabb.Include(glm::vec3(_vUberVerts[i]._tc1, 0));
|
||||
}
|
||||
extents = aabb.GetExtents();
|
||||
Scene::BaseMesh::ComputeDeq(scale, bias, extents, aabb._mn);
|
||||
World::BaseMesh::ComputeDeq(scale, bias, extents, aabb._mn);
|
||||
_tc1Scale = glm::vec2(scale);
|
||||
_tc1Bias = glm::vec2(bias);
|
||||
_vZipTc1.reserve(_vertCount);
|
||||
|
@ -377,7 +377,7 @@ void BaseConvert::Mesh::Compress()
|
|||
{
|
||||
Mesh::Vec2Short tc;
|
||||
glm::vec3 v((_vUberVerts[i]._tc1), 0);
|
||||
Scene::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
World::BaseMesh::QuantizeV(v, extents, aabb._mn);
|
||||
tc._u = short(v.x);
|
||||
tc._v = short(v.y);
|
||||
_vZipTc1.push_back(tc);
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace verus
|
|||
{
|
||||
class Cursor : public Object
|
||||
{
|
||||
Scene::TexturePwn _tex;
|
||||
World::TexturePwn _tex;
|
||||
CGI::CSHandle _csh;
|
||||
float _x = 0.5f;
|
||||
float _y = 0.5f;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace verus
|
|||
{
|
||||
class Image : public Widget
|
||||
{
|
||||
Scene::TexturePwn _tex;
|
||||
World::TexturePwn _tex;
|
||||
CGI::CSHandle _csh;
|
||||
Vector4 _tcScale = Vector4(1, 1);
|
||||
Linear<Vector4> _tcBias;
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace verus
|
|||
String _locale = "RU";
|
||||
TMapStrings _mapStrings;
|
||||
Vector<PWidget> _vTabList;
|
||||
Scene::TexturePwn _tex;
|
||||
World::TexturePwn _tex;
|
||||
PWidget _pLastHovered = nullptr;
|
||||
PInputFocus _pInputFocus = nullptr;
|
||||
State _state = State::done;
|
||||
|
|
|
@ -436,8 +436,8 @@ Matrix4 ViewManager::GetXrMatrix() const
|
|||
if (CGI::ViewType::openXR != renderer.GetCurrentViewType())
|
||||
return Matrix4::identity();
|
||||
|
||||
VERUS_QREF_SM;
|
||||
return (_xrMatrixEnabled && sm.GetHeadCamera() && sm.GetPassCamera()) ?
|
||||
sm.GetPassCamera()->GetMatrixVP() * sm.GetHeadCamera()->GetMatrixInvV() *
|
||||
VERUS_QREF_WM;
|
||||
return (_xrMatrixEnabled && wm.GetHeadCamera() && wm.GetPassCamera()) ?
|
||||
wm.GetPassCamera()->GetMatrixVP() * wm.GetHeadCamera()->GetMatrixInvV() *
|
||||
Transform3(Matrix3::scale(Vector3(0.25f * (16 / 9.f), 0.25f)), Vector3(0, 0, -1)) : Matrix4::identity();
|
||||
}
|
||||
|
|
|
@ -251,7 +251,7 @@ void BaseCharacter::EndRagdoll()
|
|||
|
||||
void BaseCharacter::ComputeThirdPersonCameraArgs(RcVector3 offset, RPoint3 eye, RPoint3 at)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
const float r = 0.1f;
|
||||
Point3 point;
|
||||
|
@ -262,14 +262,14 @@ void BaseCharacter::ComputeThirdPersonCameraArgs(RcVector3 offset, RPoint3 eye,
|
|||
const float startAt = _cc.GetRadius() + _cc.GetHeight() * 0.5f; // Inside capsule.
|
||||
const Point3 origin = pos + Vector3(0, startAt, 0);
|
||||
at = pos + offsetW;
|
||||
if (sm.RayCastingTest(origin, at, nullptr, &point, &norm, &r))
|
||||
if (wm.RayTestEx(origin, at, nullptr, &point, &norm, &r, Physics::Bullet::I().GetMainMask()))
|
||||
at = point + norm * r;
|
||||
eye = at - GetFrontDirection() * _cameraRadius.GetValue() + offsetW * 0.05f;
|
||||
}
|
||||
|
||||
float BaseCharacter::ComputeThirdPersonCamera(Scene::RCamera camera, Anim::RcOrbit orbit, RcVector3 offset)
|
||||
float BaseCharacter::ComputeThirdPersonCamera(World::RCamera camera, Anim::RcOrbit orbit, RcVector3 offset)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
const float r = 0.1f;
|
||||
Point3 point;
|
||||
|
@ -288,7 +288,7 @@ float BaseCharacter::ComputeThirdPersonCamera(Scene::RCamera camera, Anim::RcOrb
|
|||
eye = at + Vector3(toEye);
|
||||
|
||||
float ret = 0;
|
||||
if (sm.RayCastingTest(at, eye, nullptr, &point, &norm, &r)) // Hitting the wall?
|
||||
if (wm.RayTestEx(at, eye, nullptr, &point, &norm, &r, Physics::Bullet::I().GetMainMask())) // Hitting the wall?
|
||||
{
|
||||
eye = point + norm * r;
|
||||
const float maxCameraRadius = VMath::dist(at, eye) + r;
|
||||
|
@ -315,7 +315,7 @@ float BaseCharacter::ComputeThirdPersonCamera(Scene::RCamera camera, Anim::RcOrb
|
|||
|
||||
void BaseCharacter::ComputeThirdPersonAim(RPoint3 aimPos, RVector3 aimDir, RcVector3 offset)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
const float r = 0.1f;
|
||||
Point3 point;
|
||||
|
@ -324,7 +324,7 @@ void BaseCharacter::ComputeThirdPersonAim(RPoint3 aimPos, RVector3 aimDir, RcVec
|
|||
Point3 eye, at;
|
||||
ComputeThirdPersonCameraArgs(offset, eye, at);
|
||||
|
||||
if (sm.RayCastingTest(at, eye, nullptr, &point, &norm, &r)) // Hitting the wall?
|
||||
if (wm.RayTestEx(at, eye, nullptr, &point, &norm, &r, Physics::Bullet::I().GetMainMask())) // Hitting the wall?
|
||||
{
|
||||
eye = point + norm * r;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace verus
|
|||
virtual void BaseCharacter_OnDoneRagdoll() {}
|
||||
|
||||
virtual void ComputeThirdPersonCameraArgs(RcVector3 offset, RPoint3 eye, RPoint3 at);
|
||||
float ComputeThirdPersonCamera(Scene::RCamera camera, Anim::RcOrbit orbit, RcVector3 offset = Vector3(0));
|
||||
float ComputeThirdPersonCamera(World::RCamera camera, Anim::RcOrbit orbit, RcVector3 offset = Vector3(0));
|
||||
void ComputeThirdPersonAim(RPoint3 aimPos, RVector3 aimDir, RcVector3 offset = Vector3(0));
|
||||
void SetMaxCameraRadius(float r);
|
||||
float GetCameraRadius() const { return _cameraRadius.GetValue(); }
|
||||
|
|
|
@ -26,7 +26,7 @@ VERUS_TYPEDEFS(MyRendererDelegate);
|
|||
struct BaseGame::Pimpl : AllocatorAware
|
||||
{
|
||||
PBaseGame _p = nullptr;
|
||||
Scene::MainCamera _camera;
|
||||
World::MainCamera _camera;
|
||||
Spirit _cameraSpirit;
|
||||
bool _defaultCameraMovement = true;
|
||||
bool _escapeKeyExitGame = true;
|
||||
|
@ -107,14 +107,14 @@ void BaseGame::Initialize(VERUS_MAIN_DEFAULT_ARGS, App::Window::RcDesc windowDes
|
|||
// Configure:
|
||||
VERUS_QREF_RENDERER;
|
||||
_p->_camera.Update();
|
||||
if (Scene::SceneManager::IsValidSingleton())
|
||||
Scene::SceneManager::I().SetAllCameras(&_p->_camera);
|
||||
if (World::WorldManager::IsValidSingleton())
|
||||
World::WorldManager::I().SetAllCameras(&_p->_camera);
|
||||
|
||||
renderer.BeginFrame(); // Begin recording a command buffer.
|
||||
renderer.InitCmd();
|
||||
_engineInit.InitCmd();
|
||||
if (Scene::MaterialManager::IsValidSingleton())
|
||||
Scene::MaterialManager::I().InitCmd();
|
||||
if (World::MaterialManager::IsValidSingleton())
|
||||
World::MaterialManager::I().InitCmd();
|
||||
BaseGame_LoadContent();
|
||||
renderer.EndFrame(); // End recording a command buffer.
|
||||
|
||||
|
@ -161,7 +161,6 @@ void BaseGame::Loop(bool relativeMouseMode)
|
|||
{
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
if (event.key.keysym.mod & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT))
|
||||
keyboardShortcut = BaseGame_SDL_OnKeyboardShortcut(event.key.keysym.sym, event.key.keysym.mod);
|
||||
}
|
||||
break;
|
||||
|
@ -298,20 +297,20 @@ void BaseGame::Loop(bool relativeMouseMode)
|
|||
_p->_cameraSpirit.Update();
|
||||
_p->_camera.MoveEyeTo(_p->_cameraSpirit.GetPosition());
|
||||
_p->_camera.MoveAtTo(_p->_cameraSpirit.GetPosition() + _p->_cameraSpirit.GetFrontDirection());
|
||||
if (Scene::Water::IsValidSingleton())
|
||||
if (World::Water::IsValidSingleton())
|
||||
{
|
||||
VERUS_QREF_WATER;
|
||||
if (water.IsInitialized())
|
||||
_p->_camera.ExcludeWaterLine();
|
||||
}
|
||||
_p->_camera.Update();
|
||||
if (Scene::SceneManager::IsValidSingleton())
|
||||
Scene::SceneManager::I().SetAllCameras(&_p->_camera);
|
||||
if (World::WorldManager::IsValidSingleton())
|
||||
World::WorldManager::I().SetAllCameras(&_p->_camera);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Scene::SceneManager::IsValidSingleton())
|
||||
Scene::SceneManager::I().SetAllCameras(nullptr);
|
||||
if (World::WorldManager::IsValidSingleton())
|
||||
World::WorldManager::I().SetAllCameras(nullptr);
|
||||
}
|
||||
|
||||
BaseGame_Update(); // Between physics and audio update.
|
||||
|
@ -379,7 +378,7 @@ void BaseGame::ToggleFullscreen()
|
|||
throw VERUS_RUNTIME_ERROR << "SDL_SetWindowFullscreen()";
|
||||
}
|
||||
|
||||
Scene::RCamera BaseGame::GetDefaultCamera()
|
||||
World::RCamera BaseGame::GetDefaultCamera()
|
||||
{
|
||||
return _p->_camera;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace verus
|
|||
void ToggleFullscreen();
|
||||
|
||||
// Camera:
|
||||
Scene::RCamera GetDefaultCamera();
|
||||
World::RCamera GetDefaultCamera();
|
||||
RSpirit GetCameraSpirit();
|
||||
|
||||
// Configuration:
|
||||
|
|
|
@ -183,11 +183,11 @@ bool ActiveMechanics::UpdateMultiplayer()
|
|||
return false;
|
||||
}
|
||||
|
||||
Scene::PMainCamera ActiveMechanics::GetScreenCamera()
|
||||
World::PMainCamera ActiveMechanics::GetScreenCamera()
|
||||
{
|
||||
for (auto p : _vStack)
|
||||
{
|
||||
Scene::PMainCamera pCamera = p->GetScreenCamera();
|
||||
World::PMainCamera pCamera = p->GetScreenCamera();
|
||||
if (pCamera)
|
||||
return pCamera;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace verus
|
|||
bool OnTakeDamage(int id, float amount);
|
||||
void OnViewChanged(CGI::RcViewDesc viewDesc);
|
||||
bool UpdateMultiplayer();
|
||||
Scene::PMainCamera GetScreenCamera();
|
||||
World::PMainCamera GetScreenCamera();
|
||||
|
||||
void Reset();
|
||||
bool Push(RMechanics mech);
|
||||
|
|
|
@ -571,7 +571,7 @@ void Cutscene::OnViewChanged(CGI::RcViewDesc viewDesc)
|
|||
}
|
||||
}
|
||||
|
||||
Scene::PMainCamera Cutscene::GetScreenCamera()
|
||||
World::PMainCamera Cutscene::GetScreenCamera()
|
||||
{
|
||||
return _pCurrentCameraCommand ? &_screenCamera : nullptr;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace verus
|
|||
Vector<PCommand> _vCommands;
|
||||
std::function<void(int)> _fnOnEnd;
|
||||
PCameraCommand _pCurrentCameraCommand = nullptr;
|
||||
Scene::MainCamera _screenCamera;
|
||||
World::MainCamera _screenCamera;
|
||||
int _beginIndex = 0;
|
||||
int _endIndex = 0;
|
||||
float _timeSinceBarrier = 0;
|
||||
|
@ -166,7 +166,7 @@ namespace verus
|
|||
virtual bool IsDefaultInputEnabled() override;
|
||||
virtual Continue OnMouseMove(float x, float y) override;
|
||||
virtual void OnViewChanged(CGI::RcViewDesc viewDesc) override;
|
||||
virtual Scene::PMainCamera GetScreenCamera() override;
|
||||
virtual World::PMainCamera GetScreenCamera() override;
|
||||
|
||||
void SetOnEndCallback(std::function<void(int)> fn) { _fnOnEnd = fn; }
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace verus
|
|||
virtual Continue OnTakeDamage(int id, float amount) { return Continue::yes; }
|
||||
virtual void OnViewChanged(CGI::RcViewDesc viewDesc) {}
|
||||
virtual Continue UpdateMultiplayer() { return Continue::yes; }
|
||||
virtual Scene::PMainCamera GetScreenCamera() { return nullptr; }
|
||||
virtual World::PMainCamera GetScreenCamera() { return nullptr; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Mechanics);
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ Transform3 Spirit::GetUprightWithLeanMatrix() const
|
|||
|
||||
float Spirit::GetMotionBlur() const
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
Scene::PMainCamera pViewCamera = sm.GetViewCamera();
|
||||
VERUS_QREF_WM;
|
||||
World::PMainCamera pViewCamera = wm.GetViewCamera();
|
||||
return pViewCamera ? pViewCamera->ComputeMotionBlur(_smoothPosition, _smoothPrevPosition) : 1;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ void EngineInit::Make()
|
|||
Make_Effects();
|
||||
if (_makeExtra)
|
||||
Make_Extra();
|
||||
if (_makeScene)
|
||||
Make_Scene();
|
||||
if (_makeWorld)
|
||||
Make_World();
|
||||
if (_makeGUI)
|
||||
Make_GUI();
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ void EngineInit::Free()
|
|||
// Some object must outlive others, so the order is important:
|
||||
if (_makeGUI)
|
||||
Free_GUI();
|
||||
if (_makeScene)
|
||||
Free_Scene();
|
||||
if (_makeWorld)
|
||||
Free_World();
|
||||
if (_makeExtra)
|
||||
Free_Extra();
|
||||
if (_makeEffects)
|
||||
|
@ -79,19 +79,22 @@ void EngineInit::Init(CGI::RendererDelegate* pRendererDelegate)
|
|||
Effects::Particles::InitStatic();
|
||||
if (_makeGUI)
|
||||
GUI::Font::InitStatic();
|
||||
if (_makeScene)
|
||||
if (_makeWorld)
|
||||
{
|
||||
Scene::Mesh::InitStatic();
|
||||
Scene::Terrain::InitStatic();
|
||||
Scene::Grass::InitStatic();
|
||||
Scene::Forest::InitStatic();
|
||||
World::Mesh::InitStatic();
|
||||
World::Terrain::InitStatic();
|
||||
World::Grass::InitStatic();
|
||||
World::Forest::InitStatic();
|
||||
}
|
||||
|
||||
// Helpers:
|
||||
if (_makeCGI && _allowInitShaders)
|
||||
CGI::DebugDraw::I().Init();
|
||||
if (_makeScene)
|
||||
Scene::Helpers::I().Init();
|
||||
if (_makeWorld)
|
||||
{
|
||||
World::WorldUtils::I().Init();
|
||||
World::EditorOverlays::I().Init();
|
||||
}
|
||||
|
||||
// Effects:
|
||||
if (_makeEffects)
|
||||
|
@ -104,8 +107,8 @@ void EngineInit::Init(CGI::RendererDelegate* pRendererDelegate)
|
|||
}
|
||||
|
||||
// Materials & textures:
|
||||
if (_makeScene)
|
||||
Scene::MaterialManager::I().Init();
|
||||
if (_makeWorld)
|
||||
World::MaterialManager::I().Init();
|
||||
|
||||
if (_makeGUI)
|
||||
GUI::ViewManager::I().Init();
|
||||
|
@ -125,6 +128,6 @@ void EngineInit::ReducedFeatureSet()
|
|||
_makeGUI = false;
|
||||
_makeNet = false;
|
||||
_makePhysics = false;
|
||||
_makeScene = false;
|
||||
_makeWorld = false;
|
||||
_allowInitShaders = false;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace verus
|
|||
bool _makeIO = true;
|
||||
bool _makeNet = true;
|
||||
bool _makePhysics = true;
|
||||
bool _makeScene = true;
|
||||
bool _makeWorld = true;
|
||||
bool _allowInitShaders = true;
|
||||
|
||||
void Make();
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#define _C(x) ((x).c_str())
|
||||
|
||||
#define VERUS_MAKE_VERSION(major, minor, patch) (((major)<<24)|((minor)<<12)|(patch))
|
||||
|
||||
#define VERUS_P_FOR(i, to) Parallel::For(0, to, [&](int i)
|
||||
#define VERUS_U_FOR(i, to) for(UINT32 i = 0; i < to; ++i)
|
||||
#define VERUS_FOR(i, to) for(int i = 0; i < to; ++i)
|
||||
|
|
|
@ -3,28 +3,28 @@
|
|||
|
||||
#define VERUS_QREF_ASYNC IO::RAsync async = IO::Async::I()
|
||||
#define VERUS_QREF_ASYS Audio::RAudioSystem asys = Audio::AudioSystem::I()
|
||||
#define VERUS_QREF_ATMO Scene::RAtmosphere atmo = Scene::Atmosphere::I()
|
||||
#define VERUS_QREF_ATMO World::RAtmosphere atmo = World::Atmosphere::I()
|
||||
#define VERUS_QREF_BLOOM Effects::RBloom bloom = Effects::Bloom::I()
|
||||
#define VERUS_QREF_BLUR Effects::RBlur blur = Effects::Blur::I()
|
||||
#define VERUS_QREF_BULLET Physics::RBullet bullet = Physics::Bullet::I()
|
||||
#define VERUS_QREF_CINEMA Effects::RCinema cinema = Effects::Cinema::I()
|
||||
#define VERUS_QREF_CONST_SETTINGS App::RcSettings settings = App::Settings::IConst()
|
||||
#define VERUS_QREF_DD CGI::RDebugDraw dd = CGI::DebugDraw::I()
|
||||
#define VERUS_QREF_EO World::REditorOverlays eo = World::EditorOverlays::I()
|
||||
#define VERUS_QREF_FSYS IO::RFileSystem fsys = IO::FileSystem::I()
|
||||
#define VERUS_QREF_GRASS Scene::RGrass grass = Scene::Grass::I()
|
||||
#define VERUS_QREF_HELPERS Scene::RHelpers helpers = Scene::Helpers::I()
|
||||
#define VERUS_QREF_GRASS World::RGrass grass = World::Grass::I()
|
||||
#define VERUS_QREF_IM Input::RInputManager im = Input::InputManager::I()
|
||||
#define VERUS_QREF_LMB Scene::RLightMapBaker lmb = Scene::LightMapBaker::I()
|
||||
#define VERUS_QREF_MM Scene::RMaterialManager mm = Scene::MaterialManager::I()
|
||||
#define VERUS_QREF_LMB World::RLightMapBaker lmb = World::LightMapBaker::I()
|
||||
#define VERUS_QREF_MM World::RMaterialManager mm = World::MaterialManager::I()
|
||||
#define VERUS_QREF_MP Net::RMultiplayer mp = Net::Multiplayer::I()
|
||||
#define VERUS_QREF_PHYSICS Physics::RPhysics physics = Physics::Physics::I()
|
||||
#define VERUS_QREF_RENDERER CGI::RRenderer renderer = CGI::Renderer::I()
|
||||
#define VERUS_QREF_SETTINGS App::RSettings settings = App::Settings::I()
|
||||
#define VERUS_QREF_SM Scene::RSceneManager sm = Scene::SceneManager::I()
|
||||
#define VERUS_QREF_SSAO Effects::RSsao ssao = Effects::Ssao::I()
|
||||
#define VERUS_QREF_SSR Effects::RSsr ssr = Effects::Ssr::I()
|
||||
#define VERUS_QREF_TIMER RTimer timer = Timer::I(); const float dt = timer.GetDeltaTime()
|
||||
#define VERUS_QREF_TIMER_GUI RTimer timer = Timer::I(); const float dt = timer.GetDeltaTime(Timer::Type::gui)
|
||||
#define VERUS_QREF_UTILS RUtils utils = Utils::I()
|
||||
#define VERUS_QREF_VM GUI::RViewManager vm = GUI::ViewManager::I()
|
||||
#define VERUS_QREF_WATER Scene::RWater water = Scene::Water::I()
|
||||
#define VERUS_QREF_WATER World::RWater water = World::Water::I()
|
||||
#define VERUS_QREF_WM World::RWorldManager wm = World::WorldManager::I()
|
||||
#define VERUS_QREF_WU World::RWorldUtils wu = World::WorldUtils::I()
|
||||
|
|
|
@ -113,14 +113,18 @@ namespace verus
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void Delete(const TKey& key)
|
||||
bool Delete(const TKey& key)
|
||||
{
|
||||
VERUS_IF_FOUND_IN(TMap, _map, key, it)
|
||||
{
|
||||
if (it->second.Done())
|
||||
{
|
||||
_map.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeleteAll()
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace verus
|
|||
|
||||
bool operator==(const Str& that) const { return !strcmp(_sz, that._sz); }
|
||||
bool operator!=(const Str& that) const { return 0 != strcmp(_sz, that._sz); }
|
||||
bool operator<(const Str& that) const { return strcmp(_sz, that._sz) < 0; }
|
||||
|
||||
size_t Size() const { return strlen(_sz) + 1; }
|
||||
size_t Length() const { return strlen(_sz); }
|
||||
|
|
|
@ -407,7 +407,7 @@ bool FileSystem::FileExist(CSZ url)
|
|||
File file;
|
||||
if (file.Open(_C(pathname))) // Normal filename:
|
||||
return true;
|
||||
if (file.Open(_C(pakPathname))) // PAK filename:
|
||||
if (file.Open(_C(pakPathname))) // PAK filename (don't check contents, just assume that it's there):
|
||||
return true;
|
||||
if (file.Open(_C(projectPathname))) // File in another project dir:
|
||||
return true;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "Json.h"
|
||||
#include "Xml.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Xxx.h"
|
||||
#include "Vwx.h"
|
||||
|
||||
namespace verus
|
||||
{
|
||||
|
|
147
Verus/src/IO/Vwx.cpp
Normal file
147
Verus/src/IO/Vwx.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::IO;
|
||||
|
||||
Vwx::Vwx()
|
||||
{
|
||||
}
|
||||
|
||||
Vwx::~Vwx()
|
||||
{
|
||||
Async::I().Cancel(this);
|
||||
}
|
||||
|
||||
void Vwx::Async_WhenLoaded(CSZ url, RcBlob blob)
|
||||
{
|
||||
if (Str::EndsWith(url, ".xxx", false))
|
||||
{
|
||||
Deserialize_LegacyXXX(url, blob);
|
||||
return;
|
||||
}
|
||||
|
||||
VERUS_QREF_WM;
|
||||
|
||||
IO::StreamPtr sp(blob);
|
||||
|
||||
UINT32 temp;
|
||||
UINT32 blockType = 0;
|
||||
INT64 blockSize = 0;
|
||||
char buffer[IO::Stream::s_bufferSize] = {};
|
||||
|
||||
sp.Read(buffer, 5);
|
||||
VERUS_RT_ASSERT(!strcmp(buffer, "<VWX>"));
|
||||
sp >> temp;
|
||||
sp >> temp;
|
||||
sp.ReadString(buffer);
|
||||
VERUS_RT_ASSERT(!strcmp(buffer, "1.0.0"));
|
||||
UINT32 verMajor = 0, verMinor = 0, verPatch = 0;
|
||||
sscanf(buffer, "%d.%d.%d", &verMajor, &verMinor, &verPatch);
|
||||
sp.SetVersion(VERUS_MAKE_VERSION(verMajor, verMinor, verPatch));
|
||||
|
||||
while (!sp.IsEnd())
|
||||
{
|
||||
sp >> temp;
|
||||
sp >> blockType;
|
||||
sp >> blockSize;
|
||||
switch (blockType)
|
||||
{
|
||||
case '>MW<':
|
||||
{
|
||||
wm.Deserialize(sp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
sp.Advance(blockSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Vwx::Serialize(CSZ url)
|
||||
{
|
||||
File file;
|
||||
if (!file.Open(url, "wb"))
|
||||
return;
|
||||
|
||||
VERUS_QREF_WM;
|
||||
|
||||
file.WriteText("<VWX>");
|
||||
|
||||
file.WriteText(VERUS_CRNL VERUS_CRNL "<VN>");
|
||||
file.WriteString("1.0.0");
|
||||
|
||||
wm.Serialize(file);
|
||||
}
|
||||
|
||||
void Vwx::Deserialize(CSZ url, bool sync)
|
||||
{
|
||||
if (sync)
|
||||
{
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::LoadResource(url, vData);
|
||||
Async_WhenLoaded(url, Blob(vData.data(), vData.size()));
|
||||
}
|
||||
else
|
||||
Async::I().Load(url, this);
|
||||
}
|
||||
|
||||
void Vwx::Deserialize_LegacyXXX(CSZ url, RcBlob blob)
|
||||
{
|
||||
VERUS_QREF_WM;
|
||||
|
||||
IO::StreamPtr sp(blob);
|
||||
|
||||
UINT32 temp;
|
||||
UINT32 blockType = 0;
|
||||
INT64 blockSize = 0;
|
||||
char buffer[IO::Stream::s_bufferSize] = {};
|
||||
|
||||
sp.Read(buffer, 5);
|
||||
VERUS_RT_ASSERT(!strcmp(buffer, "<XXX>"));
|
||||
sp >> temp;
|
||||
sp >> temp;
|
||||
sp.ReadString(buffer);
|
||||
VERUS_RT_ASSERT(!strcmp(buffer, "3.0"));
|
||||
UINT32 verMajor = 0, verMinor = 0;
|
||||
sscanf(buffer, "%d.%d", &verMajor, &verMinor);
|
||||
sp.SetVersion(VERUS_MAKE_VERSION(1, 0, 0));
|
||||
|
||||
Vector<BYTE> vTerrain;
|
||||
while (!sp.IsEnd())
|
||||
{
|
||||
sp >> temp;
|
||||
sp >> blockType;
|
||||
sp >> blockSize;
|
||||
switch (blockType)
|
||||
{
|
||||
case '>RT<':
|
||||
{
|
||||
vTerrain.resize(blockSize);
|
||||
sp.Read(vTerrain.data(), blockSize);
|
||||
}
|
||||
break;
|
||||
case '>MS<':
|
||||
{
|
||||
wm.Deserialize_LegacyXXX(sp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
sp.Advance(blockSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vTerrain.empty() && wm.IsInitialized())
|
||||
{
|
||||
IO::StreamPtr sp(Blob(vTerrain.data(), vTerrain.size()));
|
||||
World::TerrainNode::Desc desc;
|
||||
desc._terrainDesc._mapSide = 0;
|
||||
World::TerrainNodePtr terrainNode;
|
||||
terrainNode.Init(desc);
|
||||
terrainNode->GetTerrain().Deserialize(sp);
|
||||
}
|
||||
}
|
22
Verus/src/IO/Vwx.h
Normal file
22
Verus/src/IO/Vwx.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace IO
|
||||
{
|
||||
class Vwx : public AsyncDelegate
|
||||
{
|
||||
public:
|
||||
Vwx();
|
||||
~Vwx();
|
||||
|
||||
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
|
||||
|
||||
void Serialize(CSZ url);
|
||||
void Deserialize(CSZ url, bool sync);
|
||||
|
||||
void Deserialize_LegacyXXX(CSZ url, RcBlob blob);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::IO;
|
||||
|
||||
void Xxx::Serialize(CSZ path)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_MM;
|
||||
|
||||
File file;
|
||||
if (!file.Open(path, "wb"))
|
||||
return;
|
||||
const UINT32 magic = '2XXX';
|
||||
file << magic;
|
||||
const UINT16 version = 0x0105;
|
||||
file << version;
|
||||
|
||||
mm.Serialize(file);
|
||||
sm.Serialize(file);
|
||||
}
|
||||
|
||||
void Xxx::Deserialize(CSZ path, RString error, bool keepExisting)
|
||||
{
|
||||
#if 0
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_MM;
|
||||
|
||||
if (!IO::CFileSys::FileExist(path))
|
||||
{
|
||||
error = "File not found.";
|
||||
return;
|
||||
}
|
||||
CVector<BYTE> vData;
|
||||
IO::CFileSys::LoadResource(path, vData);
|
||||
if (vData.size() < 4)
|
||||
{
|
||||
error = "Invalid file size.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (CStr::EndsWith(path, ".xml", false))
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.Parse(reinterpret_cast<CSZ>(&vData.front()));
|
||||
if (doc.Error())
|
||||
{
|
||||
error = "Invalid XML.";
|
||||
return;
|
||||
}
|
||||
|
||||
tinyxml2::XMLHandle hDoc(&doc);
|
||||
tinyxml2::XMLHandle hRoot = hDoc.FirstChildElement();
|
||||
|
||||
// Restart material manager:
|
||||
if (!keepExisting)
|
||||
{
|
||||
mm.Done();
|
||||
mm.Init();
|
||||
}
|
||||
|
||||
CString levelName = strrchr(path, '\\') + 1;
|
||||
levelName = levelName.substr(0, levelName.length() - 4);
|
||||
|
||||
tinyxml2::XMLElement* pElemPath = hRoot.FirstChildElement("path").ToElement();
|
||||
if (pElemPath && pElemPath->GetText())
|
||||
levelName = pElemPath->GetText();
|
||||
|
||||
CStringStream ssMissingTextures;
|
||||
for (tinyxml2::XMLElement* pElem = hRoot.FirstChildElement("material").ToElement(); pElem; pElem = pElem->NextSiblingElement("material"))
|
||||
{
|
||||
CSZ name = pElem->GetText();
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
CString nameEx = strchr(name, '\\') ? CStr::FixCyrillicX(name, false) : name;
|
||||
CString nameEx2 = strchr(name, '\\') ? CStr::FixCyrillicX(name, true) : name;
|
||||
|
||||
CString textureUrl = CString("Textures:") + levelName + "/" + nameEx;
|
||||
textureUrl = textureUrl.substr(0, textureUrl.length() - 4) + ".dds";
|
||||
|
||||
if (!IO::CFileSys::FileExist(textureUrl.c_str()))
|
||||
{
|
||||
ssMissingTextures << textureUrl << VERUS_CRNL;
|
||||
textureUrl = CString("Textures:") + levelName + "/" + nameEx2;
|
||||
textureUrl = textureUrl.substr(0, textureUrl.length() - 4) + ".dds";
|
||||
}
|
||||
|
||||
if (IO::CFileSys::FileExist(textureUrl.c_str()))
|
||||
{
|
||||
Scene::PMaterial pMat = new Scene::CMaterial(pElem->Attribute("name"));
|
||||
pMat->m_texAlbedoID = mm.Texture_Add(textureUrl.c_str());
|
||||
pMat->m_colorDiffuse.FromString4(pElem->Attribute("faceColor"));
|
||||
pMat->m_colorSpec.FromString3(pElem->Attribute("specularColor"));
|
||||
pMat->m_colorEmission.FromString3(pElem->Attribute("emissiveColor"));
|
||||
pElem->QueryFloatAttribute("power", &pMat->m_specPower);
|
||||
mm.Material_Add(pMat, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssMissingTextures << textureUrl << VERUS_CRNL;
|
||||
}
|
||||
}
|
||||
if (!ssMissingTextures.str().empty())
|
||||
{
|
||||
IO::CFileSys::SaveString(IO::CFileSys::ReplaceFilename(path, "MissingTextures.txt").c_str(), ssMissingTextures.str().c_str());
|
||||
}
|
||||
|
||||
if (!keepExisting)
|
||||
sm.DeleteAll();
|
||||
|
||||
CStringStream ssMissingObjects;
|
||||
for (tinyxml2::XMLElement* pElem = hRoot.FirstChildElement("object").ToElement(); pElem; pElem = pElem->NextSiblingElement("object"))
|
||||
{
|
||||
CSZ name = pElem->GetText();
|
||||
if (!name)
|
||||
continue;
|
||||
CSZ copyOf = pElem->Attribute("copyOf");
|
||||
float4x4 initialMatrix;
|
||||
initialMatrix.FromString(pElem->Attribute("matrix"));
|
||||
CSZ material = pElem->Attribute("mat");
|
||||
if (copyOf && strlen(copyOf) > 0)
|
||||
{
|
||||
Scene::PUnit pu = static_cast<Scene::PUnit>(sm.GetObjectByID(sm.FindUnitID(copyOf)));
|
||||
Scene::PModel pModel = sm.FindModel(pu->GetModelID());
|
||||
|
||||
Math::CBounds modelBounds;
|
||||
modelBounds.FromOrientedBox(pModel->GetMesh().GetBounds(), initialMatrix);
|
||||
const float size = modelBounds.GetSmartSize();
|
||||
|
||||
Scene::CUnit::CInitParams ip;
|
||||
ip.m_initialMatrix = initialMatrix;
|
||||
ip.m_url = name;
|
||||
ip.m_urlModel = pu->GetModelName().c_str();
|
||||
ip.m_material = material;
|
||||
sm.AddUnit(ip);
|
||||
|
||||
pu = static_cast<Scene::PUnit>(sm.GetObjectByID(sm.FindUnitID(name)));
|
||||
|
||||
if (size > 20)
|
||||
{
|
||||
char scale[16];
|
||||
sprintf_s(scale, "%g", 20 / size);
|
||||
pu->GetParamList().Add("$LM_SCALE", scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CString modelUrl = CString("Geometry:") + levelName + "/" + name + ".x3d";
|
||||
if (IO::CFileSys::FileExist(modelUrl.c_str()))
|
||||
{
|
||||
sm.InsertModel(modelUrl.c_str(), false, material);
|
||||
Scene::PModel pModel = sm.FindModel(sm.FindModelID(modelUrl.c_str()));
|
||||
|
||||
Math::CBounds modelBounds;
|
||||
modelBounds.FromOrientedBox(pModel->GetMesh().GetBounds(), initialMatrix);
|
||||
const float size = modelBounds.GetSmartSize();
|
||||
|
||||
Scene::CUnit::CInitParams ip;
|
||||
ip.m_initialMatrix = initialMatrix;
|
||||
ip.m_url = name;
|
||||
ip.m_urlModel = modelUrl.c_str();
|
||||
ip.m_material = material;
|
||||
sm.AddUnit(ip);
|
||||
|
||||
Scene::PUnit pu = static_cast<Scene::PUnit>(sm.GetObjectByID(sm.FindUnitID(name)));
|
||||
|
||||
if (size > 20)
|
||||
{
|
||||
char scale[16];
|
||||
sprintf_s(scale, "%g", 20 / size);
|
||||
pu->GetParamList().Add("$LM_SCALE", scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ssMissingObjects << modelUrl << VERUS_CRNL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ssMissingObjects.str().empty())
|
||||
{
|
||||
IO::CFileSys::SaveString(IO::CFileSys::ReplaceFilename(path, "MissingObjects.txt").c_str(), ssMissingObjects.str().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IO::StreamPtr sp(&vData.front(), vData.size());
|
||||
UINT32 magic = 0;
|
||||
sp >> magic;
|
||||
if (magic != '2XXX')
|
||||
{
|
||||
error = "File format is not XXX2.";
|
||||
return;
|
||||
}
|
||||
UINT16 version = 0;
|
||||
sp >> version;
|
||||
if (version != 0x0105)
|
||||
{
|
||||
CStringStream ss;
|
||||
ss << "Invalid file version (0x" << std::hex << version << ").";
|
||||
error = ss.str();
|
||||
return;
|
||||
}
|
||||
UINT16 chunkID = 0;
|
||||
int blockSize, blockBegin, blockEnd;
|
||||
while (sp.GetOffset() < sp.GetSize())
|
||||
{
|
||||
sp >> chunkID;
|
||||
sp >> blockSize;
|
||||
blockBegin = sp.GetOffset();
|
||||
switch (chunkID)
|
||||
{
|
||||
case VERUS_XXX_MATERIALMANAGER:
|
||||
mm.Deserialize(sp);
|
||||
break;
|
||||
case VERUS_XXX_LANDSCAPE:
|
||||
break;
|
||||
case VERUS_XXX_SCENEMANAGER:
|
||||
sm.Deserialize(sp);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
sp.Advance(blockSize);
|
||||
}
|
||||
}
|
||||
blockEnd = sp.GetOffset();
|
||||
if (blockEnd - blockBegin != blockSize)
|
||||
{
|
||||
error = "File is corrupted.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Xxx::Xxx(Scene::Terrain* pTerrain) :
|
||||
_pTerrain(pTerrain)
|
||||
{
|
||||
}
|
||||
|
||||
Xxx::~Xxx()
|
||||
{
|
||||
Async::I().Cancel(this);
|
||||
}
|
||||
|
||||
void Xxx::Async_WhenLoaded(CSZ url, RcBlob blob)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
|
||||
IO::StreamPtr sp(blob);
|
||||
|
||||
UINT32 temp;
|
||||
UINT32 blockType = 0;
|
||||
INT64 blockSize = 0;
|
||||
char buffer[IO::Stream::s_bufferSize] = {};
|
||||
sp.Read(buffer, 5);
|
||||
sp >> temp;
|
||||
sp >> temp;
|
||||
sp.ReadString(buffer);
|
||||
VERUS_RT_ASSERT(!strcmp(buffer, "3.0"));
|
||||
UINT32 verMajor = 0, verMinor = 0;
|
||||
sscanf(buffer, "%d.%d", &verMajor, &verMinor);
|
||||
sp.SetVersion(MakeVersion(verMajor, verMinor));
|
||||
|
||||
while (!sp.IsEnd())
|
||||
{
|
||||
sp >> temp;
|
||||
sp >> blockType;
|
||||
sp >> blockSize;
|
||||
switch (blockType)
|
||||
{
|
||||
case '>RT<':
|
||||
{
|
||||
if (_pTerrain)
|
||||
_pTerrain->Deserialize(sp);
|
||||
else
|
||||
sp.Advance(blockSize);
|
||||
}
|
||||
break;
|
||||
case '>MS<':
|
||||
{
|
||||
sm.Deserialize(sp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
sp.Advance(blockSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Xxx::SerializeXXX3(CSZ url)
|
||||
{
|
||||
File file;
|
||||
if (!file.Open(url, "wb"))
|
||||
return;
|
||||
|
||||
VERUS_QREF_SM;
|
||||
|
||||
file.WriteText("<XXX>");
|
||||
|
||||
file.WriteText(VERUS_CRNL VERUS_CRNL "<VN>");
|
||||
file.WriteString("3.0");
|
||||
|
||||
if (_pTerrain)
|
||||
_pTerrain->Serialize(file);
|
||||
|
||||
sm.Serialize(file);
|
||||
}
|
||||
|
||||
void Xxx::DeserializeXXX3(CSZ url, bool sync)
|
||||
{
|
||||
if (sync)
|
||||
{
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::LoadResource(url, vData);
|
||||
Async_WhenLoaded(url, Blob(vData.data(), vData.size()));
|
||||
}
|
||||
else
|
||||
Async::I().Load(url, this);
|
||||
}
|
||||
|
||||
UINT32 Xxx::MakeVersion(UINT32 verMajor, UINT32 verMinor)
|
||||
{
|
||||
return (verMajor << 16) | (verMinor & 0xFFFF);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Terrain;
|
||||
}
|
||||
}
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace IO
|
||||
{
|
||||
class Xxx : public AsyncDelegate
|
||||
{
|
||||
Scene::Terrain* _pTerrain = nullptr;
|
||||
|
||||
public:
|
||||
static void Serialize(CSZ path);
|
||||
static void Deserialize(CSZ path, RString error, bool keepExisting = false);
|
||||
|
||||
Xxx(Scene::Terrain* pTerrain = nullptr);
|
||||
~Xxx();
|
||||
|
||||
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
|
||||
|
||||
void SerializeXXX3(CSZ url);
|
||||
void DeserializeXXX3(CSZ url, bool sync);
|
||||
|
||||
static UINT32 MakeVersion(UINT32 verMajor, UINT32 verMinor);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -194,6 +194,11 @@ Transform3 Bounds::GetDrawTransform() const
|
|||
return Math::BoundsDrawMatrix(_min, _max);
|
||||
}
|
||||
|
||||
Transform3 Bounds::GetBoxTransform() const
|
||||
{
|
||||
return Math::BoundsBoxMatrix(_min, _max);
|
||||
}
|
||||
|
||||
RBounds Bounds::MirrorY()
|
||||
{
|
||||
const float miny = _min.getY();
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace verus
|
|||
Sphere GetSphere() const;
|
||||
Matrix4 GetMatrix() const;
|
||||
Transform3 GetDrawTransform() const;
|
||||
Transform3 GetBoxTransform() const;
|
||||
|
||||
Bounds& MirrorY();
|
||||
Bounds& Wrap();
|
||||
|
|
|
@ -130,27 +130,15 @@ void Frustum::Draw()
|
|||
dd.End();
|
||||
}
|
||||
|
||||
Vector4 Frustum::GetBounds(RcMatrix4 m, float& zNear, float& zFar) const
|
||||
Bounds Frustum::GetBounds(RcTransform3 tr, PPoint3 pFocusedCenterPos) const
|
||||
{
|
||||
Vector4 ret(
|
||||
+FLT_MAX,
|
||||
+FLT_MAX,
|
||||
-FLT_MAX,
|
||||
-FLT_MAX);
|
||||
zNear = -FLT_MAX;
|
||||
zFar = FLT_MAX;
|
||||
Bounds ret;
|
||||
VERUS_FOR(i, 8)
|
||||
ret.Include(tr * _corners[i]);
|
||||
if (pFocusedCenterPos)
|
||||
{
|
||||
const Vector4 matSpace = m * _corners[i];
|
||||
ret = Vector4(
|
||||
Math::Min<float>(ret.getX(), matSpace.getX()),
|
||||
Math::Min<float>(ret.getY(), matSpace.getY()),
|
||||
Math::Max<float>(ret.getZ(), matSpace.getX()),
|
||||
Math::Max<float>(ret.getW(), matSpace.getY()));
|
||||
|
||||
// In RH-system closer objects have larger z values!
|
||||
zNear = Math::Max<float>(zNear, matSpace.getZ());
|
||||
zFar = Math::Min<float>(zFar, matSpace.getZ());
|
||||
*pFocusedCenterPos = ret.GetCenter();
|
||||
pFocusedCenterPos->setZ((tr * _corners[8]).getZ());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace verus
|
|||
RcPoint3 GetZNearPosition() const { return _corners[8]; }
|
||||
RcPoint3 GetZFarPosition() const { return _corners[9]; }
|
||||
|
||||
Vector4 GetBounds(RcMatrix4 m, float& zNear, float& zFar) const;
|
||||
Bounds GetBounds(RcTransform3 tr, PPoint3 pFocusedCenterPos = nullptr) const;
|
||||
|
||||
Frustum& SetNearPlane(RcPoint3 eye, RcVector3 front, float zNear);
|
||||
Frustum& SetFarPlane(RcPoint3 eye, RcVector3 front, float zFar);
|
||||
|
|
|
@ -379,6 +379,13 @@ Transform3 Math::BoundsDrawMatrix(RcPoint3 mn, RcPoint3 mx)
|
|||
return VMath::appendScale(Transform3::translation(c - Point3(0, d.getY() * 0.5f, 0)), d);
|
||||
}
|
||||
|
||||
Transform3 Math::BoundsBoxMatrix(RcPoint3 mn, RcPoint3 mx)
|
||||
{
|
||||
const Vector3 d = mx - mn;
|
||||
const Vector3 c = VMath::lerp(0.5f, mn, mx);
|
||||
return VMath::appendScale(Transform3::translation(c), d);
|
||||
}
|
||||
|
||||
float Math::ComputeOnePixelDistance(float objectSize, float viewportHeightInPixels, float fovY)
|
||||
{
|
||||
// Assume that object occupies one pixel, then the whole viewport height will be:
|
||||
|
@ -474,6 +481,20 @@ float Math::Reduce(float val, float reduction)
|
|||
return val - glm::sign(val) * reduction;
|
||||
}
|
||||
|
||||
Point3 Math::ClosestPointOnSegment(RcPoint3 segA, RcPoint3 segB, RcPoint3 point)
|
||||
{
|
||||
const float lenSq = VMath::distSqr(segA, segB);
|
||||
if (lenSq < VERUS_FLOAT_THRESHOLD)
|
||||
return segA;
|
||||
const float t = Math::Clamp<float>(VMath::dot(point - segA, segB - segA) / lenSq, 0, 1);
|
||||
return VMath::lerp(t, segA, segB);
|
||||
}
|
||||
|
||||
float Math::SegmentToPointDistance(RcPoint3 segA, RcPoint3 segB, RcPoint3 point)
|
||||
{
|
||||
return VMath::dist(point, ClosestPointOnSegment(segA, segB, point));
|
||||
}
|
||||
|
||||
void Math::Test()
|
||||
{
|
||||
const float e = 1e-6f;
|
||||
|
@ -655,11 +676,11 @@ void Math::Test()
|
|||
}
|
||||
|
||||
{
|
||||
//const Point3 a(1, 0, 0), b(3, 0, 0), p(1.25f, 3, 0), p2(10, 10, 0);
|
||||
//Point3 res = ClosestPointOnLineSegment(a, b, p);
|
||||
//VERUS_RT_ASSERT(glm::all(glm::epsilonEqual(res.GLM(), glm::vec3(1.25f, 0, 0), eps)));
|
||||
//Point3 res2 = ClosestPointOnLineSegment(a, b, p2);
|
||||
//VERUS_RT_ASSERT(glm::all(glm::epsilonEqual(res2.GLM(), glm::vec3(3, 0, 0), eps)));
|
||||
const Point3 a(1, 0, 0), b(3, 0, 0), p(1.25f, 3, 0), p2(10, 10, 0);
|
||||
Point3 res = ClosestPointOnSegment(a, b, p);
|
||||
VERUS_RT_ASSERT(glm::all(glm::epsilonEqual(res.GLM(), glm::vec3(1.25f, 0, 0), eps)));
|
||||
Point3 res2 = ClosestPointOnSegment(a, b, p2);
|
||||
VERUS_RT_ASSERT(glm::all(glm::epsilonEqual(res2.GLM(), glm::vec3(3, 0, 0), eps)));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -693,7 +714,7 @@ void Math::Test()
|
|||
|
||||
{
|
||||
// Right-handed mode (default):
|
||||
Scene::Camera camera;
|
||||
World::Camera camera;
|
||||
camera.MoveEyeTo(Point3(0, 0, 3));
|
||||
camera.MoveAtTo(Point3(0, 0, 4));
|
||||
camera.SetYFov(VERUS_PI * 0.25f);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define VERUS_E 2.718281828f
|
||||
#define VERUS_GR 1.618034f
|
||||
|
||||
#define VERUS_HERMITE_CIRCLE ((0.707107f-0.5f)*8.f)
|
||||
|
||||
#define VERUS_FLOAT_THRESHOLD 1e-4f
|
||||
|
||||
namespace verus
|
||||
|
@ -151,6 +153,7 @@ namespace verus
|
|||
|
||||
// Scene:
|
||||
Transform3 BoundsDrawMatrix(RcPoint3 mn, RcPoint3 mx);
|
||||
Transform3 BoundsBoxMatrix(RcPoint3 mn, RcPoint3 mx);
|
||||
float ComputeOnePixelDistance(float objectSize, float viewportHeightInPixels = 135, float fovY = VERUS_PI / 4);
|
||||
float ComputeDistToMipScale(float texHeight, float viewportHeightInPixels, float objectSize, float fovY);
|
||||
void Quadrant(const int** ppSrcMinMax, int** ppDestMinMax, int half, int id);
|
||||
|
@ -165,6 +168,9 @@ namespace verus
|
|||
|
||||
float Reduce(float val, float reduction);
|
||||
|
||||
Point3 ClosestPointOnSegment(RcPoint3 segA, RcPoint3 segB, RcPoint3 point);
|
||||
float SegmentToPointDistance(RcPoint3 segA, RcPoint3 segB, RcPoint3 point);
|
||||
|
||||
void Test();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ Continue Octree::TraverseVisible(RcFrustum frustum, PResult pResult, int current
|
|||
pResult->_testCount = 0;
|
||||
pResult->_passedTestCount = 0;
|
||||
pResult->_pLastFoundToken = nullptr;
|
||||
pResult->_depth = Scene::SceneManager::IsDrawingDepth(Scene::DrawDepth::automatic);
|
||||
pResult->_depth = World::WorldManager::IsDrawingDepth(World::DrawDepth::automatic);
|
||||
}
|
||||
|
||||
pResult->_testCount++;
|
||||
|
|
|
@ -153,7 +153,7 @@ void QuadtreeIntegral::InitNodes(int currentNode, int depth)
|
|||
|
||||
void QuadtreeIntegral::TraverseVisible(int currentNode, int depth)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
|
||||
if (!currentNode)
|
||||
{
|
||||
|
@ -166,7 +166,7 @@ void QuadtreeIntegral::TraverseVisible(int currentNode, int depth)
|
|||
bool testFrustum = true;
|
||||
if (_distCoarseMode && depth + 2 >= _maxDepth)
|
||||
{
|
||||
RcPoint3 headPos = sm.GetHeadCamera()->GetEyePosition();
|
||||
RcPoint3 headPos = wm.GetHeadCamera()->GetEyePosition();
|
||||
RcPoint3 nodePos = _vNodes[currentNode].GetSphere().GetCenter();
|
||||
const float distSq = VMath::distSqr(headPos, nodePos);
|
||||
if (_maxDepth == depth && distSq >= 500 * 500.f)
|
||||
|
@ -177,7 +177,7 @@ void QuadtreeIntegral::TraverseVisible(int currentNode, int depth)
|
|||
testFrustum = false;
|
||||
}
|
||||
|
||||
RFrustum frustum = sm.GetPassCamera()->GetFrustum();
|
||||
RFrustum frustum = wm.GetPassCamera()->GetFrustum();
|
||||
if (testFrustum && Relation::outside == frustum.ContainsAabb(_vNodes[currentNode].GetBounds()))
|
||||
return;
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@ btRigidBody* Bullet::AddNewRigidBody(
|
|||
float mass,
|
||||
const btTransform& startTransform,
|
||||
btCollisionShape* pShape,
|
||||
Group group,
|
||||
Group mask,
|
||||
int group,
|
||||
int mask,
|
||||
const btTransform* pCenterOfMassOffset,
|
||||
void* pPlacementMotionState,
|
||||
void* pPlacementRigidBody)
|
||||
|
@ -82,16 +82,12 @@ btRigidBody* Bullet::AddNewRigidBody(
|
|||
else
|
||||
pMotionState = new btDefaultMotionState(startTransform, pCenterOfMassOffset ? *pCenterOfMassOffset : btTransform::getIdentity());
|
||||
btRigidBody::btRigidBodyConstructionInfo rbci(mass, pMotionState, pShape, localInertia);
|
||||
rbci.m_linearDamping = 0.01f;
|
||||
rbci.m_angularDamping = 0.01f;
|
||||
rbci.m_rollingFriction = 0.001f;
|
||||
rbci.m_spinningFriction = 0.001f;
|
||||
btRigidBody* pRigidBody = nullptr;
|
||||
if (pPlacementRigidBody)
|
||||
pRigidBody = new(pPlacementRigidBody) btRigidBody(rbci);
|
||||
else
|
||||
pRigidBody = new btRigidBody(rbci);
|
||||
_pDiscreteDynamicsWorld->addRigidBody(pRigidBody, +group, +mask);
|
||||
_pDiscreteDynamicsWorld->addRigidBody(pRigidBody, group, mask);
|
||||
|
||||
return pRigidBody;
|
||||
}
|
||||
|
@ -101,8 +97,8 @@ btRigidBody* Bullet::AddNewRigidBody(
|
|||
float mass,
|
||||
const btTransform& startTransform,
|
||||
btCollisionShape* pShape,
|
||||
Group group,
|
||||
Group mask,
|
||||
int group,
|
||||
int mask,
|
||||
const btTransform* pCenterOfMassOffset)
|
||||
{
|
||||
btAssert(!pShape || pShape->getShapeType() != INVALID_SHAPE_PROXYTYPE);
|
||||
|
@ -116,12 +112,8 @@ btRigidBody* Bullet::AddNewRigidBody(
|
|||
btDefaultMotionState* pMotionState = new(localRigidBody.GetDefaultMotionStateData())
|
||||
btDefaultMotionState(startTransform, pCenterOfMassOffset ? *pCenterOfMassOffset : btTransform::getIdentity());
|
||||
btRigidBody::btRigidBodyConstructionInfo rbci(mass, pMotionState, pShape, localInertia);
|
||||
rbci.m_linearDamping = 0.01f;
|
||||
rbci.m_angularDamping = 0.01f;
|
||||
rbci.m_rollingFriction = 0.001f;
|
||||
rbci.m_spinningFriction = 0.001f;
|
||||
btRigidBody* pRigidBody = new(localRigidBody.GetRigidBodyData()) btRigidBody(rbci);
|
||||
_pDiscreteDynamicsWorld->addRigidBody(pRigidBody, +group, +mask);
|
||||
_pDiscreteDynamicsWorld->addRigidBody(pRigidBody, group, mask);
|
||||
|
||||
return pRigidBody;
|
||||
}
|
||||
|
@ -134,9 +126,9 @@ void Bullet::DeleteAllCollisionObjects()
|
|||
for (int i = _pDiscreteDynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i)
|
||||
{
|
||||
btCollisionObject* pObject = _pDiscreteDynamicsWorld->getCollisionObjectArray()[i];
|
||||
btRigidBody* pBody = btRigidBody::upcast(pObject);
|
||||
if (pBody && pBody->getMotionState())
|
||||
delete pBody->getMotionState();
|
||||
btRigidBody* pRigidBody = btRigidBody::upcast(pObject);
|
||||
if (pRigidBody && pRigidBody->getMotionState())
|
||||
delete pRigidBody->getMotionState();
|
||||
_pDiscreteDynamicsWorld->removeCollisionObject(pObject);
|
||||
delete pObject;
|
||||
}
|
||||
|
@ -196,7 +188,7 @@ void Bullet::EnableDebugPlane(bool b)
|
|||
{
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
_pStaticPlaneRigidBody = AddNewRigidBody(_pStaticPlaneRigidBody, 0, tr, _pStaticPlaneShape.Get(), Group::sceneBounds);
|
||||
_pStaticPlaneRigidBody = AddNewRigidBody(_pStaticPlaneRigidBody, 0, tr, _pStaticPlaneShape.Get(), +Group::wall);
|
||||
_pStaticPlaneRigidBody->setFriction(GetFriction(Material::wood));
|
||||
_pStaticPlaneRigidBody->setRestitution(GetRestitution(Material::wood));
|
||||
}
|
||||
|
@ -242,3 +234,28 @@ float Bullet::GetRestitution(Material m)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSZ Bullet::GroupToString(int index)
|
||||
{
|
||||
CSZ text[] =
|
||||
{
|
||||
"General",
|
||||
"Immovable",
|
||||
"Kinematic",
|
||||
"Debris",
|
||||
"Sensor",
|
||||
"Character",
|
||||
"Ragdoll",
|
||||
"Ray",
|
||||
"Node",
|
||||
"Dynamic",
|
||||
"Gizmo",
|
||||
"Particle",
|
||||
"Terrain",
|
||||
"Transport",
|
||||
"Wall"
|
||||
};
|
||||
if (index >= 0 && index < VERUS_COUNT_OF(text))
|
||||
return text[index];
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ namespace verus
|
|||
rubber,
|
||||
sand,
|
||||
stone,
|
||||
wood
|
||||
wood,
|
||||
count
|
||||
};
|
||||
|
||||
enum class DebugDrawMode : int
|
||||
|
@ -78,6 +79,7 @@ namespace verus
|
|||
LocalRigidBody _pStaticPlaneRigidBody;
|
||||
btGhostPairCallback _ghostPairCallback;
|
||||
BulletDebugDraw _debugDraw;
|
||||
Group _mainMask = Group::immovable | Group::terrain;
|
||||
bool _pauseSimulation = false;
|
||||
|
||||
public:
|
||||
|
@ -93,8 +95,8 @@ namespace verus
|
|||
float mass,
|
||||
const btTransform& startTransform,
|
||||
btCollisionShape* pShape,
|
||||
Group group = Group::general,
|
||||
Group mask = Group::all,
|
||||
int group = +Group::general,
|
||||
int mask = +Group::all,
|
||||
const btTransform* pCenterOfMassOffset = nullptr,
|
||||
void* pPlacementMotionState = nullptr,
|
||||
void* pPlacementRigidBody = nullptr);
|
||||
|
@ -103,8 +105,8 @@ namespace verus
|
|||
float mass,
|
||||
const btTransform& startTransform,
|
||||
btCollisionShape* pShape,
|
||||
Group group = Group::general,
|
||||
Group mask = Group::all,
|
||||
int group = +Group::general,
|
||||
int mask = +Group::all,
|
||||
const btTransform* pCenterOfMassOffset = nullptr);
|
||||
|
||||
void DeleteAllCollisionObjects();
|
||||
|
@ -119,6 +121,11 @@ namespace verus
|
|||
|
||||
static float GetFriction(Material m);
|
||||
static float GetRestitution(Material m);
|
||||
|
||||
static CSZ GroupToString(int index);
|
||||
|
||||
Group GetMainMask() const { return _mainMask; }
|
||||
void SetMainMask(Group mask) { _mainMask = mask; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Bullet);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ using namespace verus::Physics;
|
|||
void BulletDebugDraw::drawLine(const btVector3& from, const btVector3& to,
|
||||
const btVector3& color)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
const float maxDistSq = s_maxDrawDist * s_maxDrawDist;
|
||||
const Point3 headPos = sm.GetHeadCamera()->GetEyePosition();
|
||||
const Point3 headPos = wm.GetHeadCamera()->GetEyePosition();
|
||||
if (VMath::distSqr(headPos, Point3(from)) >= maxDistSq &&
|
||||
VMath::distSqr(headPos, Point3(to)) >= maxDistSq)
|
||||
return;
|
||||
|
@ -21,9 +21,9 @@ void BulletDebugDraw::drawLine(const btVector3& from, const btVector3& to,
|
|||
void BulletDebugDraw::drawLine(const btVector3& from, const btVector3& to,
|
||||
const btVector3& fromColor, const btVector3& toColor)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_WM;
|
||||
const float maxDistSq = s_maxDrawDist * s_maxDrawDist;
|
||||
const Point3 headPos = sm.GetHeadCamera()->GetEyePosition();
|
||||
const Point3 headPos = wm.GetHeadCamera()->GetEyePosition();
|
||||
if (VMath::distSqr(headPos, Point3(from)) >= maxDistSq &&
|
||||
VMath::distSqr(headPos, Point3(to)) >= maxDistSq)
|
||||
return;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace verus
|
|||
{
|
||||
class BulletDebugDraw : public btIDebugDraw
|
||||
{
|
||||
static const int s_maxDrawDist = 30;
|
||||
static const int s_maxDrawDist = 25;
|
||||
|
||||
int _debugMode = 0;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ void CharacterController::Done()
|
|||
|
||||
int CharacterController::UserPtr_GetType()
|
||||
{
|
||||
return +Scene::NodeType::character;
|
||||
return +World::NodeType::character;
|
||||
}
|
||||
|
||||
void CharacterController::SetRadius(float r)
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace verus
|
|||
{
|
||||
namespace Physics
|
||||
{
|
||||
enum class Group : short
|
||||
enum class Group : UINT32
|
||||
{
|
||||
none = 0,
|
||||
general = (1 << 0),
|
||||
|
@ -14,13 +14,16 @@ namespace verus
|
|||
debris = (1 << 3),
|
||||
sensor = (1 << 4),
|
||||
character = (1 << 5),
|
||||
terrain = (1 << 6),
|
||||
sceneBounds = (1 << 7),
|
||||
gizmo = (1 << 8),
|
||||
pickable = (1 << 9),
|
||||
particle = (1 << 10),
|
||||
vehicle = (1 << 11),
|
||||
all = -1
|
||||
ragdoll = (1 << 6),
|
||||
ray = (1 << 7), // rayTest
|
||||
node = (1 << 8), // World::PBaseNode
|
||||
dynamic = (1 << 9),
|
||||
gizmo = (1 << 10), // Editor::PGizmoTool
|
||||
particle = (1 << 11),
|
||||
terrain = (1 << 12),
|
||||
transport = (1 << 13),
|
||||
wall = (1 << 14),
|
||||
all = UINT32_MAX
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,34 +24,42 @@ void Vehicle::Init(RcDesc desc)
|
|||
_wheelCount = leftWheelCount + rightWheelCount;
|
||||
_invWheelCount = 1.f / _wheelCount;
|
||||
|
||||
float maxHeight = -FLT_MAX;
|
||||
// <Clearance>
|
||||
float maxWheelY = -FLT_MAX;
|
||||
Vector3 averageWheelPos(0);
|
||||
VERUS_FOR(i, leftWheelCount)
|
||||
{
|
||||
averageWheelPos += Vector3(desc._vLeftWheels[i].GetCenter());
|
||||
maxHeight = Math::Max<float>(maxHeight, desc._vLeftWheels[i].GetCenter().getY());
|
||||
maxWheelY = Math::Max<float>(maxWheelY, desc._vLeftWheels[i].GetCenter().getY());
|
||||
}
|
||||
VERUS_FOR(i, rightWheelCount)
|
||||
{
|
||||
averageWheelPos += Vector3(desc._vRightWheels[i].GetCenter());
|
||||
maxHeight = Math::Max<float>(maxHeight, desc._vRightWheels[i].GetCenter().getY());
|
||||
maxWheelY = Math::Max<float>(maxWheelY, desc._vRightWheels[i].GetCenter().getY());
|
||||
}
|
||||
// </Clearance>
|
||||
averageWheelPos *= _invWheelCount;
|
||||
|
||||
Math::Bounds chassis = desc._chassis;
|
||||
chassis.Set(maxHeight - 0.05f, chassis.GetMax().getY(), 1);
|
||||
chassis.Set(maxWheelY - 0.05f, chassis.GetMax().getY(), 1); // Adjust clearance.
|
||||
chassis.Set(
|
||||
chassis.GetMin().getZ() + chassis.GetExtents().getY(),
|
||||
chassis.GetMax().getZ() - chassis.GetExtents().getY(),
|
||||
2); // Make space for bumpers.
|
||||
|
||||
const Vector3 centerOfMassOffset = chassis.GetCenter() - Vector3(0, chassis.GetExtents().getY() * 0.7f, 0);
|
||||
// Lower the center of gravity:
|
||||
const Vector3 centerOfMassOffset = chassis.GetCenter() - Vector3(0, chassis.GetExtents().getY() * 0.8f, 0);
|
||||
const Transform3 transformCoM = Transform3::translation(-centerOfMassOffset);
|
||||
const btTransform trCoM = transformCoM.Bullet();
|
||||
const float g = bullet.GetWorld()->getGravity().length();
|
||||
const float forcePerWheel = (desc._mass * g) * _invWheelCount;
|
||||
const float k = forcePerWheel / desc._suspensionRestLength; // Hooke's law.
|
||||
const float forcePerWheel = (desc._mass * g) * _invWheelCount; // Newton's law (F = m * a).
|
||||
const float k = forcePerWheel / desc._suspensionRestLength; // Hooke's law (F = k * x).
|
||||
|
||||
_vehicleTuning.m_suspensionStiffness = k / desc._mass;
|
||||
_vehicleTuning.m_suspensionStiffness = k / desc._mass; // Per 1 kg.
|
||||
_vehicleTuning.m_suspensionCompression = _vehicleTuning.m_suspensionStiffness * 0.15f;
|
||||
_vehicleTuning.m_suspensionDamping = _vehicleTuning.m_suspensionStiffness * 0.3f;
|
||||
_vehicleTuning.m_suspensionDamping = _vehicleTuning.m_suspensionStiffness * 0.2f;
|
||||
_vehicleTuning.m_maxSuspensionTravelCm = 100 * 2 * desc._suspensionRestLength;
|
||||
_vehicleTuning.m_frictionSlip = 1.75f;
|
||||
_vehicleTuning.m_frictionSlip = 1.5f;
|
||||
_vehicleTuning.m_maxSuspensionForce = forcePerWheel * 3;
|
||||
|
||||
averageWheelPos -= centerOfMassOffset;
|
||||
|
@ -59,20 +67,31 @@ void Vehicle::Init(RcDesc desc)
|
|||
if (!desc._vRightWheels.empty())
|
||||
_frontRightWheelIndex = leftWheelCount;
|
||||
|
||||
const float bumperR = chassis.GetExtents().getY();
|
||||
const float bumperH = Math::Max(VERUS_FLOAT_THRESHOLD, chassis.GetDimensions().getX() - bumperR * 2);
|
||||
|
||||
_pChassisShape = new(_pChassisShape.GetData()) btBoxShape(chassis.GetExtents().Bullet());
|
||||
_pBumperShape = new(_pBumperShape.GetData()) btCapsuleShape(bumperR, bumperH);
|
||||
_pCompoundShape = new(_pCompoundShape.GetData()) btCompoundShape();
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(chassis.GetCenter().Bullet() - centerOfMassOffset.Bullet());
|
||||
const btTransform trCoM = transformCoM.Bullet();
|
||||
_pCompoundShape->addChildShape(tr, _pChassisShape.Get());
|
||||
tr.setIdentity();
|
||||
tr.getBasis().setEulerZYX(0, 0, VERUS_PI * 0.5f);
|
||||
tr.setOrigin(chassis.GetCenter().Bullet() - centerOfMassOffset.Bullet() + btVector3(0, 0, chassis.GetExtents().getZ()));
|
||||
_pCompoundShape->addChildShape(tr, _pBumperShape.Get());
|
||||
tr.setIdentity();
|
||||
tr.getBasis().setEulerZYX(0, 0, VERUS_PI * 0.5f);
|
||||
tr.setOrigin(chassis.GetCenter().Bullet() - centerOfMassOffset.Bullet() - btVector3(0, 0, chassis.GetExtents().getZ()));
|
||||
_pCompoundShape->addChildShape(tr, _pBumperShape.Get());
|
||||
|
||||
_pChassis = bullet.AddNewRigidBody(_pChassis, desc._mass, desc._tr.Bullet(), _pCompoundShape.Get(),
|
||||
Group::vehicle, Group::all, &trCoM);
|
||||
_pChassis->setFriction(0);
|
||||
_pChassis->setRestitution(0);
|
||||
+Group::transport, +Group::all, &trCoM);
|
||||
_pChassis->setFriction(Bullet::GetFriction(Material::metal));
|
||||
_pChassis->setRestitution(Bullet::GetRestitution(Material::metal) * 0.25f); // Energy-absorbing deformation.
|
||||
_pChassis->setUserPointer(this);
|
||||
_pChassis->setActivationState(DISABLE_DEACTIVATION);
|
||||
_pChassis->setAngularFactor(btVector3(0.5f, 1, 0.5f)); // For stability.
|
||||
_pVehicleRaycaster = new(_pVehicleRaycaster.GetData()) btDefaultVehicleRaycaster(bullet.GetWorld());
|
||||
_pRaycastVehicle = new(_pRaycastVehicle.GetData()) btRaycastVehicle(_vehicleTuning, _pChassis.Get(), _pVehicleRaycaster.Get());
|
||||
_pRaycastVehicle->setCoordinateSystem(0, 1, 2);
|
||||
|
@ -90,7 +109,7 @@ void Vehicle::Init(RcDesc desc)
|
|||
btRaycastVehicle::btVehicleTuning vehicleTuning(_vehicleTuning);
|
||||
const Point3 pos = wheel.GetCenter() - centerOfMassOffset;
|
||||
const float ratio = VMath::dist(pos, Point3(averageWheelPos)) / VMath::length(Vector3(pos));
|
||||
const float scale = ratio * ratio;
|
||||
const float scale = ratio * ratio; // Try to level out the car.
|
||||
vehicleTuning.m_suspensionStiffness *= scale;
|
||||
vehicleTuning.m_suspensionCompression *= scale;
|
||||
vehicleTuning.m_suspensionDamping *= scale;
|
||||
|
@ -131,6 +150,7 @@ void Vehicle::Done()
|
|||
_pChassis.Delete();
|
||||
}
|
||||
_pCompoundShape.Delete();
|
||||
_pBumperShape.Delete();
|
||||
_pChassisShape.Delete();
|
||||
|
||||
VERUS_DONE(Vehicle);
|
||||
|
@ -138,17 +158,6 @@ void Vehicle::Done()
|
|||
|
||||
void Vehicle::Update()
|
||||
{
|
||||
const Transform3 tr = GetTransform();
|
||||
if (tr.getCol1().getY() > 0.25f)
|
||||
{
|
||||
_pChassis->setFriction(0);
|
||||
_pChassis->setRestitution(0);
|
||||
}
|
||||
else // Rollover?
|
||||
{
|
||||
_pChassis->setFriction(Bullet::GetFriction(Material::metal) * 0.5f);
|
||||
_pChassis->setRestitution(Bullet::GetRestitution(Material::metal) * 0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
Transform3 Vehicle::GetTransform() const
|
||||
|
@ -160,11 +169,11 @@ void Vehicle::ApplyAirForce(float scale)
|
|||
{
|
||||
btVector3 v = _pChassis->getLinearVelocity();
|
||||
const float speedSq = v.length2();
|
||||
if (speedSq >= 1e-4f)
|
||||
if (speedSq >= VERUS_FLOAT_THRESHOLD)
|
||||
{
|
||||
const float speed = sqrt(speedSq);
|
||||
v /= speed;
|
||||
const float force = speed * speed * scale;
|
||||
const float force = speed * speed * scale * 2;
|
||||
_pChassis->applyCentralForce(-v * force); // Drag.
|
||||
const Transform3 tr = GetTransform();
|
||||
const Vector3 down = -tr.getCol1();
|
||||
|
@ -187,7 +196,7 @@ void Vehicle::SetBrake(float brake, float handBrake, int index)
|
|||
if (_frontRightWheelIndex > 0)
|
||||
_pRaycastVehicle->setBrake(perWheel, _frontRightWheelIndex);
|
||||
}
|
||||
else
|
||||
else // All wheel drive?
|
||||
{
|
||||
const float perWheel = brake * _invWheelCount;
|
||||
VERUS_FOR(i, _wheelCount)
|
||||
|
@ -218,7 +227,7 @@ void Vehicle::SetEngineForce(float force, int index)
|
|||
if (_frontRightWheelIndex > 0)
|
||||
_pRaycastVehicle->applyEngineForce(perWheel, _frontRightWheelIndex);
|
||||
}
|
||||
else
|
||||
else // All wheel drive?
|
||||
{
|
||||
const float perWheel = force * _invWheelCount;
|
||||
VERUS_FOR(i, _wheelCount)
|
||||
|
@ -235,7 +244,7 @@ void Vehicle::SetSteeringAngle(float angle)
|
|||
|
||||
int Vehicle::UserPtr_GetType()
|
||||
{
|
||||
return +Scene::NodeType::vehicle;
|
||||
return +World::NodeType::vehicle;
|
||||
}
|
||||
|
||||
float Vehicle::ComputeEnginePitch() const
|
||||
|
@ -250,12 +259,14 @@ float Vehicle::ComputeEnginePitch() const
|
|||
}
|
||||
}
|
||||
if (!contact)
|
||||
return 1.8f;
|
||||
return 1.5f;
|
||||
|
||||
const float speedKmHourSigned = _pRaycastVehicle->getCurrentSpeedKmHour();
|
||||
const float speedKmHour = abs(speedKmHourSigned);
|
||||
const float base = 1.6f;
|
||||
const float first = base * 10;
|
||||
const float gear = (speedKmHourSigned < first) ? Math::Clamp<float>(speedKmHour / first, 0, 0.99f) : log(speedKmHour * 0.1f) / log(base);
|
||||
const float power = 1 / 2.5f;
|
||||
const float first = 15.588f; // 3^2.5
|
||||
const float gear = (speedKmHourSigned < first) ?
|
||||
Math::Clamp<float>(speedKmHour / first, 0, 0.99f) :
|
||||
Math::Clamp<float>(pow(speedKmHour, power) - 1, 2, 5.99f);
|
||||
return 0.8f + Math::Min(0.2f, speedKmHour * 0.004f) + 0.6f * fmod(gear, 1.f);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace verus
|
|||
class Vehicle : public Object, public UserPtr
|
||||
{
|
||||
LocalPtr<btBoxShape> _pChassisShape;
|
||||
LocalPtr<btCapsuleShape> _pBumperShape;
|
||||
LocalPtr<btCompoundShape> _pCompoundShape;
|
||||
LocalRigidBody _pChassis;
|
||||
LocalPtr<btDefaultVehicleRaycaster> _pVehicleRaycaster;
|
||||
|
@ -23,7 +24,7 @@ namespace verus
|
|||
{
|
||||
float _angle = 0;
|
||||
float _speed = 1;
|
||||
float _maxAngle = Math::ToRadians(36);
|
||||
float _maxAngle = Math::ToRadians(40);
|
||||
|
||||
void Update(float stiffness)
|
||||
{
|
||||
|
@ -54,7 +55,7 @@ namespace verus
|
|||
Vector<Math::Sphere> _vLeftWheels;
|
||||
Vector<Math::Sphere> _vRightWheels;
|
||||
float _mass = 1200;
|
||||
float _suspensionRestLength = 0.2f;
|
||||
float _suspensionRestLength = 0.15f; // 0.25 for buggy, 0.05 for sports car.
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
|
@ -80,7 +81,7 @@ namespace verus
|
|||
|
||||
btRaycastVehicle* GetRaycastVehicle() { return _pRaycastVehicle.Get(); }
|
||||
|
||||
void ApplyAirForce(float scale = 2);
|
||||
void ApplyAirForce(float scale = 1);
|
||||
void SetBrake(float brake, float handBrake = 0, int index = -1);
|
||||
void SetEngineForce(float force, int index = -1);
|
||||
void SetSteeringAngle(float angle);
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
// Managed by DeferredShading:
|
||||
class DeferredLights
|
||||
{
|
||||
Mesh _meshDir;
|
||||
Mesh _meshOmni;
|
||||
Mesh _meshSpot;
|
||||
|
||||
public:
|
||||
RMesh Get(CGI::LightType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CGI::LightType::omni: return _meshOmni;
|
||||
case CGI::LightType::spot: return _meshSpot;
|
||||
}
|
||||
return _meshDir;
|
||||
}
|
||||
};
|
||||
VERUS_TYPEDEFS(DeferredLights);
|
||||
|
||||
class Helpers : public Singleton<Helpers>, public Object
|
||||
{
|
||||
private:
|
||||
struct Vertex
|
||||
{
|
||||
Point3 _pos;
|
||||
UINT32 _color;
|
||||
|
||||
Vertex() {}
|
||||
Vertex(RcPoint3 pos, UINT32 color)
|
||||
{
|
||||
_pos = pos;
|
||||
_color = color;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Vertex> _vGrid;
|
||||
Vector<Vertex> _vBasis;
|
||||
Vector<Vertex> _vCircle;
|
||||
Vector<Vertex> _vBox;
|
||||
Vector<Vertex> _vLight;
|
||||
Mesh _sphere;
|
||||
DeferredLights _deferredLights;
|
||||
|
||||
public:
|
||||
Helpers();
|
||||
~Helpers();
|
||||
|
||||
void Init();
|
||||
void Done();
|
||||
|
||||
void DrawGrid();
|
||||
void DrawBasis(PcTransform3 pMat = nullptr, int axis = -1, bool overlay = false);
|
||||
void DrawCircle(RcPoint3 pos, float radius, UINT32 color, RTerrain terrain);
|
||||
void DrawBox(PcTransform3 pMat = nullptr, UINT32 color = 0);
|
||||
void DrawLight(RcPoint3 pos, UINT32 color = 0, PcPoint3 pTarget = nullptr);
|
||||
void DrawSphere(RcPoint3 pos, float r, UINT32 color, CGI::CommandBufferPtr cb);
|
||||
|
||||
static UINT32 GetBasisColorX(bool linear = false, int alpha = 255);
|
||||
static UINT32 GetBasisColorY(bool linear = false, int alpha = 255);
|
||||
static UINT32 GetBasisColorZ(bool linear = false, int alpha = 255);
|
||||
|
||||
RDeferredLights GetDeferredLights() { return _deferredLights; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Helpers);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
namespace verus
|
||||
{
|
||||
void Make_Scene()
|
||||
{
|
||||
Scene::Helpers::Make();
|
||||
Scene::MaterialManager::Make();
|
||||
Scene::SceneManager::Make();
|
||||
Scene::Atmosphere::Make();
|
||||
Scene::Water::Make();
|
||||
Scene::LightMapBaker::Make();
|
||||
}
|
||||
void Free_Scene()
|
||||
{
|
||||
Scene::LightMapBaker::Free();
|
||||
Scene::Water::Free();
|
||||
Scene::Atmosphere::Free();
|
||||
Scene::SceneManager::Free();
|
||||
Scene::MaterialManager::Free();
|
||||
Scene::Helpers::Free();
|
||||
}
|
||||
}
|
|
@ -1,891 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
SceneManager::SceneManager()
|
||||
{
|
||||
VERUS_ZERO_MEM(_visibleCountPerType);
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void SceneManager::Init(RcDesc desc)
|
||||
{
|
||||
VERUS_INIT();
|
||||
|
||||
SetAllCameras(desc._pCamera);
|
||||
|
||||
_mapSide = desc._mapSide;
|
||||
const float sideHalf = desc._mapSide * 0.5f;
|
||||
Math::Bounds bounds;
|
||||
bounds.Set(
|
||||
Vector3(-sideHalf, -sideHalf, -sideHalf),
|
||||
Vector3(+sideHalf, +sideHalf, +sideHalf));
|
||||
const Vector3 limit(sideHalf / 14, sideHalf / 14, sideHalf / 14);
|
||||
_octree.Done();
|
||||
_octree.Init(bounds, limit);
|
||||
_octree.SetDelegate(this);
|
||||
}
|
||||
|
||||
void SceneManager::Done()
|
||||
{
|
||||
DeleteAllTriggers();
|
||||
DeleteAllPrefabs();
|
||||
DeleteAllLights();
|
||||
DeleteAllEmitters();
|
||||
DeleteAllBlocks();
|
||||
|
||||
DeleteAllSites();
|
||||
DeleteAllSceneParticles();
|
||||
DeleteAllModels();
|
||||
|
||||
VERUS_DONE(SceneManager);
|
||||
}
|
||||
|
||||
void SceneManager::ResetInstanceCount()
|
||||
{
|
||||
for (auto& x : TStoreModels::_map)
|
||||
x.second.GetMesh().ResetInstanceCount();
|
||||
}
|
||||
|
||||
void SceneManager::Update()
|
||||
{
|
||||
VERUS_UPDATE_ONCE_CHECK;
|
||||
|
||||
for (auto& x : TStoreSceneParticles::_map)
|
||||
x.second.Update();
|
||||
for (auto& x : TStoreSites::_map)
|
||||
x.second.Update();
|
||||
|
||||
for (auto& x : TStoreBlocks::_list)
|
||||
x.Update();
|
||||
for (auto& x : TStoreEmitters::_list)
|
||||
x.Update();
|
||||
for (auto& x : TStoreLights::_list)
|
||||
x.Update();
|
||||
for (auto& x : TStorePrefabs::_list)
|
||||
x.Update();
|
||||
for (auto& x : TStoreTriggers::_list)
|
||||
x.Update();
|
||||
}
|
||||
|
||||
void SceneManager::UpdateParts()
|
||||
{
|
||||
const RcPoint3 headPos = _pHeadCamera->GetEyePosition();
|
||||
for (auto& block : TStoreBlocks::_list)
|
||||
{
|
||||
const float distSq = VMath::distSqr(block.GetPosition(), headPos);
|
||||
const float part = MaterialManager::ComputePart(distSq, block.GetBounds().GetAverageSize() * 0.5f);
|
||||
block.GetMaterial()->IncludePart(part);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::Layout()
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_SM;
|
||||
|
||||
// Allocate enough space:
|
||||
int countAll = 0;
|
||||
countAll += Utils::Cast32(TStoreSites::_map.size());
|
||||
countAll += Utils::Cast32(TStoreBlocks::_list.size());
|
||||
countAll += Utils::Cast32(TStoreLights::_list.size());
|
||||
countAll += Utils::Cast32(TStorePrefabs::_list.size());
|
||||
if (_vVisibleNodes.size() != countAll)
|
||||
_vVisibleNodes.resize(countAll);
|
||||
|
||||
_visibleCount = 0;
|
||||
VERUS_ZERO_MEM(_visibleCountPerType);
|
||||
|
||||
// <Traverse>
|
||||
PCamera pPrevPassCamera = nullptr;
|
||||
// For CSM we need to create geometry beyond the view frustum (1st slice):
|
||||
if (settings._sceneShadowQuality >= App::Settings::Quality::high && atmo.GetShadowMapBaker().IsBaking())
|
||||
{
|
||||
PCamera pPassCameraCSM = atmo.GetShadowMapBaker().GetPassCameraCSM();
|
||||
if (pPassCameraCSM)
|
||||
pPrevPassCamera = sm.SetPassCamera(pPassCameraCSM);
|
||||
}
|
||||
_octree.TraverseVisible(_pPassCamera->GetFrustum());
|
||||
// Back to original camera:
|
||||
if (pPrevPassCamera)
|
||||
SetPassCamera(pPrevPassCamera);
|
||||
// </Traverse>
|
||||
|
||||
VERUS_RT_ASSERT(!_visibleCountPerType[+NodeType::unknown]);
|
||||
std::sort(_vVisibleNodes.begin(), _vVisibleNodes.begin() + _visibleCount, [](PSceneNode pA, PSceneNode pB)
|
||||
{
|
||||
// Sort by node type?
|
||||
const NodeType typeA = pA->GetType();
|
||||
const NodeType typeB = pB->GetType();
|
||||
if (typeA != typeB)
|
||||
return typeA < typeB;
|
||||
|
||||
// Both are blocks?
|
||||
if (NodeType::block == typeA)
|
||||
{
|
||||
PBlock pBlockA = static_cast<PBlock>(pA);
|
||||
PBlock pBlockB = static_cast<PBlock>(pB);
|
||||
MaterialPtr materialA = pBlockA->GetMaterial();
|
||||
MaterialPtr materialB = pBlockB->GetMaterial();
|
||||
|
||||
if (materialA && materialB) // A and B have materials, compare them.
|
||||
{
|
||||
const bool ab = *materialA < *materialB;
|
||||
const bool ba = *materialB < *materialA;
|
||||
if (ab || ba)
|
||||
return ab;
|
||||
}
|
||||
else if (materialA) // A is with material, B is without, so A goes first.
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (materialB) // A is without material, B is with, so B goes first.
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Equal materials or none have any material, compare models used:
|
||||
ModelPtr modelA = pBlockA->GetModel();
|
||||
ModelPtr modelB = pBlockB->GetModel();
|
||||
if (modelA != modelB)
|
||||
return modelA < modelB;
|
||||
}
|
||||
|
||||
// Both are lights?
|
||||
if (NodeType::light == typeA)
|
||||
{
|
||||
PLight pLightA = static_cast<PLight>(pA);
|
||||
PLight pLightB = static_cast<PLight>(pB);
|
||||
const CGI::LightType lightTypeA = pLightA->GetLightType();
|
||||
const CGI::LightType lightTypeB = pLightB->GetLightType();
|
||||
if (lightTypeA != lightTypeB)
|
||||
return lightTypeA < lightTypeB;
|
||||
}
|
||||
|
||||
// Draw same node types front-to-back:
|
||||
return pA->GetDistToHeadSq() < pB->GetDistToHeadSq();
|
||||
});
|
||||
}
|
||||
|
||||
void SceneManager::Draw()
|
||||
{
|
||||
if (!_visibleCountPerType[+NodeType::block])
|
||||
return;
|
||||
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
ModelPtr model;
|
||||
MaterialPtr material;
|
||||
bool bindPipeline = true;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
auto shader = Mesh::GetShader();
|
||||
|
||||
const int begin = FindOffsetFor(NodeType::block);
|
||||
const int end = begin + _visibleCountPerType[+NodeType::block];
|
||||
shader->BeginBindDescriptors();
|
||||
for (int i = begin; i <= end; ++i)
|
||||
{
|
||||
if (i == end)
|
||||
{
|
||||
if (model)
|
||||
model->Draw(cb);
|
||||
break;
|
||||
}
|
||||
|
||||
PSceneNode pSN = _vVisibleNodes[i];
|
||||
PBlock pBlock = static_cast<PBlock>(pSN);
|
||||
ModelPtr nextModel = pBlock->GetModel();
|
||||
MaterialPtr nextMaterial = pBlock->GetMaterial();
|
||||
|
||||
if (!nextModel->IsLoaded() || !nextMaterial->IsLoaded())
|
||||
continue;
|
||||
|
||||
const bool changeModel = nextModel != model;
|
||||
const bool changeMaterial = nextMaterial != material;
|
||||
if (changeModel || changeMaterial)
|
||||
{
|
||||
if (model)
|
||||
model->Draw(cb);
|
||||
}
|
||||
if (changeModel)
|
||||
{
|
||||
model = nextModel;
|
||||
model->MarkFirstInstance();
|
||||
if (bindPipeline)
|
||||
{
|
||||
bindPipeline = false;
|
||||
model->BindPipeline(cb);
|
||||
cb->BindDescriptors(shader, 0);
|
||||
}
|
||||
model->BindGeo(cb);
|
||||
cb->BindDescriptors(shader, 2);
|
||||
}
|
||||
if (changeMaterial)
|
||||
{
|
||||
model->MarkFirstInstance();
|
||||
material = nextMaterial;
|
||||
material->UpdateMeshUniformBuffer();
|
||||
cb->BindDescriptors(shader, 1, material->GetComplexSetHandle());
|
||||
}
|
||||
|
||||
if (model)
|
||||
model->PushInstance(pBlock->GetTransform(), pBlock->GetColor());
|
||||
}
|
||||
shader->EndBindDescriptors();
|
||||
}
|
||||
|
||||
void SceneManager::DrawSimple(DrawSimpleMode mode)
|
||||
{
|
||||
if (!_visibleCountPerType[+NodeType::block])
|
||||
return;
|
||||
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
ModelPtr model;
|
||||
MaterialPtr material;
|
||||
bool bindPipeline = true;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
auto shader = Mesh::GetSimpleShader();
|
||||
|
||||
const int begin = FindOffsetFor(NodeType::block);
|
||||
const int end = begin + _visibleCountPerType[+NodeType::block];
|
||||
shader->BeginBindDescriptors();
|
||||
for (int i = begin; i <= end; ++i)
|
||||
{
|
||||
if (i == end)
|
||||
{
|
||||
if (model)
|
||||
model->Draw(cb);
|
||||
break;
|
||||
}
|
||||
|
||||
PSceneNode pSN = _vVisibleNodes[i];
|
||||
PBlock pBlock = static_cast<PBlock>(pSN);
|
||||
ModelPtr nextModel = pBlock->GetModel();
|
||||
MaterialPtr nextMaterial = pBlock->GetMaterial();
|
||||
|
||||
if (!nextModel->IsLoaded() || !nextMaterial->IsLoaded())
|
||||
continue;
|
||||
|
||||
const bool changeModel = nextModel != model;
|
||||
const bool changeMaterial = nextMaterial != material;
|
||||
if (changeModel || changeMaterial)
|
||||
{
|
||||
if (model)
|
||||
model->Draw(cb);
|
||||
}
|
||||
if (changeModel)
|
||||
{
|
||||
model = nextModel;
|
||||
model->MarkFirstInstance();
|
||||
if (bindPipeline)
|
||||
{
|
||||
bindPipeline = false;
|
||||
model->BindPipelineSimple(mode, cb);
|
||||
cb->BindDescriptors(shader, 0);
|
||||
}
|
||||
model->BindGeo(cb);
|
||||
cb->BindDescriptors(shader, 2);
|
||||
}
|
||||
if (changeMaterial)
|
||||
{
|
||||
model->MarkFirstInstance();
|
||||
material = nextMaterial;
|
||||
material->UpdateMeshUniformBufferSimple();
|
||||
cb->BindDescriptors(shader, 1, material->GetComplexSetHandleSimple());
|
||||
}
|
||||
|
||||
if (model)
|
||||
model->PushInstance(pBlock->GetTransform(), pBlock->GetColor());
|
||||
}
|
||||
shader->EndBindDescriptors();
|
||||
}
|
||||
|
||||
void SceneManager::DrawTransparent()
|
||||
{
|
||||
for (auto& x : TStoreSceneParticles::_map)
|
||||
x.second.Draw();
|
||||
}
|
||||
|
||||
void SceneManager::DrawLights()
|
||||
{
|
||||
if (!_visibleCountPerType[+NodeType::light])
|
||||
return;
|
||||
|
||||
VERUS_QREF_HELPERS;
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
CGI::LightType type = CGI::LightType::none;
|
||||
PMesh pMesh = nullptr;
|
||||
bool bindPipeline = true;
|
||||
|
||||
auto& ds = renderer.GetDS();
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
|
||||
auto DrawMesh = [cb](PMesh pMesh)
|
||||
{
|
||||
if (pMesh && !pMesh->IsInstanceBufferEmpty(true))
|
||||
{
|
||||
pMesh->UpdateInstanceBuffer();
|
||||
cb->DrawIndexed(pMesh->GetIndexCount(), pMesh->GetInstanceCount(true), 0, 0, pMesh->GetFirstInstance());
|
||||
}
|
||||
};
|
||||
|
||||
const int begin = FindOffsetFor(NodeType::light);
|
||||
const int end = begin + _visibleCountPerType[+NodeType::light];
|
||||
for (int i = begin; i <= end; ++i)
|
||||
{
|
||||
if (i == end)
|
||||
{
|
||||
DrawMesh(pMesh);
|
||||
break;
|
||||
}
|
||||
|
||||
PSceneNode pSN = _vVisibleNodes[i];
|
||||
PLight pLight = static_cast<PLight>(pSN);
|
||||
const CGI::LightType nextType = pLight->GetLightType();
|
||||
|
||||
if (nextType != type)
|
||||
{
|
||||
DrawMesh(pMesh);
|
||||
|
||||
type = nextType;
|
||||
ds.OnNewLightType(cb, type);
|
||||
|
||||
pMesh = (type != CGI::LightType::none) ? &helpers.GetDeferredLights().Get(type) : nullptr;
|
||||
|
||||
if (pMesh)
|
||||
{
|
||||
pMesh->MarkFirstInstance();
|
||||
pMesh->BindGeo(cb, (1 << 0) | (1 << 4));
|
||||
pMesh->CopyPosDeqScale(&ds.GetUbPerMeshVS()._posDeqScale.x);
|
||||
pMesh->CopyPosDeqBias(&ds.GetUbPerMeshVS()._posDeqBias.x);
|
||||
ds.BindDescriptorsPerMeshVS(cb);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VERUS_RELEASE_DEBUG
|
||||
if (CGI::LightType::dir == type) // Must not be scaled!
|
||||
{
|
||||
RcTransform3 matW = pLight->GetTransform();
|
||||
const Vector3 s = matW.GetScale();
|
||||
VERUS_RT_ASSERT(glm::all(glm::epsilonEqual(s.GLM(), glm::vec3(1), glm::vec3(VERUS_FLOAT_THRESHOLD))));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pMesh)
|
||||
pMesh->PushInstance(pLight->GetTransform(), pLight->GetInstData());
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::DrawBounds()
|
||||
{
|
||||
VERUS_FOR(i, _visibleCount)
|
||||
{
|
||||
PSceneNode pSN = _vVisibleNodes[i];
|
||||
if (pSN->IsSelected())
|
||||
pSN->DrawBounds();
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneManager::IsDrawingDepth(DrawDepth dd)
|
||||
{
|
||||
if (DrawDepth::automatic == dd)
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
return atmo.GetShadowMapBaker().IsBaking();
|
||||
}
|
||||
else
|
||||
return DrawDepth::yes == dd;
|
||||
}
|
||||
|
||||
int SceneManager::FindOffsetFor(NodeType type) const
|
||||
{
|
||||
int ret = 0;
|
||||
VERUS_FOR(i, +type)
|
||||
ret += _visibleCountPerType[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
String SceneManager::EnsureUniqueName(CSZ name)
|
||||
{
|
||||
// Compact name:
|
||||
const char* s = strrchr(name, ':');
|
||||
s = s ? s + 1 : name;
|
||||
const char* e = strrchr(name, '.');
|
||||
if (!e)
|
||||
e = name + strlen(name);
|
||||
|
||||
// Unique name:
|
||||
int id = -1;
|
||||
String test;
|
||||
do
|
||||
{
|
||||
test = (id < 0) ? String(s, e) : String(s, e) + "_" + std::to_string(id);
|
||||
for (auto& it : TStoreBlocks::_list) if (it.GetName() == _C(test)) test.clear();
|
||||
for (auto& it : TStoreEmitters::_list) if (it.GetName() == _C(test)) test.clear();
|
||||
for (auto& it : TStoreLights::_list) if (it.GetName() == _C(test)) test.clear();
|
||||
for (auto& it : TStorePrefabs::_list) if (it.GetName() == _C(test)) test.clear();
|
||||
for (auto& it : TStoreTriggers::_list) if (it.GetName() == _C(test)) test.clear();
|
||||
id++;
|
||||
} while (test.empty());
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
PModel SceneManager::InsertModel(CSZ url)
|
||||
{
|
||||
return TStoreModels::Insert(url);
|
||||
}
|
||||
|
||||
PModel SceneManager::FindModel(CSZ url)
|
||||
{
|
||||
return TStoreModels::Find(url);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteModel(CSZ url)
|
||||
{
|
||||
TStoreModels::Delete(url);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllModels()
|
||||
{
|
||||
TStoreModels::DeleteAll();
|
||||
}
|
||||
|
||||
PSceneParticles SceneManager::InsertSceneParticles(CSZ url)
|
||||
{
|
||||
return TStoreSceneParticles::Insert(url);
|
||||
}
|
||||
|
||||
PSceneParticles SceneManager::FindSceneParticles(CSZ url)
|
||||
{
|
||||
return TStoreSceneParticles::Find(url);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteSceneParticles(CSZ url)
|
||||
{
|
||||
TStoreSceneParticles::Delete(url);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllSceneParticles()
|
||||
{
|
||||
TStoreSceneParticles::DeleteAll();
|
||||
}
|
||||
|
||||
PSite SceneManager::InsertSite(CSZ name)
|
||||
{
|
||||
return TStoreSites::Insert(name);
|
||||
}
|
||||
|
||||
PSite SceneManager::FindSite(CSZ name)
|
||||
{
|
||||
return TStoreSites::Find(name);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteSite(CSZ name)
|
||||
{
|
||||
TStoreSites::Delete(name);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllSites()
|
||||
{
|
||||
TStoreSites::DeleteAll();
|
||||
}
|
||||
|
||||
PBlock SceneManager::InsertBlock()
|
||||
{
|
||||
return TStoreBlocks::Insert();
|
||||
}
|
||||
|
||||
void SceneManager::DeleteBlock(PBlock p)
|
||||
{
|
||||
TStoreBlocks::Delete(p);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllBlocks()
|
||||
{
|
||||
TStoreBlocks::DeleteAll();
|
||||
}
|
||||
|
||||
PEmitter SceneManager::InsertEmitter()
|
||||
{
|
||||
return TStoreEmitters::Insert();
|
||||
}
|
||||
|
||||
void SceneManager::DeleteEmitter(PEmitter p)
|
||||
{
|
||||
TStoreEmitters::Delete(p);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllEmitters()
|
||||
{
|
||||
TStoreEmitters::DeleteAll();
|
||||
}
|
||||
|
||||
PLight SceneManager::InsertLight()
|
||||
{
|
||||
return TStoreLights::Insert();
|
||||
}
|
||||
|
||||
void SceneManager::DeleteLight(PLight p)
|
||||
{
|
||||
TStoreLights::Delete(p);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllLights()
|
||||
{
|
||||
TStoreLights::DeleteAll();
|
||||
}
|
||||
|
||||
PPrefab SceneManager::InsertPrefab()
|
||||
{
|
||||
return TStorePrefabs::Insert();
|
||||
}
|
||||
|
||||
void SceneManager::DeletePrefab(PPrefab p)
|
||||
{
|
||||
TStorePrefabs::Delete(p);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllPrefabs()
|
||||
{
|
||||
TStorePrefabs::DeleteAll();
|
||||
}
|
||||
|
||||
PTrigger SceneManager::InsertTrigger()
|
||||
{
|
||||
return TStoreTriggers::Insert();
|
||||
}
|
||||
|
||||
void SceneManager::DeleteTrigger(PTrigger p)
|
||||
{
|
||||
TStoreTriggers::Delete(p);
|
||||
}
|
||||
|
||||
void SceneManager::DeleteAllTriggers()
|
||||
{
|
||||
TStoreTriggers::DeleteAll();
|
||||
}
|
||||
|
||||
void SceneManager::DeleteNode(NodeType type, CSZ name)
|
||||
{
|
||||
Query query;
|
||||
query._name = name;
|
||||
query._type = type;
|
||||
ForEachNode(query, [this, type](RSceneNode node)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NodeType::block: DeleteBlock(static_cast<PBlock>(&node)); break;
|
||||
case NodeType::light: DeleteLight(static_cast<PLight>(&node)); break;
|
||||
case NodeType::prefab: DeletePrefab(static_cast<PPrefab>(&node)); break;
|
||||
}
|
||||
return Continue::yes;
|
||||
});
|
||||
}
|
||||
|
||||
bool SceneManager::IsValidNode(PSceneNode pSceneNode)
|
||||
{
|
||||
bool ret = false;
|
||||
Query query;
|
||||
ForEachNode(query, [pSceneNode, &ret](RSceneNode node)
|
||||
{
|
||||
if (&node == pSceneNode)
|
||||
{
|
||||
ret = true;
|
||||
return Continue::no;
|
||||
}
|
||||
return Continue::yes;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SceneManager::ClearSelection()
|
||||
{
|
||||
Query query;
|
||||
query._selected = 1;
|
||||
ForEachNode(query, [](RSceneNode node)
|
||||
{
|
||||
node.Select(false);
|
||||
return Continue::yes;
|
||||
});
|
||||
}
|
||||
|
||||
int SceneManager::GetSelectedCount()
|
||||
{
|
||||
int ret = 0;
|
||||
Query query;
|
||||
query._selected = 1;
|
||||
ForEachNode(query, [&ret](RSceneNode node)
|
||||
{
|
||||
ret++;
|
||||
return Continue::yes;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
Continue SceneManager::Octree_ProcessNode(void* pToken, void* pUser)
|
||||
{
|
||||
PSceneNode pSN = static_cast<PSceneNode>(pToken);
|
||||
if (pSN->IsHidden())
|
||||
return Continue::yes;
|
||||
_vVisibleNodes[_visibleCount++] = pSN;
|
||||
_visibleCountPerType[+pSN->GetType()]++;
|
||||
return Continue::yes;
|
||||
}
|
||||
|
||||
bool SceneManager::RayCastingTest(RcPoint3 pointA, RcPoint3 pointB, PBlockPtr pBlock,
|
||||
PPoint3 pPoint, PVector3 pNormal, const float* pRadius, Physics::Group mask)
|
||||
{
|
||||
VERUS_RT_ASSERT(!pBlock || *pBlock);
|
||||
VERUS_QREF_BULLET;
|
||||
if (!memcmp(pointA.ToPointer(), pointB.ToPointer(), sizeof(float) * 3))
|
||||
return false;
|
||||
btVector3 from(pointA.Bullet()), to(pointB.Bullet());
|
||||
if (pPoint || pNormal)
|
||||
{
|
||||
if (pRadius)
|
||||
{
|
||||
btSphereShape sphere(*pRadius);
|
||||
btTransform trA, trB;
|
||||
trA.setIdentity();
|
||||
trB.setIdentity();
|
||||
trA.setOrigin(pointA.Bullet());
|
||||
trB.setOrigin(pointB.Bullet());
|
||||
btCollisionWorld::ClosestConvexResultCallback ccrc(from, to);
|
||||
ccrc.m_collisionFilterMask = +mask;
|
||||
bullet.GetWorld()->convexSweepTest(&sphere, trA, trB, ccrc);
|
||||
if (ccrc.hasHit())
|
||||
{
|
||||
Physics::PUserPtr p = static_cast<Physics::PUserPtr>(ccrc.m_hitCollisionObject->getUserPointer());
|
||||
if (pBlock && p->UserPtr_GetType() == +NodeType::block)
|
||||
pBlock->Attach(static_cast<PBlock>(p));
|
||||
if (pPoint)
|
||||
*pPoint = ccrc.m_hitPointWorld;
|
||||
if (pNormal)
|
||||
*pNormal = ccrc.m_hitNormalWorld;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
btCollisionWorld::ClosestRayResultCallback crrc(from, to);
|
||||
crrc.m_collisionFilterMask = +mask;
|
||||
bullet.GetWorld()->rayTest(from, to, crrc);
|
||||
if (crrc.hasHit())
|
||||
{
|
||||
Physics::PUserPtr p = static_cast<Physics::PUserPtr>(crrc.m_collisionObject->getUserPointer());
|
||||
if (pBlock && p->UserPtr_GetType() == +NodeType::block)
|
||||
pBlock->Attach(static_cast<PBlock>(p));
|
||||
if (pPoint)
|
||||
*pPoint = crrc.m_hitPointWorld;
|
||||
if (pNormal)
|
||||
*pNormal = crrc.m_hitNormalWorld;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // Point/normal not required?
|
||||
{
|
||||
struct AnyRayResultCallback : public btCollisionWorld::RayResultCallback
|
||||
{
|
||||
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
m_closestHitFraction = 0;
|
||||
m_collisionObject = rayResult.m_collisionObject;
|
||||
return 0;
|
||||
}
|
||||
} arrc;
|
||||
arrc.m_collisionFilterMask = +mask;
|
||||
bullet.GetWorld()->rayTest(from, to, arrc);
|
||||
if (arrc.hasHit())
|
||||
{
|
||||
Physics::PUserPtr p = static_cast<Physics::PUserPtr>(arrc.m_collisionObject->getUserPointer());
|
||||
if (pBlock && p->UserPtr_GetType() == +NodeType::block)
|
||||
pBlock->Attach(static_cast<PBlock>(p));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Matrix3 SceneManager::GetBasisAt(RcPoint3 point, Physics::Group mask) const
|
||||
{
|
||||
VERUS_QREF_BULLET;
|
||||
const btVector3 from = point.Bullet();
|
||||
const btVector3 to = from - btVector3(0, 100, 0);
|
||||
btCollisionWorld::ClosestRayResultCallback crrc(from, to);
|
||||
crrc.m_collisionFilterMask = +mask;
|
||||
bullet.GetWorld()->rayTest(from, to, crrc);
|
||||
if (crrc.hasHit())
|
||||
{
|
||||
glm::vec3 nreal = Vector3(crrc.m_hitNormalWorld).GLM(), nrm(0, 1, 0), tan(1, 0, 0), bin(0, 0, 1);
|
||||
const float angle = glm::angle(nrm, nreal);
|
||||
VERUS_RT_ASSERT(angle <= VERUS_PI * 0.5f);
|
||||
if (angle >= Math::ToRadians(1))
|
||||
{
|
||||
const glm::vec3 axis = glm::normalize(glm::cross(nrm, nreal));
|
||||
const glm::quat q = glm::angleAxis(angle, axis);
|
||||
const glm::mat3 mat = glm::mat3_cast(q);
|
||||
tan = mat * tan;
|
||||
bin = mat * bin;
|
||||
}
|
||||
return Matrix3(Vector3(tan), Vector3(nreal), Vector3(bin));
|
||||
}
|
||||
else
|
||||
return Matrix3::identity();
|
||||
}
|
||||
|
||||
void SceneManager::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
stream.WriteText(VERUS_CRNL VERUS_CRNL "<SM>");
|
||||
stream.BeginBlock();
|
||||
|
||||
stream.WriteString(_C(std::to_string(_mapSide)));
|
||||
|
||||
stream.WriteString(_C(std::to_string(TStoreModels::GetStoredCount())));
|
||||
for (auto& x : TStoreModels::_map)
|
||||
{
|
||||
stream.WriteString(_C(x.first));
|
||||
x.second.Serialize(stream);
|
||||
}
|
||||
|
||||
auto GetPersistentCount = [this](NodeType type)
|
||||
{
|
||||
int count = 0;
|
||||
Query query;
|
||||
query._type = type;
|
||||
ForEachNode(query, [&count](RSceneNode node)
|
||||
{
|
||||
if (!node.IsTransient())
|
||||
count++;
|
||||
return Continue::yes;
|
||||
});
|
||||
return count;
|
||||
};
|
||||
|
||||
stream.WriteString(_C(std::to_string(GetPersistentCount(NodeType::block))));
|
||||
for (auto& x : TStoreBlocks::_list)
|
||||
{
|
||||
if (!x.IsTransient())
|
||||
x.Serialize(stream);
|
||||
}
|
||||
|
||||
stream.WriteString(_C(std::to_string(GetPersistentCount(NodeType::emitter))));
|
||||
for (auto& x : TStoreEmitters::_list)
|
||||
{
|
||||
if (!x.IsTransient())
|
||||
x.Serialize(stream);
|
||||
}
|
||||
|
||||
stream.WriteString(_C(std::to_string(GetPersistentCount(NodeType::light))));
|
||||
for (auto& x : TStoreLights::_list)
|
||||
{
|
||||
if (!x.IsTransient())
|
||||
x.Serialize(stream);
|
||||
}
|
||||
|
||||
stream.WriteString(_C(std::to_string(GetPersistentCount(NodeType::prefab))));
|
||||
for (auto& x : TStorePrefabs::_list)
|
||||
{
|
||||
if (!x.IsTransient())
|
||||
x.Serialize(stream);
|
||||
}
|
||||
|
||||
stream.WriteString(_C(std::to_string(GetPersistentCount(NodeType::trigger))));
|
||||
for (auto& x : TStoreTriggers::_list)
|
||||
{
|
||||
if (!x.IsTransient())
|
||||
x.Serialize(stream);
|
||||
}
|
||||
|
||||
stream.EndBlock();
|
||||
}
|
||||
|
||||
void SceneManager::Deserialize(IO::RStream stream)
|
||||
{
|
||||
char buffer[IO::Stream::s_bufferSize] = {};
|
||||
int count = 0;
|
||||
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
stream.ReadString(buffer);
|
||||
const int mapSide = atoi(buffer);
|
||||
|
||||
Desc desc;
|
||||
desc._mapSide = mapSide;
|
||||
PCamera pPassCamera = _pPassCamera;
|
||||
PMainCamera pHeadCamera = _pHeadCamera;
|
||||
PMainCamera pViewCamera = _pViewCamera;
|
||||
Done();
|
||||
Init(desc);
|
||||
_pPassCamera = pPassCamera;
|
||||
_pHeadCamera = pHeadCamera;
|
||||
_pViewCamera = pViewCamera;
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
stream.ReadString(buffer);
|
||||
PModel p = InsertModel(buffer);
|
||||
p->Deserialize(stream, buffer);
|
||||
}
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
PBlock p = InsertBlock();
|
||||
p->Deserialize(stream);
|
||||
}
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
PEmitter p = InsertEmitter();
|
||||
p->Deserialize(stream);
|
||||
}
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
PLight p = InsertLight();
|
||||
p->Deserialize(stream);
|
||||
}
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
PPrefab p = InsertPrefab();
|
||||
p->Deserialize(stream);
|
||||
}
|
||||
|
||||
stream.ReadString(buffer);
|
||||
count = atoi(buffer);
|
||||
VERUS_FOR(i, count)
|
||||
{
|
||||
PTrigger p = InsertTrigger();
|
||||
p->Deserialize(stream);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,257 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
typedef StoreUnique<String, Model> TStoreModels;
|
||||
typedef StoreUnique<String, SceneParticles> TStoreSceneParticles;
|
||||
typedef StoreUnique<String, Site> TStoreSites;
|
||||
typedef Store<Block> TStoreBlocks;
|
||||
typedef Store<Emitter> TStoreEmitters;
|
||||
typedef Store<Light> TStoreLights;
|
||||
typedef Store<Prefab> TStorePrefabs;
|
||||
typedef Store<Trigger> TStoreTriggers;
|
||||
class SceneManager : public Singleton<SceneManager>, public Object, public Math::OctreeDelegate,
|
||||
private TStoreModels, private TStoreSceneParticles, private TStoreSites,
|
||||
private TStoreBlocks, private TStoreEmitters, private TStoreLights, private TStorePrefabs, private TStoreTriggers
|
||||
{
|
||||
Math::Octree _octree;
|
||||
PCamera _pPassCamera = nullptr; // Render pass camera for getting view and projection matrices.
|
||||
PMainCamera _pHeadCamera = nullptr; // Head camera which is located between the eyes.
|
||||
PMainCamera _pViewCamera = nullptr; // Current view camera which is valid only inside DrawView method (eye camera).
|
||||
Vector<PSceneNode> _vVisibleNodes;
|
||||
int _visibleCount = 0;
|
||||
int _visibleCountPerType[+NodeType::count];
|
||||
int _mapSide = 0;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
PMainCamera _pCamera = nullptr;
|
||||
int _mapSide = 256;
|
||||
|
||||
Desc() {}
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
struct Query
|
||||
{
|
||||
CSZ _name = nullptr;
|
||||
CSZ _blockMesh = nullptr;
|
||||
CSZ _blockMaterial = nullptr;
|
||||
CSZ _particlesUrl = nullptr;
|
||||
NodeType _type = NodeType::unknown;
|
||||
int _selected = -1;
|
||||
|
||||
void Reset() { *this = Query(); }
|
||||
};
|
||||
VERUS_TYPEDEFS(Query);
|
||||
|
||||
SceneManager();
|
||||
virtual ~SceneManager();
|
||||
|
||||
void Init(RcDesc desc = Desc());
|
||||
void Done();
|
||||
|
||||
void ResetInstanceCount();
|
||||
void Update();
|
||||
void UpdateParts();
|
||||
void Layout();
|
||||
void Draw();
|
||||
void DrawSimple(DrawSimpleMode mode);
|
||||
void DrawTransparent();
|
||||
void DrawLights();
|
||||
void DrawBounds();
|
||||
|
||||
// Cameras:
|
||||
PCamera GetPassCamera() const { return _pPassCamera; }
|
||||
PMainCamera GetHeadCamera() const { return _pHeadCamera; }
|
||||
PMainCamera GetViewCamera() const { return _pViewCamera; }
|
||||
PCamera SetPassCamera(PCamera p) { return Utils::Swap(_pPassCamera, p); }
|
||||
PMainCamera SetHeadCamera(PMainCamera p) { return Utils::Swap(_pHeadCamera, p); }
|
||||
PMainCamera SetViewCamera(PMainCamera p) { return Utils::Swap(_pViewCamera, p); }
|
||||
void SetAllCameras(PMainCamera p) { _pPassCamera = _pHeadCamera = _pViewCamera = p; }
|
||||
|
||||
static bool IsDrawingDepth(DrawDepth dd);
|
||||
|
||||
int FindOffsetFor(NodeType type) const;
|
||||
|
||||
String EnsureUniqueName(CSZ name);
|
||||
|
||||
// Models:
|
||||
PModel InsertModel(CSZ url);
|
||||
PModel FindModel(CSZ url);
|
||||
void DeleteModel(CSZ url);
|
||||
void DeleteAllModels();
|
||||
template<typename T>
|
||||
void ForEachModel(const T& fn)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreModels::TMap, TStoreModels::_map, it)
|
||||
{
|
||||
auto& model = *it++;
|
||||
if (Continue::no == fn(model.second))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// SceneParticles:
|
||||
PSceneParticles InsertSceneParticles(CSZ url);
|
||||
PSceneParticles FindSceneParticles(CSZ url);
|
||||
void DeleteSceneParticles(CSZ url);
|
||||
void DeleteAllSceneParticles();
|
||||
template<typename T>
|
||||
void ForEachParticles(const T& fn)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreSceneParticles::TMap, TStoreSceneParticles::_map, it)
|
||||
{
|
||||
auto& particles = *it++;
|
||||
if (Continue::no == fn(particles.second))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Sites:
|
||||
PSite InsertSite(CSZ name);
|
||||
PSite FindSite(CSZ name);
|
||||
void DeleteSite(CSZ name);
|
||||
void DeleteAllSites();
|
||||
template<typename T>
|
||||
void ForEachSite(const T& fn)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreSites::TMap, TStoreSites::_map, it)
|
||||
{
|
||||
auto& site = *it++;
|
||||
if (Continue::no == fn(site.second))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks:
|
||||
PBlock InsertBlock();
|
||||
void DeleteBlock(PBlock p);
|
||||
void DeleteAllBlocks();
|
||||
|
||||
// Emitters:
|
||||
PEmitter InsertEmitter();
|
||||
void DeleteEmitter(PEmitter p);
|
||||
void DeleteAllEmitters();
|
||||
|
||||
// Lights (and Shadows):
|
||||
PLight InsertLight();
|
||||
void DeleteLight(PLight p);
|
||||
void DeleteAllLights();
|
||||
|
||||
// Prefabs:
|
||||
PPrefab InsertPrefab();
|
||||
void DeletePrefab(PPrefab p);
|
||||
void DeleteAllPrefabs();
|
||||
|
||||
// Triggers:
|
||||
PTrigger InsertTrigger();
|
||||
void DeleteTrigger(PTrigger p);
|
||||
void DeleteAllTriggers();
|
||||
|
||||
template<typename T>
|
||||
void ForEachNode(RcQuery query, const T& fn)
|
||||
{
|
||||
auto MatchName = [&query](RSceneNode node)
|
||||
{
|
||||
return !query._name || node.GetName() == query._name;
|
||||
};
|
||||
auto MatchSelected = [&query](RSceneNode node)
|
||||
{
|
||||
return -1 == query._selected || !!query._selected == node.IsSelected();
|
||||
};
|
||||
|
||||
if (NodeType::unknown == query._type || NodeType::block == query._type)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreBlocks::TList, TStoreBlocks::_list, it)
|
||||
{
|
||||
auto& block = *it++;
|
||||
if (
|
||||
MatchName(block) &&
|
||||
MatchSelected(block) &&
|
||||
(!query._blockMesh || block.GetUrl() == query._blockMesh) &&
|
||||
(!query._blockMaterial || block.GetMaterial()->_name == query._blockMaterial))
|
||||
if (Continue::no == fn(block))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (query._blockMesh || query._blockMaterial)
|
||||
return;
|
||||
|
||||
if (NodeType::unknown == query._type || NodeType::emitter == query._type)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreEmitters::TList, TStoreEmitters::_list, it)
|
||||
{
|
||||
auto& emitter = *it++;
|
||||
if (
|
||||
MatchName(emitter) &&
|
||||
MatchSelected(emitter) &&
|
||||
(!query._particlesUrl || emitter.GetUrl() == query._particlesUrl))
|
||||
if (Continue::no == fn(emitter))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NodeType::unknown == query._type || NodeType::light == query._type)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreLights::TList, TStoreLights::_list, it)
|
||||
{
|
||||
auto& light = *it++;
|
||||
if (
|
||||
MatchName(light) &&
|
||||
MatchSelected(light))
|
||||
if (Continue::no == fn(light))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NodeType::unknown == query._type || NodeType::prefab == query._type)
|
||||
{
|
||||
VERUS_FOREACH_X(TStorePrefabs::TList, TStorePrefabs::_list, it)
|
||||
{
|
||||
auto& prefab = *it++;
|
||||
if (
|
||||
MatchName(prefab) &&
|
||||
MatchSelected(prefab))
|
||||
if (Continue::no == fn(prefab))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (NodeType::unknown == query._type || NodeType::trigger == query._type)
|
||||
{
|
||||
VERUS_FOREACH_X(TStoreTriggers::TList, TStoreTriggers::_list, it)
|
||||
{
|
||||
auto& trigger = *it++;
|
||||
if (
|
||||
MatchName(trigger) &&
|
||||
MatchSelected(trigger))
|
||||
if (Continue::no == fn(trigger))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteNode(NodeType type, CSZ name);
|
||||
bool IsValidNode(PSceneNode pSceneNode);
|
||||
|
||||
void ClearSelection();
|
||||
int GetSelectedCount();
|
||||
|
||||
// Octree (Acceleration Structure):
|
||||
Math::ROctree GetOctree() { return _octree; }
|
||||
virtual Continue Octree_ProcessNode(void* pToken, void* pUser) override;
|
||||
|
||||
bool RayCastingTest(RcPoint3 pointA, RcPoint3 pointB, PBlockPtr pBlock = nullptr,
|
||||
PPoint3 pPoint = nullptr, PVector3 pNormal = nullptr, const float* pRadius = nullptr,
|
||||
Physics::Group mask = Physics::Group::immovable | Physics::Group::terrain);
|
||||
Matrix3 GetBasisAt(RcPoint3 point, Physics::Group mask = Physics::Group::immovable | Physics::Group::terrain) const;
|
||||
|
||||
void Serialize(IO::RSeekableStream stream);
|
||||
void Deserialize(IO::RStream stream);
|
||||
};
|
||||
VERUS_TYPEDEFS(SceneManager);
|
||||
}
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Block:
|
||||
|
||||
Block::Block()
|
||||
{
|
||||
_type = NodeType::block;
|
||||
}
|
||||
|
||||
Block::~Block()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Block::Init(RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
_name = sm.EnsureUniqueName(desc._name ? desc._name : desc._model);
|
||||
_matIndex = desc._matIndex;
|
||||
_collide = desc._collide;
|
||||
|
||||
Model::Desc modelDesc;
|
||||
modelDesc._url = desc._model;
|
||||
modelDesc._mat = desc._modelMat;
|
||||
_model.Init(modelDesc);
|
||||
if (1 == _model->GetRefCount())
|
||||
_model->AddRef(); // Models must be owned by blocks and scene manager.
|
||||
|
||||
if (desc._blockMat)
|
||||
{
|
||||
Material::Desc matDesc;
|
||||
matDesc._name = desc._blockMat;
|
||||
matDesc._load = true;
|
||||
_material.Init(matDesc);
|
||||
}
|
||||
|
||||
String url = desc._model;
|
||||
Str::ReplaceExtension(url, ".Extra.xml");
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::I().LoadResourceFromCache(_C(url), vData, false);
|
||||
if (vData.size() > 1)
|
||||
LoadExtra(reinterpret_cast<SZ>(vData.data()));
|
||||
}
|
||||
|
||||
void Block::Done()
|
||||
{
|
||||
RemoveRigidBody();
|
||||
_material.Done();
|
||||
_model.Done();
|
||||
SceneManager::I().GetOctree().UnbindElement(this);
|
||||
_vLights.clear();
|
||||
_vEmitters.clear();
|
||||
}
|
||||
|
||||
void Block::LoadExtra(SZ xml)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
const pugi::xml_parse_result result = doc.load_buffer_inplace(xml, strlen(xml));
|
||||
if (!result)
|
||||
throw VERUS_RECOVERABLE << "load_buffer_inplace(); " << result.description();
|
||||
pugi::xml_node root = doc.first_child();
|
||||
|
||||
int lightCount = 0;
|
||||
for (auto node : root.children("light"))
|
||||
{
|
||||
auto matAttr = node.attribute("mat");
|
||||
if (!matAttr || matAttr.as_int() == _matIndex)
|
||||
lightCount++;
|
||||
}
|
||||
int emitterCount = 0;
|
||||
for (auto node : root.children("emit"))
|
||||
emitterCount++;
|
||||
|
||||
_vLights.resize(lightCount);
|
||||
_vEmitters.resize(emitterCount);
|
||||
|
||||
int i = 0;
|
||||
for (auto node : root.children("light"))
|
||||
{
|
||||
auto matAttr = node.attribute("mat");
|
||||
if (!matAttr || matAttr.as_int() == _matIndex)
|
||||
{
|
||||
RLightPwn light = _vLights[i]._light;
|
||||
|
||||
Light::Desc desc;
|
||||
desc._node = node;
|
||||
light.Init(desc);
|
||||
light->SetTransient();
|
||||
_vLights[i]._tr = light->GetTransform();
|
||||
light->SetTransform(GetTransform() * _vLights[i]._tr);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
for (auto node : root.children("emit"))
|
||||
{
|
||||
REmitterPwn emitter = _vEmitters[i]._emitter;
|
||||
|
||||
Emitter::Desc desc;
|
||||
desc._node = node;
|
||||
emitter.Init(desc);
|
||||
emitter->SetTransient();
|
||||
_vEmitters[i]._tr = emitter->GetTransform();
|
||||
emitter->SetTransform(GetTransform() * _vEmitters[i]._tr);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void Block::Update()
|
||||
{
|
||||
if (!_async_loadedModel && _model->IsLoaded())
|
||||
{
|
||||
_async_loadedModel = true;
|
||||
if (!_dynamic)
|
||||
{
|
||||
VERUS_QREF_BULLET;
|
||||
const btTransform tr = GetTransform().Bullet();
|
||||
_pBody = bullet.AddNewRigidBody(0, tr, _model->GetMesh().GetShape(), Physics::Group::immovable);
|
||||
_pBody->setFriction(Physics::Bullet::GetFriction(Physics::Material::stone));
|
||||
_pBody->setRestitution(Physics::Bullet::GetRestitution(Physics::Material::stone));
|
||||
_pBody->setUserPointer(this);
|
||||
SetCollisionGroup(_collide ? Physics::Group::immovable : Physics::Group::general);
|
||||
}
|
||||
UpdateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
MaterialPtr Block::GetMaterial(bool orModelMat)
|
||||
{
|
||||
if (!_material && orModelMat)
|
||||
return _model->GetMaterial();
|
||||
return _material;
|
||||
}
|
||||
|
||||
void Block::UpdateBounds()
|
||||
{
|
||||
if (_model->IsLoaded())
|
||||
{
|
||||
if (!_octreeBindOnce)
|
||||
{
|
||||
_bounds = Math::Bounds::MakeFromOrientedBox(_model->GetMesh().GetBounds(), _tr);
|
||||
SceneManager::I().GetOctree().BindElement(Math::Octree::Element(_bounds, this), _dynamic);
|
||||
_octreeBindOnce = _dynamic;
|
||||
}
|
||||
if (_dynamic)
|
||||
{
|
||||
_bounds = Math::Bounds::MakeFromOrientedBox(_model->GetMesh().GetBounds(), _tr);
|
||||
SceneManager::I().GetOctree().UpdateDynamicBounds(Math::Octree::Element(_bounds, this));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& x : _vLights)
|
||||
x._light->SetTransform(GetTransform() * x._tr);
|
||||
for (auto& x : _vEmitters)
|
||||
x._emitter->SetTransform(GetTransform() * x._tr);
|
||||
}
|
||||
|
||||
void Block::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
SceneNode::Serialize(stream);
|
||||
|
||||
stream.WriteString(_C(GetUrl()));
|
||||
stream.WriteString(_material ? _C(_material->_name) : "");
|
||||
stream << _userColor.GLM();
|
||||
}
|
||||
|
||||
void Block::Deserialize(IO::RStream stream)
|
||||
{
|
||||
SceneNode::Deserialize(stream);
|
||||
const String savedName = _C(GetName());
|
||||
PreventNameCollision();
|
||||
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
char url[IO::Stream::s_bufferSize] = {};
|
||||
char material[IO::Stream::s_bufferSize] = {};
|
||||
glm::vec4 userColor;
|
||||
stream.ReadString(url);
|
||||
stream.ReadString(material);
|
||||
stream >> userColor;
|
||||
|
||||
_userColor = userColor;
|
||||
|
||||
Desc desc;
|
||||
desc._name = _C(savedName);
|
||||
desc._model = url;
|
||||
desc._blockMat = (strlen(material) > 0) ? material : nullptr;
|
||||
if (desc._blockMat)
|
||||
desc._matIndex = atoi(strrchr(desc._blockMat, '.') - 1);
|
||||
Init(desc);
|
||||
}
|
||||
}
|
||||
|
||||
void Block::SaveXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::SaveXML(node);
|
||||
|
||||
node.append_attribute("url") = _C(GetUrl());
|
||||
if (_material)
|
||||
node.append_attribute("mat") = _C(_material->_name);
|
||||
if (!_userColor.IsZero())
|
||||
node.append_attribute("color") = _C(_userColor.ToColorString());
|
||||
}
|
||||
|
||||
void Block::LoadXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::LoadXML(node);
|
||||
PreventNameCollision();
|
||||
|
||||
_userColor = Vector4(0);
|
||||
if (auto attr = node.attribute("color"))
|
||||
_userColor.FromColorString(attr.value());
|
||||
|
||||
Desc desc;
|
||||
desc._name = node.attribute("name").value();
|
||||
desc._model = node.attribute("url").value();
|
||||
if (auto attr = node.attribute("mat"))
|
||||
desc._blockMat = attr.value();
|
||||
if (desc._blockMat)
|
||||
desc._matIndex = atoi(strrchr(desc._blockMat, '.') - 1);
|
||||
Init(desc);
|
||||
}
|
||||
|
||||
// BlockPtr:
|
||||
|
||||
void BlockPtr::Init(Block::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertBlock();
|
||||
if (desc._node)
|
||||
_p->LoadXML(desc._node);
|
||||
else
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void BlockPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteBlock(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class BlockLight
|
||||
{
|
||||
public:
|
||||
Transform3 _tr = Transform3::identity();
|
||||
LightPwn _light;
|
||||
};
|
||||
VERUS_TYPEDEFS(BlockLight);
|
||||
|
||||
class BlockEmitter
|
||||
{
|
||||
public:
|
||||
Transform3 _tr = Transform3::identity();
|
||||
EmitterPwn _emitter;
|
||||
};
|
||||
VERUS_TYPEDEFS(BlockEmitter);
|
||||
|
||||
// Block is a scene node which has a model and material info.
|
||||
// Most blocks form the scene's so called static or immovable geometry.
|
||||
class Block : public SceneNode
|
||||
{
|
||||
Vector4 _userColor = Vector4(0);
|
||||
Vector<BlockLight> _vLights;
|
||||
Vector<BlockEmitter> _vEmitters;
|
||||
ModelPwn _model;
|
||||
MaterialPwn _material;
|
||||
int _matIndex = 0;
|
||||
bool _collide = true;
|
||||
bool _async_loadedModel = false;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
CSZ _name = nullptr;
|
||||
CSZ _model = nullptr;
|
||||
CSZ _modelMat = nullptr;
|
||||
CSZ _blockMat = nullptr;
|
||||
int _matIndex = 0;
|
||||
bool _collide = true;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Block();
|
||||
~Block();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
void Done();
|
||||
|
||||
VERUS_P(void LoadExtra(SZ xml));
|
||||
|
||||
virtual void Update() override;
|
||||
|
||||
virtual String GetUrl() override { return _C(_model->GetMesh().GetUrl()); }
|
||||
|
||||
bool IsLoadedModel() const { return _model->IsLoaded(); }
|
||||
|
||||
virtual void SetColor(RcVector4 color) override { _userColor = color; }
|
||||
virtual Vector4 GetColor() override { return _userColor; }
|
||||
ModelPtr GetModel() { return _model; }
|
||||
MaterialPtr GetMaterial(bool orModelMat = true);
|
||||
int GetMaterialIndex() const { return _matIndex; }
|
||||
|
||||
virtual void UpdateBounds() override;
|
||||
|
||||
// Serialization:
|
||||
virtual void Serialize(IO::RSeekableStream stream) override;
|
||||
virtual void Deserialize(IO::RStream stream) override;
|
||||
virtual void SaveXML(pugi::xml_node node) override;
|
||||
virtual void LoadXML(pugi::xml_node node) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(Block);
|
||||
|
||||
class BlockPtr : public Ptr<Block>
|
||||
{
|
||||
public:
|
||||
void Init(Block::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(BlockPtr);
|
||||
|
||||
class BlockPwn : public BlockPtr
|
||||
{
|
||||
public:
|
||||
~BlockPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(BlockPwn);
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Emitter:
|
||||
|
||||
Emitter::Emitter()
|
||||
{
|
||||
_type = NodeType::emitter;
|
||||
}
|
||||
|
||||
Emitter::~Emitter()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Emitter::Init(RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
_name = sm.EnsureUniqueName(desc._name ? desc._name : "Emitter");
|
||||
if (desc._urlParticles)
|
||||
{
|
||||
SceneParticles::Desc spDesc;
|
||||
spDesc._url = desc._urlParticles;
|
||||
_particles.Init(spDesc);
|
||||
_flow = 0;
|
||||
}
|
||||
if (desc._urlSound)
|
||||
_sound.Init(Audio::Sound::Desc(desc._urlSound).Set3D().SetLoop());
|
||||
}
|
||||
|
||||
void Emitter::Done()
|
||||
{
|
||||
_particles.Done();
|
||||
_sound.Done();
|
||||
}
|
||||
|
||||
void Emitter::Update()
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
const Point3 headPos = sm.GetHeadCamera()->GetEyePosition();
|
||||
if (_particles && VMath::distSqr(GetPosition(), headPos) < 50 * 50.f)
|
||||
_particles->GetParticles().AddFlow(GetPosition(), _flowOffset, _flowScale, &_flowColor, &_flow);
|
||||
if (_sound)
|
||||
{
|
||||
const bool inRange = VMath::distSqr(GetPosition(), headPos) < 15 * 15.f;
|
||||
if (inRange && !_src)
|
||||
{
|
||||
Audio::Source::Desc desc;
|
||||
desc._secOffset = -1;
|
||||
_sound->NewSource(&_src, desc)->PlayAt(GetPosition());
|
||||
}
|
||||
if (!inRange && _src)
|
||||
_src.Done();
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
SceneNode::Serialize(stream);
|
||||
|
||||
stream.WriteString(_C(_particles->GetParticles().GetUrl()));
|
||||
stream.WriteString(_C(_sound->GetUrl()));
|
||||
stream << _flowColor.GLM();
|
||||
stream << _flowOffset.GLM();
|
||||
stream << _flowScale;
|
||||
}
|
||||
|
||||
void Emitter::Deserialize(IO::RStream stream)
|
||||
{
|
||||
SceneNode::Deserialize(stream);
|
||||
const String savedName = _C(GetName());
|
||||
PreventNameCollision();
|
||||
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
char urlParticles[IO::Stream::s_bufferSize] = {};
|
||||
char urlAudio[IO::Stream::s_bufferSize] = {};
|
||||
glm::vec4 flowColor;
|
||||
glm::vec3 flowOffset;
|
||||
stream.ReadString(urlParticles);
|
||||
stream.ReadString(urlAudio);
|
||||
stream >> flowColor;
|
||||
stream >> flowOffset;
|
||||
stream >> _flowScale;
|
||||
|
||||
_flowColor = flowColor;
|
||||
_flowOffset = flowOffset;
|
||||
|
||||
Desc desc;
|
||||
desc._urlParticles = urlParticles;
|
||||
desc._urlSound = urlAudio;
|
||||
Init(desc);
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::SaveXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::SaveXML(node);
|
||||
|
||||
node.append_attribute("color") = _C(_flowColor.ToColorString());
|
||||
node.append_attribute("offset") = _C(_flowOffset.ToString(true));
|
||||
node.append_attribute("scale") = _flowScale;
|
||||
if (_particles)
|
||||
node.append_attribute("urlParticles") = _C(_particles->GetParticles().GetUrl());
|
||||
if (_sound)
|
||||
node.append_attribute("urlAudio") = _C(_sound->GetUrl());
|
||||
}
|
||||
|
||||
void Emitter::LoadXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::LoadXML(node);
|
||||
PreventNameCollision();
|
||||
|
||||
_flowColor = Vector4::Replicate(1);
|
||||
if (auto attr = node.attribute("color"))
|
||||
_flowColor.FromColorString(attr.value());
|
||||
_flowOffset = Vector3(0);
|
||||
if (auto attr = node.attribute("offset"))
|
||||
_flowOffset.FromString(attr.value());
|
||||
_flowScale = node.attribute("scale").as_float(_flowScale);
|
||||
|
||||
Desc desc;
|
||||
if (auto attr = node.attribute("name"))
|
||||
desc._name = attr.value();
|
||||
desc._urlParticles = node.attribute("urlParticles").value();
|
||||
desc._urlSound = node.attribute("urlAudio").value();
|
||||
Init(desc);
|
||||
}
|
||||
|
||||
// EmitterPtr:
|
||||
|
||||
void EmitterPtr::Init(Emitter::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertEmitter();
|
||||
if (desc._node)
|
||||
_p->LoadXML(desc._node);
|
||||
else
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void EmitterPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteEmitter(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Emitter : public SceneNode
|
||||
{
|
||||
Vector4 _flowColor = Vector4::Replicate(1);
|
||||
Vector3 _flowOffset = Vector3(0);
|
||||
SceneParticlesPwn _particles;
|
||||
Audio::SoundPwn _sound;
|
||||
Audio::SourcePtr _src;
|
||||
float _flow = 0;
|
||||
float _flowScale = 1;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
CSZ _name = nullptr;
|
||||
CSZ _urlParticles = nullptr;
|
||||
CSZ _urlSound = nullptr;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Emitter();
|
||||
~Emitter();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
void Done();
|
||||
|
||||
virtual void Update() override;
|
||||
|
||||
virtual String GetUrl() override { return _C(_particles->GetParticles().GetUrl()); }
|
||||
|
||||
SceneParticlesPtr GetParticles() { return _particles; }
|
||||
|
||||
// Serialization:
|
||||
virtual void Serialize(IO::RSeekableStream stream) override;
|
||||
virtual void Deserialize(IO::RStream stream) override;
|
||||
virtual void SaveXML(pugi::xml_node node) override;
|
||||
virtual void LoadXML(pugi::xml_node node) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(Emitter);
|
||||
|
||||
class EmitterPtr : public Ptr<Emitter>
|
||||
{
|
||||
public:
|
||||
void Init(Emitter::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(EmitterPtr);
|
||||
|
||||
class EmitterPwn : public EmitterPtr
|
||||
{
|
||||
public:
|
||||
~EmitterPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(EmitterPwn);
|
||||
}
|
||||
}
|
|
@ -1,335 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Light:
|
||||
|
||||
Light::Light()
|
||||
{
|
||||
_type = NodeType::light;
|
||||
}
|
||||
|
||||
Light::~Light()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Light::Init(RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
_name = sm.EnsureUniqueName(desc._name ? desc._name : "Light");
|
||||
_data = desc._data;
|
||||
_dynamic = desc._dynamic;
|
||||
if (desc._urlIntShaker)
|
||||
{
|
||||
_shaker.Load(desc._urlIntShaker);
|
||||
_shaker.Randomize();
|
||||
_shaker.SetScaleBias(0.5f * desc._intShakerScale, 1 - 0.5f * desc._intShakerScale);
|
||||
_baseIntensity = GetIntensity();
|
||||
}
|
||||
}
|
||||
|
||||
void Light::Done()
|
||||
{
|
||||
SceneManager::I().GetOctree().UnbindElement(this);
|
||||
}
|
||||
|
||||
void Light::Update()
|
||||
{
|
||||
if (!_async_loadedMesh)
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
RMesh mesh = helpers.GetDeferredLights().Get(_data._lightType);
|
||||
if (mesh.IsLoaded())
|
||||
{
|
||||
_async_loadedMesh = true;
|
||||
UpdateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
if (_shaker.IsLoaded())
|
||||
{
|
||||
_shaker.Update();
|
||||
SetIntensity(_shaker.Get() * _baseIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
void Light::SetLightType(CGI::LightType type)
|
||||
{
|
||||
_data._lightType = type;
|
||||
ComputeTransform();
|
||||
}
|
||||
|
||||
CGI::LightType Light::GetLightType() const
|
||||
{
|
||||
return _data._lightType;
|
||||
}
|
||||
|
||||
void Light::SetColor(RcVector4 color)
|
||||
{
|
||||
_data._color = color;
|
||||
}
|
||||
|
||||
Vector4 Light::GetColor()
|
||||
{
|
||||
return _data._color;
|
||||
}
|
||||
|
||||
void Light::SetIntensity(float i)
|
||||
{
|
||||
_data._color.setW(i);
|
||||
}
|
||||
|
||||
float Light::GetIntensity() const
|
||||
{
|
||||
return _data._color.getW();
|
||||
}
|
||||
|
||||
void Light::SetDirection(RcVector3 dir)
|
||||
{
|
||||
_data._dir = dir;
|
||||
ComputeTransform();
|
||||
}
|
||||
|
||||
RcVector3 Light::GetDirection() const
|
||||
{
|
||||
return _data._dir;
|
||||
}
|
||||
|
||||
void Light::SetRadius(float r)
|
||||
{
|
||||
_data._radius = r;
|
||||
ComputeTransform();
|
||||
}
|
||||
|
||||
float Light::GetRadius() const
|
||||
{
|
||||
return _data._radius;
|
||||
}
|
||||
|
||||
void Light::SetCone(float coneIn, float coneOut)
|
||||
{
|
||||
if (coneIn)
|
||||
_data._coneIn = coneIn;
|
||||
if (coneOut)
|
||||
_data._coneOut = coneOut;
|
||||
VERUS_RT_ASSERT(_data._coneIn >= _data._coneOut);
|
||||
ComputeTransform();
|
||||
}
|
||||
|
||||
float Light::GetConeIn() const
|
||||
{
|
||||
return _data._coneIn;
|
||||
}
|
||||
|
||||
float Light::GetConeOut() const
|
||||
{
|
||||
return _data._coneOut;
|
||||
}
|
||||
|
||||
Vector4 Light::GetInstData() const
|
||||
{
|
||||
return Vector4(_data._color.getXYZ() * _data._color.getW(), _data._coneIn);
|
||||
}
|
||||
|
||||
void Light::DirFromPoint(RcPoint3 point, float radiusScale)
|
||||
{
|
||||
const Vector3 to = point - GetPosition();
|
||||
const float len = VMath::length(to);
|
||||
if (len > VERUS_FLOAT_THRESHOLD)
|
||||
{
|
||||
_data._dir = to / len;
|
||||
if (radiusScale > 0)
|
||||
_data._radius = len * radiusScale;
|
||||
}
|
||||
ComputeTransform();
|
||||
}
|
||||
|
||||
void Light::ConeFromPoint(RcPoint3 point, bool coneIn)
|
||||
{
|
||||
const Vector3 to = point - GetPosition();
|
||||
const Vector3 dir = VMath::normalize(to);
|
||||
const float d = VMath::dot(dir, _data._dir);
|
||||
if (coneIn)
|
||||
_data._coneIn = d;
|
||||
else
|
||||
_data._coneIn = _data._coneOut = Math::Clamp<float>(d, cos(Math::ToRadians(80)), cos(Math::ToRadians(10)));
|
||||
const float angle = acos(_data._coneOut);
|
||||
const float minIn = cos(angle - Math::ToRadians(10));
|
||||
_data._coneIn = Math::Clamp<float>(_data._coneIn, minIn, 1);
|
||||
SetCone(_data._coneIn, _data._coneOut);
|
||||
}
|
||||
|
||||
Transform3 Light::GetTransformNoScale() const
|
||||
{
|
||||
const Matrix3 matR = Matrix3::MakeTrackToZ(_data._dir);
|
||||
return Transform3(matR, Vector3(GetPosition()));
|
||||
}
|
||||
|
||||
void Light::SetTransform(RcTransform3 mat)
|
||||
{
|
||||
_data._dir = VMath::normalize(mat.getCol2());
|
||||
const Transform3 tr = VMath::appendScale(mat, ComputeScale());
|
||||
SceneNode::SetTransform(tr);
|
||||
}
|
||||
|
||||
void Light::RestoreTransform(RcTransform3 tr, RcVector3 rot, RcVector3 scale)
|
||||
{
|
||||
_data._dir = VMath::normalize(tr.getCol2());
|
||||
SceneNode::RestoreTransform(tr, rot, scale);
|
||||
}
|
||||
|
||||
Vector3 Light::ComputeScale()
|
||||
{
|
||||
switch (_data._lightType)
|
||||
{
|
||||
case CGI::LightType::dir:
|
||||
return Vector3::Replicate(1);
|
||||
case CGI::LightType::omni:
|
||||
return Vector3::Replicate(_data._radius);
|
||||
case CGI::LightType::spot:
|
||||
const float angle = acos(_data._coneOut);
|
||||
const float scaleXY = tan(angle);
|
||||
return Vector3(_data._radius * scaleXY, _data._radius * scaleXY, _data._radius);
|
||||
}
|
||||
return Vector3::Replicate(_data._radius);
|
||||
}
|
||||
|
||||
void Light::ComputeTransform()
|
||||
{
|
||||
const Matrix3 matR = Matrix3::MakeTrackToZ(_data._dir);
|
||||
const Transform3 tr = VMath::appendScale(Transform3(matR, Vector3(GetPosition())), ComputeScale());
|
||||
SceneNode::SetTransform(tr);
|
||||
}
|
||||
|
||||
void Light::UpdateBounds()
|
||||
{
|
||||
const bool dir = (CGI::LightType::dir == _data._lightType);
|
||||
const bool octreeRoot = (_dynamic || dir);
|
||||
|
||||
VERUS_QREF_HELPERS;
|
||||
RMesh mesh = helpers.GetDeferredLights().Get(_data._lightType);
|
||||
if (mesh.IsLoaded())
|
||||
{
|
||||
if (!_octreeBindOnce)
|
||||
{
|
||||
_bounds = Math::Bounds::MakeFromOrientedBox(mesh.GetBounds(), _tr);
|
||||
SceneManager::I().GetOctree().BindElement(Math::Octree::Element(_bounds, this), octreeRoot);
|
||||
_octreeBindOnce = octreeRoot;
|
||||
}
|
||||
if (_dynamic)
|
||||
{
|
||||
_bounds = Math::Bounds::MakeFromOrientedBox(mesh.GetBounds(), _tr);
|
||||
SceneManager::I().GetOctree().UpdateDynamicBounds(Math::Octree::Element(_bounds, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Light::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
SceneNode::Serialize(stream);
|
||||
|
||||
stream << _data._lightType;
|
||||
stream << _data._color;
|
||||
stream << _data._dir;
|
||||
stream << _data._radius;
|
||||
stream << _data._coneIn;
|
||||
stream << _data._coneOut;
|
||||
}
|
||||
|
||||
void Light::Deserialize(IO::RStream stream)
|
||||
{
|
||||
SceneNode::Deserialize(stream);
|
||||
const String savedName = _C(GetName());
|
||||
PreventNameCollision();
|
||||
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
Desc desc;
|
||||
desc._name = _C(savedName);
|
||||
stream >> desc._data._lightType;
|
||||
stream >> desc._data._color;
|
||||
stream >> desc._data._dir;
|
||||
stream >> desc._data._radius;
|
||||
stream >> desc._data._coneIn;
|
||||
stream >> desc._data._coneOut;
|
||||
Init(desc);
|
||||
}
|
||||
}
|
||||
|
||||
void Light::SaveXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::SaveXML(node);
|
||||
|
||||
switch (_data._lightType)
|
||||
{
|
||||
case CGI::LightType::dir: node.append_attribute("url") = "DIR"; break;
|
||||
case CGI::LightType::omni: node.append_attribute("url") = "OMNI"; break;
|
||||
case CGI::LightType::spot: node.append_attribute("url") = "SPOT"; break;
|
||||
}
|
||||
node.append_attribute("type") = +_data._lightType;
|
||||
node.append_attribute("color") = _C(_data._color.ToString(true));
|
||||
node.append_attribute("dir") = _C(_data._dir.ToString(true));
|
||||
node.append_attribute("radius") = _data._radius;
|
||||
node.append_attribute("coneIn") = _data._coneIn;
|
||||
node.append_attribute("coneOut") = _data._coneOut;
|
||||
}
|
||||
|
||||
void Light::LoadXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::LoadXML(node);
|
||||
PreventNameCollision();
|
||||
|
||||
Desc desc;
|
||||
if (auto attr = node.attribute("name"))
|
||||
desc._name = attr.value();
|
||||
const int type = node.attribute("type").as_int(+CGI::LightType::omni);
|
||||
desc._data._lightType = static_cast<CGI::LightType>(type);
|
||||
if (auto attr = node.attribute("color"))
|
||||
desc._data._color.FromString(attr.value());
|
||||
if (auto attr = node.attribute("dir"))
|
||||
desc._data._dir.FromString(attr.value());
|
||||
desc._data._radius = node.attribute("radius").as_float(desc._data._radius);
|
||||
desc._data._coneIn = node.attribute("coneIn").as_float(desc._data._coneIn);
|
||||
desc._data._coneOut = node.attribute("coneOut").as_float(desc._data._coneOut);
|
||||
desc._intShakerScale = node.attribute("intShakerScale").as_float(desc._intShakerScale);
|
||||
if (auto attr = node.attribute("urlIntShaker"))
|
||||
desc._urlIntShaker = attr.value();
|
||||
|
||||
// Normalize:
|
||||
desc._data._dir = VMath::normalize(desc._data._dir);
|
||||
// Convert degrees to cosine:
|
||||
if (desc._data._coneIn > 1)
|
||||
desc._data._coneIn = cos(Math::ToRadians(desc._data._coneIn));
|
||||
if (desc._data._coneOut > 1)
|
||||
desc._data._coneOut = cos(Math::ToRadians(desc._data._coneOut));
|
||||
|
||||
Init(desc);
|
||||
}
|
||||
|
||||
// LightPtr:
|
||||
|
||||
void LightPtr::Init(Light::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertLight();
|
||||
if (desc._node)
|
||||
_p->LoadXML(desc._node);
|
||||
else
|
||||
{
|
||||
_p->Init(desc);
|
||||
_p->SetLightType(desc._data._lightType); // Call ComputeTransform().
|
||||
}
|
||||
}
|
||||
|
||||
void LightPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteLight(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class LightData
|
||||
{
|
||||
public:
|
||||
Vector4 _color = Vector4::Replicate(1);
|
||||
Vector3 _dir = Vector3(0, 0, 1);
|
||||
CGI::LightType _lightType = CGI::LightType::omni;
|
||||
float _radius = 10;
|
||||
float _coneIn = cos(Math::ToRadians(35)); // [0, coneOut-10] angle cosine.
|
||||
float _coneOut = cos(Math::ToRadians(45)); // [10, 80] angle cosine.
|
||||
};
|
||||
VERUS_TYPEDEFS(LightData);
|
||||
|
||||
// Light is a scene node with light's info.
|
||||
class Light : public SceneNode
|
||||
{
|
||||
LightData _data;
|
||||
Anim::Shaker _shaker;
|
||||
float _baseIntensity = 1;
|
||||
bool _async_loadedMesh = false;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
CSZ _name = nullptr;
|
||||
CSZ _urlIntShaker = nullptr;
|
||||
float _intShakerScale = 0.25f;
|
||||
LightData _data;
|
||||
bool _dynamic = false;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Light();
|
||||
~Light();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
void Done();
|
||||
|
||||
virtual void Update() override;
|
||||
|
||||
void SetLightType(CGI::LightType type);
|
||||
CGI::LightType GetLightType() const;
|
||||
virtual void SetColor(RcVector4 color) override;
|
||||
virtual Vector4 GetColor() override;
|
||||
void SetIntensity(float i);
|
||||
float GetIntensity() const;
|
||||
void SetDirection(RcVector3 dir);
|
||||
RcVector3 GetDirection() const;
|
||||
void SetRadius(float r);
|
||||
float GetRadius() const;
|
||||
void SetCone(float coneIn = 0, float coneOut = 0);
|
||||
float GetConeIn() const;
|
||||
float GetConeOut() const;
|
||||
Vector4 GetInstData() const;
|
||||
|
||||
void DirFromPoint(RcPoint3 point, float radiusScale = 0);
|
||||
void ConeFromPoint(RcPoint3 point, bool coneIn = false);
|
||||
|
||||
Transform3 GetTransformNoScale() const;
|
||||
virtual void SetTransform(RcTransform3 mat) override;
|
||||
virtual void RestoreTransform(RcTransform3 tr, RcVector3 rot, RcVector3 scale) override;
|
||||
Vector3 ComputeScale();
|
||||
void ComputeTransform();
|
||||
|
||||
virtual void UpdateBounds() override;
|
||||
|
||||
// Serialization:
|
||||
virtual void Serialize(IO::RSeekableStream stream) override;
|
||||
virtual void Deserialize(IO::RStream stream) override;
|
||||
virtual void SaveXML(pugi::xml_node node) override;
|
||||
virtual void LoadXML(pugi::xml_node node) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(Light);
|
||||
|
||||
class LightPtr : public Ptr<Light>
|
||||
{
|
||||
public:
|
||||
void Init(Light::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(LightPtr);
|
||||
|
||||
class LightPwn : public LightPtr
|
||||
{
|
||||
public:
|
||||
~LightPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(LightPwn);
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Model:
|
||||
|
||||
Model::Model()
|
||||
{
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Model::Init(RcDesc desc)
|
||||
{
|
||||
if (_refCount)
|
||||
return;
|
||||
|
||||
VERUS_INIT();
|
||||
_refCount = 1;
|
||||
|
||||
Mesh::Desc meshDesc;
|
||||
meshDesc._url = desc._url;
|
||||
meshDesc._instanceCapacity = 1000;
|
||||
meshDesc._initShape = true;
|
||||
_mesh.Init(meshDesc);
|
||||
|
||||
Material::Desc matDesc;
|
||||
matDesc._name = desc._mat ? desc._mat : desc._url;
|
||||
matDesc._load = true;
|
||||
_material.Init(matDesc);
|
||||
}
|
||||
|
||||
bool Model::Done()
|
||||
{
|
||||
_refCount--;
|
||||
if (_refCount <= 0)
|
||||
{
|
||||
VERUS_DONE(Model);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Model::MarkFirstInstance()
|
||||
{
|
||||
_mesh.MarkFirstInstance();
|
||||
}
|
||||
|
||||
void Model::Draw(CGI::CommandBufferPtr cb)
|
||||
{
|
||||
if (!_mesh.IsInstanceBufferEmpty(true))
|
||||
{
|
||||
_mesh.UpdateInstanceBuffer();
|
||||
cb->DrawIndexed(_mesh.GetIndexCount(), _mesh.GetInstanceCount(true), 0, 0, _mesh.GetFirstInstance());
|
||||
}
|
||||
}
|
||||
|
||||
void Model::BindPipeline(CGI::CommandBufferPtr cb)
|
||||
{
|
||||
_mesh.BindPipelineInstanced(cb, false);
|
||||
_mesh.UpdateUniformBufferPerFrame();
|
||||
}
|
||||
|
||||
void Model::BindPipelineSimple(DrawSimpleMode mode, CGI::CommandBufferPtr cb)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case DrawSimpleMode::envMap: _mesh.BindPipeline(Mesh::PIPE_SIMPLE_ENV_MAP_INSTANCED, cb); break;
|
||||
case DrawSimpleMode::planarReflection: _mesh.BindPipeline(Mesh::PIPE_SIMPLE_PLANAR_REF_INSTANCED, cb); break;
|
||||
}
|
||||
_mesh.UpdateUniformBufferSimplePerFrame(mode);
|
||||
}
|
||||
|
||||
void Model::BindGeo(CGI::CommandBufferPtr cb)
|
||||
{
|
||||
_mesh.BindGeo(cb);
|
||||
_mesh.UpdateUniformBufferPerMeshVS();
|
||||
}
|
||||
|
||||
void Model::PushInstance(RcTransform3 matW, RcVector4 instData)
|
||||
{
|
||||
_mesh.PushInstance(matW, instData);
|
||||
}
|
||||
|
||||
void Model::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
stream.WriteString(_C(_material->_name));
|
||||
}
|
||||
|
||||
void Model::Deserialize(IO::RStream stream, CSZ url)
|
||||
{
|
||||
char mat[IO::Stream::s_bufferSize] = {};
|
||||
stream.ReadString(mat);
|
||||
|
||||
// TODO: handle old names, remove later:
|
||||
char* pOldExt = strstr(mat, ".xmt");
|
||||
if (pOldExt)
|
||||
strncpy(pOldExt, ".vml", 4);
|
||||
|
||||
Desc desc;
|
||||
desc._url = url;
|
||||
desc._mat = mat;
|
||||
Init(desc);
|
||||
}
|
||||
|
||||
// ModelPtr:
|
||||
|
||||
void ModelPtr::Init(Model::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertModel(desc._url);
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void ModelPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteModel(_C(_p->GetMesh().GetUrl()));
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
// Model is an element of the scene manager container
|
||||
// * has a mesh
|
||||
// * has a material
|
||||
// * has generic parameters
|
||||
class Model : public Object
|
||||
{
|
||||
Mesh _mesh;
|
||||
MaterialPwn _material;
|
||||
IO::Dictionary _dict;
|
||||
int _refCount = 0;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
CSZ _url = nullptr;
|
||||
CSZ _mat = nullptr;
|
||||
|
||||
Desc(CSZ url = nullptr) : _url(url) {}
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Model();
|
||||
~Model();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
bool Done();
|
||||
|
||||
bool IsLoaded() const { return _mesh.IsLoaded(); }
|
||||
|
||||
void AddRef() { _refCount++; }
|
||||
int GetRefCount() const { return _refCount; }
|
||||
|
||||
void MarkFirstInstance();
|
||||
void Draw(CGI::CommandBufferPtr cb);
|
||||
void BindPipeline(CGI::CommandBufferPtr cb);
|
||||
void BindPipelineSimple(DrawSimpleMode mode, CGI::CommandBufferPtr cb);
|
||||
void BindGeo(CGI::CommandBufferPtr cb);
|
||||
void PushInstance(RcTransform3 matW, RcVector4 instData);
|
||||
|
||||
RMesh GetMesh() { return _mesh; }
|
||||
MaterialPtr GetMaterial() { return _material; }
|
||||
|
||||
void Serialize(IO::RSeekableStream stream);
|
||||
void Deserialize(IO::RStream stream, CSZ url);
|
||||
};
|
||||
VERUS_TYPEDEFS(Model);
|
||||
|
||||
class ModelPtr : public Ptr<Model>
|
||||
{
|
||||
public:
|
||||
void Init(Model::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(ModelPtr);
|
||||
|
||||
class ModelPwn : public ModelPtr
|
||||
{
|
||||
public:
|
||||
~ModelPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(ModelPwn);
|
||||
}
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Prefab:
|
||||
|
||||
Prefab::Prefab()
|
||||
{
|
||||
_type = NodeType::prefab;
|
||||
}
|
||||
|
||||
Prefab::~Prefab()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Prefab::Init(RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
_name = sm.EnsureUniqueName(desc._url);
|
||||
_url = desc._url;
|
||||
_collide = desc._collide;
|
||||
|
||||
Vector<BYTE> vData;
|
||||
IO::FileSystem::I().LoadResourceFromCache(_C(_url), vData);
|
||||
LoadPrefab(reinterpret_cast<SZ>(vData.data()));
|
||||
}
|
||||
|
||||
void Prefab::Done()
|
||||
{
|
||||
for (auto& f : _vFragments)
|
||||
f._block.Done();
|
||||
SceneManager::I().GetOctree().UnbindElement(this);
|
||||
}
|
||||
|
||||
void Prefab::LoadPrefab(SZ xml)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
const pugi::xml_parse_result result = doc.load_buffer_inplace(xml, strlen(xml));
|
||||
if (!result)
|
||||
throw VERUS_RECOVERABLE << "load_buffer_inplace(); " << result.description();
|
||||
pugi::xml_node root = doc.first_child();
|
||||
|
||||
int fragCount = 0;
|
||||
for (auto node : root.children("frag"))
|
||||
fragCount++;
|
||||
_vFragments.resize(fragCount);
|
||||
|
||||
int i = 0;
|
||||
for (auto node : root.children("frag"))
|
||||
{
|
||||
RFragment f = _vFragments[i];
|
||||
|
||||
CSZ txt = node.text().as_string();
|
||||
CSZ mat = node.attribute("mat").value();
|
||||
|
||||
String urlFrag = _url;
|
||||
String matFrag;
|
||||
Str::ReplaceFilename(urlFrag, txt);
|
||||
urlFrag += ".x3d";
|
||||
if (strchr(mat, ':'))
|
||||
{
|
||||
matFrag = mat;
|
||||
}
|
||||
else
|
||||
{
|
||||
matFrag = _url;
|
||||
Str::ReplaceFilename(matFrag, mat);
|
||||
matFrag += ".vml";
|
||||
}
|
||||
|
||||
Block::Desc desc;
|
||||
desc._model = _C(urlFrag);
|
||||
desc._modelMat = _C(matFrag);
|
||||
desc._collide = _collide;
|
||||
f._block.Init(desc);
|
||||
f._block->SetLinkedNode(this);
|
||||
f._block->SetTransient();
|
||||
CSZ tr = node.attribute("tr").value();
|
||||
f._tr.FromString(tr);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void Prefab::Update()
|
||||
{
|
||||
if (!_async_loadedAllBlocks)
|
||||
{
|
||||
bool all = true;
|
||||
for (auto& f : _vFragments)
|
||||
{
|
||||
if (!f._block->IsLoadedModel())
|
||||
{
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all)
|
||||
{
|
||||
_async_loadedAllBlocks = true;
|
||||
UpdateBounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Prefab::Draw()
|
||||
{
|
||||
}
|
||||
|
||||
Vector4 Prefab::GetColor()
|
||||
{
|
||||
if (_vFragments[0]._block)
|
||||
return _vFragments[0]._block->GetColor();
|
||||
return Vector4(0);
|
||||
}
|
||||
|
||||
void Prefab::SetColor(RcVector4 color)
|
||||
{
|
||||
for (auto& f : _vFragments)
|
||||
{
|
||||
if (f._block) // Async loaded?
|
||||
f._block->SetColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
void Prefab::UpdateBounds()
|
||||
{
|
||||
for (auto& f : _vFragments)
|
||||
{
|
||||
if (f._block) // Async loaded?
|
||||
{
|
||||
const Transform3 tr = GetTransform() * f._tr;
|
||||
f._block->SetTransform(tr);
|
||||
}
|
||||
}
|
||||
if (_async_loadedAllBlocks)
|
||||
{
|
||||
_bounds.Reset();
|
||||
for (auto& f : _vFragments)
|
||||
_bounds.CombineWith(f._block->GetBounds());
|
||||
|
||||
if (!_octreeBindOnce)
|
||||
{
|
||||
SceneManager::I().GetOctree().BindElement(Math::Octree::Element(_bounds, this), _dynamic);
|
||||
_octreeBindOnce = _dynamic;
|
||||
}
|
||||
if (_dynamic)
|
||||
{
|
||||
SceneManager::I().GetOctree().UpdateDynamicBounds(Math::Octree::Element(_bounds, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Prefab::SetCollisionGroup(Physics::Group g)
|
||||
{
|
||||
for (auto& f : _vFragments)
|
||||
f._block->SetCollisionGroup(g);
|
||||
}
|
||||
|
||||
void Prefab::MoveRigidBody()
|
||||
{
|
||||
for (auto& f : _vFragments)
|
||||
f._block->MoveRigidBody();
|
||||
}
|
||||
|
||||
void Prefab::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
SceneNode::Serialize(stream);
|
||||
|
||||
stream.WriteString(_C(GetUrl()));
|
||||
}
|
||||
|
||||
void Prefab::Deserialize(IO::RStream stream)
|
||||
{
|
||||
SceneNode::Deserialize(stream);
|
||||
const String savedName = _C(GetName());
|
||||
PreventNameCollision();
|
||||
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
char url[IO::Stream::s_bufferSize] = {};
|
||||
stream.ReadString(url);
|
||||
|
||||
Desc desc;
|
||||
desc._url = url;
|
||||
Init(desc);
|
||||
}
|
||||
}
|
||||
|
||||
void Prefab::SaveXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::SaveXML(node);
|
||||
|
||||
node.attribute("url").set_value(_C(GetUrl()));
|
||||
}
|
||||
|
||||
void Prefab::LoadXML(pugi::xml_node node)
|
||||
{
|
||||
SceneNode::LoadXML(node);
|
||||
PreventNameCollision();
|
||||
|
||||
Desc desc;
|
||||
desc._url = node.attribute("url").value();
|
||||
Init(desc);
|
||||
}
|
||||
|
||||
// PrefabPtr:
|
||||
|
||||
void PrefabPtr::Init(Prefab::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertPrefab();
|
||||
if (desc._node)
|
||||
_p->LoadXML(desc._node);
|
||||
else
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void PrefabPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeletePrefab(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Fragment
|
||||
{
|
||||
public:
|
||||
Transform3 _tr = Transform3::identity();
|
||||
BlockPwn _block;
|
||||
};
|
||||
VERUS_TYPEDEFS(Fragment);
|
||||
|
||||
class Prefab : public SceneNode
|
||||
{
|
||||
Vector<Fragment> _vFragments;
|
||||
String _url;
|
||||
bool _collide = true;
|
||||
bool _async_loadedAllBlocks = false;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
CSZ _url = nullptr;
|
||||
bool _collide = true;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Prefab();
|
||||
~Prefab();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
void Done();
|
||||
|
||||
VERUS_P(void LoadPrefab(SZ xml));
|
||||
|
||||
virtual void Update() override;
|
||||
virtual void Draw() override;
|
||||
|
||||
virtual String GetUrl() override { return _url; }
|
||||
|
||||
virtual Vector4 GetColor() override;
|
||||
virtual void SetColor(RcVector4 color) override;
|
||||
|
||||
virtual void UpdateBounds() override;
|
||||
|
||||
// Physics engine:
|
||||
virtual void SetCollisionGroup(Physics::Group g = Physics::Group::immovable) override;
|
||||
virtual void MoveRigidBody() override;
|
||||
|
||||
// Serialization:
|
||||
virtual void Serialize(IO::RSeekableStream stream) override;
|
||||
virtual void Deserialize(IO::RStream stream) override;
|
||||
virtual void SaveXML(pugi::xml_node node) override;
|
||||
virtual void LoadXML(pugi::xml_node node) override;
|
||||
};
|
||||
VERUS_TYPEDEFS(Prefab);
|
||||
|
||||
class PrefabPtr : public Ptr<Prefab>
|
||||
{
|
||||
public:
|
||||
void Init(Prefab::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(PrefabPtr);
|
||||
|
||||
class PrefabPwn : public PrefabPtr
|
||||
{
|
||||
public:
|
||||
~PrefabPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(PrefabPwn);
|
||||
}
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// SceneNode:
|
||||
|
||||
void SceneNode::PreventNameCollision()
|
||||
{
|
||||
_name.clear();
|
||||
}
|
||||
|
||||
SceneNode::SceneNode()
|
||||
{
|
||||
}
|
||||
|
||||
SceneNode::~SceneNode()
|
||||
{
|
||||
}
|
||||
|
||||
int SceneNode::UserPtr_GetType()
|
||||
{
|
||||
return +_type;
|
||||
}
|
||||
|
||||
void SceneNode::DrawBounds()
|
||||
{
|
||||
if (!_bounds.IsNull())
|
||||
{
|
||||
VERUS_QREF_HELPERS;
|
||||
const Transform3 tr = _bounds.GetDrawTransform();
|
||||
helpers.DrawBox(&tr);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::Rename(CSZ name)
|
||||
{
|
||||
if (_name == name)
|
||||
return;
|
||||
VERUS_QREF_SM;
|
||||
_name = sm.EnsureUniqueName(name);
|
||||
}
|
||||
|
||||
void SceneNode::SetDynamic(bool mode)
|
||||
{
|
||||
_dynamic = mode;
|
||||
_octreeBindOnce = false;
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::SetTransform(RcTransform3 tr)
|
||||
{
|
||||
_tr = tr;
|
||||
// Also update the UI values and bounds:
|
||||
const Quat q(_tr.getUpper3x3());
|
||||
_uiRotation.EulerFromQuaternion(q);
|
||||
_uiScale = _tr.GetScale();
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::RestoreTransform(RcTransform3 tr, RcVector3 rot, RcVector3 scale)
|
||||
{
|
||||
_tr = tr;
|
||||
_uiRotation = rot;
|
||||
_uiScale = scale;
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::ComputeTransform()
|
||||
{
|
||||
Quat q;
|
||||
_uiRotation.EulerToQuaternion(q);
|
||||
_tr = VMath::appendScale(Transform3(q, _tr.getTranslation()), _uiScale);
|
||||
}
|
||||
|
||||
Point3 SceneNode::GetPosition() const
|
||||
{
|
||||
return _tr.getTranslation();
|
||||
}
|
||||
|
||||
Vector3 SceneNode::GetRotation() const
|
||||
{
|
||||
return _uiRotation;
|
||||
}
|
||||
|
||||
Vector3 SceneNode::GetScale() const
|
||||
{
|
||||
return _uiScale;
|
||||
}
|
||||
|
||||
void SceneNode::MoveTo(RcPoint3 pos)
|
||||
{
|
||||
_tr.setTranslation(Vector3(pos));
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::RotateTo(RcVector3 v)
|
||||
{
|
||||
_uiRotation = v;
|
||||
ComputeTransform();
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::ScaleTo(RcVector3 v)
|
||||
{
|
||||
_uiScale = v;
|
||||
ComputeTransform();
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SceneNode::RemoveRigidBody()
|
||||
{
|
||||
if (_pBody)
|
||||
{
|
||||
VERUS_QREF_BULLET;
|
||||
bullet.GetWorld()->removeRigidBody(_pBody);
|
||||
delete _pBody->getMotionState();
|
||||
delete _pBody;
|
||||
_pBody = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::SetCollisionGroup(Physics::Group g)
|
||||
{
|
||||
if (_pBody && _pBody->getBroadphaseHandle()->m_collisionFilterGroup != +g)
|
||||
{
|
||||
// https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=7538
|
||||
VERUS_QREF_BULLET;
|
||||
bullet.GetWorld()->removeRigidBody(_pBody);
|
||||
bullet.GetWorld()->addRigidBody(_pBody, +g, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::MoveRigidBody()
|
||||
{
|
||||
if (_pBody)
|
||||
{
|
||||
// https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=6729
|
||||
VERUS_QREF_BULLET;
|
||||
_pBody->setWorldTransform(_tr.Bullet());
|
||||
bullet.GetWorld()->updateSingleAabb(_pBody);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::Serialize(IO::RSeekableStream stream)
|
||||
{
|
||||
stream.WriteString(_C(_name));
|
||||
stream << _uiRotation.GLM();
|
||||
stream << _uiScale.GLM();
|
||||
stream << _tr.GLM4x3();
|
||||
_dict.Serialize(stream);
|
||||
}
|
||||
|
||||
void SceneNode::Deserialize(IO::RStream stream)
|
||||
{
|
||||
if (stream.GetVersion() >= IO::Xxx::MakeVersion(3, 0))
|
||||
{
|
||||
char name[IO::Stream::s_bufferSize] = {};
|
||||
glm::vec3 uiRotation;
|
||||
glm::vec3 uiScale;
|
||||
glm::mat4x3 tr;
|
||||
|
||||
stream.ReadString(name);
|
||||
stream >> uiRotation;
|
||||
stream >> uiScale;
|
||||
stream >> tr;
|
||||
_dict.Deserialize(stream);
|
||||
|
||||
_name = name;
|
||||
_uiRotation = uiRotation;
|
||||
_uiScale = uiScale;
|
||||
_tr = tr;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneNode::SaveXML(pugi::xml_node node)
|
||||
{
|
||||
node.append_attribute("name") = _C(_name);
|
||||
node.append_attribute("uiR") = _C(_uiRotation.ToString(true));
|
||||
node.append_attribute("uiS") = _C(_uiScale.ToString(true));
|
||||
node.append_attribute("tr") = _C(_tr.ToString());
|
||||
}
|
||||
|
||||
void SceneNode::LoadXML(pugi::xml_node node)
|
||||
{
|
||||
if (auto attr = node.attribute("name"))
|
||||
_name = attr.value();
|
||||
_uiRotation.FromString(node.attribute("uiR").value());
|
||||
_uiScale.FromString(node.attribute("uiS").value());
|
||||
_tr.FromString(node.attribute("tr").value());
|
||||
}
|
||||
|
||||
float SceneNode::GetDistToHeadSq() const
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
return VMath::distSqr(sm.GetHeadCamera()->GetEyePosition(), GetPosition());
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
// SceneNode is an element of the scene manager container.
|
||||
// * has a name
|
||||
// * can be parent or child
|
||||
// * has generic parameters
|
||||
// * has bounds
|
||||
class SceneNode : public AllocatorAware, public Physics::UserPtr
|
||||
{
|
||||
protected:
|
||||
Transform3 _tr = Transform3::identity(); // Main transformation matrix.
|
||||
Vector3 _uiRotation = Vector3(0); // User-friendly rotation used in editor's UI.
|
||||
Vector3 _uiScale = Vector3(1, 1, 1); // User-friendly scale used in editor's UI.
|
||||
Math::Bounds _bounds;
|
||||
IO::Dictionary _dict;
|
||||
String _name;
|
||||
SceneNode* _pLinkedNode = nullptr;
|
||||
btRigidBody* _pBody = nullptr;
|
||||
NodeType _type = NodeType::unknown;
|
||||
bool _dynamic = false;
|
||||
bool _hidden = false;
|
||||
bool _octreeBindOnce = false; // Don't rebind this node after every bounds change.
|
||||
bool _selected = false;
|
||||
bool _transient = false;
|
||||
|
||||
void PreventNameCollision();
|
||||
|
||||
public:
|
||||
SceneNode();
|
||||
virtual ~SceneNode();
|
||||
|
||||
virtual int UserPtr_GetType() override;
|
||||
|
||||
virtual void Update() {}
|
||||
virtual void Draw() {}
|
||||
virtual void DrawImmediate() {}
|
||||
void DrawBounds();
|
||||
|
||||
Str GetName() const { return _C(_name); }
|
||||
void Rename(CSZ name);
|
||||
NodeType GetType() const { return _type; }
|
||||
virtual String GetUrl() { return ""; }
|
||||
IO::RDictionary GetDictionary() { return _dict; }
|
||||
void SetDictionary(IO::RcDictionary dict) { _dict = dict; };
|
||||
|
||||
SceneNode* GetLinkedNode() const { return _pLinkedNode; }
|
||||
void SetLinkedNode(SceneNode* p) { _pLinkedNode = p; }
|
||||
|
||||
bool IsDynamic() const { return _dynamic; }
|
||||
void SetDynamic(bool mode);
|
||||
|
||||
bool IsHidden() const { return _hidden; }
|
||||
void Hide(bool hide = true) { _hidden = hide; }
|
||||
|
||||
bool IsSelected() const { return _selected; }
|
||||
void Select(bool select = true) { _selected = select; }
|
||||
|
||||
bool IsTransient() const { return _transient; }
|
||||
void SetTransient(bool transient = true) { _transient = transient; }
|
||||
|
||||
virtual Vector4 GetColor() { return Vector4(0); }
|
||||
virtual void SetColor(RcVector4 color) {}
|
||||
|
||||
RcTransform3 GetTransform() const { return _tr; }
|
||||
virtual void SetTransform(RcTransform3 tr);
|
||||
virtual void RestoreTransform(RcTransform3 tr, RcVector3 rot, RcVector3 scale);
|
||||
VERUS_P(void ComputeTransform());
|
||||
|
||||
Point3 GetPosition() const; // Gets the position from the main transformation matrix.
|
||||
Vector3 GetRotation() const; // Gets the user-friendly rotation.
|
||||
Vector3 GetScale() const; // Gets the user-friendly scale.
|
||||
virtual void MoveTo(RcPoint3 pos);
|
||||
virtual void RotateTo(RcVector3 v);
|
||||
virtual void ScaleTo(RcVector3 v);
|
||||
|
||||
// Bounds:
|
||||
Math::RcBounds GetBounds() const { return _bounds; }
|
||||
virtual void UpdateBounds() {}
|
||||
|
||||
// Physics engine:
|
||||
void RemoveRigidBody();
|
||||
virtual void SetCollisionGroup(Physics::Group g = Physics::Group::immovable);
|
||||
virtual void MoveRigidBody();
|
||||
|
||||
// Serialization:
|
||||
virtual void Serialize(IO::RSeekableStream stream);
|
||||
virtual void Deserialize(IO::RStream stream);
|
||||
virtual void SaveXML(pugi::xml_node node);
|
||||
virtual void LoadXML(pugi::xml_node node);
|
||||
|
||||
float GetDistToHeadSq() const;
|
||||
};
|
||||
VERUS_TYPEDEFS(SceneNode);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include "Types.h"
|
||||
#include "SceneNode.h"
|
||||
|
||||
#include "Model.h"
|
||||
#include "SceneParticles.h"
|
||||
|
||||
#include "Light.h"
|
||||
#include "Emitter.h"
|
||||
#include "Block.h"
|
||||
#include "Prefab.h"
|
||||
#include "Trigger.h"
|
||||
|
||||
#include "Site.h"
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// SceneParticles:
|
||||
|
||||
SceneParticles::SceneParticles()
|
||||
{
|
||||
}
|
||||
|
||||
SceneParticles::~SceneParticles()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void SceneParticles::Init(RcDesc desc)
|
||||
{
|
||||
if (_refCount)
|
||||
return;
|
||||
|
||||
VERUS_INIT();
|
||||
_refCount = 1;
|
||||
|
||||
_particles.Init(desc._url);
|
||||
}
|
||||
|
||||
bool SceneParticles::Done()
|
||||
{
|
||||
_refCount--;
|
||||
if (_refCount <= 0)
|
||||
{
|
||||
VERUS_DONE(SceneParticles);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SceneParticles::Update()
|
||||
{
|
||||
_particles.Update();
|
||||
}
|
||||
|
||||
void SceneParticles::Draw()
|
||||
{
|
||||
_particles.Draw();
|
||||
}
|
||||
|
||||
// SceneParticlesPtr:
|
||||
|
||||
void SceneParticlesPtr::Init(SceneParticles::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertSceneParticles(desc._url);
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void SceneParticlesPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteSceneParticles(_C(_p->GetParticles().GetUrl()));
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class SceneParticles : public Object
|
||||
{
|
||||
Effects::Particles _particles;
|
||||
int _refCount = 0;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
CSZ _url = nullptr;
|
||||
|
||||
Desc(CSZ url = nullptr) : _url(url) {}
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
SceneParticles();
|
||||
~SceneParticles();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
bool Done();
|
||||
|
||||
void AddRef() { _refCount++; }
|
||||
Effects::RParticles GetParticles() { return _particles; }
|
||||
|
||||
void Update();
|
||||
void Draw();
|
||||
};
|
||||
VERUS_TYPEDEFS(SceneParticles);
|
||||
|
||||
class SceneParticlesPtr : public Ptr<SceneParticles>
|
||||
{
|
||||
public:
|
||||
void Init(SceneParticles::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(SceneParticlesPtr);
|
||||
|
||||
class SceneParticlesPwn : public SceneParticlesPtr
|
||||
{
|
||||
public:
|
||||
~SceneParticlesPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(SceneParticlesPwn);
|
||||
}
|
||||
}
|
|
@ -1,398 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Draft:
|
||||
|
||||
Draft::Draft()
|
||||
{
|
||||
}
|
||||
|
||||
Draft::~Draft()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Draft::Init(Site* p, RcDesc desc)
|
||||
{
|
||||
_pParent = desc._pParent;
|
||||
CGI::LightType type = CGI::LightType::none;
|
||||
if (!strcmp(desc._url, "OMNI"))
|
||||
type = CGI::LightType::omni;
|
||||
if (!strcmp(desc._url, "SPOT"))
|
||||
type = CGI::LightType::spot;
|
||||
if (type != CGI::LightType::none)
|
||||
{
|
||||
Light::Desc lightDesc;
|
||||
lightDesc._node = desc._node;
|
||||
lightDesc._data._lightType = type;
|
||||
if (p->GetRadius())
|
||||
lightDesc._data._radius = p->GetRadius();
|
||||
_light.Init(lightDesc);
|
||||
_p = _light.Get();
|
||||
}
|
||||
else if (Str::EndsWith(desc._url, ".Prefab.xml"))
|
||||
{
|
||||
Prefab::Desc prefabDesc;
|
||||
prefabDesc._node = desc._node;
|
||||
prefabDesc._url = desc._url;
|
||||
prefabDesc._collide = desc._collide;
|
||||
_prefab.Init(prefabDesc);
|
||||
_p = _prefab.Get();
|
||||
}
|
||||
else
|
||||
{
|
||||
Block::Desc blockDesc;
|
||||
blockDesc._node = desc._node;
|
||||
blockDesc._model = desc._url;
|
||||
blockDesc._matIndex = desc._matIndex;
|
||||
blockDesc._collide = desc._collide;
|
||||
String mat;
|
||||
if (desc._matIndex)
|
||||
{
|
||||
mat = desc._url;
|
||||
Str::ReplaceExtension(mat, _C(std::to_string(desc._matIndex) + ".xmt"));
|
||||
blockDesc._blockMat = _C(mat);
|
||||
}
|
||||
_block.Init(blockDesc);
|
||||
_p = _block.Get();
|
||||
}
|
||||
_p->GetDictionary().Insert("Site", _C(p->GetName()));
|
||||
}
|
||||
|
||||
void Draft::Done()
|
||||
{
|
||||
_block.Done();
|
||||
_light.Done();
|
||||
_prefab.Done();
|
||||
}
|
||||
|
||||
// DraftPtr:
|
||||
|
||||
void DraftPtr::Init(Site* p, Draft::RcDesc desc)
|
||||
{
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = p->InsertDraft();
|
||||
_p->Init(p, desc);
|
||||
}
|
||||
|
||||
void DraftPtr::Done(Site* p)
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
p->DeleteDraft(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Site:
|
||||
|
||||
Site::Site()
|
||||
{
|
||||
_type = NodeType::site;
|
||||
}
|
||||
|
||||
Site::~Site()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Site::Init(RcDesc desc)
|
||||
{
|
||||
if (_refCount)
|
||||
return;
|
||||
|
||||
_name = desc._name;
|
||||
_refCount = 1;
|
||||
}
|
||||
|
||||
bool Site::Done()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Site::Update()
|
||||
{
|
||||
if (_activeDraft)
|
||||
{
|
||||
if (_activeDraft->GetLight() && _params._radius)
|
||||
_activeDraft->GetLight()->SetRadius(_params._radius);
|
||||
const Transform3 mat = Transform3::translation(_pDelegate->Site_TransformOffset(_params._offset)) *
|
||||
_pDelegate->Site_GetTransform(_params);
|
||||
_activeDraft->Get()->SetTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
void Site::Draw()
|
||||
{
|
||||
}
|
||||
|
||||
void Site::DrawImmediate()
|
||||
{
|
||||
if (!_pDelegate)
|
||||
return;
|
||||
|
||||
VERUS_QREF_DD;
|
||||
VERUS_QREF_HELPERS;
|
||||
|
||||
const Transform3 mat = _pDelegate->Site_GetTransform(_params);
|
||||
const Point3 at = mat.getTranslation();
|
||||
const Point3 to = at + _pDelegate->Site_TransformOffset(_params._offset);
|
||||
|
||||
if (_activeDraft)
|
||||
{
|
||||
_activeDraft->Get()->DrawBounds();
|
||||
helpers.DrawBasis(&_activeDraft->Get()->GetTransform(), -1, true);
|
||||
}
|
||||
|
||||
if (!_params._offset.IsZero())
|
||||
{
|
||||
//dr.Begin(CGI::CDebugRender::T_LINES, nullptr, false);
|
||||
//dr.AddLine(at, to, VERUS_COLOR_RGBA(0, 255, 0, 255));
|
||||
//dr.End();
|
||||
}
|
||||
|
||||
if (_params._radius)
|
||||
{
|
||||
helpers.DrawCircle(at, _params._radius, VERUS_COLOR_WHITE, *_params._pTerrain);
|
||||
}
|
||||
|
||||
if (_linkedDraft)
|
||||
{
|
||||
const Point3 from = _linkedDraft->Get()->GetPosition();
|
||||
//dr.Begin(CGI::CDebugRender::T_LINES, nullptr, false);
|
||||
//dr.AddLine(from, to, VERUS_COLOR_RGBA(255, 0, 255, 255));
|
||||
//dr.End();
|
||||
}
|
||||
|
||||
for (auto& draft : TStoreDrafts::_list)
|
||||
{
|
||||
if (draft.GetLight())
|
||||
{
|
||||
LightPtr light = draft.GetLight();
|
||||
if (CGI::LightType::spot == light->GetLightType())
|
||||
{
|
||||
const Point3 target = light->GetPosition() + light->GetDirection() * light->GetRadius();
|
||||
helpers.DrawLight(light->GetPosition(), 0, &target);
|
||||
}
|
||||
else
|
||||
helpers.DrawLight(light->GetPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PDraft Site::InsertDraft()
|
||||
{
|
||||
return TStoreDrafts::Insert();
|
||||
}
|
||||
|
||||
void Site::DeleteDraft(PDraft p)
|
||||
{
|
||||
TStoreDrafts::Delete(p);
|
||||
}
|
||||
|
||||
void Site::DeleteAllDrafts()
|
||||
{
|
||||
TStoreDrafts::DeleteAll();
|
||||
}
|
||||
|
||||
void Site::Save()
|
||||
{
|
||||
IO::Xml xml;
|
||||
xml.SetFilename(_C("Site_" + _name + ".xml"));
|
||||
for (auto& draft : TStoreDrafts::_list)
|
||||
{
|
||||
pugi::xml_node node = xml.AddElement("draft");
|
||||
draft.Get()->SaveXML(node);
|
||||
if (draft.GetParent() && draft.GetLight())
|
||||
{
|
||||
const Transform3 tr = VMath::inverse(draft.GetParent()->Get()->GetTransform()) * draft.GetLight()->GetTransformNoScale();
|
||||
node.attribute("relative").set_value("1");
|
||||
node.attribute("m").set_value(_C(tr.ToString()));
|
||||
}
|
||||
}
|
||||
xml.Save();
|
||||
}
|
||||
|
||||
void Site::Load(CSZ pathname)
|
||||
{
|
||||
IO::Xml xml;
|
||||
if (pathname)
|
||||
{
|
||||
xml.SetFilename(pathname);
|
||||
}
|
||||
else if (String::npos != _name.find(':'))
|
||||
{
|
||||
const String path = IO::FileSystem::ConvertRelativePathToAbsolute(_name, true);
|
||||
xml.SetFilename(_C(path));
|
||||
}
|
||||
else
|
||||
xml.SetFilename(_C("Site_" + _name + ".xml"));
|
||||
StringStream ss;
|
||||
ss << "Site::Load(), url = " << _C(xml.GetFilename());
|
||||
xml.Load();
|
||||
|
||||
int draftCount = 0;
|
||||
auto root = xml.GetRoot();
|
||||
for (auto node : root.children("draft"))
|
||||
{
|
||||
DraftPtr draft;
|
||||
Draft::Desc draftDesc;
|
||||
draftDesc._node = node;
|
||||
draftDesc._url = node.attribute("url").value();
|
||||
draftDesc._collide = true;
|
||||
draft.Init(this, draftDesc);
|
||||
draftCount++;
|
||||
}
|
||||
ss << ", draftCount = " << draftCount;
|
||||
VERUS_LOG_INFO(ss.str());
|
||||
}
|
||||
|
||||
void Site::Add(CSZ url, int matIndex)
|
||||
{
|
||||
if (!_activeDraft)
|
||||
{
|
||||
_prevUrl = url;
|
||||
_prevMatIndex = matIndex;
|
||||
Draft::Desc draftDesc;
|
||||
draftDesc._url = url;
|
||||
draftDesc._matIndex = matIndex;
|
||||
if (_linkedDraft)
|
||||
draftDesc._pParent = _linkedDraft.Get();
|
||||
_activeDraft.Init(this, draftDesc);
|
||||
}
|
||||
}
|
||||
|
||||
void Site::Delete()
|
||||
{
|
||||
if (_activeDraft)
|
||||
{
|
||||
if (_linkedDraft == _activeDraft)
|
||||
_linkedDraft.Detach();
|
||||
_prevUrl = _activeDraft->Get()->GetUrl();
|
||||
_prevMatIndex = 0;
|
||||
_activeDraft.Done(this);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
void Site::Edit(bool link)
|
||||
{
|
||||
RDraftPtr draft = link ? _linkedDraft : _activeDraft;
|
||||
if (!draft) // Find the nearest block?
|
||||
{
|
||||
FindNearest(&draft);
|
||||
if (draft && !link)
|
||||
{
|
||||
draft->Get()->SetCollisionGroup(Physics::Group::general);
|
||||
_prevUrl = draft->Get()->GetUrl();
|
||||
_prevMatIndex = 0;
|
||||
}
|
||||
}
|
||||
else // Reset block's matrix:
|
||||
{
|
||||
if (link)
|
||||
_linkedDraft.Detach();
|
||||
}
|
||||
}
|
||||
|
||||
void Site::Duplicate()
|
||||
{
|
||||
if (!_prevUrl.empty())
|
||||
Add(_C(_prevUrl), _prevMatIndex);
|
||||
}
|
||||
|
||||
void Site::Put()
|
||||
{
|
||||
if (_activeDraft)
|
||||
{
|
||||
_activeDraft->Get()->MoveRigidBody();
|
||||
_activeDraft->Get()->SetCollisionGroup(Physics::Group::immovable);
|
||||
_activeDraft.Detach();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
PSceneNode Site::FindNearest(PDraftPtr pAttach)
|
||||
{
|
||||
PSceneNode p = nullptr;
|
||||
const Transform3 mat = Transform3::translation(_pDelegate->Site_TransformOffset(_params._offset)) *
|
||||
_pDelegate->Site_GetTransform(_params);
|
||||
const Point3 at = mat.getTranslation();
|
||||
float minDist = FLT_MAX;
|
||||
for (auto& d : TStoreDrafts::_list)
|
||||
{
|
||||
const float dist = VMath::dist(at, d.Get()->GetPosition());
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
if (pAttach)
|
||||
pAttach->Attach(&d);
|
||||
p = d.Get();
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Site::Dir(RcVector3 dir)
|
||||
{
|
||||
if (_linkedDraft && _linkedDraft->GetLight())
|
||||
{
|
||||
_linkedDraft->GetLight()->SetDirection(dir);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
void Site::DirFromPoint(float radiusScale)
|
||||
{
|
||||
if (_linkedDraft && _linkedDraft->GetLight())
|
||||
{
|
||||
const Transform3 mat = Transform3::translation(_pDelegate->Site_TransformOffset(_params._offset)) *
|
||||
_pDelegate->Site_GetTransform(_params);
|
||||
const Point3 at = mat.getTranslation();
|
||||
_linkedDraft->GetLight()->DirFromPoint(at, radiusScale);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
void Site::ConeFromPoint(bool coneIn)
|
||||
{
|
||||
if (_linkedDraft && _linkedDraft->GetLight())
|
||||
{
|
||||
const Transform3 mat = Transform3::translation(_pDelegate->Site_TransformOffset(_params._offset)) *
|
||||
_pDelegate->Site_GetTransform(_params);
|
||||
const Point3 at = mat.getTranslation();
|
||||
_linkedDraft->GetLight()->ConeFromPoint(at, coneIn);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
void Site::Commit()
|
||||
{
|
||||
}
|
||||
|
||||
PSiteDelegate Site::SetDelegate(PSiteDelegate p)
|
||||
{
|
||||
return Utils::Swap(_pDelegate, p);
|
||||
}
|
||||
|
||||
// SitePtr:
|
||||
|
||||
void SitePtr::Init(Site::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertSite(desc._name);
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void SitePwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteSite(_C(_p->GetName()));
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Site;
|
||||
|
||||
class Draft
|
||||
{
|
||||
Draft* _pParent = nullptr;
|
||||
PSceneNode _p = nullptr;
|
||||
BlockPwn _block;
|
||||
LightPwn _light;
|
||||
PrefabPwn _prefab;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
Draft* _pParent = nullptr;
|
||||
CSZ _url = nullptr;
|
||||
int _matIndex = 0;
|
||||
bool _collide = false;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Draft();
|
||||
~Draft();
|
||||
|
||||
void Init(Site* p, RcDesc desc);
|
||||
void Done();
|
||||
|
||||
Draft* GetParent() { return _pParent; }
|
||||
PSceneNode Get() { return _p; }
|
||||
BlockPtr GetBlock() { return _block; }
|
||||
LightPtr GetLight() { return _light; }
|
||||
PrefabPtr GetPrefab() { return _prefab; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Draft);
|
||||
|
||||
class DraftPtr : public Ptr<Draft>
|
||||
{
|
||||
public:
|
||||
void Init(Site* p, Draft::RcDesc desc);
|
||||
void Done(Site* p);
|
||||
};
|
||||
VERUS_TYPEDEFS(DraftPtr);
|
||||
|
||||
class SiteParams
|
||||
{
|
||||
public:
|
||||
Vector3 _offset = Vector3(0);
|
||||
PTerrain _pTerrain = nullptr;
|
||||
float _radius = 0;
|
||||
float _turn = 0;
|
||||
bool _align = true;
|
||||
bool _tilt = false;
|
||||
};
|
||||
VERUS_TYPEDEFS(SiteParams);
|
||||
|
||||
class SiteDelegate
|
||||
{
|
||||
public:
|
||||
virtual Transform3 Site_GetTransform(RcSiteParams params) = 0;
|
||||
virtual Vector3 Site_TransformOffset(RcVector3 offset) = 0;
|
||||
};
|
||||
VERUS_TYPEDEFS(SiteDelegate);
|
||||
|
||||
typedef Store<Draft> TStoreDrafts;
|
||||
class Site : public SceneNode, private TStoreDrafts
|
||||
{
|
||||
PSiteDelegate _pDelegate = nullptr;
|
||||
DraftPtr _activeDraft;
|
||||
DraftPtr _linkedDraft;
|
||||
String _prevUrl;
|
||||
int _prevMatIndex = 0;
|
||||
int _refCount = 0;
|
||||
SiteParams _params;
|
||||
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
CSZ _name = nullptr;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Site();
|
||||
~Site();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
bool Done();
|
||||
|
||||
void AddRef() { _refCount++; }
|
||||
|
||||
virtual void Update() override;
|
||||
virtual void Draw() override;
|
||||
virtual void DrawImmediate() override;
|
||||
|
||||
// Drafts:
|
||||
PDraft InsertDraft();
|
||||
void DeleteDraft(PDraft p);
|
||||
void DeleteAllDrafts();
|
||||
DraftPtr GetActiveDraft() const { return _activeDraft; }
|
||||
DraftPtr GetLinkedDraft() const { return _linkedDraft; }
|
||||
|
||||
void Save();
|
||||
void Load(CSZ pathname = nullptr);
|
||||
|
||||
// Commands:
|
||||
void Add(CSZ url, int matIndex); // +
|
||||
void Delete(); // -
|
||||
void Edit(bool link = false); // !
|
||||
void Duplicate(); // *
|
||||
void Put(); // =
|
||||
PSceneNode FindNearest(PDraftPtr pAttach = nullptr);
|
||||
|
||||
void Dir(RcVector3 dir);
|
||||
void DirFromPoint(float radiusScale = 0);
|
||||
void ConeFromPoint(bool coneIn = false);
|
||||
|
||||
void Commit();
|
||||
|
||||
PSiteDelegate SetDelegate(PSiteDelegate p);
|
||||
|
||||
// Parameters:
|
||||
void SetTerrain(PTerrain p) { _params._pTerrain = p; }
|
||||
RcVector3 GetOffset() const { return _params._offset; }
|
||||
void SetOffset(RcVector3 v) { _params._offset = v; }
|
||||
float GetRadius() const { return _params._radius; }
|
||||
void SetRadius(float x) { _params._radius = x; }
|
||||
float GetTurn() const { return _params._turn; }
|
||||
void SetTurn(float x) { _params._turn = x; }
|
||||
bool GetAlign() const { return _params._align; }
|
||||
void SetAlign(bool b) { _params._align = b; }
|
||||
bool GetTilt() const { return _params._tilt; }
|
||||
void SetTilt(bool b) { _params._tilt = b; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Site);
|
||||
|
||||
class SitePtr : public Ptr<Site>
|
||||
{
|
||||
public:
|
||||
void Init(Site::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(SitePtr);
|
||||
|
||||
class SitePwn : public SitePtr
|
||||
{
|
||||
public:
|
||||
~SitePwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(SitePwn);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "verus.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::Scene;
|
||||
|
||||
// Trigger:
|
||||
|
||||
Trigger::Trigger()
|
||||
{
|
||||
_type = NodeType::trigger;
|
||||
}
|
||||
|
||||
Trigger::~Trigger()
|
||||
{
|
||||
Done();
|
||||
}
|
||||
|
||||
void Trigger::Init(RcDesc desc)
|
||||
{
|
||||
}
|
||||
|
||||
void Trigger::Done()
|
||||
{
|
||||
}
|
||||
|
||||
// TriggerPtr:
|
||||
|
||||
void TriggerPtr::Init(Trigger::RcDesc desc)
|
||||
{
|
||||
VERUS_QREF_SM;
|
||||
VERUS_RT_ASSERT(!_p);
|
||||
_p = sm.InsertTrigger();
|
||||
if (desc._node)
|
||||
_p->LoadXML(desc._node);
|
||||
else
|
||||
_p->Init(desc);
|
||||
}
|
||||
|
||||
void TriggerPwn::Done()
|
||||
{
|
||||
if (_p)
|
||||
{
|
||||
SceneManager::I().DeleteTrigger(_p);
|
||||
_p = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
{
|
||||
namespace Scene
|
||||
{
|
||||
class Trigger : public SceneNode
|
||||
{
|
||||
public:
|
||||
struct Desc
|
||||
{
|
||||
pugi::xml_node _node;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
Trigger();
|
||||
~Trigger();
|
||||
|
||||
void Init(RcDesc desc);
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(Trigger);
|
||||
|
||||
class TriggerPtr : public Ptr<Trigger>
|
||||
{
|
||||
public:
|
||||
void Init(Trigger::RcDesc desc);
|
||||
};
|
||||
VERUS_TYPEDEFS(TriggerPtr);
|
||||
|
||||
class TriggerPwn : public TriggerPtr
|
||||
{
|
||||
public:
|
||||
~TriggerPwn() { Done(); }
|
||||
void Done();
|
||||
};
|
||||
VERUS_TYPEDEFS(TriggerPwn);
|
||||
}
|
||||
}
|
|
@ -199,7 +199,7 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
#ifdef DEF_DIR
|
||||
float4 shadowConfig = g_ubShadowFS._shadowConfig;
|
||||
shadowConfig.y = 1.0 - saturate(wrapDiffuse * shadowConfig.y);
|
||||
const float3 posForShadow = AdjustPosForShadow(posWV, normalWV, dirToLightWV, -posWV.z);
|
||||
const float3 posForShadow = AdjustPosForShadow(posWV, normalWV, dirToLightWV, -posWV.z, shadowConfig.z);
|
||||
shadowMask = ShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
g_samShadowCmp,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue