From 0353b402a8c6ae07dc804c639034f4b8120b125b Mon Sep 17 00:00:00 2001 From: Human Gamer <39096122+HumanGamer@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:49:21 -0500 Subject: [PATCH] Multiple Physics Modes --- engine/source/game/marble/marble.cpp | 47 +++++++++++++++++++++ engine/source/game/marble/marble.h | 10 +++++ engine/source/game/marble/marblephysics.cpp | 11 +++-- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/engine/source/game/marble/marble.cpp b/engine/source/game/marble/marble.cpp index 454ccbc2..84bcafda 100644 --- a/engine/source/game/marble/marble.cpp +++ b/engine/source/game/marble/marble.cpp @@ -147,6 +147,8 @@ Marble::Marble() mSinglePrecision.mPosition = mPosition; mSinglePrecision.mVelocity = mVelocity; mSinglePrecision.mOmega = mOmega; + + mPhysics = XNA; } Marble::~Marble() @@ -407,6 +409,13 @@ void Marble::setMode(U32 mode) setMaskBits(PowerUpMask); } +void Marble::setPhysics(U32 physics) +{ + mPhysics = physics; + + setMaskBits(GravityMask); +} + void Marble::setOOB(bool isOOB) { mOOB = isOOB; @@ -551,6 +560,11 @@ U32 Marble::packUpdate(NetConnection* conn, U32 mask, BitStream* stream) stream->writeFlag(isControl); stream->writeFlag(gravityChange); + if (stream->writeFlag((mask & GravityMask) != 0)) + { + stream->writeInt(mPhysics, 7); + } + if (stream->writeFlag((mask & PowerUpMask) != 0)) { stream->writeRangedU32(mPowerUpId, 0, PowerUpData::MaxPowerUps - 1); @@ -639,6 +653,11 @@ void Marble::unpackUpdate(NetConnection* conn, BitStream* stream) bool warp = stream->readFlag(); bool isGravWarp = stream->readFlag(); + if (stream->readFlag()) + { + setPhysics(stream->readInt(7)); + } + if (stream->readFlag()) { mPowerUpId = stream->readRangedU32(0, PowerUpData::MaxPowerUps - 1); @@ -2240,6 +2259,34 @@ ConsoleMethod(Marble, setMode, void, 3, 3, "(mode)") object->setMode(newMode | modeFlags[i]); } +ConsoleMethod(Marble, setPhysics, void, 3, 3, "(physics)") +{ + const char* physics = argv[2]; + U32 physicsFlags[3]; + const char* physicsStrings[3]; + + physicsStrings[0] = "MBU"; + physicsFlags[0] = Marble::MBU; + + physicsStrings[1] = "MBG"; + physicsFlags[1] = Marble::MBG; + + physicsStrings[2] = "XNA"; + physicsFlags[2] = Marble::XNA; + + S32 i = 0; + while (dStricmp(physicsStrings[i], physics)) + { + if (++i >= 3) + { + Con::errorf("Marble:: Unknown physics mode: %s", physics); + return; + } + } + + object->setPhysics(physicsFlags[i]); +} + ConsoleMethod(Marble, setPad, void, 3, 3, "(pad)") { U32 padId = dAtoi(argv[2]); diff --git a/engine/source/game/marble/marble.h b/engine/source/game/marble/marble.h index bfe7dfbe..54588f2e 100644 --- a/engine/source/game/marble/marble.h +++ b/engine/source/game/marble/marble.h @@ -66,6 +66,13 @@ class Marble : public ShapeBase FinishMode = 0x40 }; + enum MBPhysics + { + MBU, + MBG, + XNA + }; + enum UpdateMaskBits { ActiveModeBits = 0x4, @@ -216,6 +223,8 @@ class Marble : public ShapeBase bool mShadowGenerated; MatInstance* mStencilMaterial; + U32 mPhysics; + public: DECLARE_CONOBJECT(Marble); @@ -253,6 +262,7 @@ class Marble : public ShapeBase Point3F& getPosition(); void victorySequence(); void setMode(U32 mode); + void setPhysics(U32 physics); U32 getMode() { return mMode; } void setOOB(bool isOOB); virtual void interpolateTick(F32 delta); diff --git a/engine/source/game/marble/marblephysics.cpp b/engine/source/game/marble/marblephysics.cpp index a276a67c..2b439ba0 100644 --- a/engine/source/game/marble/marblephysics.cpp +++ b/engine/source/game/marble/marblephysics.cpp @@ -360,9 +360,9 @@ void Marble::velocityCancel(bool surfaceSlide, bool noBounce, bool& bouncedYet, contact->surfaceVelocity = otherMarble->getVelocityD(); } else { - if (contact->surfaceVelocity.len() == 0.0 && !surfaceSlide && surfaceDot > -mDataBlock->maxDotSlide * velLen) + // XNA has contact->surfaceVelocity.len() > 0.0001f while MBU360 has contact->surfaceVelocity.len() == 0.0 + if (((mPhysics == XNA && contact->surfaceVelocity.len() > 0.0001f) || (mPhysics != XNA && contact->surfaceVelocity.len() == 0.0)) && !surfaceSlide && surfaceDot > -mDataBlock->maxDotSlide * velLen) { - mVelocity -= surfaceVel; m_point3D_normalize(mVelocity); mVelocity *= velLen; @@ -454,6 +454,7 @@ void Marble::velocityCancel(bool surfaceSlide, bool noBounce, bool& bouncedYet, { Contact* contact = &mContacts[j]; + // TODO: should contactDistance have mRadius added to it in this check? (comparing to XNA) if (mRadius > contact->contactDistance) { Point3F normal = contact->normal; @@ -633,8 +634,10 @@ void Marble::advancePhysics(const Move* move, U32 timeDelta) F64 moveTime = timeStep; computeFirstPlatformIntersect(moveTime, smPathItrVec); - testMove(mVelocity, mPosition, moveTime, mRadius, sCollisionMask, false); - //mPosition += mVelocity * moveTime; + if (mPhysics == XNA) + mPosition += mVelocity * moveTime; // XNA + else + testMove(mVelocity, mPosition, moveTime, mRadius, sCollisionMask, false); // MBU if (!mMovePathSize && timeStep * 0.99 > moveTime && moveTime > 0.001000000047497451) {