diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp
index e076b96e7..428bbb349 100644
--- a/Editor/ObjectWindow.cpp
+++ b/Editor/ObjectWindow.cpp
@@ -94,33 +94,26 @@ ObjectWindow::ObjectWindow(wiGUI* gui) : GUI(gui)
rigidBodyCheckBox->OnClick([&](wiEventArgs args)
{
Scene& scene = wiRenderer::GetScene();
+ RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity);
+
if (args.bValue)
{
- TransformComponent* transform = scene.transforms.GetComponent(entity);
- ObjectComponent* object = scene.objects.GetComponent(entity);
- if (transform != nullptr && object != nullptr)
+ if (physicscomponent == nullptr)
{
- MeshComponent* mesh = scene.meshes.GetComponent(object->meshID);
-
- RigidBodyPhysicsComponent* physicscomponent = scene.rigidbodies.GetComponent(entity);
- if (physicscomponent == nullptr)
- {
- RigidBodyPhysicsComponent& rigidbody = scene.rigidbodies.Create(entity);
- rigidbody.kinematic = kinematicCheckBox->GetCheck();
- rigidbody.shape = (RigidBodyPhysicsComponent::CollisionShape)collisionShapeComboBox->GetSelected();
- //wiRenderer::physicsEngine->addRigidBody(rigidbody, *mesh, *transform);
- }
+ RigidBodyPhysicsComponent& rigidbody = scene.rigidbodies.Create(entity);
+ rigidbody.SetKinematic(kinematicCheckBox->GetCheck());
+ rigidbody.SetDisableDeactivation(disabledeactivationCheckBox->GetCheck());
+ rigidbody.shape = (RigidBodyPhysicsComponent::CollisionShape)collisionShapeComboBox->GetSelected();
}
}
else
{
- RigidBodyPhysicsComponent* physicscomponent = wiRenderer::GetScene().rigidbodies.GetComponent(entity);
if (physicscomponent != nullptr)
{
- //wiRenderer::physicsEngine->removeRigidBody(*physicscomponent);
- //scene.rigidbodies.Remove(entity);
+ scene.rigidbodies.Remove(entity);
}
}
+
});
objectWindow->AddWidget(rigidBodyCheckBox);
@@ -132,11 +125,24 @@ ObjectWindow::ObjectWindow(wiGUI* gui) : GUI(gui)
RigidBodyPhysicsComponent* physicscomponent = wiRenderer::GetScene().rigidbodies.GetComponent(entity);
if (physicscomponent != nullptr)
{
- physicscomponent->kinematic = args.bValue;
+ physicscomponent->SetKinematic(args.bValue);
}
});
objectWindow->AddWidget(kinematicCheckBox);
+ disabledeactivationCheckBox = new wiCheckBox("Disable Deactivation: ");
+ disabledeactivationCheckBox->SetTooltip("Toggle kinematic behaviour.");
+ disabledeactivationCheckBox->SetPos(XMFLOAT2(x, y += 30));
+ disabledeactivationCheckBox->SetCheck(false);
+ disabledeactivationCheckBox->OnClick([&](wiEventArgs args) {
+ RigidBodyPhysicsComponent* physicscomponent = wiRenderer::GetScene().rigidbodies.GetComponent(entity);
+ if (physicscomponent != nullptr)
+ {
+ physicscomponent->SetDisableDeactivation(args.bValue);
+ }
+ });
+ objectWindow->AddWidget(disabledeactivationCheckBox);
+
collisionShapeComboBox = new wiComboBox("Collision Shape:");
collisionShapeComboBox->SetSize(XMFLOAT2(100, 20));
collisionShapeComboBox->SetPos(XMFLOAT2(x, y += 30));
@@ -218,7 +224,8 @@ void ObjectWindow::SetEntity(Entity entity)
if (physicsComponent != nullptr)
{
- kinematicCheckBox->SetCheck(physicsComponent->kinematic);
+ kinematicCheckBox->SetCheck(physicsComponent->IsKinematic());
+ disabledeactivationCheckBox->SetCheck(physicsComponent->IsDisableDeactivation());
if (physicsComponent->shape == RigidBodyPhysicsComponent::CollisionShape::BOX)
{
diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h
index 8c734d699..678b8309d 100644
--- a/Editor/ObjectWindow.h
+++ b/Editor/ObjectWindow.h
@@ -28,6 +28,7 @@ public:
wiLabel* physicsLabel;
wiCheckBox* rigidBodyCheckBox;
+ wiCheckBox* disabledeactivationCheckBox;
wiCheckBox* kinematicCheckBox;
wiComboBox* collisionShapeComboBox;
};
diff --git a/WickedEngine/MainComponent.cpp b/WickedEngine/MainComponent.cpp
index f84878f56..c4b5184a8 100644
--- a/WickedEngine/MainComponent.cpp
+++ b/WickedEngine/MainComponent.cpp
@@ -14,8 +14,6 @@
#include "wiProfiler.h"
#include "wiInitializer.h"
#include "wiStartupArguments.h"
-#include "wiPHYSICS.h"
-#include "wiBULLET.h"
#include "wiGraphicsDevice_DX11.h"
#include "wiGraphicsDevice_DX12.h"
@@ -43,16 +41,12 @@ MainComponent::MainComponent()
infoDisplay = InfoDisplayer();
fadeManager.Clear();
-
- physicsEngine = new wiBULLET;
}
MainComponent::~MainComponent()
{
wiRenderer::GetDevice()->WaitForGPU();
-
- SAFE_DELETE(physicsEngine);
}
void MainComponent::Initialize()
@@ -154,10 +148,6 @@ void MainComponent::Run()
}
wiProfiler::GetInstance().EndRange(); // Fixed Update
- wiProfiler::GetInstance().BeginRange("Physics", wiProfiler::DOMAIN_CPU);
- physicsEngine->Update((float)elapsedTime);
- wiProfiler::GetInstance().EndRange(); // Physics
-
wiLua::GetGlobal()->SetDeltaTime(elapsedTime);
// Variable-timed update:
diff --git a/WickedEngine/MainComponent.h b/WickedEngine/MainComponent.h
index 9c05e6b75..49556ad05 100644
--- a/WickedEngine/MainComponent.h
+++ b/WickedEngine/MainComponent.h
@@ -6,7 +6,6 @@
#include "wiWindowRegistration.h"
class RenderableComponent;
-class PHYSICS;
class MainComponent
{
@@ -25,8 +24,6 @@ public:
int screenW, screenH;
bool fullscreen;
- PHYSICS* physicsEngine = nullptr;
-
// Runs the main engine loop
void Run();
diff --git a/WickedEngine/WickedEngine.h b/WickedEngine/WickedEngine.h
index 27d9c1441..b0b13a4b0 100644
--- a/WickedEngine/WickedEngine.h
+++ b/WickedEngine/WickedEngine.h
@@ -37,8 +37,7 @@
#include "wiTextureHelper.h"
#include "wiRandom.h"
#include "wiColor.h"
-#include "wiPHYSICS.h"
-#include "wiBULLET.h"
+#include "wiPhysics.h"
#include "wiEnums.h"
#include "wiInitializer.h"
#include "wiLua.h"
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems
index 80c728c8d..a1a49b46d 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems
@@ -309,7 +309,6 @@
-
@@ -339,6 +338,7 @@
+
@@ -347,7 +347,6 @@
-
@@ -654,7 +653,6 @@
-
@@ -679,6 +677,7 @@
+
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
index cb15240d0..0b1d574e8 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
@@ -951,9 +951,6 @@
ENGINE\Audio
-
- ENGINE\Physics
-
ENGINE\Graphics
@@ -1002,9 +999,6 @@
ENGINE\Input
-
- ENGINE\Physics
-
ENGINE\Tools
@@ -1143,6 +1137,9 @@
ENGINE\Helpers
+
+ ENGINE\Physics
+
@@ -1814,9 +1811,6 @@
ENGINE\Audio
-
- ENGINE\Physics
-
ENGINE\Graphics
@@ -1934,6 +1928,9 @@
ENGINE\Scripting\LuaBindings
+
+ ENGINE\Physics
+
diff --git a/WickedEngine/wiBULLET.cpp b/WickedEngine/wiBULLET.cpp
deleted file mode 100644
index 541ec1a28..000000000
--- a/WickedEngine/wiBULLET.cpp
+++ /dev/null
@@ -1,825 +0,0 @@
-#include "wiBULLET.h"
-#include "wiSceneSystem.h"
-#include "wiRenderer.h"
-
-#include "btBulletDynamicsCommon.h"
-
-#include "LinearMath/btHashMap.h"
-#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
-#include "BulletSoftBody/btSoftBodyHelpers.h"
-
-#include "BulletSoftBody/btSoftBodySolvers.h"
-#include "BulletSoftBody/btDefaultSoftBodySolver.h"
-#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
-
-using namespace std;
-using namespace wiSceneSystem;
-using namespace wiECS;
-
-int PHYSICS::softBodyIterationCount=5;
-bool PHYSICS::rigidBodyPhysicsEnabled = true, PHYSICS::softBodyPhysicsEnabled = true;
-
-struct BulletPhysicsWorld
-{
- btCollisionConfiguration* collisionConfiguration;
- btCollisionDispatcher* dispatcher;
- btBroadphaseInterface* overlappingPairCache;
- btSequentialImpulseConstraintSolver* solver;
- btDynamicsWorld* dynamicsWorld;
- btAlignedObjectArray collisionShapes;
-
- btSoftBodySolver* softBodySolver;
- btSoftBodySolverOutput* softBodySolverOutput;
-
- btVector3 wind;
-};
-
-wiBULLET::wiBULLET()
-{
- bulletPhysics = new BulletPhysicsWorld;
-
- registeredObjects=-1;
-
- ///-----initialization_start-----
- //softBodySolver = new btDefaultSoftBodySolver();
- bulletPhysics->softBodySolver = nullptr;
-
- ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
- //collisionConfiguration = new btDefaultCollisionConfiguration();
- bulletPhysics->collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
-
- ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
- bulletPhysics->dispatcher = new btCollisionDispatcher(bulletPhysics->collisionConfiguration);
-
- ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
- bulletPhysics->overlappingPairCache = new btDbvtBroadphase();
-
- ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
- bulletPhysics->solver = new btSequentialImpulseConstraintSolver;
-
- //dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
- bulletPhysics->dynamicsWorld = new btSoftRigidDynamicsWorld(bulletPhysics->dispatcher, bulletPhysics->overlappingPairCache, bulletPhysics->solver, bulletPhysics->collisionConfiguration, bulletPhysics->softBodySolver);
-
-
- bulletPhysics->dynamicsWorld->getSolverInfo().m_solverMode|=SOLVER_RANDMIZE_ORDER;
- bulletPhysics->dynamicsWorld->getDispatchInfo().m_enableSatConvex = true;
- bulletPhysics->dynamicsWorld->getSolverInfo().m_splitImpulse=true;
-
- bulletPhysics->dynamicsWorld->setGravity(btVector3(0,-11,0));
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().air_density = (btScalar)0.0;
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().water_density = 0;
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().water_offset = 0;
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().water_normal = btVector3(0,0,0);
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().m_gravity.setValue(0,-11,0);
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->getWorldInfo().m_sparsesdf.Initialize(); //???
-
- //dynamicsWorld->setInternalTickCallback(soundTickCallback,this,true);
- //dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true);
-
-
-#ifdef BACKLOG
- wiBackLog::post("wiBULLET physics Initialized");
-#endif
-
- ///-----initialization_end-----
-}
-
-wiBULLET::~wiBULLET()
-{
- //cleanup in the reverse order of creation/initialization
-
- ///-----cleanup_start-----
-
- ClearWorld();
-
- //delete dynamics world
- delete bulletPhysics->dynamicsWorld;
-
- //delete solver
- delete bulletPhysics->solver;
-
- //delete broadphase
- delete bulletPhysics->overlappingPairCache;
-
- //delete dispatcher
- delete bulletPhysics->dispatcher;
-
- delete bulletPhysics->collisionConfiguration;
-
- //next line is optional: it will be cleared by the destructor when the array goes out of scope
- bulletPhysics->collisionShapes.clear();
-
- ///-----cleanup_end-----
- CleanUp();
-
- delete bulletPhysics;
-}
-
-
-void wiBULLET::setWind(const XMFLOAT3& wind){
- this->bulletPhysics->wind = btVector3(btScalar(wind.x),btScalar(wind.y),btScalar(wind.z));
-}
-
-
-void wiBULLET::connectVerticesToSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh)
-{
- //if (!softBodyPhysicsEnabled)
- // return;
-
- //btCollisionObject* obj = bulletPhysics->dynamicsWorld->getCollisionObjectArray()[physicscomponent.physicsObjectID];
- //btSoftBody* softBody = btSoftBody::upcast(obj);
-
- //if (softBody)
- //{
- // btVector3 min, max;
- // softBody->getAabb(min, max);
- // mesh.aabb.create(XMFLOAT3(min.x(), min.y(), min.z()), XMFLOAT3(max.x(), max.y(), max.z()));
-
- // softBody->setWindVelocity(bulletPhysics->wind);
-
- // btSoftBody::tNodeArray& nodes(softBody->m_nodes);
-
- // int gvg = physicscomponent.goalVG;
- // for (size_t i = 0; i < mesh.vertex_positions.size(); ++i)
- // {
- // int indexP = physicscomponent.physicalmapGP[i];
- // float weight = mesh.vertexGroups[gvg].vertex_weights[indexP];
-
- // MeshComponent::Vertex_POS& vert = mesh.vertices_Transformed_POS[i];
-
- // mesh.vertices_Transformed_PRE[i] = vert;
- // vert.pos.x = nodes[indexP].m_x.getX();
- // vert.pos.y = nodes[indexP].m_x.getY();
- // vert.pos.z = nodes[indexP].m_x.getZ();
- // mesh.vertices_Transformed_POS[i].MakeFromParams(XMFLOAT3(-nodes[indexP].m_n.getX(), -nodes[indexP].m_n.getY(), -nodes[indexP].m_n.getZ())/*, vert.GetWind(), vert.GetMaterialIndex()*/);
- // }
- //}
-}
-void wiBULLET::connectSoftBodyToVertices(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh)
-{
- //if (!softBodyPhysicsEnabled)
- // return;
-
- //if (!firstRunWorld)
- //{
- // btCollisionObject* obj = bulletPhysics->dynamicsWorld->getCollisionObjectArray()[physicscomponent.physicsObjectID];
- // btSoftBody* softBody = btSoftBody::upcast(obj);
-
- // if (softBody) {
- // btSoftBody::tNodeArray& nodes(softBody->m_nodes);
-
- // int gvg = physicscomponent.goalVG;
- // if (gvg >= 0)
- // {
- // int j = 0;
- // for (auto it = mesh.vertexGroups[gvg].vertex_weights.begin(); it != mesh.vertexGroups[gvg].vertex_weights.end(); ++it)
- // {
- // int vi = (*it).first;
- // int index = physicscomponent.physicalmapGP[vi];
- // float weight = (*it).second;
- // nodes[index].m_x = nodes[index].m_x.lerp(btVector3(physicscomponent.goalPositions[j].x, physicscomponent.goalPositions[j].y, physicscomponent.goalPositions[j].z), weight);
- // ++j;
- // }
- // }
- // }
- //}
-}
-void wiBULLET::transformBody(const XMFLOAT4& rot, const XMFLOAT3& pos, int objectI)
-{
- if (objectI < 0)
- {
- return;
- }
-
- btCollisionObject* obj = bulletPhysics->dynamicsWorld->getCollisionObjectArray()[objectI];
- btRigidBody* rigidBody = btRigidBody::upcast(obj);
- if (rigidBody)
- {
- btTransform transform;
- transform.setIdentity();
- transform.setRotation(btQuaternion(rot.x, rot.y, rot.z, rot.w));
- transform.setOrigin(btVector3(pos.x, pos.y, pos.z));
- rigidBody->getMotionState()->setWorldTransform(transform);
- }
-}
-
-PHYSICS::PhysicsTransform* wiBULLET::getObject(int index)
-{
-
- btCollisionObject* obj = bulletPhysics->dynamicsWorld->getCollisionObjectArray()[index];
- btTransform trans;
-
- btRigidBody* body = btRigidBody::upcast(obj);
- if (body && body->getMotionState())
- {
- body->getMotionState()->getWorldTransform(trans);
- }
-
- btSoftBody* softBody = btSoftBody::upcast(obj);
- if(softBody)
- {
- trans = softBody->getWorldTransform();
- }
-
- btQuaternion rot = trans.getRotation();
- btVector3 pos = trans.getOrigin();
- transforms[index]->rotation=XMFLOAT4(rot.getX(),rot.getY(),rot.getZ(),rot.getW());
- transforms[index]->position=XMFLOAT3(pos.getX(),pos.getY(),pos.getZ());
- return transforms[index];
-}
-
-void wiBULLET::addRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform)
-{
- if (!rigidBodyPhysicsEnabled)
- {
- return;
- }
-
- 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);
-
- switch(physicscomponent.shape)
- {
- case RigidBodyPhysicsComponent::CollisionShape::BOX:
- {
- btCollisionShape* shape = new btBoxShape(S);
- shape->setMargin(btScalar(0.05));
- bulletPhysics->collisionShapes.push_back(shape);
-
- btTransform shapeTransform;
- shapeTransform.setIdentity();
- shapeTransform.setOrigin(T);
- shapeTransform.setRotation(R);
- {
- btScalar mass(physicscomponent.mass);
-
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f && !physicscomponent.kinematic);
-
- btVector3 localInertia(0, 0, 0);
- if (isDynamic)
- shape->calculateLocalInertia(mass, localInertia);
- else
- mass = 0;
-
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
- rbInfo.m_friction = physicscomponent.friction;
- rbInfo.m_restitution = physicscomponent.restitution;
- rbInfo.m_linearDamping = physicscomponent.damping;
- rbInfo.m_angularDamping = physicscomponent.damping;
- btRigidBody* body = new btRigidBody(rbInfo);
- if (physicscomponent.kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
-
- //add the body to the dynamics world
- bulletPhysics->dynamicsWorld->addRigidBody(body);
-
-
- if (body->getMotionState())
- {
- btTransform trans;
- body->getMotionState()->getWorldTransform(trans);
- btQuaternion nRot = trans.getRotation();
- btVector3 nPos = trans.getOrigin();
- transforms.push_back(new PhysicsTransform(
- XMFLOAT4(nRot.getX(), nRot.getY(), nRot.getZ(), nRot.getW()), XMFLOAT3(nPos.getX(), nPos.getY(), nPos.getZ()))
- );
- }
- }
- }
- break;
-
- case RigidBodyPhysicsComponent::CollisionShape::SPHERE:
- {
- btCollisionShape* shape = new btSphereShape(btScalar(S.x()));
- shape->setMargin(btScalar(0.05));
- bulletPhysics->collisionShapes.push_back(shape);
-
- btTransform shapeTransform;
- shapeTransform.setIdentity();
- shapeTransform.setOrigin(T);
- {
- btScalar mass(physicscomponent.mass);
-
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f && !physicscomponent.kinematic);
-
- btVector3 localInertia(0, 0, 0);
- if (isDynamic)
- shape->calculateLocalInertia(mass, localInertia);
- else
- mass = 0;
-
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
- rbInfo.m_friction = physicscomponent.friction;
- rbInfo.m_restitution = physicscomponent.restitution;
- rbInfo.m_linearDamping = physicscomponent.damping;
- rbInfo.m_angularDamping = physicscomponent.damping;
- btRigidBody* body = new btRigidBody(rbInfo);
- if (physicscomponent.kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
-
- //add the body to the dynamics world
- bulletPhysics->dynamicsWorld->addRigidBody(body);
-
-
- if (body->getMotionState())
- {
- btTransform trans;
- body->getMotionState()->getWorldTransform(trans);
- btQuaternion nRot = trans.getRotation();
- btVector3 nPos = trans.getOrigin();
- transforms.push_back(new PhysicsTransform(
- XMFLOAT4(nRot.getX(), nRot.getY(), nRot.getZ(), nRot.getW()), XMFLOAT3(nPos.getX(), nPos.getY(), nPos.getZ()))
- );
- }
- }
-
- }
- break;
-
- case RigidBodyPhysicsComponent::CollisionShape::CAPSULE:
- {
- btCollisionShape* shape = new btCapsuleShape(btScalar(S.x()), btScalar(S.y()));
- shape->setMargin(btScalar(0.05));
- bulletPhysics->collisionShapes.push_back(shape);
-
- btTransform shapeTransform;
- shapeTransform.setIdentity();
- shapeTransform.setOrigin(T);
- shapeTransform.setRotation(R);
- {
- btScalar mass(physicscomponent.mass);
-
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f && !physicscomponent.kinematic);
-
- btVector3 localInertia(0, 0, 0);
- if (isDynamic)
- shape->calculateLocalInertia(mass, localInertia);
- else
- mass = 0;
-
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
- rbInfo.m_friction = physicscomponent.friction;
- rbInfo.m_restitution = physicscomponent.restitution;
- rbInfo.m_linearDamping = physicscomponent.damping;
- rbInfo.m_angularDamping = physicscomponent.damping;
- btRigidBody* body = new btRigidBody(rbInfo);
- if (physicscomponent.kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
-
- //add the body to the dynamics world
- bulletPhysics->dynamicsWorld->addRigidBody(body);
-
-
- if (body->getMotionState())
- {
- btTransform trans;
- body->getMotionState()->getWorldTransform(trans);
- btQuaternion nRot = trans.getRotation();
- btVector3 nPos = trans.getOrigin();
- transforms.push_back(new PhysicsTransform(
- XMFLOAT4(nRot.getX(), nRot.getY(), nRot.getZ(), nRot.getW()), XMFLOAT3(nPos.getX(), nPos.getY(), nPos.getZ()))
- );
- }
- }
- }
- break;
-
- case RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL:
- {
- btCollisionShape* shape = new btConvexHullShape();
- for (auto& pos : mesh.vertex_positions)
- {
- ((btConvexHullShape*)shape)->addPoint(btVector3(pos.x, pos.y, pos.z));
- }
- shape->setLocalScaling(S);
- shape->setMargin(btScalar(0.05));
-
- bulletPhysics->collisionShapes.push_back(shape);
-
- btTransform shapeTransform;
- shapeTransform.setIdentity();
- shapeTransform.setOrigin(T);
- shapeTransform.setRotation(R);
- {
- btScalar mass(physicscomponent.mass);
-
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f && !physicscomponent.kinematic);
-
- btVector3 localInertia(0, 0, 0);
- if (isDynamic)
- shape->calculateLocalInertia(mass, localInertia);
- else
- mass = 0;
-
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
- rbInfo.m_friction = physicscomponent.friction;
- rbInfo.m_restitution = physicscomponent.restitution;
- rbInfo.m_linearDamping = physicscomponent.damping;
- rbInfo.m_angularDamping = physicscomponent.damping;
- btRigidBody* body = new btRigidBody(rbInfo);
- if (physicscomponent.kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
-
- //add the body to the dynamics world
- bulletPhysics->dynamicsWorld->addRigidBody(body);
-
-
- if (body->getMotionState())
- {
- btTransform trans;
- body->getMotionState()->getWorldTransform(trans);
- btQuaternion nRot = trans.getRotation();
- btVector3 nPos = trans.getOrigin();
- transforms.push_back(new PhysicsTransform(
- XMFLOAT4(nRot.getX(), nRot.getY(), nRot.getZ(), nRot.getW()), XMFLOAT3(nPos.getX(), nPos.getY(), nPos.getZ()))
- );
- }
- }
- }
- break;
-
- case RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH:
- {
- int totalVerts = (int)mesh.vertex_positions.size();
- int totalTriangles = (int)mesh.indices.size() / 3;
-
- btVector3* btVerts = new btVector3[totalVerts];
- size_t i = 0;
- for (auto& pos : mesh.vertex_positions)
- {
- btVerts[i++] = btVector3(pos.x, pos.y, pos.z);
- }
-
- int* btInd = new int[mesh.indices.size()];
- i = 0;
- for (auto& ind : mesh.indices)
- {
- btInd[i++] = ind;
- }
-
- int vertStride = sizeof(btVector3);
- int indexStride = 3 * sizeof(int);
-
- btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(
- totalTriangles,
- btInd,
- indexStride,
- totalVerts,
- (btScalar*)&btVerts[0].x(),
- vertStride
- );
-
- bool useQuantizedAabbCompression = true;
-
- btCollisionShape* shape = new btBvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression);
- shape->setMargin(btScalar(0.05));
- shape->setLocalScaling(S);
-
- bulletPhysics->collisionShapes.push_back(shape);
-
- btTransform shapeTransform;
- shapeTransform.setIdentity();
- shapeTransform.setOrigin(T);
- shapeTransform.setRotation(R);
- {
- btScalar mass(physicscomponent.mass);
-
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f && !physicscomponent.kinematic);
-
- btVector3 localInertia(0, 0, 0);
- if (isDynamic)
- shape->calculateLocalInertia(mass, localInertia);
- else
- mass = 0;
-
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
- rbInfo.m_friction = physicscomponent.friction;
- rbInfo.m_restitution = physicscomponent.restitution;
- rbInfo.m_linearDamping = physicscomponent.damping;
- rbInfo.m_angularDamping = physicscomponent.damping;
- btRigidBody* body = new btRigidBody(rbInfo);
- if (physicscomponent.kinematic)
- body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- body->setActivationState(DISABLE_DEACTIVATION);
-
- //add the body to the dynamics world
- bulletPhysics->dynamicsWorld->addRigidBody(body);
-
-
- if (body->getMotionState())
- {
- btTransform trans;
- body->getMotionState()->getWorldTransform(trans);
- btQuaternion nRot = trans.getRotation();
- btVector3 nPos = trans.getOrigin();
- transforms.push_back(new PhysicsTransform(
- XMFLOAT4(nRot.getX(), nRot.getY(), nRot.getZ(), nRot.getW()), XMFLOAT3(nPos.getX(), nPos.getY(), nPos.getZ()))
- );
- }
- }
- }
- }
-
-
-
- physicscomponent.physicsObjectID = ++registeredObjects;
-}
-void wiBULLET::addSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform)
-{
- if (!softBodyPhysicsEnabled)
- {
- return;
- }
-
- 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);
-
- {
- const int vCount = (int)physicscomponent.physicsvertices.size();
- btScalar* btVerts = new btScalar[vCount * 3];
- for (int i = 0; idynamicsWorld)->getWorldInfo()
- , &btVerts[0]
- , &btInd[0]
- , tCount
- , false
- );
-
-
- delete[] btVerts;
- delete[] btInd;
-
- if (softBody)
- {
- btSoftBody::Material* pm = softBody->appendMaterial();
- pm->m_kLST = 0.5;
- pm->m_kVST = 0.5;
- pm->m_kAST = 0.5;
- pm->m_flags = 0;
- 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.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]
- softBody->m_cfg.kLF = btScalar(0.1); //0 Lift coefficient [0,+inf]
- softBody->m_cfg.kMT = btScalar(0.0); //0 Pose matching coefficient [0,1]
- softBody->m_cfg.kPR = btScalar(0.0); //0 Pressure coefficient [-1,1]
- softBody->m_cfg.kSHR = btScalar(1.0); //1 Soft contacts hardness [0,1]
- softBody->m_cfg.kVC = btScalar(0.0); //0 Volume conseration coefficient [0,+inf]
- softBody->m_cfg.kVCF = btScalar(1.0); //1 Velocities correction factor (Baumgarte)
-
- softBody->m_cfg.kSKHR_CL = btScalar(1.0); //1 Soft vs. kinetic hardness [0,1]
- softBody->m_cfg.kSK_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
- softBody->m_cfg.kSRHR_CL = btScalar(0.1); //0.1 Soft vs. rigid hardness [0,1]
- softBody->m_cfg.kSR_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
- softBody->m_cfg.kSSHR_CL = btScalar(0.5); //0.5 Soft vs. soft hardness [0,1]
- softBody->m_cfg.kSS_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
-
-
- btScalar mass = btScalar(physicscomponent.mass);
- softBody->setTotalMass(mass);
-
- //int mvg = physicscomponent.massVG;
- //if (mvg >= 0) {
- // for (auto it = mesh.vertexGroups[mvg].vertex_weights.begin(); it != mesh.vertexGroups[mvg].vertex_weights.end(); ++it) {
- // int vi = (*it).first;
- // float wei = (*it).second;
- // int index = physicscomponent.physicalmapGP[vi];
- // softBody->setMass(index, softBody->getMass(index)*btScalar(wei));
- // }
- //}
-
-
- //int gvg = physicscomponent.goalVG;
- //if (gvg >= 0) {
- // for (auto it = mesh.vertexGroups[gvg].vertex_weights.begin(); it != mesh.vertexGroups[gvg].vertex_weights.end(); ++it) {
- // int vi = (*it).first;
- // int index = physicscomponent.physicalmapGP[vi];
- // float weight = (*it).second;
- // if (weight == 1)
- // softBody->setMass(index, 0);
- // }
- //}
-
- softBody->getCollisionShape()->setMargin(btScalar(0.2));
-
- softBody->setWindVelocity(bulletPhysics->wind);
-
- softBody->setPose(true, true);
-
- softBody->setActivationState(DISABLE_DEACTIVATION);
-
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->addSoftBody(softBody);
-
- transforms.push_back(new PhysicsTransform);
- }
- }
-
- physicscomponent.physicsObjectID = ++registeredObjects;
-}
-void wiBULLET::removeRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent)
-{
- if (physicscomponent.physicsObjectID < 0)
- {
- return;
- }
-
- deleteObject(physicscomponent.physicsObjectID);
-
- physicscomponent.physicsObjectID = -1;
-}
-void wiBULLET::removeSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent)
-{
- if (physicscomponent.physicsObjectID < 0)
- {
- return;
- }
-
- deleteObject(physicscomponent.physicsObjectID);
-
- physicscomponent.physicsObjectID = -1;
-}
-
-void wiBULLET::Update(float dt)
-{
- if (rigidBodyPhysicsEnabled || softBodyPhysicsEnabled)
- bulletPhysics->dynamicsWorld->stepSimulation(dt, 6);
-}
-void wiBULLET::ClearWorld()
-{
- for (int i = bulletPhysics->dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
- {
- deleteObject(i);
- }
-
- //delete collision shapes
- for (int j = 0; j < bulletPhysics->collisionShapes.size(); j++)
- {
- btCollisionShape* shape = bulletPhysics->collisionShapes[j];
- bulletPhysics->collisionShapes[j] = 0;
- delete shape;
- }
-
- //delete transfom interface
- for (unsigned int i = 0; i < transforms.size(); ++i)
- delete transforms[i];
- transforms.clear();
- registeredObjects = -1;
-}
-void wiBULLET::CleanUp()
-{
- for (unsigned int i = 0; i < transforms.size(); ++i)
- delete transforms[i];
- transforms.clear();
-}
-
-void wiBULLET::deleteObject(int id)
-{
- btCollisionObject* obj = bulletPhysics->dynamicsWorld->getCollisionObjectArray()[id];
- btRigidBody* body = btRigidBody::upcast(obj);
-
- if (body && body->getMotionState())
- {
- delete body->getMotionState();
- }
- while (bulletPhysics->dynamicsWorld->getNumConstraints())
- {
- btTypedConstraint* pc = bulletPhysics->dynamicsWorld->getConstraint(0);
- bulletPhysics->dynamicsWorld->removeConstraint(pc);
- delete pc;
- }
-
- btSoftBody* softBody = btSoftBody::upcast(obj);
- if (softBody)
- {
- ((btSoftRigidDynamicsWorld*)bulletPhysics->dynamicsWorld)->removeSoftBody(softBody);
- }
- else
- {
- btRigidBody* body = btRigidBody::upcast(obj);
- if (body)
- bulletPhysics->dynamicsWorld->removeRigidBody(body);
- else
- bulletPhysics->dynamicsWorld->removeCollisionObject(obj);
- }
- delete obj;
-
- registeredObjects--;
-}
-
-//
-//void wiBULLET::soundTickCallback(btDynamicsWorld *world, btScalar timeStep) {
-// int numManifolds = world->getDispatcher()->getNumManifolds();
-// for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i);
-// btCollisionObject* obA = (btCollisionObject*)(contactManifold->getBody0());
-// btCollisionObject* obB = (btCollisionObject*)(contactManifold->getBody1());
-//
-// int numContacts = contactManifold->getNumContacts();
-// for (int j=0;jgetContactPoint(j);
-// if (pt.getDistance()<0.f)
-// {
-// if(pt.getAppliedImpulse()>10.f){
-// //TODO: play some sound
-// }
-// const btVector3& ptA = pt.getPositionWorldOnA();
-// const btVector3& ptB = pt.getPositionWorldOnB();
-// const btVector3& normalOnB = pt.m_normalWorldOnB;
-// }
-// }
-// }
-//}
-//
-//void wiBULLET::pickingPreTickCallback (btDynamicsWorld *world, btScalar timeStep)
-//{
-//// world->getWorldUserInfo();
-////
-//// if(grab)
-//// {
-//// /*const int x=softDemo->m_lastmousepos[0];
-//// const int y=softDemo->m_lastmousepos[1];
-//// const btVector3 rayFrom=softDemo->getCameraPosition();
-//// const btVector3 rayTo=softDemo->getRayTo(x,y);
-//// const btVector3 rayDir=(rayTo-rayFrom).normalized();
-//// const btVector3 N=(softDemo->getCameraTargetPosition()-softDemo->getCameraPosition()).normalized();
-//// const btScalar O=btDot(softDemo->m_impact,N);*/
-//// const btVector3 rayFrom=btVector3(grabRay.origin.x,grabRay.origin.y,grabRay.origin.z);
-//// const btVector3 rayDir=btVector3(grabRay.direction.x,grabRay.direction.y,grabRay.direction.z);
-//// //const btScalar den=btDot(N,rayDir);
-//// //if((den*den)>0)
-/////* {
-//// const btScalar num=O-btDot(N,rayFrom);
-//// const btScalar hit=num/den;
-//// if((hit>0)&&(hit<1500))
-//// {
-//// softDemo->m_goal=rayFrom+rayDir*hit;
-//// }
-//// }*/
-//// btVector3 delta=softDemo->m_goal-softDemo->m_node->m_x;
-//// static const btScalar maxdrag=10;
-//// if(delta.length2()>(maxdrag*maxdrag))
-//// {
-//// delta=delta.normalized()*maxdrag;
-//// }
-//// softDemo->m_node->m_v+=delta/timeStep;
-//// }
-////
-//}
-//void wiBULLET::setGrab(bool value, const RAY& ray){
-// grab=value;
-// grabRay=ray;
-//}
diff --git a/WickedEngine/wiBULLET.h b/WickedEngine/wiBULLET.h
deleted file mode 100644
index 9e588ca72..000000000
--- a/WickedEngine/wiBULLET.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-#include "wiPHYSICS.h"
-
-struct BulletPhysicsWorld;
-
-struct RAY;
-
-class wiBULLET:public PHYSICS
-{
-private:
- BulletPhysicsWorld * bulletPhysics = nullptr;
-
- void deleteObject(int id);
-public:
- wiBULLET();
- ~wiBULLET();
-
- virtual void setWind(const XMFLOAT3& wind) override;
-
- virtual void connectVerticesToSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh) override;
- virtual void connectSoftBodyToVertices(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh) override;
- virtual void transformBody(const XMFLOAT4& rot, const XMFLOAT3& pos, int objectI) override;
-
- virtual PhysicsTransform* getObject(int index) override;
-
- virtual void addRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform) override;
- virtual void addSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform) override;
-
- virtual void removeRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent) override;
- virtual void removeSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent) override;
-
- virtual void Update(float dt) override;
- virtual void ClearWorld() override;
- virtual void CleanUp() override;
-
-};
-
diff --git a/WickedEngine/wiInitializer.cpp b/WickedEngine/wiInitializer.cpp
index 433e34605..28e49097c 100644
--- a/WickedEngine/wiInitializer.cpp
+++ b/WickedEngine/wiInitializer.cpp
@@ -11,6 +11,7 @@
#include "wiHelper.h"
#include "wiWidget.h"
#include "wiGPUSortLib.h"
+#include "wiPhysics.h"
using namespace std;
@@ -32,6 +33,8 @@ namespace wiInitializer
wiWidget::LoadShaders();
wiGPUSortLib::LoadShaders();
+ wiPhysics::Initialize();
+
if (FAILED(wiSoundEffect::Initialize()) || FAILED(wiMusic::Initialize()))
{
stringstream ss("");
@@ -39,4 +42,5 @@ namespace wiInitializer
wiHelper::messageBox(ss.str());
}
}
+
}
\ No newline at end of file
diff --git a/WickedEngine/wiPHYSICS.h b/WickedEngine/wiPHYSICS.h
index 2d053a3a3..d934820b9 100644
--- a/WickedEngine/wiPHYSICS.h
+++ b/WickedEngine/wiPHYSICS.h
@@ -1,51 +1,19 @@
#pragma once
-#include "CommonInclude.h"
+#include "wiECS.h"
#include "wiSceneSystem_Decl.h"
-#include
-
-class PHYSICS
+namespace wiPhysics
{
-public:
- struct PhysicsTransform
- {
- XMFLOAT4 rotation;
- XMFLOAT3 position;
- PhysicsTransform() {
- rotation = XMFLOAT4(0, 0, 0, 1);
- position = XMFLOAT3(0, 0, 0);
- }
- PhysicsTransform(const XMFLOAT4& newRot, const XMFLOAT3& newPos) {
- rotation = newRot;
- position = newPos;
- }
- };
- static int softBodyIterationCount;
- static bool rigidBodyPhysicsEnabled, softBodyPhysicsEnabled;
-protected:
- std::vector transforms;
- bool firstRunWorld;
- int registeredObjects;
-public:
- void FirstRunWorld() { firstRunWorld = true; }
- void NextRunWorld() { firstRunWorld = false; }
- int getObjectCount() { return registeredObjects + 1; }
+ void Initialize();
+ void CleanUp();
- virtual void Update(float dt)=0;
- virtual void ClearWorld()=0;
- virtual void CleanUp()=0;
-
- virtual void setWind(const XMFLOAT3& wind)=0;
-
- virtual void connectVerticesToSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh) = 0;
- virtual void connectSoftBodyToVertices(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh) = 0;
- virtual void transformBody(const XMFLOAT4& rot, const XMFLOAT3& pos, int objectI) = 0;
-
- virtual PhysicsTransform* getObject(int index)=0;
-
- virtual void addRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform) = 0;
- virtual void addSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, wiSceneSystem::MeshComponent& mesh, wiSceneSystem::TransformComponent& transform) = 0;
-
- virtual void removeRigidBody(wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent) = 0;
- virtual void removeSoftBody(wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent) = 0;
-};
+ void RunPhysicsUpdateSystem(
+ const wiSceneSystem::WeatherComponent& weather,
+ wiECS::ComponentManager& transforms,
+ wiECS::ComponentManager& meshes,
+ wiECS::ComponentManager& objects,
+ wiECS::ComponentManager& rigidbodies,
+ wiECS::ComponentManager& softbodies,
+ float dt
+ );
+}
diff --git a/WickedEngine/wiPhysics_Bullet.cpp b/WickedEngine/wiPhysics_Bullet.cpp
new file mode 100644
index 000000000..489616250
--- /dev/null
+++ b/WickedEngine/wiPhysics_Bullet.cpp
@@ -0,0 +1,466 @@
+#include "wiPhysics.h"
+#include "wiSceneSystem.h"
+#include "wiProfiler.h"
+
+
+#include "btBulletDynamicsCommon.h"
+
+#include "LinearMath/btHashMap.h"
+#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
+#include "BulletSoftBody/btSoftBodyHelpers.h"
+
+#include "BulletSoftBody/btSoftBodySolvers.h"
+#include "BulletSoftBody/btDefaultSoftBodySolver.h"
+#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
+
+#include
+
+using namespace std;
+using namespace wiECS;
+using namespace wiSceneSystem;
+
+namespace wiPhysics
+{
+ btVector3 gravity(0, -11, 0);
+ int softbodyIterationCount = 5;
+ btCollisionConfiguration* collisionConfiguration = nullptr;
+ btCollisionDispatcher* dispatcher = nullptr;
+ btBroadphaseInterface* overlappingPairCache = nullptr;
+ btSequentialImpulseConstraintSolver* solver = nullptr;
+ btDynamicsWorld* dynamicsWorld = nullptr;
+
+ btSoftBodySolver* softBodySolver = nullptr;
+ btSoftBodySolverOutput* softBodySolverOutput = nullptr;
+
+
+ unordered_map lookup;
+
+
+ void Initialize()
+ {
+ // collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
+ collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+
+ // use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
+ dispatcher = new btCollisionDispatcher(collisionConfiguration);
+
+ // btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
+ overlappingPairCache = new btDbvtBroadphase();
+
+ // the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
+ solver = new btSequentialImpulseConstraintSolver;
+
+ //dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
+ dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration, softBodySolver);
+
+ dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER;
+ dynamicsWorld->getDispatchInfo().m_enableSatConvex = true;
+ dynamicsWorld->getSolverInfo().m_splitImpulse = true;
+
+ dynamicsWorld->setGravity(gravity);
+
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().air_density = (btScalar)0.0;
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().water_density = 0;
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().water_offset = 0;
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().water_normal = btVector3(0, 0, 0);
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().m_gravity.setValue(gravity.x(), gravity.y(), gravity.z());
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo().m_sparsesdf.Initialize();
+
+ }
+ void CleanUp()
+ {
+ delete dynamicsWorld;
+ delete solver;
+ delete overlappingPairCache;
+ delete dispatcher;
+ delete collisionConfiguration;
+ }
+
+
+ void Remove(Entity entity)
+ {
+ auto it = lookup.find(entity);
+ if (it != lookup.end())
+ {
+ int id = it->second;
+ lookup.erase(it);
+
+ btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[id];
+ btRigidBody* body = btRigidBody::upcast(obj);
+
+ if (body && body->getMotionState())
+ {
+ delete body->getMotionState();
+ }
+ while (dynamicsWorld->getNumConstraints())
+ {
+ btTypedConstraint* pc = dynamicsWorld->getConstraint(0);
+ dynamicsWorld->removeConstraint(pc);
+ delete pc;
+ }
+
+ btSoftBody* softBody = btSoftBody::upcast(obj);
+ if (softBody)
+ {
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->removeSoftBody(softBody);
+ }
+ else
+ {
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body)
+ dynamicsWorld->removeRigidBody(body);
+ else
+ dynamicsWorld->removeCollisionObject(obj);
+ }
+
+ delete obj;
+ }
+ }
+ int AddRigidBody(Entity entity, wiSceneSystem::RigidBodyPhysicsComponent& physicscomponent, const wiSceneSystem::MeshComponent& mesh, const wiSceneSystem::TransformComponent& transform)
+ {
+ btVector3 S(transform.scale_local.x, transform.scale_local.y, transform.scale_local.z);
+
+ btCollisionShape* shape = nullptr;
+
+ switch (physicscomponent.shape)
+ {
+ case RigidBodyPhysicsComponent::CollisionShape::BOX:
+ shape = new btBoxShape(S);
+ break;
+
+ case RigidBodyPhysicsComponent::CollisionShape::SPHERE:
+ shape = new btSphereShape(btScalar(S.x()));
+ break;
+
+ case RigidBodyPhysicsComponent::CollisionShape::CAPSULE:
+ shape = new btCapsuleShape(btScalar(S.x()), btScalar(S.y()));
+ break;
+
+ case RigidBodyPhysicsComponent::CollisionShape::CONVEX_HULL:
+ {
+ shape = new btConvexHullShape();
+ for (auto& pos : mesh.vertex_positions)
+ {
+ ((btConvexHullShape*)shape)->addPoint(btVector3(pos.x, pos.y, pos.z));
+ }
+ shape->setLocalScaling(S);
+ }
+ break;
+
+ case RigidBodyPhysicsComponent::CollisionShape::TRIANGLE_MESH:
+ {
+ int totalVerts = (int)mesh.vertex_positions.size();
+ int totalTriangles = (int)mesh.indices.size() / 3;
+
+ btVector3* btVerts = new btVector3[totalVerts];
+ size_t i = 0;
+ for (auto& pos : mesh.vertex_positions)
+ {
+ btVerts[i++] = btVector3(pos.x, pos.y, pos.z);
+ }
+
+ int* btInd = new int[mesh.indices.size()];
+ i = 0;
+ for (auto& ind : mesh.indices)
+ {
+ btInd[i++] = ind;
+ }
+
+ int vertStride = sizeof(btVector3);
+ int indexStride = 3 * sizeof(int);
+
+ btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(
+ totalTriangles,
+ btInd,
+ indexStride,
+ totalVerts,
+ (btScalar*)&btVerts[0].x(),
+ vertStride
+ );
+
+ bool useQuantizedAabbCompression = true;
+ shape = new btBvhTriangleMeshShape(indexVertexArrays, useQuantizedAabbCompression);
+ shape->setLocalScaling(S);
+ }
+ break;
+ }
+
+ if (shape != nullptr)
+ {
+ shape->setMargin(btScalar(0.05));
+
+ btScalar mass(physicscomponent.mass);
+
+ bool isDynamic = (mass != 0.f && !physicscomponent.IsKinematic());
+
+ btVector3 localInertia(0, 0, 0);
+ if (isDynamic)
+ {
+ shape->calculateLocalInertia(mass, localInertia);
+ }
+ else
+ {
+ mass = 0;
+ }
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btTransform shapeTransform;
+ shapeTransform.setIdentity();
+ shapeTransform.setOrigin(btVector3(transform.translation_local.x, transform.translation_local.y, transform.translation_local.z));
+ shapeTransform.setRotation(btQuaternion(transform.rotation_local.x, transform.rotation_local.y, transform.rotation_local.z, transform.rotation_local.w));
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(shapeTransform);
+
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia);
+ rbInfo.m_friction = physicscomponent.friction;
+ rbInfo.m_restitution = physicscomponent.restitution;
+ rbInfo.m_linearDamping = physicscomponent.damping;
+ rbInfo.m_angularDamping = physicscomponent.damping;
+
+ btRigidBody* body = new btRigidBody(rbInfo);
+ if (physicscomponent.IsKinematic())
+ {
+ body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+ if (physicscomponent.IsDisableDeactivation())
+ {
+ body->setActivationState(DISABLE_DEACTIVATION);
+ }
+
+ int id = dynamicsWorld->getCollisionObjectArray().size();
+ lookup[entity] = id;
+ dynamicsWorld->addRigidBody(body);
+ return id;
+ }
+
+ return -1;
+ }
+ int AddSoftBody(Entity entity, wiSceneSystem::SoftBodyPhysicsComponent& physicscomponent, const wiSceneSystem::MeshComponent& mesh, const wiSceneSystem::TransformComponent& transform)
+ {
+ 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);
+
+ const int vCount = (int)physicscomponent.physicsvertices.size();
+ btScalar* btVerts = new btScalar[vCount * 3];
+ for (int i = 0; i < vCount * 3; i += 3) {
+ const int vindex = i / 3;
+ btVerts[i] = btScalar(physicscomponent.physicsvertices[vindex].x);
+ btVerts[i + 1] = btScalar(physicscomponent.physicsvertices[vindex].y);
+ btVerts[i + 2] = btScalar(physicscomponent.physicsvertices[vindex].z);
+ }
+ const int iCount = (int)physicscomponent.physicsindices.size();
+ const int tCount = iCount / 3;
+ int* btInd = new int[iCount];
+ for (int i = 0; i < iCount; ++i) {
+ btInd[i] = physicscomponent.physicsindices[i];
+ }
+
+
+ btSoftBody* softBody = btSoftBodyHelpers::CreateFromTriMesh(
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->getWorldInfo()
+ , &btVerts[0]
+ , &btInd[0]
+ , tCount
+ , false
+ );
+
+
+ delete[] btVerts;
+ delete[] btInd;
+
+ if (softBody)
+ {
+ btSoftBody::Material* pm = softBody->appendMaterial();
+ pm->m_kLST = 0.5;
+ pm->m_kVST = 0.5;
+ pm->m_kAST = 0.5;
+ pm->m_flags = 0;
+ 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.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]
+ softBody->m_cfg.kLF = btScalar(0.1); //0 Lift coefficient [0,+inf]
+ softBody->m_cfg.kMT = btScalar(0.0); //0 Pose matching coefficient [0,1]
+ softBody->m_cfg.kPR = btScalar(0.0); //0 Pressure coefficient [-1,1]
+ softBody->m_cfg.kSHR = btScalar(1.0); //1 Soft contacts hardness [0,1]
+ softBody->m_cfg.kVC = btScalar(0.0); //0 Volume conseration coefficient [0,+inf]
+ softBody->m_cfg.kVCF = btScalar(1.0); //1 Velocities correction factor (Baumgarte)
+
+ softBody->m_cfg.kSKHR_CL = btScalar(1.0); //1 Soft vs. kinetic hardness [0,1]
+ softBody->m_cfg.kSK_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
+ softBody->m_cfg.kSRHR_CL = btScalar(0.1); //0.1 Soft vs. rigid hardness [0,1]
+ softBody->m_cfg.kSR_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
+ softBody->m_cfg.kSSHR_CL = btScalar(0.5); //0.5 Soft vs. soft hardness [0,1]
+ softBody->m_cfg.kSS_SPLT_CL = btScalar(0.5); //0.5 Soft vs. rigid impulse split [0,1]
+
+
+ btScalar mass = btScalar(physicscomponent.mass);
+ softBody->setTotalMass(mass);
+
+ //int mvg = physicscomponent.massVG;
+ //if (mvg >= 0) {
+ // for (auto it = mesh.vertexGroups[mvg].vertex_weights.begin(); it != mesh.vertexGroups[mvg].vertex_weights.end(); ++it) {
+ // int vi = (*it).first;
+ // float wei = (*it).second;
+ // int index = physicscomponent.physicalmapGP[vi];
+ // softBody->setMass(index, softBody->getMass(index)*btScalar(wei));
+ // }
+ //}
+
+
+ //int gvg = physicscomponent.goalVG;
+ //if (gvg >= 0) {
+ // for (auto it = mesh.vertexGroups[gvg].vertex_weights.begin(); it != mesh.vertexGroups[gvg].vertex_weights.end(); ++it) {
+ // int vi = (*it).first;
+ // int index = physicscomponent.physicalmapGP[vi];
+ // float weight = (*it).second;
+ // if (weight == 1)
+ // softBody->setMass(index, 0);
+ // }
+ //}
+
+ softBody->getCollisionShape()->setMargin(btScalar(0.2));
+
+ //softBody->setWindVelocity(wind);
+
+ softBody->setPose(true, true);
+
+ softBody->setActivationState(DISABLE_DEACTIVATION);
+
+ int id = dynamicsWorld->getCollisionObjectArray().size();
+ lookup[entity] = id;
+ ((btSoftRigidDynamicsWorld*)dynamicsWorld)->addSoftBody(softBody);
+ return id;
+ }
+
+ return -1;
+ }
+
+ void RunPhysicsUpdateSystem(
+ const WeatherComponent& weather,
+ ComponentManager& transforms,
+ ComponentManager& meshes,
+ ComponentManager& objects,
+ ComponentManager& rigidbodies,
+ ComponentManager& softbodies,
+ float dt
+ )
+ {
+ wiProfiler::GetInstance().BeginRange("Physics", wiProfiler::DOMAIN_CPU);
+
+ btVector3 wind = btVector3(weather.windDirection.x, weather.windDirection.y, weather.windDirection.z);
+
+
+ // Rigid bodies - Objects:
+ for (size_t i = 0; i < rigidbodies.GetCount(); ++i)
+ {
+ Entity entity = rigidbodies.GetEntity(i);
+ RigidBodyPhysicsComponent& rigidbody = rigidbodies[i];
+ TransformComponent& transform = *transforms.GetComponent(entity);
+ int id = -1;
+
+ auto it = lookup.find(entity);
+ if (it == lookup.end())
+ {
+ const ObjectComponent& object = *objects.GetComponent(entity);
+ const MeshComponent& mesh = *meshes.GetComponent(object.meshID);
+ id = AddRigidBody(entity, rigidbody, mesh, transform);
+ }
+ else
+ {
+ id = it->second;
+ }
+ assert(id >= 0 && id <= dynamicsWorld->getCollisionObjectArray().size());
+
+ btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[id];
+ btRigidBody* body = btRigidBody::upcast(obj);
+
+ if (body != nullptr)
+ {
+ btMotionState* motionState = body->getMotionState();
+ btTransform physicsTransform;
+
+ if (rigidbody.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);
+ physicsTransform.setOrigin(T);
+ physicsTransform.setRotation(R);
+ motionState->setWorldTransform(physicsTransform);
+ }
+ else
+ {
+ motionState->getWorldTransform(physicsTransform);
+ btVector3 T = physicsTransform.getOrigin();
+ btQuaternion R = physicsTransform.getRotation();
+
+ transform.translation_local = XMFLOAT3(T.x(), T.y(), T.z());
+ transform.rotation_local = XMFLOAT4(R.x(), R.y(), R.z(), R.w());
+ transform.SetDirty();
+ }
+ }
+
+
+ }
+
+ // Soft bodies - Meshes:
+ for (size_t i = 0; i < softbodies.GetCount(); ++i)
+ {
+ Entity entity = softbodies.GetEntity(i);
+ SoftBodyPhysicsComponent& softbody = softbodies[i];
+ MeshComponent& mesh = *meshes.GetComponent(entity);
+ mesh.SetDynamic(true);
+ int id = -1;
+
+ auto it = lookup.find(entity);
+ if (it == lookup.end())
+ {
+ TransformComponent transform;
+ id = AddSoftBody(entity, softbody, mesh, transform);
+ }
+ else
+ {
+ id = it->second;
+ }
+ assert(id >= 0 && id <= dynamicsWorld->getCollisionObjectArray().size());
+
+ }
+
+ // Tidy:
+ for (auto it : lookup)
+ {
+ Entity entity = it.first;
+ bool exists = rigidbodies.Contains(entity);
+ if (!exists)
+ {
+ exists = softbodies.Contains(entity);
+ }
+
+ if (!exists)
+ {
+ Remove(entity);
+ break;
+ }
+ }
+
+ dynamicsWorld->stepSimulation(dt, 6);
+
+ wiProfiler::GetInstance().EndRange(); // Physics
+ }
+}
diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp
index b25dffa6a..f7919b5fb 100644
--- a/WickedEngine/wiSceneSystem.cpp
+++ b/WickedEngine/wiSceneSystem.cpp
@@ -4,6 +4,7 @@
#include "wiResourceManager.h"
#include "wiPHYSICS.h"
#include "wiArchive.h"
+#include "wiPhysics.h"
using namespace wiECS;
using namespace wiGraphicsTypes;
@@ -814,7 +815,7 @@ namespace wiSceneSystem
RunAnimationUpdateSystem(animations, transforms, dt);
- RunPhysicsUpdateSystem(transforms, meshes, objects, rigidbodies, softbodies, dt);
+ wiPhysics::RunPhysicsUpdateSystem(weather, transforms, meshes, objects, rigidbodies, softbodies, dt);
RunTransformUpdateSystem(transforms);
@@ -1410,57 +1411,6 @@ namespace wiSceneSystem
animation.timer = min(animation.timer, animationLength);
}
}
- void RunPhysicsUpdateSystem(
- ComponentManager& transforms,
- ComponentManager& meshes,
- ComponentManager& objects,
- ComponentManager& rigidbodies,
- ComponentManager& softbodies,
- float dt
- )
- {
- //PHYSICS* physicsEngine = wiRenderer::physicsEngine;
-
- //if (physicsEngine != nullptr)
- //{
- // physicsEngine->Update(dt);
-
- // // Rigid bodies - Objects:
- // for (size_t i = 0; i < rigidbodies.GetCount(); ++i)
- // {
- // RigidBodyPhysicsComponent& rigidbody = rigidbodies[i];
- // Entity entity = rigidbodies.GetEntity(i);
- // TransformComponent& transform = *transforms.GetComponent(entity);
-
- // if (rigidbody.kinematic)
- // {
- // //physicsEngine->transformBody(transform.rotation, transform.translation, rigidbody.physicsObjectID);
- // }
- // else
- // {
- // PHYSICS::PhysicsTransform* pt = physicsEngine->getObject(rigidbody.physicsObjectID);
- // transform.translation_local = pt->position;
- // transform.rotation_local = pt->rotation;
- // transform.SetDirty();
- // }
-
- // }
-
- // // Soft bodies - Meshes:
- // for (size_t i = 0; i < softbodies.GetCount(); ++i)
- // {
- // SoftBodyPhysicsComponent& softbody = softbodies[i];
- // Entity entity = softbodies.GetEntity(i);
-
- // MeshComponent& mesh = *meshes.GetComponent(entity);
- // mesh.SetDynamic(true);
-
- // }
-
- // physicsEngine->NextRunWorld();
- //}
-
- }
void RunTransformUpdateSystem(ComponentManager& transforms)
{
for (size_t i = 0; i < transforms.GetCount(); ++i)
diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h
index bf3cdd799..ba4996a22 100644
--- a/WickedEngine/wiSceneSystem.h
+++ b/WickedEngine/wiSceneSystem.h
@@ -435,14 +435,16 @@ namespace wiSceneSystem
ENUM_FORCE_UINT32 = 0xFFFFFFFF
};
CollisionShape shape;
- bool kinematic = false;
float mass = 1.0f;
float friction = 1.0f;
float restitution = 1.0f;
float damping = 1.0f;
- // Non-serialized attributes:
- int physicsObjectID = -1;
+ inline void SetDisableDeactivation(bool value) { if (value) { _flags |= DISABLE_DEACTIVATION; } else { _flags &= ~DISABLE_DEACTIVATION; } }
+ inline void SetKinematic(bool value) { if (value) { _flags |= KINEMATIC; } else { _flags &= ~KINEMATIC; } }
+
+ inline bool IsDisableDeactivation() const { return _flags & DISABLE_DEACTIVATION; }
+ inline bool IsKinematic() const { return _flags & KINEMATIC; }
void Serialize(wiArchive& archive, uint32_t seed = 0);
};
@@ -461,9 +463,6 @@ namespace wiSceneSystem
std::vector physicsvertices;
std::vector physicsindices;
- // Non-serialized attributes:
- int physicsObjectID = -1;
-
void Serialize(wiArchive& archive, uint32_t seed = 0);
};
@@ -989,14 +988,6 @@ namespace wiSceneSystem
wiECS::ComponentManager& transforms,
float dt
);
- void RunPhysicsUpdateSystem(
- wiECS::ComponentManager& transforms,
- wiECS::ComponentManager& meshes,
- wiECS::ComponentManager& objects,
- wiECS::ComponentManager& rigidbodies,
- wiECS::ComponentManager& softbodies,
- float dt
- );
void RunTransformUpdateSystem(wiECS::ComponentManager& transforms);
void RunHierarchyUpdateSystem(
const wiECS::ComponentManager& hierarchy,
diff --git a/WickedEngine/wiSceneSystem_Serializers.cpp b/WickedEngine/wiSceneSystem_Serializers.cpp
index 488665003..8dddd5be6 100644
--- a/WickedEngine/wiSceneSystem_Serializers.cpp
+++ b/WickedEngine/wiSceneSystem_Serializers.cpp
@@ -229,7 +229,6 @@ namespace wiSceneSystem
{
archive >> _flags;
archive >> (uint32_t&)shape;
- archive >> kinematic;
archive >> mass;
archive >> friction;
archive >> restitution;
@@ -239,7 +238,6 @@ namespace wiSceneSystem
{
archive << _flags;
archive << (uint32_t&)shape;
- archive << kinematic;
archive << mass;
archive << friction;
archive << restitution;