Steve_Yorkshire Posted February 18, 2018 Share Posted February 18, 2018 So I've been trying to temporarily disable PlayerObjectMask vs PlayerObjectMask. The idea was set a flag in shapeBase.cpp or Player.cpp, check for the flag when a player bumps into another and then ignore the collision ...... but it's not been going well ...First off I went looking for the collision object versus mask function and tried to disable collision by getting the colMask in shapebase's QueueCollision. I could get the object's mask but telling it to stop collision was a no no. So I went looking elsewhere ...Then I went hunting through convex and in workingListUpdate added an ignore value which is the ID of the object set in Player's updateWorkingCollisionSet. nah ...Then I went back into convex and caused rather a lot of crashing. Then I disabled ALL player collisions and fell through the floor.Any thoughts, pointers, hints on what function I should be looking in, etc welcome. :?: So, I'm a bit stumped on this. Next plan is to try and add a collisionTimeOut to shapebase like projectiles have when they first spawn so they don't their shooting object, to see if that will work.========================================[edit] okay I think I got this working see below! :idea: ========================================After much barking up the wrong tree and following the spilled spaghetti of collision functions through the various Cthulhuesque innards of the engine ... it turns out simpler than it seems (effin' typical :evil: ).Anyhow this is what I've got, I had no idea whether it is the best thing or not, but it seems to work (at least on local server - other PC is in bits so can't test multiplayer).Turns out the magic all happens in Player::updateWorkingCollisionSet. Here it looks for either the client (for triggers) or server (for triggers and everything else) collisionContactMasks. Server collision that pulls in the moveMask which has the playerObjectType. So I created a new set of modified server collision and move masks (minus the playerObjectMask) which get used instead, if the toggle value is set to true (in this case mNoClip).This worked, though the last playerObject to collide with would need 2 collisions before it updated because it was still on the old collision list. Adding a flag to say that mNoClip had changed and we need to refresh the collision list. After that the player could move through other ai/players fine (though there is a barely visible shake when this happens but it doesn't affect speed and to be honest might just be me hallucinating I have been staring at it all for so long).Here's the list of what happens:set noClip true and also resetClip truebool noClip? true;is the collision a player? true;has noClip just changed? then resetClip is true;if resetClip is true, rebuild the collision list to clear out the last playerObject storedif noClip and collision is a player, use the new collisionContactMask, else just use the old one.Here's what it looks like in code:player.hclass Player: public ShapeBase { typedef ShapeBase Parent; public: //.. protected: //... //yorks at the end of protected bool mNoClip = false;//yorks no collision vs players bool mRetestClip = false;//yorks mNoClip state has changed //.. public: DECLARE_CONOBJECT(Player); //... //yorks new at the end bool getClipState();//yorks the state of mNoClip void setClipState(bool val);//yorks set mNoClip void resetClipState();//yorks set to false bool toggleClipState(bool val);//yorks defineEngineMethod not a real toggle either, just a bool bool getRetestClipState();//yorks do we need to retest if mNoClip state has changed? void clearResetClipState();//yorks reset the reset for the clip state //yorks end }; player.cpp//... static U32 sCollisionMoveMask = TerrainObjectType | WaterObjectType | PlayerObjectType | StaticShapeObjectType | VehicleObjectType | PhysicalZoneObjectType; static U32 sServerCollisionContactMask = sCollisionMoveMask | ItemObjectType | TriggerObjectType | CorpseObjectType; static U32 sClientCollisionContactMask = sCollisionMoveMask | TriggerObjectType; //yorks new CollisionMasks up near the top static U32 sCollisionMoveMaskMod = TerrainObjectType |//yorks playerObjectTypeRemoved WaterObjectType | StaticShapeObjectType | VehicleObjectType | PhysicalZoneObjectType; static U32 sServerCollisionContactMaskMod = sCollisionMoveMaskMod |//yorks to call above collisionMoveMaskMod ItemObjectType | TriggerObjectType | CorpseObjectType; //... void Player::updateWorkingCollisionSet() { //yorks bool noClip = false; bool isPlayer = false; bool retest = false; if (getClipState() == true) { noClip = true; if (mConvex.getObject()->getTypeMask() & PlayerObjectType) isPlayer = true; if (getRetestClipState() == true) retest = true; } //yorks // First, we need to adjust our velocity for possible acceleration. It is assumed // that we will never accelerate more than 20 m/s for gravity, plus 10 m/s for // jetting, and an equivalent 10 m/s for jumping. We also assume that the // working list is updated on a Tick basis, which means we only expand our // box by the possible movement in that tick. Point3F scaledVelocity = mVelocity * TickSec; F32 len = scaledVelocity.len(); F32 newLen = len + (10.0f * TickSec); // Check to see if it is actually necessary to construct the new working list, // or if we can use the cached version from the last query. We use the x // component of the min member of the mWorkingQueryBox, which is lame, but // it works ok. bool updateSet = false; Box3F convexBox = mConvex.getBoundingBox(getTransform(), getScale()); F32 l = (newLen * 1.1f) + 0.1f; // from Convex::updateWorkingList const Point3F lPoint( l, l, l ); convexBox.minExtents -= lPoint; convexBox.maxExtents += lPoint; // Check containment if (mWorkingQueryBox.minExtents.x != -1e9f) { if (mWorkingQueryBox.isContained(convexBox) == false) // Needed region is outside the cached region. Update it. updateSet = true; } else { // Must update updateSet = true; } //yorks new if (updateSet != true && retest == true) { updateSet = true; clearResetClipState(); } // Actually perform the query, if necessary if (updateSet == true) { const Point3F twolPoint(2.0f * l, 2.0f * l, 2.0f * l); mWorkingQueryBox = convexBox; mWorkingQueryBox.minExtents -= twolPoint; mWorkingQueryBox.maxExtents += twolPoint; disableCollision(); //yorks new start if (noClip == true && isPlayer == true) { mConvex.updateWorkingList(mWorkingQueryBox, isGhost() ? sClientCollisionContactMask : sServerCollisionContactMaskMod); enableCollision(); } else { //yorks this is the original bit mConvex.updateWorkingList(mWorkingQueryBox, isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask); enableCollision(); //yorks this is the original bit } //yorks new end } } And finally add our new working functions near the bottom of player.cpp: bool Player::getClipState() { return mNoClip; } void Player::setClipState(bool val) { bool cur = getClipState(); if (cur == true && val == false) { mNoClip = false; mRetestClip = true; } else { if (cur == false && val == true) { mNoClip = true; mRetestClip = true; } else mRetestClip = false; } } bool Player::getRetestClipState() { return mRetestClip; } void Player::clearResetClipState() { mRetestClip = false; } DefineEngineMethod(Player, resetClipState, void, (), , "Set the object's clip State to false.\n" "@returns nothing\n") { object->setClipState(false); } DefineEngineMethod(Player, toggleClipState, void, (bool val), , "Set the object's clip State.\n" "@returns nothing\n") { object->setClipState(val); } DefineEngineMethod(Player, getClipState, bool, (), , "@brief Check if the object has mClipState state.\n\n" "@return true if mNoClip state is \"Enabled\", false if not\n") { return object->getClipState(); } Now spawn some Ai - keep them still it helps when you're trying to collide with them ;) yourPlayerID.toggleClipState(true);//to set the player v player clip stateNow run through the AiPlayers!yourPlayerID.resetClipState();//to turn it off againAs I say, I am not sure if this is all the best way to do it, but it certainly seems to work okay. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.