updated physics, skinning, systems; added softbody to physics test
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+45
-15
@@ -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);
|
||||
|
||||
@@ -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<size_t, size_t> uniquePositions;
|
||||
std::unordered_map<size_t, uint32_t> 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<PreviousFrameTransformComponent>& prev_transforms,
|
||||
const ComponentManager<TransformComponent>& transforms,
|
||||
const ComponentManager<MeshComponent>& meshes,
|
||||
const ComponentManager<MaterialComponent>& materials,
|
||||
ComponentManager<ObjectComponent>& objects,
|
||||
ComponentManager<AABB>& aabb_objects,
|
||||
ComponentManager<ImpostorComponent>& impostors,
|
||||
ComponentManager<SoftBodyPhysicsComponent>& 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +227,8 @@ namespace wiSceneSystem
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> vertexBuffer_BON;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> vertexBuffer_COL;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> vertexBuffer_ATL;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> vertexBuffer_PRE;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> streamoutBuffer_POS;
|
||||
std::unique_ptr<wiGraphicsTypes::GPUBuffer> 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<XMFLOAT3> physicsvertices;
|
||||
std::vector<uint32_t> graphicsToPhysicsVertexMapping;
|
||||
std::vector<uint32_t> physicsToGraphicsVertexMapping; // maps graphics vertex index to physics vertex index of the same position
|
||||
std::vector<uint32_t> graphicsToPhysicsVertexMapping; // maps a physics vertex index to first graphics vertex index of the same position
|
||||
std::vector<float> 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<MaterialComponent>& materials, float dt);
|
||||
void RunImpostorUpdateSystem(wiECS::ComponentManager<ImpostorComponent>& impostors);
|
||||
void RunObjectUpdateSystem(
|
||||
const wiECS::ComponentManager<PreviousFrameTransformComponent>& prev_transforms,
|
||||
const wiECS::ComponentManager<TransformComponent>& transforms,
|
||||
const wiECS::ComponentManager<MeshComponent>& meshes,
|
||||
const wiECS::ComponentManager<MaterialComponent>& materials,
|
||||
wiECS::ComponentManager<ObjectComponent>& objects,
|
||||
wiECS::ComponentManager<AABB>& aabb_objects,
|
||||
wiECS::ComponentManager<ImpostorComponent>& impostors,
|
||||
wiECS::ComponentManager<SoftBodyPhysicsComponent>& softbodies,
|
||||
AABB& sceneBounds,
|
||||
XMFLOAT4& waterPlane
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user