Skip to content

Commit

Permalink
Fixed player physics position delta.
Browse files Browse the repository at this point in the history
Still not sure about the first frame of the player getting pushed to the side a bit.
  • Loading branch information
afritz1 committed Dec 15, 2024
1 parent 3ff5462 commit 6755777
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 27 deletions.
14 changes: 7 additions & 7 deletions OpenTESArena/src/Game/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,8 @@ void GameState::applyPendingSceneChange(Game &game, JPH::PhysicsSystem &physicsS
const double ceilingScale = this->getActiveCeilingScale();
const CoordDouble3 newPlayerPos(
startCoord.chunk,
VoxelDouble3(startCoord.point.x + startOffset.x, ceilingScale + PlayerConstants::HEIGHT, startCoord.point.y + startOffset.y));
player.setPhysicsPosition(VoxelUtils::coordToWorldPoint(newPlayerPos));
VoxelDouble3(startCoord.point.x + startOffset.x, ceilingScale, startCoord.point.y + startOffset.y));
player.setPhysicsPositionRelativeToFeet(VoxelUtils::coordToWorldPoint(newPlayerPos));

this->nextMapPlayerStartOffset = VoxelInt2::Zero;
}
Expand All @@ -601,14 +601,14 @@ void GameState::applyPendingSceneChange(Game &game, JPH::PhysicsSystem &physicsS

const double ceilingScale = this->getActiveCeilingScale();

const CoordDouble3 oldPlayerCoord = player.getEyeCoord(); // The player should be inside the transition voxel.
const VoxelInt3 oldPlayerVoxel = VoxelUtils::pointToVoxel(oldPlayerCoord.point);
const CoordDouble3 oldPlayerEyeCoord = player.getEyeCoord(); // The player should be inside the transition voxel.
const VoxelInt3 oldPlayerVoxel = VoxelUtils::pointToVoxel(oldPlayerEyeCoord.point);
const VoxelDouble3 oldPlayerCenteredPoint = VoxelUtils::getVoxelCenter(oldPlayerVoxel);
const CoordDouble3 newPlayerCoord(
oldPlayerCoord.chunk,
VoxelDouble3(oldPlayerCenteredPoint.x + startOffset.x, ceilingScale + PlayerConstants::HEIGHT, oldPlayerCenteredPoint.z + startOffset.y));
oldPlayerEyeCoord.chunk,
VoxelDouble3(oldPlayerCenteredPoint.x + startOffset.x, ceilingScale, oldPlayerCenteredPoint.z + startOffset.y));

player.setPhysicsPosition(VoxelUtils::coordToWorldPoint(newPlayerCoord));
player.setPhysicsPositionRelativeToFeet(VoxelUtils::coordToWorldPoint(newPlayerCoord));
player.lookAt(newPlayerCoord + VoxelDouble3(startOffset.x, 0.0, startOffset.y));

this->nextMapPlayerStartOffset = VoxelInt2::Zero;
Expand Down
4 changes: 2 additions & 2 deletions OpenTESArena/src/Interface/CharacterCreationUiController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ void ChooseAttributesUiController::onSavedDoneButtonSelected(Game &game)
gameState.queueMapDefChange(std::move(mapDefinition), std::nullopt, std::nullopt, VoxelInt2::Zero, worldMapLocationIDs, true);

// Initialize player.
const CoordDouble3 dummyPosition(ChunkInt2::Zero, VoxelDouble3::Zero);
const CoordDouble3 dummyCoord(ChunkInt2::Zero, VoxelDouble3::Zero);
const Double3 direction(
CardinalDirection::North.x,
0.0,
Expand Down Expand Up @@ -567,7 +567,7 @@ void ChooseAttributesUiController::onSavedDoneButtonSelected(Game &game)

Player &player = game.player;
player.init(std::string(name), male, raceIndex, charClassDefID, attributes, portraitIndex,
dummyPosition, direction, velocity, PlayerConstants::DEFAULT_WALK_SPEED, weaponID, exeData, game.physicsSystem);
dummyCoord, direction, velocity, PlayerConstants::DEFAULT_WALK_SPEED, weaponID, exeData, game.physicsSystem);
};

gameStateFunction(game);
Expand Down
23 changes: 18 additions & 5 deletions OpenTESArena/src/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Player::~Player()
}

void Player::init(const std::string &displayName, bool male, int raceID, int charClassDefID,
int portraitID, const CoordDouble3 &position, const Double3 &direction, const Double3 &velocity,
int portraitID, const CoordDouble3 &feetCoord, const Double3 &direction, const Double3 &velocity,
double maxWalkSpeed, int weaponID, const ExeData &exeData, JPH::PhysicsSystem &physicsSystem, Random &random)
{
this->displayName = displayName;
Expand All @@ -172,13 +172,13 @@ void Player::init(const std::string &displayName, bool male, int raceID, int cha
DebugCrash("Couldn't create player physics collider.");
}

this->setPhysicsPosition(VoxelUtils::coordToWorldPoint(position));
this->setPhysicsPositionRelativeToFeet(VoxelUtils::coordToWorldPoint(feetCoord));
this->setPhysicsVelocity(velocity);
this->setCameraFrame(direction);
}

void Player::init(const std::string &displayName, bool male, int raceID, int charClassDefID,
const PrimaryAttributes &primaryAttributes, int portraitID, const CoordDouble3 &position, const Double3 &direction,
const PrimaryAttributes &primaryAttributes, int portraitID, const CoordDouble3 &feetCoord, const Double3 &direction,
const Double3 &velocity, double maxWalkSpeed, int weaponID, const ExeData &exeData, JPH::PhysicsSystem &physicsSystem)
{
this->displayName = displayName;
Expand All @@ -197,7 +197,7 @@ void Player::init(const std::string &displayName, bool male, int raceID, int cha
DebugCrash("Couldn't create player physics collider.");
}

this->setPhysicsPosition(VoxelUtils::coordToWorldPoint(position));
this->setPhysicsPositionRelativeToFeet(VoxelUtils::coordToWorldPoint(feetCoord));
this->setPhysicsVelocity(velocity);
this->setCameraFrame(direction);
}
Expand Down Expand Up @@ -230,7 +230,7 @@ void Player::initRandom(const CharacterClassLibrary &charClassLibrary, const Exe
}

const CoordDouble3 position(ChunkInt2::Zero, VoxelDouble3::Zero);
this->setPhysicsPosition(VoxelUtils::coordToWorldPoint(position));
this->setPhysicsPositionRelativeToFeet(VoxelUtils::coordToWorldPoint(position));
this->setPhysicsVelocity(Double3::Zero);

const Double3 direction(CardinalDirection::North.x, 0.0, CardinalDirection::North.y);
Expand Down Expand Up @@ -304,6 +304,19 @@ void Player::setPhysicsPosition(const WorldDouble3 &position)
this->physicsCharacterVirtual->SetPosition(physicsPosition);
}

void Player::setPhysicsPositionRelativeToFeet(const WorldDouble3 &feetPosition)
{
DebugAssert(this->isPhysicsInited());
const JPH::Shape *colliderShape = this->physicsCharacter->GetShape();
const JPH::AABox colliderBBox = colliderShape->GetLocalBounds();
const float colliderHeight = colliderBBox.GetSize().GetY();
const WorldDouble3 newPhysicsPosition(
feetPosition.x,
feetPosition.y + (static_cast<double>(colliderHeight) * 0.5),
feetPosition.z);
this->setPhysicsPosition(newPhysicsPosition);
}

void Player::setPhysicsVelocity(const Double3 &velocity)
{
DebugAssert(this->isPhysicsInited());
Expand Down
9 changes: 5 additions & 4 deletions OpenTESArena/src/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ struct Player

// Make player with rolled attributes based on race & gender.
void init(const std::string &displayName, bool male, int raceID, int charClassDefID,
int portraitID, const CoordDouble3 &position, const Double3 &direction, const Double3 &velocity,
int portraitID, const CoordDouble3 &feetCoord, const Double3 &direction, const Double3 &velocity,
double maxWalkSpeed, int weaponID, const ExeData &exeData, JPH::PhysicsSystem &physicsSystem, Random &random);

// Make player with given attributes.
void init(const std::string &displayName, bool male, int raceID, int charClassDefID, const PrimaryAttributes &primaryAttributes,
int portraitID, const CoordDouble3 &position, const Double3 &direction, const Double3 &velocity,
int portraitID, const CoordDouble3 &feetCoord, const Double3 &direction, const Double3 &velocity,
double maxWalkSpeed, int weaponID, const ExeData &exeData, JPH::PhysicsSystem &physicsSystem);

// Initializes a random player for testing.
Expand All @@ -76,9 +76,10 @@ struct Player
void setCameraFrame(const Double3 &forward);

bool isPhysicsInited() const;
WorldDouble3 getPhysicsPosition() const; // Center of the character collider.
WorldDouble3 getPhysicsPosition() const; // Center of the character collider (halfway between eyes and feet).
Double3 getPhysicsVelocity() const;
void setPhysicsPosition(const WorldDouble3 &position); // Instantly sets position of the collider. Not the camera eye.
void setPhysicsPosition(const WorldDouble3 &position); // Instantly sets collider position. Drives where camera eye is next.
void setPhysicsPositionRelativeToFeet(const WorldDouble3 &feetPosition); // Instantly sets collider position using new feet as reference.
void setPhysicsVelocity(const Double3 &velocity);
WorldDouble3 getEyePosition() const;
CoordDouble3 getEyeCoord() const;
Expand Down
8 changes: 4 additions & 4 deletions OpenTESArena/src/Player/PlayerLogicController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,11 @@ namespace PlayerLogicController
{
accelDirection = accelDirection.normalized();

const CoordDouble3 playerCoord = player.getEyeCoord();
constexpr double ghostSpeed = 10.0;
const VoxelDouble3 deltaPoint = accelDirection * (ghostSpeed * dt);
const CoordDouble3 newPlayerCoord = ChunkUtils::recalculateCoord(playerCoord.chunk, playerCoord.point + deltaPoint);
player.setPhysicsPosition(VoxelUtils::coordToWorldPoint(newPlayerCoord));
const WorldDouble3 playerFeetPosition = player.getFeetPosition();
const WorldDouble3 deltaPosition = accelDirection * (ghostSpeed * dt);
const WorldDouble3 newPlayerFeetPosition = playerFeetPosition + deltaPosition;
player.setPhysicsPositionRelativeToFeet(newPlayerFeetPosition);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions OpenTESArena/src/World/MapLogicController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,18 +574,18 @@ void MapLogicController::handleLevelTransition(Game &game, const CoordInt3 &play

// Lambda for opening the world map when the player enters a transition voxel
// that will "lead to the surface of the dungeon".
auto switchToWorldMap = [&playerCoord, &game, &player]()
auto switchToWorldMap = [&playerCoord, &game, &gameState, &player]()
{
// Move player to center of previous voxel in case they change their mind
// about fast traveling. Don't change their direction.
const VoxelInt2 playerVoxelXZ(playerCoord.voxel.x, playerCoord.voxel.z);
const VoxelDouble2 playerVoxelCenterXZ = VoxelUtils::getVoxelCenter(playerVoxelXZ);
const VoxelDouble3 playerDestinationPoint(
const VoxelDouble3 playerFeetDestinationPoint(
playerVoxelCenterXZ.x,
player.getEyeCoord().point.y,
gameState.getActiveCeilingScale(),
playerVoxelCenterXZ.y);
const CoordDouble3 playerDestinationCoord(playerCoord.chunk, playerDestinationPoint);
player.setPhysicsPosition(VoxelUtils::coordToWorldPoint(playerDestinationCoord));
const WorldDouble3 playerFeetDestinationPosition = VoxelUtils::coordToWorldPoint(CoordDouble3(playerCoord.chunk, playerFeetDestinationPoint));
player.setPhysicsPositionRelativeToFeet(playerFeetDestinationPosition);
player.setPhysicsVelocity(Double3::Zero);

game.setPanel<WorldMapPanel>();
Expand Down

0 comments on commit 6755777

Please sign in to comment.