Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,288 @@
|
||||
const double orbitSpeedFactor = 2.0;
|
||||
|
||||
tidy class Orbit : Component_Orbit, Savable {
|
||||
Object@ center_obj;
|
||||
vec3d center_pos;
|
||||
double radius;
|
||||
|
||||
double yearPos;
|
||||
double yearLen;
|
||||
|
||||
double dayPos;
|
||||
double dayLen;
|
||||
bool delta = false;
|
||||
|
||||
Orbit() {
|
||||
dayLen = 0;
|
||||
yearLen = 0;
|
||||
}
|
||||
|
||||
void load(SaveFile& data) {
|
||||
data >> center_obj;
|
||||
if(center_obj is null)
|
||||
data >> center_pos;
|
||||
|
||||
data >> radius;
|
||||
data >> yearPos;
|
||||
data >> yearLen;
|
||||
data >> dayPos;
|
||||
data >> dayLen;
|
||||
}
|
||||
|
||||
void save(SaveFile& data) {
|
||||
data << center_obj;
|
||||
if(center_obj is null)
|
||||
data << center_pos;
|
||||
|
||||
data << radius;
|
||||
data << yearPos;
|
||||
data << yearLen;
|
||||
data << dayPos;
|
||||
data << dayLen;
|
||||
}
|
||||
|
||||
void orbitTick(Object& obj, double time) {
|
||||
if(yearLen != 0) {
|
||||
yearPos = (yearPos + time) % yearLen;
|
||||
vec3d position;
|
||||
|
||||
quaterniond rotation = quaterniond_fromAxisAngle(vec3d_up(), yearPos / yearLen * twopi);
|
||||
position = rotation * vec3d_front(radius);
|
||||
|
||||
if(center_obj is null) {
|
||||
position += center_pos;
|
||||
}
|
||||
else {
|
||||
if(!center_obj.initialized)
|
||||
return;
|
||||
position += center_obj.position;
|
||||
}
|
||||
|
||||
if(time > 0.01) {
|
||||
vec3d newVel = (position - obj.position) / time;
|
||||
obj.acceleration = (newVel - obj.velocity) / time;
|
||||
obj.velocity = newVel;
|
||||
}
|
||||
obj.position = position;
|
||||
|
||||
if(obj.hasMover)
|
||||
obj.clearMovement();
|
||||
}
|
||||
else {
|
||||
obj.position += obj.velocity * time;
|
||||
obj.velocity += obj.acceleration * time;
|
||||
}
|
||||
if(dayLen != 0) {
|
||||
if(dayLen < 0) {
|
||||
vec3d center = obj.position;
|
||||
if(center_obj is null)
|
||||
center = center_pos;
|
||||
else
|
||||
center = center_obj.position;
|
||||
|
||||
obj.rotation = quaterniond_fromVecToVec(vec3d_front(), obj.position - center);
|
||||
}
|
||||
else {
|
||||
dayPos = (dayPos + time) % dayLen;
|
||||
obj.rotation = quaterniond_fromAxisAngle(vec3d_up(), dayPos / dayLen * twopi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setOrbitPct(Object& obj, double pct) {
|
||||
yearPos = yearLen * pct;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitRadius(Object& obj, double newRadius) {
|
||||
radius = newRadius;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, vec3d point) {
|
||||
orbitAround_minRad(obj, point, 0.0);
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, double minRadius, vec3d point) {
|
||||
orbitAround_minRad(obj, point, minRadius);
|
||||
}
|
||||
|
||||
void stopOrbit() {
|
||||
yearLen = 0;
|
||||
}
|
||||
|
||||
bool get_inOrbit() {
|
||||
return yearLen != 0;
|
||||
}
|
||||
|
||||
void remakeStandardOrbit(Object& obj, bool orbitPlanets = true) {
|
||||
Region@ reg = obj.region;
|
||||
yearLen = 0;
|
||||
if(reg is null)
|
||||
return;
|
||||
if(reg.starCount == 0)
|
||||
return;
|
||||
if(obj.position.distanceTo(reg.position) < obj.radius)
|
||||
return;
|
||||
Object@ orbObj;
|
||||
if(orbitPlanets && !obj.isPlanet)
|
||||
@orbObj = reg.getOrbitObject(obj.position);
|
||||
if(orbObj !is null)
|
||||
obj.orbitAround(orbObj);
|
||||
else
|
||||
obj.orbitAround(200, reg.position);
|
||||
}
|
||||
|
||||
Object@ getOrbitingAround() {
|
||||
return center_obj;
|
||||
}
|
||||
|
||||
bool get_hasOrbitCenter() const {
|
||||
return center_obj !is null;
|
||||
}
|
||||
|
||||
bool isOrbitingAround(Object@ around) const {
|
||||
if(around is center_obj)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, vec3d position, vec3d origin) {
|
||||
obj.position = position;
|
||||
orbitAround(obj, origin);
|
||||
}
|
||||
|
||||
void orbitAround_minRad(Object& obj, vec3d point, double minRadius = 0) {
|
||||
vec3d offset = (obj.position - point);
|
||||
center_pos = point;
|
||||
@center_obj = null;
|
||||
radius = max(offset.length, minRadius);
|
||||
double angle = (vec2d(obj.position.x, -obj.position.z) - vec2d(point.x, -point.z)).radians();
|
||||
if(angle < 0)
|
||||
angle += twopi;
|
||||
yearLen = sqrt(pow(radius, 3.0)) / orbitSpeedFactor;
|
||||
yearPos = yearLen * angle / twopi;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, vec3d point, double orbRadius) {
|
||||
center_pos = point;
|
||||
@center_obj = null;
|
||||
radius = orbRadius;
|
||||
yearLen = sqrt(pow(radius, 3.0)) / orbitSpeedFactor;
|
||||
double angle = (vec2d(obj.position.x, -obj.position.z) - vec2d(point.x, -point.z)).radians();
|
||||
if(angle < 0)
|
||||
angle += twopi;
|
||||
yearPos = yearLen * angle / twopi;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, Object& around, double orbRadius, double angle) {
|
||||
@center_obj = around;
|
||||
radius = orbRadius;
|
||||
yearLen = sqrt(pow(radius, 3.0)) / orbitSpeedFactor;
|
||||
yearPos = yearLen * angle / twopi;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, Object& around, double orbRadius) {
|
||||
@center_obj = around;
|
||||
radius = orbRadius;
|
||||
yearLen = sqrt(pow(radius, 3.0)) / orbitSpeedFactor;
|
||||
double angle = (vec2d(obj.position.x, -obj.position.z) - vec2d(around.position.x, -around.position.z)).radians();
|
||||
if(angle < 0)
|
||||
angle += twopi;
|
||||
yearPos = yearLen * angle / twopi;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitAround(Object& obj, Object& around) {
|
||||
@center_obj = around;
|
||||
radius = max(obj.position.distanceTo(around.position), obj.radius + around.radius);
|
||||
yearLen = sqrt(pow(radius, 3.0)) / orbitSpeedFactor;
|
||||
double angle = (vec2d(obj.position.x, -obj.position.z) - vec2d(around.position.x, -around.position.z)).radians();
|
||||
if(angle < 0)
|
||||
angle += twopi;
|
||||
yearPos = yearLen * angle / twopi;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitSpin(Object& obj, double dayLength, bool staticPos) {
|
||||
dayLen = dayLength;
|
||||
if(staticPos && dayLen > 0)
|
||||
dayPos = gameTime % dayLen;
|
||||
else
|
||||
dayPos = 0;
|
||||
orbitTick(obj, 0);
|
||||
delta = true;
|
||||
}
|
||||
|
||||
void orbitDuration(double duration) {
|
||||
yearLen = duration;
|
||||
}
|
||||
|
||||
void writeOrbit(const Object& obj, Message& msg) {
|
||||
msg << float(yearLen);
|
||||
msg << float(dayLen);
|
||||
msg.writeFixed(dayPos, 0.0, dayLen);
|
||||
|
||||
if(center_obj !is null) {
|
||||
msg.write1();
|
||||
msg << center_obj;
|
||||
}
|
||||
else {
|
||||
msg.write0();
|
||||
msg.writeMedVec3(center_pos);
|
||||
}
|
||||
|
||||
msg << float(radius);
|
||||
msg.writeFixed(yearPos, 0.0, yearLen);
|
||||
|
||||
if(yearLen == 0) {
|
||||
msg.writeMedVec3(obj.position);
|
||||
msg.writeSmallVec3(obj.velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void readOrbit(Object& obj, Message& msg) {
|
||||
yearLen = msg.read_float();
|
||||
dayLen = msg.read_float();
|
||||
dayPos = msg.readFixed(0.0, dayLen);
|
||||
|
||||
if(msg.readBit()) {
|
||||
msg >> center_obj;
|
||||
}
|
||||
else {
|
||||
center_pos = msg.readMedVec3();
|
||||
@center_obj = null;
|
||||
}
|
||||
|
||||
radius = msg.read_float();
|
||||
yearPos = msg.readFixed(0.0, yearLen);
|
||||
|
||||
if(yearLen == 0) {
|
||||
obj.position = msg.readMedVec3();
|
||||
obj.velocity = msg.readSmallVec3();
|
||||
}
|
||||
}
|
||||
|
||||
bool writeOrbitDelta(const Object& obj, Message& msg) {
|
||||
if(!delta && yearLen != 0)
|
||||
return false;
|
||||
delta = false;
|
||||
msg.write1();
|
||||
writeOrbit(obj, msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void readOrbitDelta(Object& obj, Message& msg) {
|
||||
readOrbit(obj, msg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user