fixed PhysX issues? + added rotation constraints

This commit is contained in:
Anemunt
2025-12-17 03:35:57 -05:00
parent c23fcecc9f
commit 2eca8493e1
6 changed files with 57 additions and 13 deletions

View File

@@ -321,15 +321,15 @@ void Engine::run() {
}
}
if (isPlaying) {
updatePlayerController(deltaTime);
}
bool simulatePhysics = physics.isReady() && ((isPlaying && !isPaused) || (!isPlaying && specMode));
if (simulatePhysics) {
physics.simulate(deltaTime, sceneObjects);
}
if (isPlaying) {
updatePlayerController(deltaTime);
}
bool audioShouldPlay = isPlaying || specMode || testMode;
Camera listenerCamera = camera;
for (const auto& obj : sceneObjects) {
@@ -875,11 +875,13 @@ void Engine::updatePlayerController(float delta) {
if (grounded) {
pc.verticalVelocity = 0.0f;
if (!havePhysVel) {
if (hitGround) {
player->position.y = std::max(player->position.y, hitPos.y + capsuleHalf);
} else {
player->position.y = capsuleHalf;
}
}
if (key(GLFW_KEY_SPACE)) {
pc.verticalVelocity = pc.jumpStrength;
}

View File

@@ -2331,6 +2331,16 @@ void Engine::renderInspectorPanel() {
obj.rigidbody.angularDamping = std::clamp(obj.rigidbody.angularDamping, 0.0f, 10.0f);
changed = true;
}
ImGui::TextDisabled("Rotation Constraints");
if (ImGui::Checkbox("Lock Rotation X", &obj.rigidbody.lockRotationX)) {
changed = true;
}
if (ImGui::Checkbox("Lock Rotation Y", &obj.rigidbody.lockRotationY)) {
changed = true;
}
if (ImGui::Checkbox("Lock Rotation Z", &obj.rigidbody.lockRotationZ)) {
changed = true;
}
ImGui::Unindent(10.0f);
ImGui::PopID();
}

View File

@@ -332,7 +332,11 @@ PhysicsSystem::ActorRecord PhysicsSystem::createActorFor(const SceneObject& obj)
dyn->setLinearDamping(obj.rigidbody.linearDamping);
dyn->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, obj.rigidbody.isKinematic);
dyn->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, !obj.rigidbody.useGravity);
dyn->setRigidDynamicLockFlags(PxRigidDynamicLockFlag::eLOCK_ANGULAR_X | PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z);
PxRigidDynamicLockFlags lockFlags;
if (obj.rigidbody.lockRotationX) lockFlags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_X;
if (obj.rigidbody.lockRotationY) lockFlags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y;
if (obj.rigidbody.lockRotationZ) lockFlags |= PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z;
dyn->setRigidDynamicLockFlags(lockFlags);
if (obj.hasPlayerController) {
dyn->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true);
dyn->setMaxDepenetrationVelocity(1.5f);
@@ -404,9 +408,6 @@ bool PhysicsSystem::setActorYaw(int id, float yawDegrees) {
PxQuat yawQuat(static_cast<float>(glm::radians(yawDegrees)), PxVec3(0, 1, 0));
pose.q = yawQuat;
rec.actor->setGlobalPose(pose);
if (PxRigidDynamic* dyn = rec.actor->is<PxRigidDynamic>()) {
dyn->setRigidDynamicLockFlags(PxRigidDynamicLockFlag::eLOCK_ANGULAR_X | PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z);
}
return true;
#endif
return false;
@@ -507,7 +508,23 @@ void PhysicsSystem::simulate(float deltaTime, std::vector<SceneObject>& objects)
if (it == objects.end() || !it->enabled) continue;
it->position = ToGlmVec3(pose.p);
it->rotation.y = ToGlmEulerDeg(pose.q).y;
if (it->hasPlayerController && it->playerController.enabled) {
continue;
}
glm::vec3 euler = ToGlmEulerDeg(pose.q);
if (PxRigidDynamic* dyn = rec.actor->is<PxRigidDynamic>()) {
PxRigidDynamicLockFlags lockFlags = dyn->getRigidDynamicLockFlags();
bool lockX = lockFlags.isSet(PxRigidDynamicLockFlag::eLOCK_ANGULAR_X);
bool lockY = lockFlags.isSet(PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y);
bool lockZ = lockFlags.isSet(PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z);
if (lockX && lockZ && !lockY) {
it->rotation.y = euler.y;
} else {
it->rotation = euler;
}
} else {
it->rotation.y = euler.y;
}
}
}

View File

@@ -283,6 +283,9 @@ bool SceneSerializer::saveScene(const fs::path& filePath,
file << "rbKinematic=" << (obj.rigidbody.isKinematic ? 1 : 0) << "\n";
file << "rbLinearDamping=" << obj.rigidbody.linearDamping << "\n";
file << "rbAngularDamping=" << obj.rigidbody.angularDamping << "\n";
file << "rbLockRotX=" << (obj.rigidbody.lockRotationX ? 1 : 0) << "\n";
file << "rbLockRotY=" << (obj.rigidbody.lockRotationY ? 1 : 0) << "\n";
file << "rbLockRotZ=" << (obj.rigidbody.lockRotationZ ? 1 : 0) << "\n";
}
file << "hasCollider=" << (obj.hasCollider ? 1 : 0) << "\n";
if (obj.hasCollider) {
@@ -495,6 +498,12 @@ bool SceneSerializer::loadScene(const fs::path& filePath,
currentObj->rigidbody.linearDamping = std::stof(value);
} else if (key == "rbAngularDamping") {
currentObj->rigidbody.angularDamping = std::stof(value);
} else if (key == "rbLockRotX") {
currentObj->rigidbody.lockRotationX = std::stoi(value) != 0;
} else if (key == "rbLockRotY") {
currentObj->rigidbody.lockRotationY = std::stoi(value) != 0;
} else if (key == "rbLockRotZ") {
currentObj->rigidbody.lockRotationZ = std::stoi(value) != 0;
} else if (key == "hasCollider") {
currentObj->hasCollider = std::stoi(value) != 0;
} else if (key == "colliderEnabled") {

View File

@@ -107,6 +107,9 @@ struct RigidbodyComponent {
bool isKinematic = false;
float linearDamping = 0.05f;
float angularDamping = 0.05f;
bool lockRotationX = true;
bool lockRotationY = false;
bool lockRotationZ = true;
};
enum class ColliderType {

View File

@@ -76,6 +76,9 @@ void ScriptContext::SetRotation(const glm::vec3& rot) {
if (object) {
object->rotation = NormalizeEulerDegrees(rot);
MarkDirty();
if (engine && HasRigidbody()) {
engine->teleportPhysicsActorFromScript(object->id, object->position, object->rotation);
}
}
}