#include "PhysicsObject.hpp" #include "MathF.hpp" #include "elements/Transformable.hpp" #include "elements/PhysicsEngine.hpp" TSE::PhysicsObject::PhysicsObject(BodyType t, ColliderShape s, float d, float f, Vector3 cs) { type = t; shape = s; density = d; friction = f; collidersize = cs; } TSE::PhysicsObject::~PhysicsObject() { PhysicsEngine::UnRegisterPhysicsObject(this); if(b2Body_IsValid(bodyId)) b2DestroyBody(bodyId); } void TSE::PhysicsObject::UpdatePosition() { b2Vec2 b2newPos = b2Body_GetPosition(bodyId); if(lastPos.x != b2newPos.x || lastPos.y != b2newPos.y) { Vector3 newPos(b2newPos.x, b2newPos.y, lastPos.z); lastPos = newPos; Vector3 delta = baseObject->GlobalToLocalPosition(newPos); baseObject->position = baseObject->position + delta; } float newRot = b2Rot_GetAngle(b2Body_GetRotation(bodyId)); if(newRot != lastRot) { lastRot = newRot; Vector3 euler = baseObject->GetEuler(); euler.z = Rad2Deg(newRot); } } void TSE::PhysicsObject::OnUpdate() { Vector3 globalPos = baseObject->GetGlobalPosition(); float rot = Deg2Rad(baseObject->GetEuler().z); if(globalPos != lastPos || rot != lastRot) { lastPos = globalPos; lastRot = rot; b2Vec2 pos; pos.x = globalPos.x; pos.y = globalPos.y; b2Body_SetTransform(bodyId, pos, b2MakeRot(rot)); b2Body_SetAwake(bodyId, true); } } void TSE::PhysicsObject::Start() { b2WorldId& wid = PhysicsEngine::GetWorldId(); b2BodyDef def = b2DefaultBodyDef(); b2Vec2 pos; Vector3 globalPos = baseObject->GetGlobalPosition(); pos.x = globalPos.x; pos.y = globalPos.y; def.position = pos; lastPos = globalPos; float rot = Deg2Rad(baseObject->GetEuler().z); def.rotation = b2MakeRot(rot); lastRot = rot; b2BodyType b2type; switch(type) { case BodyType::Dynamic: b2type = b2_dynamicBody; break; case BodyType::Static: b2type = b2_staticBody; break; } def.type = b2type; bodyId = b2CreateBody(wid, &def); b2ShapeDef shapeDef = b2DefaultShapeDef(); shapeDef.density = density; shapeDef.material.friction = friction; b2Polygon b2shape; b2Circle b2circle; b2Capsule b2capsule; switch (shape) { case ColliderShape::Box: b2shape = b2MakeBox(collidersize.x * 0.5f, collidersize.y * 0.5f); b2CreatePolygonShape(bodyId, &shapeDef, &b2shape); break; case ColliderShape::RoundedBox: b2shape = b2MakeRoundedBox(collidersize.x * 0.5f, collidersize.y * 0.5f, collidersize.z); b2CreatePolygonShape(bodyId, &shapeDef, &b2shape); break; case ColliderShape::Circle: b2circle.radius = collidersize.x; b2CreateCircleShape(bodyId, &shapeDef, &b2circle); break; case ColliderShape::Capsule: b2capsule.radius = collidersize.x; b2capsule.center1 = {0, collidersize.y * 0.5f}; b2capsule.center1 = {0, collidersize.y * -0.5f}; b2CreateCapsuleShape(bodyId, &shapeDef, &b2capsule); break; } PhysicsEngine::RegisterPhysicsObject(this); }