physics teleport

This commit is contained in:
Turánszki János
2025-04-06 08:16:25 +02:00
parent 107b9c8b27
commit 27c770b9cc
6 changed files with 168 additions and 31 deletions
@@ -2091,6 +2091,8 @@ Playstation button codes:
- GetVelocity() : Vector-- returns linear velocity of a body
- SetGhostMode(RigidBodyPhysicsComponent|HumanoidComponent component, bool value) -- enable/disable ghost mode for rigid body or ragdoll (all collision disabled)
- SetRagdollGhostMode(HumanoidComponent humanoid, bool value) -- enable/disable ghost mode for a ragdoll. In ghost mode, the ragdoll will not collide with anything. Enable this if the humanoid sits inside a vehicle for example.
- SetPosition(RigidBodyPhysicsComponent component, Vector position) -- teleport a dynamic body
- SetPositionAndRotation(RigidBodyPhysicsComponent component, Vector position, Vector rotationQuaternion) -- teleport a dynamic body
- SetLinearVelocity(RigidBodyPhysicsComponent component, Vector velocity) -- Set the linear velocity manually
- SetAngularVelocity(RigidBodyPhysicsComponent component, Vector velocity) -- Set the angular velocity manually
- ApplyForce(RigidBodyPhysicsComponent component, Vector force) -- Apply force at body center
+11
View File
@@ -47,6 +47,17 @@ namespace wi::physics
float dt
);
// Teleport a dynamic rigid body:
void SetPosition(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& position
);
void SetPositionAndRotation(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& position,
const XMFLOAT4& rotation
);
// Set linear velocity to rigid body
void SetLinearVelocity(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
+61
View File
@@ -19,6 +19,8 @@ namespace wi::lua
lunamethod(Physics_BindLua, GetAccuracy),
lunamethod(Physics_BindLua, SetFrameRate),
lunamethod(Physics_BindLua, GetFrameRate),
lunamethod(Physics_BindLua, SetPosition),
lunamethod(Physics_BindLua, SetPositionAndRotation),
lunamethod(Physics_BindLua, SetLinearVelocity),
lunamethod(Physics_BindLua, SetAngularVelocity),
lunamethod(Physics_BindLua, ApplyForceAt),
@@ -141,6 +143,65 @@ namespace wi::lua
return 1;
}
int Physics_BindLua::SetPosition(lua_State* L)
{
int argc = wi::lua::SGetArgCount(L);
if (argc > 1)
{
scene::RigidBodyPhysicsComponent_BindLua* component = Luna<scene::RigidBodyPhysicsComponent_BindLua>::lightcheck(L, 1);
if (component == nullptr)
{
wi::lua::SError(L, "SetPosition(RigidBodyPhysicsComponent component, Vector position) first argument is not a RigidBodyPhysicsComponent!");
return 0;
}
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 2);
if (vec == nullptr)
{
wi::lua::SError(L, "SetPosition(RigidBodyPhysicsComponent component, Vector position) second argument is not a Vector!");
return 0;
}
wi::physics::SetPosition(
*component->component,
*(XMFLOAT3*)vec
);
}
else
wi::lua::SError(L, "SetPosition(RigidBodyPhysicsComponent component, Vector position) not enough arguments!");
return 0;
}
int Physics_BindLua::SetPositionAndRotation(lua_State* L)
{
int argc = wi::lua::SGetArgCount(L);
if (argc > 2)
{
scene::RigidBodyPhysicsComponent_BindLua* component = Luna<scene::RigidBodyPhysicsComponent_BindLua>::lightcheck(L, 1);
if (component == nullptr)
{
wi::lua::SError(L, "SetPositionAndRotation(RigidBodyPhysicsComponent component, Vector position, Vector rotationQuaternion) first argument is not a RigidBodyPhysicsComponent!");
return 0;
}
Vector_BindLua* vec = Luna<Vector_BindLua>::lightcheck(L, 2);
if (vec == nullptr)
{
wi::lua::SError(L, "SetPositionAndRotation(RigidBodyPhysicsComponent component, Vector position, Vector rotationQuaternion) second argument is not a Vector!");
return 0;
}
Vector_BindLua* vec2 = Luna<Vector_BindLua>::lightcheck(L, 3);
if (vec2 == nullptr)
{
wi::lua::SError(L, "SetPositionAndRotation(RigidBodyPhysicsComponent component, Vector position, Vector rotationQuaternion) third argument is not a Vector!");
return 0;
}
wi::physics::SetPositionAndRotation(
*component->component,
vec->GetFloat3(),
vec2->data
);
}
else
wi::lua::SError(L, "SetPositionAndRotation(RigidBodyPhysicsComponent component, Vector position, Vector rotationQuaternion) not enough arguments!");
return 0;
}
int Physics_BindLua::SetLinearVelocity(lua_State* L)
{
int argc = wi::lua::SGetArgCount(L);
+2
View File
@@ -28,6 +28,8 @@ namespace wi::lua
int SetFrameRate(lua_State* L);
int GetFrameRate(lua_State* L);
int SetPosition(lua_State* L);
int SetPositionAndRotation(lua_State* L);
int SetLinearVelocity(lua_State* L);
int SetAngularVelocity(lua_State* L);
int ApplyForce(lua_State* L);
+91 -30
View File
@@ -266,9 +266,10 @@ namespace wi::physics
float friction = 0;
float restitution = 0;
EMotionType motiontype = EMotionType::Static;
bool start_deactivated = false;
bool was_underwater = false;
bool was_active_prev_frame = false;
uint8_t start_deactivated : 1;
uint8_t was_underwater : 1;
uint8_t was_active_prev_frame : 1;
uint8_t teleporting : 1;
Vec3 initial_position = Vec3::sZero();
Quat initial_rotation = Quat::sIdentity();
@@ -316,6 +317,13 @@ namespace wi::physics
shape = nullptr;
}
RigidBody()
{
start_deactivated = 0;
was_underwater = 0;
was_active_prev_frame = 0;
teleporting = 0;
}
~RigidBody()
{
Delete();
@@ -2040,25 +2048,44 @@ namespace wi::physics
}
}
const Vec3 position = cast(transform->GetPosition());
const Quat rotation = cast(transform->GetRotation());
Mat44 m = Mat44::sTranslation(position) * Mat44::sRotation(rotation);
m = m * physicsobject.additionalTransform;
if (IsSimulationEnabled())
if (physicsobject.teleporting)
{
// Feedback system transform to kinematic and static physics objects:
if (currentMotionType == EMotionType::Kinematic)
physicsobject.teleporting = false;
}
else
{
const Vec3 position = cast(transform->GetPosition());
const Quat rotation = cast(transform->GetRotation());
Mat44 m = Mat44::sTranslation(position) * Mat44::sRotation(rotation);
m = m * physicsobject.additionalTransform;
if (IsSimulationEnabled())
{
body_interface.MoveKinematic(
physicsobject.bodyID,
m.GetTranslation(),
m.GetQuaternion().Normalized(),
physics_scene.GetKinematicDT(scene.dt)
);
// Feedback system transform to kinematic and static physics objects:
if (currentMotionType == EMotionType::Kinematic)
{
body_interface.MoveKinematic(
physicsobject.bodyID,
m.GetTranslation(),
m.GetQuaternion().Normalized(),
physics_scene.GetKinematicDT(scene.dt)
);
}
else if (currentMotionType == EMotionType::Static || !is_active)
{
body_interface.SetPositionAndRotation(
physicsobject.bodyID,
m.GetTranslation(),
m.GetQuaternion().Normalized(),
EActivation::DontActivate
);
}
}
else if (currentMotionType == EMotionType::Static || !is_active)
else
{
// Simulation is disabled, update physics state immediately:
physicsobject.prev_position = position;
physicsobject.prev_rotation = rotation;
body_interface.SetPositionAndRotation(
physicsobject.bodyID,
m.GetTranslation(),
@@ -2067,18 +2094,6 @@ namespace wi::physics
);
}
}
else
{
// Simulation is disabled, update physics state immediately:
physicsobject.prev_position = position;
physicsobject.prev_rotation = rotation;
body_interface.SetPositionAndRotation(
physicsobject.bodyID,
m.GetTranslation(),
m.GetQuaternion().Normalized(),
EActivation::DontActivate
);
}
});
// System will register softbodies to meshes and update physics engine state:
@@ -2617,6 +2632,52 @@ namespace wi::physics
wi::profiler::EndRange(range); // Physics
}
void SetPosition(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& position
)
{
if (physicscomponent.physicsobject == nullptr)
return;
RigidBody& physicsobject = GetRigidBody(physicscomponent);
PhysicsScene& physics_scene = *(PhysicsScene*)physicsobject.physics_scene.get();
BodyInterface& body_interface = physics_scene.physics_system.GetBodyInterfaceNoLock();
physicsobject.prev_position = cast(position);
Mat44 m = Mat44::sTranslation(physicsobject.prev_position) * Mat44::sRotation(physicsobject.prev_rotation);
m = m * physicsobject.additionalTransform;
body_interface.SetPosition(
physicsobject.bodyID,
m.GetTranslation(),
EActivation::DontActivate
);
physicsobject.teleporting = true;
}
void SetPositionAndRotation(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& position,
const XMFLOAT4& rotation
)
{
if (physicscomponent.physicsobject == nullptr)
return;
RigidBody& physicsobject = GetRigidBody(physicscomponent);
PhysicsScene& physics_scene = *(PhysicsScene*)physicsobject.physics_scene.get();
BodyInterface& body_interface = physics_scene.physics_system.GetBodyInterfaceNoLock();
physicsobject.prev_position = cast(position);
physicsobject.prev_rotation = cast(rotation).Normalized();
Mat44 m = Mat44::sTranslation(physicsobject.prev_position) * Mat44::sRotation(physicsobject.prev_rotation);
m = m * physicsobject.additionalTransform;
body_interface.SetPositionAndRotation(
physicsobject.bodyID,
m.GetTranslation(),
m.GetQuaternion().Normalized(),
EActivation::DontActivate
);
physicsobject.teleporting = true;
}
void SetLinearVelocity(
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const XMFLOAT3& velocity
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 730;
const int revision = 731;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);