diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp index b5d71c885..76fcfeb86 100644 --- a/Editor/MeshWindow.cpp +++ b/Editor/MeshWindow.cpp @@ -266,9 +266,14 @@ void MeshWindow::SetEntity(Entity entity) } tessellationFactorSlider->SetValue(mesh->GetTessellationFactor()); + softbodyCheckBox->SetEnabled(false); + massSlider->SetValue(0); + frictionSlider->SetValue(0); + SoftBodyPhysicsComponent* physicscomponent = wiRenderer::GetScene().softbodies.GetComponent(entity); if (physicscomponent != nullptr) { + softbodyCheckBox->SetEnabled(true); massSlider->SetValue(physicscomponent->mass); frictionSlider->SetValue(physicscomponent->friction); } diff --git a/WickedEngine/skinningCS.hlsl b/WickedEngine/skinningCS.hlsl index 26df8861d..ccee6262b 100644 --- a/WickedEngine/skinningCS.hlsl +++ b/WickedEngine/skinningCS.hlsl @@ -20,8 +20,6 @@ RAWBUFFER(vertexBuffer_POS, SKINNINGSLOT_IN_VERTEX_POS); RAWBUFFER(vertexBuffer_BON, SKINNINGSLOT_IN_VERTEX_BON); RWRAWBUFFER(streamoutBuffer_POS, SKINNINGSLOT_OUT_VERTEX_POS); -RWRAWBUFFER(streamoutBuffer_PRE, SKINNINGSLOT_OUT_VERTEX_PRE); - inline void Skinning(inout float3 pos, inout float3 nor, in float4 inBon, in float4 inWei) @@ -131,6 +129,5 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) } // Store data: - streamoutBuffer_PRE.Store4(fetchAddress_POS_NOR, streamoutBuffer_POS.Load4(fetchAddress_POS_NOR)); // copy prev frame current pos to current frame prev pos streamoutBuffer_POS.Store4(fetchAddress_POS_NOR, pos_nor_u); } \ No newline at end of file diff --git a/WickedEngine/wiGPUBVH.cpp b/WickedEngine/wiGPUBVH.cpp index 73fa93475..ad00f1c2d 100644 --- a/WickedEngine/wiGPUBVH.cpp +++ b/WickedEngine/wiGPUBVH.cpp @@ -261,11 +261,9 @@ void wiGPUBVH::Build(const Scene& scene, GRAPHICSTHREAD threadID) if (object.meshID != INVALID_ENTITY) { const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); - Entity entity = scene.objects.GetEntity(i); - const TransformComponent& transform = scene.transforms[object.transformComponentIndex]; BVHCB cb; - cb.xTraceBVHWorld = transform.world; + cb.xTraceBVHWorld = object.transform_index >= 0 ? scene.transforms[object.transform_index].world : IDENTITYMATRIX; cb.xTraceBVHMaterialOffset = materialCount; cb.xTraceBVHMeshTriangleOffset = triangleCount; cb.xTraceBVHMeshTriangleCount = (uint)mesh.indices.size() / 3; diff --git a/WickedEngine/wiPhysicsEngine_Bullet.cpp b/WickedEngine/wiPhysicsEngine_Bullet.cpp index 4cf89dd52..211c3ade0 100644 --- a/WickedEngine/wiPhysicsEngine_Bullet.cpp +++ b/WickedEngine/wiPhysicsEngine_Bullet.cpp @@ -198,24 +198,29 @@ namespace wiPhysicsEngine physicscomponent.physicsobject = body; } } - void AddSoftBody(Entity entity, wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, const wiSceneSystem::MeshComponent& mesh, const wiSceneSystem::TransformComponent& transform) + void AddSoftBody(Entity entity, wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, const wiSceneSystem::MeshComponent& mesh) { - btVector3 S = btVector3(transform.scale_local.x, transform.scale_local.y, transform.scale_local.z); - btQuaternion R = btQuaternion(transform.rotation_local.x, transform.rotation_local.y, transform.rotation_local.z, transform.rotation_local.z); - btVector3 T = btVector3(transform.translation_local.x, transform.translation_local.y, transform.translation_local.z); - - if (physicscomponent.physicsvertices.empty()) + if (physicscomponent.physicsToGraphicsVertexMapping.empty()) { physicscomponent.CreateFromMesh(mesh); } - const int vCount = (int)physicscomponent.physicsvertices.size(); + XMMATRIX worldMatrix = XMLoadFloat4x4(&physicscomponent.worldMatrix); + + const int vCount = (int)physicscomponent.physicsToGraphicsVertexMapping.size(); btScalar* btVerts = new btScalar[vCount * 3]; for (int i = 0; i < vCount; ++i) { - btVerts[i * 3 + 0] = btScalar(physicscomponent.physicsvertices[i].x); - btVerts[i * 3 + 1] = btScalar(physicscomponent.physicsvertices[i].y); - btVerts[i * 3 + 2] = btScalar(physicscomponent.physicsvertices[i].z); + uint32_t graphicsInd = physicscomponent.physicsToGraphicsVertexMapping[i]; + + XMFLOAT3 position = mesh.vertex_positions[graphicsInd]; + XMVECTOR P = XMLoadFloat3(&position); + P = XMVector3Transform(P, worldMatrix); + XMStoreFloat3(&position, P); + + btVerts[i * 3 + 0] = btScalar(position.x); + btVerts[i * 3 + 1] = btScalar(position.y); + btVerts[i * 3 + 2] = btScalar(position.z); } const int iCount = (int)mesh.indices.size(); @@ -253,20 +258,12 @@ namespace wiPhysicsEngine softBody->generateBendingConstraints(2, pm); softBody->randomizeConstraints(); - //btTransform shapeTransform; - //shapeTransform.setIdentity(); - //shapeTransform.setOrigin(T); - //shapeTransform.setRotation(R); - //softBody->scale(S); - //softBody->transform(shapeTransform); - - softBody->m_cfg.piterations = softbodyIterationCount; softBody->m_cfg.aeromodel = btSoftBody::eAeroModel::F_TwoSidedLiftDrag; softBody->m_cfg.kAHR = btScalar(.69); //0.69 Anchor hardness [0,1] softBody->m_cfg.kCHR = btScalar(1.0); //1 Rigid contact hardness [0,1] - softBody->m_cfg.kDF = btScalar(physicscomponent.friction); //0.2 Dynamic friction coefficient [0,1] + softBody->m_cfg.kDF = btScalar(0.2); //0.2 Dynamic friction coefficient [0,1] softBody->m_cfg.kDG = btScalar(0.01); //0 Drag coefficient [0,+inf] softBody->m_cfg.kDP = btScalar(0.0); //0 Damping coefficient [0,1] softBody->m_cfg.kKHR = btScalar(0.1); //0.1 Kinetic contact hardness [0,1] @@ -285,18 +282,20 @@ namespace wiPhysicsEngine softBody->m_cfg.kSS_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1] - softBody->setTotalMass(physicscomponent.mass * physicscomponent.physicsvertices.size()); + softBody->setTotalMass(physicscomponent.mass); - for (size_t i = 0; i < physicscomponent.physicsvertices.size(); ++i) + for (size_t i = 0; i < physicscomponent.physicsToGraphicsVertexMapping.size(); ++i) { - softBody->setMass((int)i, physicscomponent.mass); + float weight = physicscomponent.weights[i]; + softBody->setMass((int)i, weight); } - //softBody->getCollisionShape()->setMargin(btScalar(0.2)); - softBody->setPose(true, true); - softBody->setActivationState(DISABLE_DEACTIVATION); + if (physicscomponent.IsDisableDeactivation()) + { + softBody->setActivationState(DISABLE_DEACTIVATION); + } ((btSoftRigidDynamicsWorld*)dynamicsWorld)->addSoftBody(softBody); physicscomponent.physicsobject = softBody; @@ -340,19 +339,21 @@ namespace wiPhysicsEngine // Try to register softbodies to Meshes: for (size_t i = 0; i < softbodies.GetCount(); ++i) { - Entity entity = softbodies.GetEntity(i); SoftBodyPhysicsComponent& physicscomponent = softbodies[i]; + Entity entity = softbodies.GetEntity(i); MeshComponent& mesh = *meshes.GetComponent(entity); mesh.SetDynamic(true); - if (physicscomponent.physicsobject == nullptr) + if (physicscomponent._flags & SoftBodyPhysicsComponent::SAFE_TO_REGISTER && physicscomponent.physicsobject == nullptr) { - TransformComponent transform; - AddSoftBody(entity, physicscomponent, mesh, transform); + AddSoftBody(entity, physicscomponent, mesh); } } - // Update all physics components and remove from simulation if components no longer exist: + // Perform internal simulation step: + dynamicsWorld->stepSimulation(dt, 10); + + // Synchronize scene entities with physics engine: for (int i = 0; i < dynamicsWorld->getCollisionObjectArray().size(); ++i) { btCollisionObject* collisionobject = dynamicsWorld->getCollisionObjectArray()[i]; @@ -375,10 +376,13 @@ namespace wiPhysicsEngine btMotionState* motionState = rigidbody->getMotionState(); btTransform physicsTransform; + // For kinematic object, system updates physics state, else the physics updates system state: if (physicscomponent->IsKinematic()) { - btVector3 T(transform.translation_local.x, transform.translation_local.y, transform.translation_local.z); - btQuaternion R(transform.rotation_local.x, transform.rotation_local.y, transform.rotation_local.z, transform.rotation_local.w); + XMFLOAT3 position = transform.GetPosition(); + XMFLOAT4 rotation = transform.GetRotation(); + btVector3 T(position.x, position.y, position.z); + btQuaternion R(rotation.x, rotation.y, rotation.z, rotation.w); physicsTransform.setOrigin(T); physicsTransform.setRotation(R); motionState->setWorldTransform(physicsTransform); @@ -417,30 +421,54 @@ namespace wiPhysicsEngine softbody->getAabb(aabb_min, aabb_max); mesh.aabb = AABB(XMFLOAT3(aabb_min.x(), aabb_min.y(), aabb_min.z()), XMFLOAT3(aabb_max.x(), aabb_max.y(), aabb_max.z())); + // This is different from rigid bodies, because soft body is a per mesh component. World matrix is propagated down from single mesh instance (ObjectUpdateSystem). + XMMATRIX worldMatrix = XMLoadFloat4x4(&physicscomponent->worldMatrix); + + // System can control zero weight soft body nodes: + for (size_t ind = 0; ind < physicscomponent->weights.size(); ++ind) + { + float weight = physicscomponent->weights[ind]; + + if (weight == 0) + { + btSoftBody::Node& node = softbody->m_nodes[(uint32_t)ind]; + uint32_t graphicsInd = physicscomponent->physicsToGraphicsVertexMapping[ind]; + XMFLOAT3 position = mesh.vertex_positions[graphicsInd]; + XMVECTOR P = XMLoadFloat3(&position); + P = XMVector3Transform(P, worldMatrix); + XMStoreFloat3(&position, P); + node.m_x = btVector3(position.x, position.y, position.z); + } + } + + // Soft body simulation nodes will update graphics mesh: for (size_t ind = 0; ind < mesh.vertex_positions.size(); ++ind) { uint32_t physicsInd = physicscomponent->graphicsToPhysicsVertexMapping[ind]; - btSoftBody::Node& node = softbody->m_nodes[physicsInd]; + float weight = physicscomponent->weights[physicsInd]; - XMFLOAT3& position = mesh.vertex_positions[ind]; - position.x = node.m_x.getX(); - position.y = node.m_x.getY(); - position.z = node.m_x.getZ(); - - if (!mesh.vertex_normals.empty()) + if (weight > 0) { - XMFLOAT3& normal = mesh.vertex_normals[ind]; - normal.x = -node.m_n.getX(); - normal.y = -node.m_n.getY(); - normal.z = -node.m_n.getZ(); + btSoftBody::Node& node = softbody->m_nodes[physicsInd]; + + XMFLOAT3& position = mesh.vertex_positions[ind]; + position.x = node.m_x.getX(); + position.y = node.m_x.getY(); + position.z = node.m_x.getZ(); + + if (!mesh.vertex_normals.empty()) + { + XMFLOAT3& normal = mesh.vertex_normals[ind]; + normal.x = -node.m_n.getX(); + normal.y = -node.m_n.getY(); + normal.z = -node.m_n.getZ(); + } } } } } } - dynamicsWorld->stepSimulation(dt, 10); - wiProfiler::GetInstance().EndRange(); // Physics } } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 30063df17..f782e3940 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -1433,21 +1433,19 @@ void RenderMeshes(const RenderQueue& renderQueue, SHADERTYPE shaderType, UINT re instancedBatchArray[instancedBatchCount - 1].forceAlphatestForDithering = 1; } - const TransformComponent& transform = scene.transforms[instance.transformComponentIndex]; + const XMFLOAT4X4& worldMatrix = instance.transform_index >= 0 ? scene.transforms[instance.transform_index].world : IDENTITYMATRIX; // Write into actual GPU-buffer: if (advancedVBRequest) { - ((volatile InstBuf*)instances)[batchID].instance.Create(transform.world, instance.color, dither); + ((volatile InstBuf*)instances)[batchID].instance.Create(worldMatrix, instance.color, dither); - // The following GetComponent() is going to be a map lookup in this hot loop, but ideally just once per frame per object. Might need to optimize later if it becomes a problem: - Entity objectEntity = scene.objects.GetEntity(instanceIndex); - const PreviousFrameTransformComponent& prev_transform = *scene.prev_transforms.GetComponent(objectEntity); - ((volatile InstBuf*)instances)[batchID].instancePrev.Create(prev_transform.world_prev); + const XMFLOAT4X4& prev_worldMatrix = instance.prev_transform_index >= 0 ? scene.prev_transforms[instance.prev_transform_index].world_prev : IDENTITYMATRIX; + ((volatile InstBuf*)instances)[batchID].instancePrev.Create(prev_worldMatrix); } else { - ((volatile Instance*)instances)[batchID].Create(transform.world, instance.color, dither); + ((volatile Instance*)instances)[batchID].Create(worldMatrix, instance.color, dither); } instancedBatchArray[instancedBatchCount - 1].instanceCount++; // next instance in current InstancedBatch @@ -1608,7 +1606,7 @@ void RenderMeshes(const RenderQueue& renderQueue, SHADERTYPE shaderType, UINT re GPUBuffer* vbs[] = { mesh.streamoutBuffer_POS.get() != nullptr ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), mesh.vertexBuffer_TEX.get(), - mesh.streamoutBuffer_PRE.get() != nullptr ? mesh.streamoutBuffer_PRE.get() : mesh.vertexBuffer_POS.get(), + mesh.vertexBuffer_PRE.get() != nullptr ? mesh.vertexBuffer_PRE.get() : mesh.vertexBuffer_POS.get(), &dynamicVertexBufferPools[threadID] }; UINT strides[] = { @@ -3367,10 +3365,43 @@ void SetUpStates() void UpdatePerFrameData(float dt) { + GraphicsDevice* device = GetDevice(); Scene& scene = GetScene(); scene.Update(dt * GetGameSpeed()); + // Need to swap prev and current vertex buffers for any dynamic meshes BEFORE render threads are kicked: + { + for (size_t i = 0; i < scene.meshes.GetCount(); ++i) + { + MeshComponent& mesh = scene.meshes[i]; + + if (mesh.IsSkinned() && scene.armatures.Contains(mesh.armatureID)) + { + if (mesh.vertexBuffer_PRE == nullptr) + { + mesh.vertexBuffer_PRE.reset(new GPUBuffer); + HRESULT hr = device->CreateBuffer(&mesh.streamoutBuffer_POS->GetDesc(), nullptr, mesh.vertexBuffer_PRE.get()); + assert(SUCCEEDED(hr)); + } + mesh.streamoutBuffer_POS.swap(mesh.vertexBuffer_PRE); + } + } + for (size_t i = 0; i < scene.softbodies.GetCount(); ++i) + { + Entity entity = scene.softbodies.GetEntity(i); + MeshComponent& mesh = *scene.meshes.GetComponent(entity); + + if (mesh.vertexBuffer_PRE == nullptr) + { + mesh.vertexBuffer_PRE.reset(new GPUBuffer); + HRESULT hr = device->CreateBuffer(&mesh.vertexBuffer_POS->GetDesc(), nullptr, mesh.vertexBuffer_PRE.get()); + assert(SUCCEEDED(hr)); + } + mesh.vertexBuffer_POS.swap(mesh.vertexBuffer_PRE); + } + } + // Update Voxelization parameters: if (scene.objects.GetCount() > 0) { @@ -3895,16 +3926,15 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) mesh.vertexBuffer_POS.get(), mesh.vertexBuffer_BON.get(), }; - GPUResource* sos[] = { + GPUResource* so[] = { mesh.streamoutBuffer_POS.get(), - mesh.streamoutBuffer_PRE.get(), }; device->BindResources(CS, vbs, SKINNINGSLOT_IN_VERTEX_POS, ARRAYSIZE(vbs), threadID); - device->BindUAVs(CS, sos, 0, ARRAYSIZE(sos), threadID); + device->BindUAVs(CS, so, 0, ARRAYSIZE(so), threadID); device->Dispatch((UINT)ceilf((float)mesh.vertex_positions.size() / SKINNING_COMPUTE_THREADCOUNT), 1, 1, threadID); - device->UAVBarrier(sos, ARRAYSIZE(sos), threadID); // todo: defer, to gain from async compute + device->UAVBarrier(so, ARRAYSIZE(so), threadID); // todo: defer, to gain from async compute } } @@ -3925,6 +3955,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) Entity entity = scene.softbodies.GetEntity(i); MeshComponent& mesh = *scene.meshes.GetComponent(entity); + // Copy new simulation data to vertex buffer const size_t vb_size = sizeof(MeshComponent::Vertex_POS) * mesh.vertex_positions.size(); MeshComponent::Vertex_POS* vb = (MeshComponent::Vertex_POS*)frameAllocators[threadID].allocate(vb_size); @@ -5943,7 +5974,7 @@ void RefreshImpostors(GRAPHICSTHREAD threadID) GPUBuffer* vbs[] = { mesh.IsSkinned() ? mesh.streamoutBuffer_POS.get() : mesh.vertexBuffer_POS.get(), mesh.vertexBuffer_TEX.get(), - mesh.IsSkinned() ? mesh.streamoutBuffer_PRE.get() : mesh.vertexBuffer_POS.get(), + mesh.vertexBuffer_POS.get(), &dynamicVertexBufferPools[threadID] }; UINT strides[] = { @@ -7719,8 +7750,7 @@ RayIntersectWorldResult RayIntersectWorld(const RAY& ray, UINT renderTypeMask, u if (layer.GetLayerMask() & layerMask) { const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); - - const TransformComponent& transform = scene.transforms[object.transformComponentIndex]; + const TransformComponent& transform = scene.transforms[object.transform_index]; const XMMATRIX objectMat = XMLoadFloat4x4(&transform.world); const XMMATRIX objectMat_Inverse = XMMatrixInverse(nullptr, objectMat); diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index 28d4f1747..fdf01204e 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -395,11 +395,6 @@ namespace wiSceneSystem streamoutBuffer_POS.reset(new GPUBuffer); hr = wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, streamoutBuffer_POS.get()); assert(SUCCEEDED(hr)); - - bd.ByteWidth = (UINT)(sizeof(Vertex_POS) * vertex_positions.size()); - streamoutBuffer_PRE.reset(new GPUBuffer); - hr = wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, streamoutBuffer_PRE.get()); - assert(SUCCEEDED(hr)); } // vertexBuffer - TEXCOORDS @@ -471,6 +466,8 @@ namespace wiSceneSystem assert(SUCCEEDED(hr)); } + // vertexBuffer_PRE will be created on demand later! + } void MeshComponent::ComputeNormals(bool smooth) { @@ -750,8 +747,10 @@ namespace wiSceneSystem void SoftBodyPhysicsComponent::CreateFromMesh(const MeshComponent& mesh) { // Create a mapping that maps unique vertex positions to all vertex indices that share that. Unique vertex positions will make up the physics mesh: - std::unordered_map uniquePositions; + std::unordered_map uniquePositions; graphicsToPhysicsVertexMapping.resize(mesh.vertex_positions.size()); + physicsToGraphicsVertexMapping.clear(); + weights.clear(); for (size_t i = 0; i < mesh.vertex_positions.size(); ++i) { @@ -766,11 +765,14 @@ namespace wiSceneSystem if (uniquePositions.count(vertexHash) == 0) { - physicsvertices.push_back(position); - uniquePositions[vertexHash] = physicsvertices.size(); + uniquePositions[vertexHash] = (uint32_t)physicsToGraphicsVertexMapping.size(); + physicsToGraphicsVertexMapping.push_back((uint32_t)i); } - graphicsToPhysicsVertexMapping[i] = (uint32_t)uniquePositions[vertexHash]; + graphicsToPhysicsVertexMapping[i] = uniquePositions[vertexHash]; } + + weights.resize(physicsToGraphicsVertexMapping.size()); + std::fill(weights.begin(), weights.end(), 1.0f); } void CameraComponent::CreatePerspective(float newWidth, float newHeight, float newNear, float newFar, float newFOV) @@ -876,7 +878,7 @@ namespace wiSceneSystem RunImpostorUpdateSystem(impostors); - RunObjectUpdateSystem(transforms, meshes, materials, objects, aabb_objects, impostors, bounds, waterPlane); + RunObjectUpdateSystem(prev_transforms, transforms, meshes, materials, objects, aabb_objects, impostors, softbodies, bounds, waterPlane); RunCameraUpdateSystem(transforms, cameras); @@ -1562,12 +1564,14 @@ namespace wiSceneSystem } } void RunObjectUpdateSystem( + const wiECS::ComponentManager& prev_transforms, const ComponentManager& transforms, const ComponentManager& meshes, const ComponentManager& materials, ComponentManager& objects, ComponentManager& aabb_objects, ComponentManager& impostors, + ComponentManager& softbodies, AABB& sceneBounds, XMFLOAT4& waterPlane ) @@ -1591,16 +1595,17 @@ namespace wiSceneSystem if (object.meshID != INVALID_ENTITY) { Entity entity = objects.GetEntity(i); - - object.transformComponentIndex = (uint32_t)transforms.GetIndex(entity); - - const TransformComponent& transform = transforms[object.transformComponentIndex]; const MeshComponent* mesh = meshes.GetComponent(object.meshID); + // These will only be valid for a single frame: + object.transform_index = (int)transforms.GetIndex(entity); + object.prev_transform_index = (int)prev_transforms.GetIndex(entity); + + const TransformComponent& transform = transforms[object.transform_index]; + if (mesh != nullptr) { aabb = mesh->aabb.get(transform.world); - sceneBounds = AABB::Merge(sceneBounds, aabb); // This is instance bounding box matrix: XMFLOAT4X4 meshMatrix; @@ -1656,6 +1661,26 @@ namespace wiSceneSystem impostor->fadeThresholdRadius = object.impostorFadeThresholdRadius; impostor->instanceMatrices.push_back(meshMatrix); } + + SoftBodyPhysicsComponent* softBody = softbodies.GetComponent(object.meshID); + if (softBody != nullptr) + { + softBody->_flags |= SoftBodyPhysicsComponent::SAFE_TO_REGISTER; // this will be registered as soft body in the next frame + softBody->worldMatrix = transform.world; + + if (wiPhysicsEngine::IsEnabled() && softBody->physicsobject != nullptr) + { + // If physics engine is enabled and this object was registered, it will update soft body vertices in world space, so after that they no longer need to be transformed: + object.transform_index = -1; + object.prev_transform_index = -1; + + // mesh aabb will be used for soft bodies + aabb = mesh->aabb; + } + + } + + sceneBounds = AABB::Merge(sceneBounds, aabb); } } } diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index d17023b7a..6cf56b2ef 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -227,8 +227,8 @@ namespace wiSceneSystem std::unique_ptr vertexBuffer_BON; std::unique_ptr vertexBuffer_COL; std::unique_ptr vertexBuffer_ATL; + std::unique_ptr vertexBuffer_PRE; std::unique_ptr streamoutBuffer_POS; - std::unique_ptr streamoutBuffer_PRE; inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } } @@ -412,8 +412,9 @@ namespace wiSceneSystem float impostorFadeThresholdRadius; float impostorSwapDistance; - // single frame-lifetime, to directly index transform component: - uint32_t transformComponentIndex; + // these will only be valid for a single frame: + int transform_index = -1; + int prev_transform_index = -1; // occlusion result history bitfield (32 bit->32 frame history) uint32_t occlusionHistory = ~0; @@ -489,17 +490,24 @@ namespace wiSceneSystem enum FLAGS { EMPTY = 0, - DISABLE_DEACTIVATION = 1 << 0, + SAFE_TO_REGISTER = 1 << 0, + DISABLE_DEACTIVATION = 1 << 1, }; - uint32_t _flags = EMPTY; + uint32_t _flags = DISABLE_DEACTIVATION; float mass = 1.0f; float friction = 1.0f; - std::vector physicsvertices; - std::vector graphicsToPhysicsVertexMapping; + std::vector physicsToGraphicsVertexMapping; // maps graphics vertex index to physics vertex index of the same position + std::vector graphicsToPhysicsVertexMapping; // maps a physics vertex index to first graphics vertex index of the same position + std::vector weights; // weight per physics vertex controlling the mass. (0: disable weight (no physics, only animation), 1: default weight) // Non-serialized attributes: void* physicsobject = nullptr; + XMFLOAT4X4 worldMatrix = IDENTITYMATRIX; + + inline void SetDisableDeactivation(bool value) { if (value) { _flags |= DISABLE_DEACTIVATION; } else { _flags &= ~DISABLE_DEACTIVATION; } } + + inline bool IsDisableDeactivation() const { return _flags & DISABLE_DEACTIVATION; } // Create physics represenation of graphics mesh void CreateFromMesh(const MeshComponent& mesh); @@ -999,12 +1007,14 @@ namespace wiSceneSystem void RunMaterialUpdateSystem(wiECS::ComponentManager& materials, float dt); void RunImpostorUpdateSystem(wiECS::ComponentManager& impostors); void RunObjectUpdateSystem( + const wiECS::ComponentManager& prev_transforms, const wiECS::ComponentManager& transforms, const wiECS::ComponentManager& meshes, const wiECS::ComponentManager& materials, wiECS::ComponentManager& objects, wiECS::ComponentManager& aabb_objects, wiECS::ComponentManager& impostors, + wiECS::ComponentManager& softbodies, AABB& sceneBounds, XMFLOAT4& waterPlane ); diff --git a/WickedEngine/wiSceneSystem_Serializers.cpp b/WickedEngine/wiSceneSystem_Serializers.cpp index 4cfeb68ec..b51355c37 100644 --- a/WickedEngine/wiSceneSystem_Serializers.cpp +++ b/WickedEngine/wiSceneSystem_Serializers.cpp @@ -267,16 +267,20 @@ namespace wiSceneSystem archive >> _flags; archive >> mass; archive >> friction; - archive >> physicsvertices; + archive >> physicsToGraphicsVertexMapping; archive >> graphicsToPhysicsVertexMapping; + archive >> weights; + + _flags &= ~SAFE_TO_REGISTER; } else { archive << _flags; archive << mass; archive << friction; - archive << physicsvertices; + archive << physicsToGraphicsVertexMapping; archive << graphicsToPhysicsVertexMapping; + archive << weights; } } void ArmatureComponent::Serialize(wiArchive& archive, uint32_t seed) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b0c075a5b..6eced5de9 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 21; // minor bug fixes, alterations, refactors, updates - const int revision = 13; + const int revision = 14; long GetVersion() diff --git a/models/physics_test.wiscene b/models/physics_test.wiscene index ab2ef1bed..0debf8337 100644 Binary files a/models/physics_test.wiscene and b/models/physics_test.wiscene differ