This commit is contained in:
turanszkij
2018-09-04 18:05:23 +01:00
parent d34c6058e0
commit 381d4163d4
6 changed files with 1274 additions and 1095 deletions
+154 -134
View File
@@ -31,128 +31,138 @@ MeshWindow::MeshWindow(wiGUI* gui) : GUI(gui)
y += 160;
//doubleSidedCheckBox = new wiCheckBox("Double Sided: ");
//doubleSidedCheckBox->SetTooltip("If enabled, the inside of the mesh will be visible.");
//doubleSidedCheckBox->SetPos(XMFLOAT2(x, y += step));
//doubleSidedCheckBox->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->doubleSided = args.bValue;
// }
//});
//meshWindow->AddWidget(doubleSidedCheckBox);
doubleSidedCheckBox = new wiCheckBox("Double Sided: ");
doubleSidedCheckBox->SetTooltip("If enabled, the inside of the mesh will be visible.");
doubleSidedCheckBox->SetPos(XMFLOAT2(x, y += step));
doubleSidedCheckBox->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->doubleSided = args.bValue;
}
});
meshWindow->AddWidget(doubleSidedCheckBox);
//massSlider = new wiSlider(0, 5000, 0, 100000, "Mass: ");
//massSlider->SetTooltip("Set the mass amount for the physics engine.");
//massSlider->SetSize(XMFLOAT2(100, 30));
//massSlider->SetPos(XMFLOAT2(x, y += step));
//massSlider->OnSlide([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->mass = args.fValue;
// }
//});
//meshWindow->AddWidget(massSlider);
massSlider = new wiSlider(0, 5000, 0, 100000, "Mass: ");
massSlider->SetTooltip("Set the mass amount for the physics engine.");
massSlider->SetSize(XMFLOAT2(100, 30));
massSlider->SetPos(XMFLOAT2(x, y += step));
massSlider->OnSlide([&](wiEventArgs args) {
PhysicsComponent* physicscomponent = wiRenderer::GetScene().physicscomponents.GetComponent(entity);
if (physicscomponent != nullptr)
{
physicscomponent->mass = args.fValue;
}
});
meshWindow->AddWidget(massSlider);
//frictionSlider = new wiSlider(0, 5000, 0, 100000, "Friction: ");
//frictionSlider->SetTooltip("Set the friction amount for the physics engine.");
//frictionSlider->SetSize(XMFLOAT2(100, 30));
//frictionSlider->SetPos(XMFLOAT2(x, y += step));
//frictionSlider->OnSlide([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->friction = args.fValue;
// }
//});
//meshWindow->AddWidget(frictionSlider);
frictionSlider = new wiSlider(0, 5000, 0, 100000, "Friction: ");
frictionSlider->SetTooltip("Set the friction amount for the physics engine.");
frictionSlider->SetSize(XMFLOAT2(100, 30));
frictionSlider->SetPos(XMFLOAT2(x, y += step));
frictionSlider->OnSlide([&](wiEventArgs args) {
PhysicsComponent* physicscomponent = wiRenderer::GetScene().physicscomponents.GetComponent(entity);
if (physicscomponent != nullptr)
{
physicscomponent->friction = args.fValue;
}
});
meshWindow->AddWidget(frictionSlider);
//impostorCreateButton = new wiButton("Create Impostor");
//impostorCreateButton->SetTooltip("Create an impostor image of the mesh. The mesh will be replaced by this image when far away, to render faster.");
//impostorCreateButton->SetSize(XMFLOAT2(240, 30));
//impostorCreateButton->SetPos(XMFLOAT2(x - 50, y += step));
//impostorCreateButton->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// wiRenderer::CreateImpostor(mesh, GRAPHICSTHREAD_IMMEDIATE);
// }
//});
//meshWindow->AddWidget(impostorCreateButton);
impostorCreateButton = new wiButton("Create Impostor");
impostorCreateButton->SetTooltip("Create an impostor image of the mesh. The mesh will be replaced by this image when far away, to render faster.");
impostorCreateButton->SetSize(XMFLOAT2(240, 30));
impostorCreateButton->SetPos(XMFLOAT2(x - 50, y += step));
impostorCreateButton->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
wiRenderer::CreateImpostor(entity, GRAPHICSTHREAD_IMMEDIATE);
}
});
meshWindow->AddWidget(impostorCreateButton);
//impostorDistanceSlider = new wiSlider(0, 1000, 100, 10000, "Impostor Distance: ");
//impostorDistanceSlider->SetTooltip("Assign the distance where the mesh geometry should be switched to the impostor image.");
//impostorDistanceSlider->SetSize(XMFLOAT2(100, 30));
//impostorDistanceSlider->SetPos(XMFLOAT2(x, y += step));
//impostorDistanceSlider->OnSlide([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->impostorDistance = args.fValue;
// }
//});
//meshWindow->AddWidget(impostorDistanceSlider);
impostorDistanceSlider = new wiSlider(0, 1000, 100, 10000, "Impostor Distance: ");
impostorDistanceSlider->SetTooltip("Assign the distance where the mesh geometry should be switched to the impostor image.");
impostorDistanceSlider->SetSize(XMFLOAT2(100, 30));
impostorDistanceSlider->SetPos(XMFLOAT2(x, y += step));
impostorDistanceSlider->OnSlide([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->impostorDistance = args.fValue;
}
});
meshWindow->AddWidget(impostorDistanceSlider);
//tessellationFactorSlider = new wiSlider(0, 16, 0, 10000, "Tessellation Factor: ");
//tessellationFactorSlider->SetTooltip("Set the dynamic tessellation amount. Tessellation should be enabled in the Renderer window and your GPU must support it!");
//tessellationFactorSlider->SetSize(XMFLOAT2(100, 30));
//tessellationFactorSlider->SetPos(XMFLOAT2(x, y += step));
//tessellationFactorSlider->OnSlide([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->tessellationFactor = args.fValue;
// }
//});
//meshWindow->AddWidget(tessellationFactorSlider);
tessellationFactorSlider = new wiSlider(0, 16, 0, 10000, "Tessellation Factor: ");
tessellationFactorSlider->SetTooltip("Set the dynamic tessellation amount. Tessellation should be enabled in the Renderer window and your GPU must support it!");
tessellationFactorSlider->SetSize(XMFLOAT2(100, 30));
tessellationFactorSlider->SetPos(XMFLOAT2(x, y += step));
tessellationFactorSlider->OnSlide([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->tessellationFactor = args.fValue;
}
});
meshWindow->AddWidget(tessellationFactorSlider);
//flipCullingButton = new wiButton("Flip Culling");
//flipCullingButton->SetTooltip("Flip faces to reverse triangle culling order.");
//flipCullingButton->SetSize(XMFLOAT2(240, 30));
//flipCullingButton->SetPos(XMFLOAT2(x - 50, y += step));
//flipCullingButton->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->FlipCulling();
// SetMesh(mesh);
// }
//});
//meshWindow->AddWidget(flipCullingButton);
flipCullingButton = new wiButton("Flip Culling");
flipCullingButton->SetTooltip("Flip faces to reverse triangle culling order.");
flipCullingButton->SetSize(XMFLOAT2(240, 30));
flipCullingButton->SetPos(XMFLOAT2(x - 50, y += step));
flipCullingButton->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->FlipCulling();
SetEntity(entity);
}
});
meshWindow->AddWidget(flipCullingButton);
//flipNormalsButton = new wiButton("Flip Normals");
//flipNormalsButton->SetTooltip("Flip surface normals.");
//flipNormalsButton->SetSize(XMFLOAT2(240, 30));
//flipNormalsButton->SetPos(XMFLOAT2(x - 50, y += step));
//flipNormalsButton->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->FlipNormals();
// SetMesh(mesh);
// }
//});
//meshWindow->AddWidget(flipNormalsButton);
flipNormalsButton = new wiButton("Flip Normals");
flipNormalsButton->SetTooltip("Flip surface normals.");
flipNormalsButton->SetSize(XMFLOAT2(240, 30));
flipNormalsButton->SetPos(XMFLOAT2(x - 50, y += step));
flipNormalsButton->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->FlipNormals();
SetEntity(entity);
}
});
meshWindow->AddWidget(flipNormalsButton);
//computeNormalsSmoothButton = new wiButton("Compute Normals [SMOOTH]");
//computeNormalsSmoothButton->SetTooltip("Compute surface normals of the mesh. Resulting normals will be unique per vertex.");
//computeNormalsSmoothButton->SetSize(XMFLOAT2(240, 30));
//computeNormalsSmoothButton->SetPos(XMFLOAT2(x - 50, y += step));
//computeNormalsSmoothButton->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->ComputeNormals(true);
// SetMesh(mesh);
// }
//});
//meshWindow->AddWidget(computeNormalsSmoothButton);
computeNormalsSmoothButton = new wiButton("Compute Normals [SMOOTH]");
computeNormalsSmoothButton->SetTooltip("Compute surface normals of the mesh. Resulting normals will be unique per vertex.");
computeNormalsSmoothButton->SetSize(XMFLOAT2(240, 30));
computeNormalsSmoothButton->SetPos(XMFLOAT2(x - 50, y += step));
computeNormalsSmoothButton->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->ComputeNormals(true);
SetEntity(entity);
}
});
meshWindow->AddWidget(computeNormalsSmoothButton);
//computeNormalsHardButton = new wiButton("Compute Normals [HARD]");
//computeNormalsHardButton->SetTooltip("Compute surface normals of the mesh. Resulting normals will be unique per face.");
//computeNormalsHardButton->SetSize(XMFLOAT2(240, 30));
//computeNormalsHardButton->SetPos(XMFLOAT2(x - 50, y += step));
//computeNormalsHardButton->OnClick([&](wiEventArgs args) {
// if (mesh != nullptr)
// {
// mesh->ComputeNormals(false);
// SetMesh(mesh);
// }
//});
//meshWindow->AddWidget(computeNormalsHardButton);
computeNormalsHardButton = new wiButton("Compute Normals [HARD]");
computeNormalsHardButton->SetTooltip("Compute surface normals of the mesh. Resulting normals will be unique per face.");
computeNormalsHardButton->SetSize(XMFLOAT2(240, 30));
computeNormalsHardButton->SetPos(XMFLOAT2(x - 50, y += step));
computeNormalsHardButton->OnClick([&](wiEventArgs args) {
MeshComponent* mesh = wiRenderer::GetScene().meshes.GetComponent(entity);
if (mesh != nullptr)
{
mesh->ComputeNormals(false);
SetEntity(entity);
}
});
meshWindow->AddWidget(computeNormalsHardButton);
@@ -175,26 +185,36 @@ void MeshWindow::SetEntity(Entity entity)
{
this->entity = entity;
//this->mesh = mesh;
//if (mesh != nullptr)
//{
// stringstream ss("");
// ss << "Mesh name: " << mesh->name << endl;
// ss << "Vertex count: " << mesh->vertices_POS.size() << endl;
// ss << "Index count: " << mesh->indices.size() << endl;
// ss << "Subset count: " << mesh->subsets.size() << endl;
// meshInfoLabel->SetText(ss.str());
Scene&scene = wiRenderer::GetScene();
// doubleSidedCheckBox->SetCheck(mesh->doubleSided);
// massSlider->SetValue(mesh->mass);
// frictionSlider->SetValue(mesh->friction);
// impostorDistanceSlider->SetValue(mesh->impostorDistance);
// tessellationFactorSlider->SetValue(mesh->getTessellationFactor());
// meshWindow->SetEnabled(true);
//}
//else
//{
// meshInfoLabel->SetText("Select a mesh...");
// meshWindow->SetEnabled(false);
//}
const MeshComponent* mesh = scene.meshes.GetComponent(entity);
if (mesh != nullptr)
{
const NameComponent& name = *scene.names.GetComponent(entity);
stringstream ss("");
ss << "Mesh name: " << name.name << endl;
ss << "Vertex count: " << mesh->vertices_POS.size() << endl;
ss << "Index count: " << mesh->indices.size() << endl;
ss << "Subset count: " << mesh->subsets.size() << endl;
meshInfoLabel->SetText(ss.str());
doubleSidedCheckBox->SetCheck(mesh->doubleSided);
impostorDistanceSlider->SetValue(mesh->impostorDistance);
tessellationFactorSlider->SetValue(mesh->GetTessellationFactor());
const PhysicsComponent* physicscomponent = scene.physicscomponents.GetComponent(entity);
if (physicscomponent != nullptr)
{
massSlider->SetValue(physicscomponent->mass);
frictionSlider->SetValue(physicscomponent->friction);
}
meshWindow->SetEnabled(true);
}
else
{
meshInfoLabel->SetText("Select a mesh...");
meshWindow->SetEnabled(false);
}
}
File diff suppressed because it is too large Load Diff
+279 -264
View File
File diff suppressed because it is too large Load Diff
+132 -127
View File
@@ -8137,150 +8137,155 @@ void wiRenderer::SynchronizeWithPhysicsEngine(float dt)
void wiRenderer::CreateImpostor(Entity entity, GRAPHICSTHREAD threadID)
{
//MeshComponent& mesh = GetScene().meshes.GetComponent(mesh_ref);
Scene& scene = GetScene();
//static const int res = 256;
MeshComponent& mesh = *scene.meshes.GetComponent(entity);
//const AABB& bbox = mesh.aabb;
//const XMFLOAT3 extents = bbox.getHalfWidth();
//if (!mesh.impostorTarget.IsInitialized())
//{
// mesh.impostorTarget.Initialize(res * 6, res, true, RTFormat_impostor_albedo, 0);
// mesh.impostorTarget.Add(RTFormat_impostor_normal); // normal, roughness
// mesh.impostorTarget.Add(RTFormat_impostor_surface); // surface properties
//}
static const int res = 256;
//CameraComponent savedCam = *cam;
const AABB& bbox = mesh.aabb;
const XMFLOAT3 extents = bbox.getHalfWidth();
if (!mesh.impostorTarget.IsInitialized())
{
mesh.impostorTarget.Initialize(res * 6, res, true, RTFormat_impostor_albedo, 0);
mesh.impostorTarget.Add(RTFormat_impostor_normal); // normal, roughness
mesh.impostorTarget.Add(RTFormat_impostor_surface); // surface properties
}
//BindPersistentState(threadID);
//const XMFLOAT4X4 __identity = XMFLOAT4X4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
//struct InstBuf
//{
// Instance instance;
// InstancePrev instancePrev;
//};
//UINT instancesOffset;
//volatile InstBuf* buff = (volatile InstBuf*)GetDevice()->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf), instancesOffset, threadID);
//buff->instance.Create(__identity);
//buff->instancePrev.Create(__identity);
//GetDevice()->InvalidateBufferAccess(dynamicVertexBufferPool, threadID);
CameraComponent camera = *getCamera();
TransformComponent camera_transform = *scene.transforms.GetComponent(getCameraID());
//GPUBuffer* vbs[] = {
// mesh.IsSkinned() ? mesh.streamoutBuffer_POS : mesh.vertexBuffer_POS,
// mesh.vertexBuffer_TEX,
// mesh.IsSkinned() ? mesh.streamoutBuffer_PRE : mesh.vertexBuffer_POS,
// dynamicVertexBufferPool
//};
//UINT strides[] = {
// sizeof(MeshComponent::Vertex_POS),
// sizeof(MeshComponent::Vertex_TEX),
// sizeof(MeshComponent::Vertex_POS),
// sizeof(InstBuf)
//};
//UINT offsets[] = {
// 0,
// 0,
// 0,
// instancesOffset
//};
//GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID);
BindPersistentState(threadID);
//GetDevice()->BindIndexBuffer(mesh.indexBuffer, mesh.GetIndexFormat(), 0, threadID);
const XMFLOAT4X4 __identity = XMFLOAT4X4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
struct InstBuf
{
Instance instance;
InstancePrev instancePrev;
};
UINT instancesOffset;
volatile InstBuf* buff = (volatile InstBuf*)GetDevice()->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf), instancesOffset, threadID);
buff->instance.Create(__identity);
buff->instancePrev.Create(__identity);
GetDevice()->InvalidateBufferAccess(dynamicVertexBufferPool, threadID);
//GetDevice()->BindGraphicsPSO(PSO_captureimpostor, threadID);
GPUBuffer* vbs[] = {
mesh.IsSkinned() ? mesh.streamoutBuffer_POS : mesh.vertexBuffer_POS,
mesh.vertexBuffer_TEX,
mesh.IsSkinned() ? mesh.streamoutBuffer_PRE : mesh.vertexBuffer_POS,
dynamicVertexBufferPool
};
UINT strides[] = {
sizeof(MeshComponent::Vertex_POS),
sizeof(MeshComponent::Vertex_TEX),
sizeof(MeshComponent::Vertex_POS),
sizeof(InstBuf)
};
UINT offsets[] = {
0,
0,
0,
instancesOffset
};
GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID);
//ViewPort savedViewPort = mesh.impostorTarget.viewPort;
//mesh.impostorTarget.Activate(threadID, 0, 0, 0, 0);
//for (size_t i = 0; i < 6; ++i)
//{
// mesh.impostorTarget.viewPort.Height = (float)res;
// mesh.impostorTarget.viewPort.Width = (float)res;
// mesh.impostorTarget.viewPort.TopLeftX = (float)(i*res);
// mesh.impostorTarget.viewPort.TopLeftY = 0.f;
// mesh.impostorTarget.Set(threadID);
GetDevice()->BindIndexBuffer(mesh.indexBuffer, mesh.GetIndexFormat(), 0, threadID);
// cam->ClearTransform();
// cam->Translate(bbox.getCenter());
// switch (i)
// {
// case 0:
// {
// // front capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z);
// XMStoreFloat4x4(&cam->Projection, ortho);
// }
// break;
// case 1:
// {
// // right capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.z, extents.z, -extents.y, extents.y, -extents.x, extents.x);
// XMStoreFloat4x4(&cam->Projection, ortho);
// cam->RotateRollPitchYaw(XMFLOAT3(0, -XM_PIDIV2, 0));
// }
// break;
// case 2:
// {
// // back capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z);
// XMStoreFloat4x4(&cam->Projection, ortho);
// cam->RotateRollPitchYaw(XMFLOAT3(0, -XM_PI, 0));
// }
// break;
// case 3:
// {
// // left capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.z, extents.z, -extents.y, extents.y, -extents.x, extents.x);
// XMStoreFloat4x4(&cam->Projection, ortho);
// cam->RotateRollPitchYaw(XMFLOAT3(0, XM_PIDIV2, 0));
// }
// break;
// case 4:
// {
// // bottom capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.z, extents.z, -extents.y, extents.y);
// XMStoreFloat4x4(&cam->Projection, ortho);
// cam->RotateRollPitchYaw(XMFLOAT3(-XM_PIDIV2, 0, 0));
// }
// break;
// case 5:
// {
// // top capture
// XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.z, extents.z, -extents.y, extents.y);
// XMStoreFloat4x4(&cam->Projection, ortho);
// cam->RotateRollPitchYaw(XMFLOAT3(XM_PIDIV2, 0, 0));
// }
// break;
// default:
// break;
// }
// cam->UpdateProps();
// UpdateCameraCB(cam, threadID);
GetDevice()->BindGraphicsPSO(PSO_captureimpostor, threadID);
// for (MeshComponent::MeshSubset& subset : mesh.subsets)
// {
// if (subset.subsetIndices.empty())
// {
// continue;
// }
// MaterialComponent& material = GetScene().materials.GetComponent(subset.material_ref);
ViewPort savedViewPort = mesh.impostorTarget.viewPort;
mesh.impostorTarget.Activate(threadID, 0, 0, 0, 0);
for (size_t i = 0; i < 6; ++i)
{
mesh.impostorTarget.viewPort.Height = (float)res;
mesh.impostorTarget.viewPort.Width = (float)res;
mesh.impostorTarget.viewPort.TopLeftX = (float)(i*res);
mesh.impostorTarget.viewPort.TopLeftY = 0.f;
mesh.impostorTarget.Set(threadID);
// GetDevice()->BindConstantBuffer(PS, material.constantBuffer, CB_GETBINDSLOT(MaterialCB), threadID);
camera_transform.ClearTransform();
camera_transform.Translate(bbox.getCenter());
switch (i)
{
case 0:
{
// front capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z);
XMStoreFloat4x4(&camera.Projection, ortho);
}
break;
case 1:
{
// right capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.z, extents.z, -extents.y, extents.y, -extents.x, extents.x);
XMStoreFloat4x4(&camera.Projection, ortho);
camera_transform.RotateRollPitchYaw(XMFLOAT3(0, -XM_PIDIV2, 0));
}
break;
case 2:
{
// back capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.y, extents.y, -extents.z, extents.z);
XMStoreFloat4x4(&camera.Projection, ortho);
camera_transform.RotateRollPitchYaw(XMFLOAT3(0, -XM_PI, 0));
}
break;
case 3:
{
// left capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.z, extents.z, -extents.y, extents.y, -extents.x, extents.x);
XMStoreFloat4x4(&camera.Projection, ortho);
camera_transform.RotateRollPitchYaw(XMFLOAT3(0, XM_PIDIV2, 0));
}
break;
case 4:
{
// bottom capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.z, extents.z, -extents.y, extents.y);
XMStoreFloat4x4(&camera.Projection, ortho);
camera_transform.RotateRollPitchYaw(XMFLOAT3(-XM_PIDIV2, 0, 0));
}
break;
case 5:
{
// top capture
XMMATRIX ortho = XMMatrixOrthographicOffCenterLH(-extents.x, extents.x, -extents.z, extents.z, -extents.y, extents.y);
XMStoreFloat4x4(&camera.Projection, ortho);
camera_transform.RotateRollPitchYaw(XMFLOAT3(XM_PIDIV2, 0, 0));
}
break;
default:
break;
}
camera_transform.UpdateTransform();
camera.UpdateCamera(&camera_transform);
camera.UpdateProjection();
UpdateCameraCB(&camera, threadID);
// GetDevice()->BindResource(PS, material.GetBaseColorMap(), TEXSLOT_ONDEMAND0, threadID);
// GetDevice()->BindResource(PS, material.GetNormalMap(), TEXSLOT_ONDEMAND1, threadID);
// GetDevice()->BindResource(PS, material.GetSurfaceMap(), TEXSLOT_ONDEMAND2, threadID);
for (MeshComponent::MeshSubset& subset : mesh.subsets)
{
if (subset.subsetIndices.empty())
{
continue;
}
MaterialComponent& material = *GetScene().materials.GetComponent(subset.materialID);
// GetDevice()->DrawIndexedInstanced((int)subset.subsetIndices.size(), 1, subset.indexBufferOffset, 0, 0, threadID);
GetDevice()->BindConstantBuffer(PS, material.constantBuffer, CB_GETBINDSLOT(MaterialCB), threadID);
// }
GetDevice()->BindResource(PS, material.GetBaseColorMap(), TEXSLOT_ONDEMAND0, threadID);
GetDevice()->BindResource(PS, material.GetNormalMap(), TEXSLOT_ONDEMAND1, threadID);
GetDevice()->BindResource(PS, material.GetSurfaceMap(), TEXSLOT_ONDEMAND2, threadID);
//}
//wiRenderer::GenerateMipChain(mesh.impostorTarget.GetTexture(), wiRenderer::MIPGENFILTER_LINEAR, threadID);
GetDevice()->DrawIndexedInstanced((int)subset.subsetIndices.size(), 1, subset.indexBufferOffset, 0, 0, threadID);
//mesh.impostorTarget.viewPort = savedViewPort;
//*cam = savedCam;
//UpdateCameraCB(cam, threadID);
}
}
wiRenderer::GenerateMipChain(mesh.impostorTarget.GetTexture(), wiRenderer::MIPGENFILTER_LINEAR, threadID);
mesh.impostorTarget.viewPort = savedViewPort;
UpdateCameraCB(getCamera(), threadID);
}
void wiRenderer::AddRenderableBox(const XMFLOAT4X4& boxMatrix, const XMFLOAT4& color)
+205
View File
@@ -426,6 +426,191 @@ namespace wiSceneSystem
SAFE_DELETE_ARRAY(gpuIndexData);
}
void MeshComponent::ComputeNormals(bool smooth)
{
// Start recalculating normals:
if (smooth)
{
// Compute smooth surface normals:
// 1.) Zero normals, they will be averaged later
for (size_t i = 0; i < vertices_FULL.size() - 1; i++)
{
vertices_FULL[i].nor = XMFLOAT4(0, 0, 0, 0);
}
// 2.) Find identical vertices by POSITION, accumulate face normals
for (size_t i = 0; i < vertices_FULL.size() - 1; i++)
{
Vertex_FULL& v_search = vertices_FULL[i];
for (size_t ind = 0; ind < indices.size() / 3; ++ind)
{
uint32_t i0 = indices[ind * 3 + 0];
uint32_t i1 = indices[ind * 3 + 1];
uint32_t i2 = indices[ind * 3 + 2];
Vertex_FULL& v0 = vertices_FULL[i0];
Vertex_FULL& v1 = vertices_FULL[i1];
Vertex_FULL& v2 = vertices_FULL[i2];
bool match_pos0 =
fabs(v_search.pos.x - v0.pos.x) < FLT_EPSILON &&
fabs(v_search.pos.y - v0.pos.y) < FLT_EPSILON &&
fabs(v_search.pos.z - v0.pos.z) < FLT_EPSILON;
bool match_pos1 =
fabs(v_search.pos.x - v1.pos.x) < FLT_EPSILON &&
fabs(v_search.pos.y - v1.pos.y) < FLT_EPSILON &&
fabs(v_search.pos.z - v1.pos.z) < FLT_EPSILON;
bool match_pos2 =
fabs(v_search.pos.x - v2.pos.x) < FLT_EPSILON &&
fabs(v_search.pos.y - v2.pos.y) < FLT_EPSILON &&
fabs(v_search.pos.z - v2.pos.z) < FLT_EPSILON;
if (match_pos0 || match_pos1 || match_pos2)
{
XMVECTOR U = XMLoadFloat4(&v2.pos) - XMLoadFloat4(&v0.pos);
XMVECTOR V = XMLoadFloat4(&v1.pos) - XMLoadFloat4(&v0.pos);
XMVECTOR N = XMVector3Cross(U, V);
N = XMVector3Normalize(N);
XMFLOAT3 normal;
XMStoreFloat3(&normal, N);
v_search.nor.x += normal.x;
v_search.nor.y += normal.y;
v_search.nor.z += normal.z;
}
}
}
// 3.) Find unique vertices by POSITION and TEXCOORD and MATERIAL and remove duplicates
for (size_t i = 0; i < vertices_FULL.size() - 1; i++)
{
const Vertex_FULL& v0 = vertices_FULL[i];
for (size_t j = i + 1; j < vertices_FULL.size(); j++)
{
const Vertex_FULL& v1 = vertices_FULL[j];
bool unique_pos =
fabs(v0.pos.x - v1.pos.x) < FLT_EPSILON &&
fabs(v0.pos.y - v1.pos.y) < FLT_EPSILON &&
fabs(v0.pos.z - v1.pos.z) < FLT_EPSILON;
bool unique_tex =
fabs(v0.tex.x - v1.tex.x) < FLT_EPSILON &&
fabs(v0.tex.y - v1.tex.y) < FLT_EPSILON &&
(int)v0.tex.z == (int)v1.tex.z;
if (unique_pos && unique_tex)
{
for (size_t ind = 0; ind < indices.size(); ++ind)
{
if (indices[ind] == j)
{
indices[ind] = static_cast<uint32_t>(i);
}
else if (indices[ind] > j && indices[ind] > 0)
{
indices[ind]--;
}
}
vertices_FULL.erase(vertices_FULL.begin() + j);
}
}
}
}
else
{
// Compute hard surface normals:
std::vector<uint32_t> newIndexBuffer;
std::vector<Vertex_FULL> newVertexBuffer;
for (size_t face = 0; face < indices.size() / 3; face++)
{
uint32_t i0 = indices[face * 3 + 0];
uint32_t i1 = indices[face * 3 + 1];
uint32_t i2 = indices[face * 3 + 2];
Vertex_FULL& v0 = vertices_FULL[i0];
Vertex_FULL& v1 = vertices_FULL[i1];
Vertex_FULL& v2 = vertices_FULL[i2];
XMVECTOR U = XMLoadFloat4(&v2.pos) - XMLoadFloat4(&v0.pos);
XMVECTOR V = XMLoadFloat4(&v1.pos) - XMLoadFloat4(&v0.pos);
XMVECTOR N = XMVector3Cross(U, V);
N = XMVector3Normalize(N);
XMFLOAT3 normal;
XMStoreFloat3(&normal, N);
v0.nor.x = normal.x;
v0.nor.y = normal.y;
v0.nor.z = normal.z;
v1.nor.x = normal.x;
v1.nor.y = normal.y;
v1.nor.z = normal.z;
v2.nor.x = normal.x;
v2.nor.y = normal.y;
v2.nor.z = normal.z;
newVertexBuffer.push_back(v0);
newVertexBuffer.push_back(v1);
newVertexBuffer.push_back(v2);
newIndexBuffer.push_back(static_cast<uint32_t>(newIndexBuffer.size()));
newIndexBuffer.push_back(static_cast<uint32_t>(newIndexBuffer.size()));
newIndexBuffer.push_back(static_cast<uint32_t>(newIndexBuffer.size()));
}
// For hard surface normals, we created a new mesh in the previous loop through faces, so swap data:
vertices_FULL = newVertexBuffer;
indices = newIndexBuffer;
}
CreateRenderData();
}
void MeshComponent::FlipCulling()
{
for (size_t face = 0; face < indices.size() / 3; face++)
{
uint32_t i0 = indices[face * 3 + 0];
uint32_t i1 = indices[face * 3 + 1];
uint32_t i2 = indices[face * 3 + 2];
indices[face * 3 + 0] = i0;
indices[face * 3 + 1] = i2;
indices[face * 3 + 2] = i1;
}
CreateRenderData();
}
void MeshComponent::FlipNormals()
{
for (size_t i = 0; i < vertices_FULL.size() - 1; i++)
{
Vertex_FULL& v0 = vertices_FULL[i];
v0.nor.x *= -1;
v0.nor.y *= -1;
v0.nor.z *= -1;
}
CreateRenderData();
}
void CameraComponent::CreatePerspective(float newWidth, float newHeight, float newNear, float newFar, float newFOV)
{
@@ -1094,6 +1279,26 @@ namespace wiSceneSystem
return entity;
}
wiECS::Entity Scene::Entity_CreateCamera(
const std::string& name,
float width, float height, float nearPlane, float farPlane, float fov
)
{
Entity entity = CreateEntity();
owned_entities.insert(entity);
names.Create(entity) = name;
layers.Create(entity);
transforms.Create(entity);
CameraComponent& camera = cameras.Create(entity);
camera.CreatePerspective(width, height, nearPlane, farPlane, fov);
return entity;
}
void Scene::Component_Attach(Entity entity, Entity parent)
{
+9 -1
View File
@@ -20,7 +20,7 @@ namespace wiSceneSystem
struct NameComponent
{
char name[32];
char name[128];
inline void operator=(const std::string& str) { strcpy_s(name, str.c_str()); }
};
@@ -328,6 +328,9 @@ namespace wiSceneSystem
inline bool IsDynamicVB() const { return dynamicVB; }
void CreateRenderData();
void ComputeNormals(bool smooth);
void FlipCulling();
void FlipNormals();
};
struct CullableComponent
@@ -719,6 +722,11 @@ namespace wiSceneSystem
const std::string& textureName,
const std::string& normalMapName = ""
);
// Helper function to create a camera entity:
wiECS::Entity Entity_CreateCamera(
const std::string& name,
float width, float height, float nearPlane = 0.01f, float farPlane = 1000.0f, float fov = XM_PIDIV4
);
// Attaches an entity to a parent:
void Component_Attach(wiECS::Entity entity, wiECS::Entity parent);