Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(ship): Allow ships to define their center of rotation (No.2) #9423

Merged
merged 20 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion source/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ this program. If not, see <https://www.gnu.org/licenses/>.

#include "Body.h"

#include "Angle.h"
#include "DataNode.h"
#include "DataWriter.h"
#include "GameData.h"
#include "Mask.h"
#include "MaskManager.h"
#include "pi.h"
#include "Point.h"
#include "Random.h"
#include "Sprite.h"
#include "SpriteSet.h"
Expand All @@ -33,8 +36,9 @@ using namespace std;

// Constructor, based on a Sprite.
Body::Body(const Sprite *sprite, Point position, Point velocity, Angle facing, double zoom)
: position(position), velocity(velocity), angle(facing), zoom(zoom), sprite(sprite), randomize(true)
: position(position), velocity(velocity), zoom(zoom), sprite(sprite), randomize(true)
{
Turn(facing);
}


Expand Down Expand Up @@ -147,6 +151,13 @@ const Point &Body::Velocity() const



const Point Body::Center() const
{
return -rotatedCenter + position;
}



// Direction this Body is facing in.
const Angle &Body::Facing() const
{
Expand Down Expand Up @@ -231,6 +242,8 @@ void Body::LoadSprite(const DataNode &node)
}
else if(child.Token(0) == "rewind")
rewind = true;
else if(child.Token(0) == "center" && child.Size() >= 3)
center = Point(child.Value(1), child.Value(2));
else
child.PrintTrace("Skipping unrecognized attribute:");
}
Expand Down Expand Up @@ -262,6 +275,8 @@ void Body::SaveSprite(DataWriter &out, const string &tag) const
out.Write("no repeat");
if(rewind)
out.Write("rewind");
if(center)
out.Write("center", center.X(), center.Y());
}
out.EndChild();
}
Expand Down Expand Up @@ -332,6 +347,39 @@ void Body::UnmarkForRemoval()



// Turn this object around its center of rotation.
void Body::Turn(double amount)
{
angle += amount;
if(!center)
return;

auto RotatePointAroundOrigin = [](Point &toRotate, double radians) -> Point {
float si = sin(radians);
float co = cos(radians);
float newX = toRotate.X() * co - toRotate.Y() * si;
float newY = toRotate.X() * si + toRotate.Y() * co;
return Point(newX, newY);
};

rotatedCenter = -RotatePointAroundOrigin(center, (angle - amount).Degrees() * TO_RAD);

position -= rotatedCenter;

rotatedCenter = RotatePointAroundOrigin(rotatedCenter, Angle(amount).Degrees() * TO_RAD);

position += rotatedCenter;
}



void Body::Turn(const Angle &amount)
{
Turn(amount.Degrees());
}



// Set the current time step.
void Body::SetStep(int step) const
{
Expand Down
6 changes: 6 additions & 0 deletions source/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Body {
// Positional attributes.
const Point &Position() const;
const Point &Velocity() const;
const Point Center() const;
const Angle &Facing() const;
Point Unit() const;
double Zoom() const;
Expand Down Expand Up @@ -88,13 +89,18 @@ class Body {
void MarkForRemoval();
// Mark that this object should not be removed (e.g. a launched fighter).
void UnmarkForRemoval();
// Turn this object around its center of rotation.
void Turn(double amount);
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
void Turn(const Angle &amount);


protected:
// Basic positional attributes.
Point position;
Point velocity;
Angle angle;
Point center;
Point rotatedCenter;
// A zoom of 1 means the sprite should be drawn at half size. For objects
// whose sprites should be full size, use zoom = 2.
float zoom = 1.f;
Expand Down
4 changes: 2 additions & 2 deletions source/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ void Engine::Step(bool isActive)
}
else if(flagship)
{
center = flagship->Position();
center = flagship->Center();
centerVelocity = flagship->Velocity();
Preferences::ExtendedJumpEffects jumpEffectState = Preferences::GetExtendedJumpEffects();
if(flagship->IsHyperspacing() && jumpEffectState != Preferences::ExtendedJumpEffects::OFF)
Expand Down Expand Up @@ -1574,7 +1574,7 @@ void Engine::CalculateStep()
Point newCenterVelocity;
if(flagship)
{
newCenter = flagship->Position();
newCenter = flagship->Center();
newCenterVelocity = flagship->Velocity();
zoomMod = 2. - flagship->Zoom();
}
Expand Down
2 changes: 1 addition & 1 deletion source/Flotsam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void Flotsam::Move(vector<Visual> &visuals)
{
position += velocity;
velocity *= drag;
angle += spin;
Turn(spin);
--lifetime;
if(lifetime > 0)
return;
Expand Down
2 changes: 1 addition & 1 deletion source/Minable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ bool Minable::Move(vector<Visual> &visuals, list<shared_ptr<Flotsam>> &flotsam)
}

// Spin the object.
angle += spin;
Turn(spin);

// Advance the object forward one step.
theta += angularMomentum / (radius * radius);
Expand Down
2 changes: 1 addition & 1 deletion source/Projectile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ void Projectile::Move(vector<Visual> &visuals, vector<Projectile> &projectiles)
turn = 0.;

if(turn)
angle += Angle(turn);
Turn(turn);

if(accel)
{
Expand Down
4 changes: 2 additions & 2 deletions source/Ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ void Ship::Place(Point position, Point velocity, Angle angle, bool isDeparting)
{
this->position = position;
this->velocity = velocity;
this->angle = angle;
this->Turn(angle);

// If landed, place the ship right above the planet.
// Escorts should take off a bit behind their flagships.
Expand Down Expand Up @@ -4233,7 +4233,7 @@ void Ship::DoMovement(bool &isUsingAfterburner)
slowness += scale * attributes.Get("turning slowing");
disruption += scale * attributes.Get("turning disruption");

angle += commands.Turn() * TurnRate() * slowMultiplier;
Turn(commands.Turn() * TurnRate() * slowMultiplier);
}
}
double thrustCommand = commands.Has(Command::FORWARD) - commands.Has(Command::BACK);
Expand Down
4 changes: 2 additions & 2 deletions source/Visual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Visual::Visual(const Effect &effect, Point pos, Point vel, Angle facing, Point h
if(effect.randomLifetime > 0)
lifetime += Random::Int(effect.randomLifetime + 1);

angle += Angle::Random(effect.randomAngle) - Angle::Random(effect.randomAngle);
Turn((Angle::Random(effect.randomAngle) - Angle::Random(effect.randomAngle)).Degrees());
RisingLeaf marked this conversation as resolved.
Show resolved Hide resolved
spin = Angle::Random(effect.randomSpin) - Angle::Random(effect.randomSpin);

if(effect.hasAbsoluteVelocity)
Expand Down Expand Up @@ -62,6 +62,6 @@ void Visual::Move()
else
{
position += velocity;
angle += spin;
Turn(spin);
}
}
Loading