diff --git a/Editor/CameraWindow.cpp b/Editor/CameraWindow.cpp index 0d2cdd479..9cdafe42b 100644 --- a/Editor/CameraWindow.cpp +++ b/Editor/CameraWindow.cpp @@ -16,6 +16,8 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) fpscamera = true; orbitalCamTarget = new Transform; + movespeed = 10.0f; + rotationspeed = 1.0f; cameraWindow = new wiWindow(GUI, "Camera Window"); cameraWindow->SetSize(XMFLOAT2(400, 300)); @@ -54,7 +56,25 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) }); cameraWindow->AddWidget(fovSlider); - resetButton = new wiButton("Reset Pos"); + movespeedSlider = new wiSlider(1, 100, 10, 10000, "Movement Speed: "); + movespeedSlider->SetSize(XMFLOAT2(100, 30)); + movespeedSlider->SetPos(XMFLOAT2(x, y += inc)); + movespeedSlider->OnSlide([&](wiEventArgs args) { + movespeed = args.fValue; + }); + movespeedSlider->SetValue(rotationspeed); + cameraWindow->AddWidget(movespeedSlider); + + rotationspeedSlider = new wiSlider(0.1f, 2, 1, 10000, "Rotation Speed: "); + rotationspeedSlider->SetSize(XMFLOAT2(100, 30)); + rotationspeedSlider->SetPos(XMFLOAT2(x, y += inc)); + rotationspeedSlider->OnSlide([&](wiEventArgs args) { + rotationspeed = args.fValue; + }); + rotationspeedSlider->SetValue(rotationspeed); + cameraWindow->AddWidget(rotationspeedSlider); + + resetButton = new wiButton("Reset Camera"); resetButton->SetSize(XMFLOAT2(140, 30)); resetButton->SetPos(XMFLOAT2(x, y += inc)); resetButton->OnClick([&](wiEventArgs args) { diff --git a/Editor/CameraWindow.h b/Editor/CameraWindow.h index 822008b90..1fe476d4a 100644 --- a/Editor/CameraWindow.h +++ b/Editor/CameraWindow.h @@ -17,6 +17,8 @@ public: bool fpscamera; Transform* orbitalCamTarget; + float movespeed; + float rotationspeed; wiGUI* GUI; @@ -24,6 +26,8 @@ public: wiSlider* farPlaneSlider; wiSlider* nearPlaneSlider; wiSlider* fovSlider; + wiSlider* movespeedSlider; + wiSlider* rotationspeedSlider; wiButton* resetButton; wiCheckBox* fpsCheckBox; }; diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 1263adb6c..a13aa2910 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -308,6 +308,8 @@ void EditorComponent::DeleteWindows() SAFE_DELETE(objectWnd); SAFE_DELETE(meshWnd); SAFE_DELETE(cameraWnd); + SAFE_DELETE(rendererWnd); + SAFE_DELETE(envProbeWnd); SAFE_DELETE(decalWnd); SAFE_DELETE(lightWnd); SAFE_DELETE(animWnd); @@ -329,6 +331,7 @@ void EditorComponent::Initialize() SAFE_INIT(meshWnd); SAFE_INIT(cameraWnd); SAFE_INIT(rendererWnd); + SAFE_INIT(envProbeWnd); SAFE_INIT(decalWnd); SAFE_INIT(lightWnd); SAFE_INIT(animWnd); @@ -796,7 +799,7 @@ void EditorComponent::Load() stringstream ss(""); ss << "Help: " << endl << "############" << endl << endl; ss << "Move camera: WASD" << endl; - ss << "Look: Middle mouse button" << endl; + ss << "Look: Middle mouse button / arrow keys" << endl; ss << "Select: Right mouse button" << endl; ss << "Place decal/interact: Left mouse button when nothing is selected" << endl; ss << "Camera speed: SHIFT button" << endl; @@ -811,6 +814,7 @@ void EditorComponent::Load() ss << "Script Console / backlog: HOME button" << endl; ss << endl; ss << "You can find sample models in the models directory. Try to load one." << endl; + ss << "You can also import models from .OBJ files." << endl; ss << "You can also export models from Blender with the io_export_wicked_wi_bin.py script." << endl; ss << "You can find a program configuration file at Editor/config.ini" << endl; ss << "You can find a startup script at Editor/startup.lua (this will be executed on program start)" << endl; @@ -905,6 +909,9 @@ void EditorComponent::Update(float dt) yDif += buttonrotSpeed; } + xDif *= cameraWnd->rotationspeed; + yDif *= cameraWnd->rotationspeed; + Camera* cam = wiRenderer::getCamera(); if (cameraWnd->fpscamera) @@ -912,7 +919,7 @@ void EditorComponent::Update(float dt) // FPS Camera cam->detach(); - float speed = (wiInputManager::GetInstance()->down(VK_SHIFT) ? 100.0f : 10.0f) * dt; + const float speed = (wiInputManager::GetInstance()->down(VK_SHIFT) ? 10.0f : 1.0f) * cameraWnd->movespeed * dt; static XMVECTOR move = XMVectorSet(0, 0, 0, 0); XMVECTOR moveNew = XMVectorSet(0, 0, 0, 0); @@ -1709,8 +1716,7 @@ void ConsumeHistoryOperation(bool undo) object->mesh->subsets[i].material = new Material; object->mesh->subsets[i].material->Serialize(*archive); } - object->mesh->CreateVertexArrays(); - object->mesh->CreateBuffers(); + object->mesh->CreateRenderData(); model->Add(object); } } diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp index 41dddb6e3..227699201 100644 --- a/Editor/MeshWindow.cpp +++ b/Editor/MeshWindow.cpp @@ -100,6 +100,32 @@ MeshWindow::MeshWindow(wiGUI* gui) : GUI(gui) }); 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); + + 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); + 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)); diff --git a/Editor/MeshWindow.h b/Editor/MeshWindow.h index c748daff2..7458ef1fb 100644 --- a/Editor/MeshWindow.h +++ b/Editor/MeshWindow.h @@ -30,6 +30,8 @@ public: wiButton* impostorCreateButton; wiSlider* impostorDistanceSlider; wiSlider* tessellationFactorSlider; + wiButton* flipCullingButton; + wiButton* flipNormalsButton; wiButton* computeNormalsSmoothButton; wiButton* computeNormalsHardButton; }; diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index 70d628d00..11bd06d3b 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -320,8 +320,8 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID) GPUResource* resources[] = { wiTextureHelper::getInstance()->getRandom64x64(), - &object->mesh->indexBuffer, - &object->mesh->vertexBuffer_POS, + object->mesh->indexBuffer, + object->mesh->vertexBuffer_POS, }; device->BindResources(CS, resources, TEXSLOT_ONDEMAND0, ARRAYSIZE(resources), threadID); diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 972df4db3..3a1a72694 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -1477,6 +1477,56 @@ void VertexGroup::Serialize(wiArchive& archive) GPUBuffer Mesh::impostorVB_POS; GPUBuffer Mesh::impostorVB_TEX; +Mesh::Mesh(const string& name) : name(name) +{ + init(); +} +Mesh::~Mesh() +{ + SAFE_DELETE(indexBuffer); + SAFE_DELETE(vertexBuffer_POS); + SAFE_DELETE(vertexBuffer_TEX); + SAFE_DELETE(vertexBuffer_BON); + SAFE_DELETE(streamoutBuffer_POS); + SAFE_DELETE(streamoutBuffer_PRE); +} +void Mesh::init() +{ + parent = ""; + indices.resize(0); + renderable = false; + doubleSided = false; + aabb = AABB(); + trailInfo = RibbonTrail(); + armature = nullptr; + isBillboarded = false; + billboardAxis = XMFLOAT3(0, 0, 0); + vertexGroups.clear(); + softBody = false; + mass = friction = 1; + massVG = -1; + goalVG = -1; + softVG = -1; + goalPositions.clear(); + goalNormals.clear(); + renderDataComplete = false; + calculatedAO = false; + armatureName = ""; + impostorDistance = 100.0f; + tessellationFactor = 0.0f; + optimized = false; + bufferOffset_POS = 0; + bufferOffset_PRE = 0; + indexFormat = wiGraphicsTypes::INDEXFORMAT_16BIT; + + SAFE_INIT(indexBuffer); + SAFE_INIT(vertexBuffer_POS); + SAFE_INIT(vertexBuffer_TEX); + SAFE_INIT(vertexBuffer_BON); + SAFE_INIT(streamoutBuffer_POS); + SAFE_INIT(streamoutBuffer_PRE); +} + void Mesh::LoadFromFile(const std::string& newName, const std::string& fname , const MaterialCollection& materialColl, const unordered_set& armatures, const std::string& identifier) { name = newName; @@ -1798,18 +1848,122 @@ void Mesh::Optimize() optimized = true; } -void Mesh::CreateBuffers() +void Mesh::CreateRenderData() { - if (!buffersComplete) + if (!renderDataComplete) { - if (vertices_POS.empty()) + // First, assemble vertex, index arrays: + + // In case of recreate, delete data first: + vertices_POS.clear(); + vertices_TEX.clear(); + vertices_BON.clear(); + + // De-interleave vertex arrays: + vertices_POS.resize(vertices_FULL.size()); + vertices_TEX.resize(vertices_FULL.size()); + // do not resize vertices_BON just yet, not every mesh will need bone vertex data! + for (size_t i = 0; i < vertices_FULL.size(); ++i) { - renderable = false; + // Normalize normals: + float alpha = vertices_FULL[i].nor.w; + XMVECTOR nor = XMLoadFloat4(&vertices_FULL[i].nor); + nor = XMVector3Normalize(nor); + XMStoreFloat4(&vertices_FULL[i].nor, nor); + vertices_FULL[i].nor.w = alpha; + + // Normalize bone weights: + XMFLOAT4& wei = vertices_FULL[i].wei; + float len = wei.x + wei.y + wei.z + wei.w; + if (len > 0) + { + wei.x /= len; + wei.y /= len; + wei.z /= len; + wei.w /= len; + + if (vertices_BON.empty()) + { + // Allocate full bone vertex data when we find a correct bone weight. + vertices_BON.resize(vertices_FULL.size()); + } + vertices_BON[i] = Vertex_BON(vertices_FULL[i]); + } + + // Split and type conversion: + vertices_POS[i] = Vertex_POS(vertices_FULL[i]); + vertices_TEX[i] = Vertex_TEX(vertices_FULL[i]); } - if (!renderable) + + // Save original vertices. This will be input for CPU skinning / soft bodies + vertices_Transformed_POS = vertices_POS; + vertices_Transformed_PRE = vertices_POS; // pre <- pos!! (previous positions will have the current positions initially) + + // Map subset indices: + for (auto& subset : subsets) { - return; + subset.subsetIndices.clear(); } + for (size_t i = 0; i < indices.size(); ++i) + { + uint32_t index = indices[i]; + const XMFLOAT4& tex = vertices_FULL[index].tex; + unsigned int materialIndex = (unsigned int)floor(tex.z); + + assert((materialIndex < (unsigned int)subsets.size()) && "Bad subset index!"); + + MeshSubset& subset = subsets[materialIndex]; + subset.subsetIndices.push_back(index); + + if (index >= 65536) + { + indexFormat = INDEXFORMAT_32BIT; + } + } + + + // Goal positions, normals are controlling blending between animation and physics states for soft body rendering: + goalPositions.clear(); + goalNormals.clear(); + if (goalVG >= 0) + { + goalPositions.resize(vertexGroups[goalVG].vertices.size()); + goalNormals.resize(vertexGroups[goalVG].vertices.size()); + } + + + // Mapping render vertices to physics vertex representation: + // the physics vertices contain unique position, not duplicated by texcoord or normals + // this way we can map several renderable vertices to one physics vertex + // but the mapping function will actually be indexed by renderable vertex index for efficient retrieval. + if (!physicsverts.empty() && physicalmapGP.empty()) + { + for (size_t i = 0; i < vertices_POS.size(); ++i) + { + for (size_t j = 0; j < physicsverts.size(); ++j) + { + if (fabs(vertices_POS[i].pos.x - physicsverts[j].x) < FLT_EPSILON + && fabs(vertices_POS[i].pos.y - physicsverts[j].y) < FLT_EPSILON + && fabs(vertices_POS[i].pos.z - physicsverts[j].z) < FLT_EPSILON + ) + { + physicalmapGP.push_back(static_cast(j)); + break; + } + } + } + } + + + + // Create actual GPU data: + + SAFE_DELETE(indexBuffer); + SAFE_DELETE(vertexBuffer_POS); + SAFE_DELETE(vertexBuffer_TEX); + SAFE_DELETE(vertexBuffer_BON); + SAFE_DELETE(streamoutBuffer_POS); + SAFE_DELETE(streamoutBuffer_PRE); GPUBufferDesc bd; SubresourceData InitData; @@ -1825,7 +1979,8 @@ void Mesh::CreateBuffers() InitData.pSysMem = vertices_POS.data(); bd.ByteWidth = (UINT)(sizeof(Vertex_POS) * vertices_POS.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, &vertexBuffer_POS); + vertexBuffer_POS = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, vertexBuffer_POS); } if (!vertices_BON.empty()) @@ -1838,7 +1993,8 @@ void Mesh::CreateBuffers() InitData.pSysMem = vertices_BON.data(); bd.ByteWidth = (UINT)(sizeof(Vertex_BON) * vertices_BON.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, &vertexBuffer_BON); + vertexBuffer_BON = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, vertexBuffer_BON); ZeroMemory(&bd, sizeof(bd)); bd.Usage = USAGE_DEFAULT; @@ -1847,10 +2003,12 @@ void Mesh::CreateBuffers() bd.MiscFlags = RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; bd.ByteWidth = (UINT)(sizeof(Vertex_POS) * vertices_POS.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, &streamoutBuffer_POS); + streamoutBuffer_POS = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, streamoutBuffer_POS); bd.ByteWidth = (UINT)(sizeof(Vertex_POS) * vertices_POS.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, &streamoutBuffer_PRE); + streamoutBuffer_PRE = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, streamoutBuffer_PRE); } // texture coordinate buffers are always static: @@ -1861,7 +2019,8 @@ void Mesh::CreateBuffers() bd.MiscFlags = 0; InitData.pSysMem = vertices_TEX.data(); bd.ByteWidth = (UINT)(sizeof(Vertex_TEX) * vertices_TEX.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, &vertexBuffer_TEX); + vertexBuffer_TEX = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, vertexBuffer_TEX); // Remap index buffer to be continuous across subsets and create gpu buffer data: @@ -1915,12 +2074,13 @@ void Mesh::CreateBuffers() bd.Format = GetIndexFormat() == INDEXFORMAT_16BIT ? FORMAT_R16_UINT : FORMAT_R32_UINT; InitData.pSysMem = gpuIndexData; bd.ByteWidth = (UINT)(stride * indices.size()); - wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, &indexBuffer); + indexBuffer = new GPUBuffer; + wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, indexBuffer); SAFE_DELETE_ARRAY(gpuIndexData); - buffersComplete = true; + renderDataComplete = true; } } @@ -2107,115 +2267,6 @@ void Mesh::CreateImpostorVB() wiRenderer::GetDevice()->CreateBuffer(&bd, &InitData, &impostorVB_TEX); } } -void Mesh::CreateVertexArrays() -{ - if (arraysComplete) - { - return; - } - - // We can call this function anytime to recreate data, so clean up first: - vertices_POS.clear(); - vertices_TEX.clear(); - vertices_BON.clear(); - - // De-interleave vertex arrays: - vertices_POS.resize(vertices_FULL.size()); - vertices_TEX.resize(vertices_FULL.size()); - // do not resize vertices_BON just yet, not every mesh will need bone vertex data! - for (size_t i = 0; i < vertices_FULL.size(); ++i) - { - // Normalize normals: - float alpha = vertices_FULL[i].nor.w; - XMVECTOR nor = XMLoadFloat4(&vertices_FULL[i].nor); - nor = XMVector3Normalize(nor); - XMStoreFloat4(&vertices_FULL[i].nor, nor); - vertices_FULL[i].nor.w = alpha; - - // Normalize bone weights: - XMFLOAT4& wei = vertices_FULL[i].wei; - float len = wei.x + wei.y + wei.z + wei.w; - if (len > 0) - { - wei.x /= len; - wei.y /= len; - wei.z /= len; - wei.w /= len; - - if (vertices_BON.empty()) - { - // Allocate full bone vertex data when we find a correct bone weight. - vertices_BON.resize(vertices_FULL.size()); - } - vertices_BON[i] = Vertex_BON(vertices_FULL[i]); - } - - // Split and type conversion: - vertices_POS[i] = Vertex_POS(vertices_FULL[i]); - vertices_TEX[i] = Vertex_TEX(vertices_FULL[i]); - } - - // Save original vertices. This will be input for CPU skinning / soft bodies - vertices_Transformed_POS = vertices_POS; - vertices_Transformed_PRE = vertices_POS; // pre <- pos!! (previous positions will have the current positions initially) - - // Map subset indices: - for (auto& subset : subsets) - { - subset.subsetIndices.clear(); - } - for (size_t i = 0; i < indices.size(); ++i) - { - unsigned int index = indices[i]; - const XMFLOAT4& tex = vertices_FULL[index].tex; - unsigned int materialIndex = (unsigned int)floor(tex.z); - - assert((materialIndex < (unsigned int)subsets.size()) && "Bad subset index!"); - - MeshSubset& subset = subsets[materialIndex]; - subset.subsetIndices.push_back(index); - - if (index >= 65536) - { - indexFormat = INDEXFORMAT_32BIT; - } - } - - - // Goal positions, normals are controlling blending between animation and physics states for soft body rendering: - goalPositions.clear(); - goalNormals.clear(); - if (goalVG >= 0) - { - goalPositions.resize(vertexGroups[goalVG].vertices.size()); - goalNormals.resize(vertexGroups[goalVG].vertices.size()); - } - - - // Mapping render vertices to physics vertex representation: - // the physics vertices contain unique position, not duplicated by texcoord or normals - // this way we can map several renderable vertices to one physics vertex - // but the mapping function will actually be indexed by renderable vertex index for efficient retrieval. - if (!physicsverts.empty() && physicalmapGP.empty()) - { - for (size_t i = 0; i < vertices_POS.size(); ++i) - { - for (size_t j = 0; j < physicsverts.size(); ++j) - { - if (fabs(vertices_POS[i].pos.x - physicsverts[j].x) < FLT_EPSILON - && fabs(vertices_POS[i].pos.y - physicsverts[j].y) < FLT_EPSILON - && fabs(vertices_POS[i].pos.z - physicsverts[j].z) < FLT_EPSILON - ) - { - physicalmapGP.push_back(static_cast(j)); - break; - } - } - } - } - - arraysComplete = true; -} void Mesh::ComputeNormals(bool smooth) { // Start recalculating normals: @@ -2371,11 +2422,38 @@ void Mesh::ComputeNormals(bool smooth) } // force recreate: - arraysComplete = false; - buffersComplete = false; + renderDataComplete = false; + CreateRenderData(); +} +void Mesh::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]; - CreateVertexArrays(); - CreateBuffers(); + indices[face * 3 + 0] = i0; + indices[face * 3 + 1] = i2; + indices[face * 3 + 2] = i1; + } + + renderDataComplete = false; + CreateRenderData(); +} +void Mesh::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; + } + + renderDataComplete = false; + CreateRenderData(); } int Mesh::GetRenderTypes() const @@ -2963,9 +3041,8 @@ void Model::FinishLoading() } // Mesh renderdata setup - x->mesh->CreateVertexArrays(); x->mesh->Optimize(); - x->mesh->CreateBuffers(); + x->mesh->CreateRenderData(); if (x->mesh->armature != nullptr) { diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index e805f9da1..198e42b60 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -446,12 +446,12 @@ public: std::vector subsets; std::vector materialNames; - wiGraphicsTypes::GPUBuffer indexBuffer; - wiGraphicsTypes::GPUBuffer vertexBuffer_POS; - wiGraphicsTypes::GPUBuffer vertexBuffer_TEX; - wiGraphicsTypes::GPUBuffer vertexBuffer_BON; - wiGraphicsTypes::GPUBuffer streamoutBuffer_POS; - wiGraphicsTypes::GPUBuffer streamoutBuffer_PRE; + wiGraphicsTypes::GPUBuffer* indexBuffer; + wiGraphicsTypes::GPUBuffer* vertexBuffer_POS; + wiGraphicsTypes::GPUBuffer* vertexBuffer_TEX; + wiGraphicsTypes::GPUBuffer* vertexBuffer_BON; + wiGraphicsTypes::GPUBuffer* streamoutBuffer_POS; + wiGraphicsTypes::GPUBuffer* streamoutBuffer_PRE; // Dynamic vertexbuffers write into a global pool, these will be the offsets into that: UINT bufferOffset_POS; @@ -488,54 +488,19 @@ public: float tessellationFactor; bool optimized; + bool renderDataComplete; - Mesh(){ - init(); - } - Mesh(const std::string& newName){ - name=newName; - init(); - } - ~Mesh() {} + Mesh(const std::string& newName = ""); + ~Mesh(); void LoadFromFile(const std::string& newName, const std::string& fname , const MaterialCollection& materialColl, const std::unordered_set& armatures, const std::string& identifier=""); - bool buffersComplete; void Optimize(); - void CreateBuffers(); + void CreateRenderData(); static void CreateImpostorVB(); - bool arraysComplete; - void CreateVertexArrays(); void ComputeNormals(bool smooth = false); - void init() - { - parent=""; - indices.resize(0); - renderable=false; - doubleSided=false; - aabb=AABB(); - trailInfo=RibbonTrail(); - armature=nullptr; - isBillboarded=false; - billboardAxis=XMFLOAT3(0,0,0); - vertexGroups.clear(); - softBody=false; - mass=friction=1; - massVG=-1; - goalVG=-1; - softVG = -1; - goalPositions.clear(); - goalNormals.clear(); - buffersComplete = false; - arraysComplete = false; - calculatedAO = false; - armatureName = ""; - impostorDistance = 100.0f; - tessellationFactor = 0.0f; - optimized = false; - bufferOffset_POS = 0; - bufferOffset_PRE = 0; - indexFormat = wiGraphicsTypes::INDEXFORMAT_16BIT; - } + void FlipCulling(); + void FlipNormals(); + void init(); bool hasArmature() const { return armature != nullptr; } bool hasImpostor() const { return impostorTarget.IsInitialized(); } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index bababf402..6bc248a7f 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3399,7 +3399,7 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) Mesh* mesh = iter->second; if (mesh->hasArmature() && !mesh->hasDynamicVB() && mesh->renderable && !mesh->vertices_POS.empty() - && mesh->streamoutBuffer_POS.IsValid() && mesh->vertexBuffer_POS.IsValid()) + && mesh->streamoutBuffer_POS != nullptr && mesh->vertexBuffer_POS != nullptr) { Armature* armature = mesh->armature; @@ -3441,12 +3441,12 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) // Do the skinning GPUResource* vbs[] = { - &mesh->vertexBuffer_POS, - &mesh->vertexBuffer_BON, + mesh->vertexBuffer_POS, + mesh->vertexBuffer_BON, }; GPUResource* sos[] = { - &mesh->streamoutBuffer_POS, - &mesh->streamoutBuffer_PRE, + mesh->streamoutBuffer_POS, + mesh->streamoutBuffer_PRE, }; GetDevice()->BindResources(CS, vbs, SKINNINGSLOT_IN_VERTEX_POS, ARRAYSIZE(vbs), threadID); @@ -4151,13 +4151,13 @@ void wiRenderer::DrawDebugEmitters(Camera* camera, GRAPHICSTHREAD threadID) GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); GPUBuffer* vbs[] = { - &x->object->mesh->vertexBuffer_POS, + x->object->mesh->vertexBuffer_POS, }; const UINT strides[] = { sizeof(Mesh::Vertex_POS), }; GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, nullptr, threadID); - GetDevice()->BindIndexBuffer(&x->object->mesh->indexBuffer, x->object->mesh->GetIndexFormat(), 0, threadID); + GetDevice()->BindIndexBuffer(x->object->mesh->indexBuffer, x->object->mesh->GetIndexFormat(), 0, threadID); GetDevice()->DrawIndexed((int)x->object->mesh->indices.size(), 0, 0, threadID); } @@ -5241,7 +5241,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle if (k < 1) continue; - device->BindIndexBuffer(&mesh->indexBuffer, mesh->GetIndexFormat(), 0, threadID); + device->BindIndexBuffer(mesh->indexBuffer, mesh->GetIndexFormat(), 0, threadID); enum class BOUNDVERTEXBUFFERTYPE { @@ -5335,7 +5335,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::POSITION: { GPUBuffer* vbs[] = { - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS != nullptr ? mesh->streamoutBuffer_POS : mesh->vertexBuffer_POS), dynamicVertexBufferPool }; UINT strides[] = { @@ -5352,8 +5352,8 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::POSITION_TEXCOORD: { GPUBuffer* vbs[] = { - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), - &mesh->vertexBuffer_TEX, + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS != nullptr ? mesh->streamoutBuffer_POS : mesh->vertexBuffer_POS), + mesh->vertexBuffer_TEX, dynamicVertexBufferPool }; UINT strides[] = { @@ -5372,9 +5372,9 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle case BOUNDVERTEXBUFFERTYPE::EVERYTHING: { GPUBuffer* vbs[] = { - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), - &mesh->vertexBuffer_TEX, - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS != nullptr ? mesh->streamoutBuffer_POS : mesh->vertexBuffer_POS), + mesh->vertexBuffer_TEX, + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE != nullptr ? mesh->streamoutBuffer_PRE : mesh->vertexBuffer_POS), dynamicVertexBufferPool, dynamicVertexBufferPool }; @@ -7193,9 +7193,9 @@ void wiRenderer::CreateImpostor(Mesh* mesh) GetDevice()->InvalidateBufferAccess(dynamicVertexBufferPool, threadID); GPUBuffer* vbs[] = { - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS.IsValid() ? &mesh->streamoutBuffer_POS : &mesh->vertexBuffer_POS), - &mesh->vertexBuffer_TEX, - mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE.IsValid() ? &mesh->streamoutBuffer_PRE : &mesh->vertexBuffer_POS), + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_POS != nullptr ? mesh->streamoutBuffer_POS : mesh->vertexBuffer_POS), + mesh->vertexBuffer_TEX, + mesh->hasDynamicVB() ? dynamicVertexBufferPool : (mesh->streamoutBuffer_PRE != nullptr ? mesh->streamoutBuffer_PRE : mesh->vertexBuffer_POS), dynamicVertexBufferPool, dynamicVertexBufferPool }; @@ -7215,7 +7215,7 @@ void wiRenderer::CreateImpostor(Mesh* mesh) }; GetDevice()->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, offsets, threadID); - GetDevice()->BindIndexBuffer(&mesh->indexBuffer, mesh->GetIndexFormat(), 0, threadID); + GetDevice()->BindIndexBuffer(mesh->indexBuffer, mesh->GetIndexFormat(), 0, threadID); GetDevice()->BindPrimitiveTopology(TRIANGLELIST, threadID); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 890895b40..5196197cc 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -292,7 +292,7 @@ protected: UINT mips; VoxelizedSceneData() :enabled(false), res(128), voxelsize(1.0f), center(XMFLOAT3(0, 0, 0)), extents(XMFLOAT3(0, 0, 0)), numCones(8), - rayStepSize(0.5f), secondaryBounceEnabled(true), reflectionsEnabled(false), centerChangedThisFrame(true), mips(8) + rayStepSize(0.5f), secondaryBounceEnabled(true), reflectionsEnabled(false), centerChangedThisFrame(true), mips(7) {} } static voxelSceneData; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index e25f06eba..88a0ab0f1 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 16; // minor bug fixes, alterations, refactors, updates - const int revision = 35; + const int revision = 36; long GetVersion() diff --git a/models/Sponza/sponza.wimf b/models/Sponza/sponza.wimf index e59aaf0c3..297e795f2 100644 Binary files a/models/Sponza/sponza.wimf and b/models/Sponza/sponza.wimf differ