Skip to content

Commit

Permalink
Fixes and changes for functions in LuaBody
Browse files Browse the repository at this point in the history
Rewrite of GetAltitudeRelTo:
1. This function is moved to body class to support this functionality in C++ code;
2. This function is used in the LUA version of GetAltitudeRelTo, GetGroundPosition and GetGPS for consistency in calculating altitudes;
3. This function supports the choice of which height to calculate (sea-level, above-ground).

Other change:
GetGPS is moved to LuaShip.cpp to support this function for other ships, not only the player.

Fixes for this issues:

1. GetAltitudeRelTo using player pos no matter what first argument is passed;
2. GetGroundPosition returns nil when not in the rotating frame of ref;
3. GetGPS sometimes return different height than GetAltitudeRelTo;
4. Access violation when trying to access frameBody, frameRotation and call GetGroundPosition when body doesn't have frame of ref (ex. when ship is hyperspacing).

Co-Authored-By: Webster Sheets <[email protected]>
  • Loading branch information
Max5377 and sturnclaw committed Oct 24, 2023
1 parent 04c6111 commit 9bb464e
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 138 deletions.
30 changes: 30 additions & 0 deletions src/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,36 @@ vector3d Body::GetVelocityRelTo(const Body *relTo) const
return GetVelocityRelTo(relTo->m_frame) - relTo->GetVelocityRelTo(relTo->m_frame);
}

double Body::GetAltitudeRelTo(const Body* relTo, AltitudeType altType)
{
vector3d pos = GetPositionRelTo(relTo);
double center_dist = pos.Length();
if (relTo && relTo->IsType(ObjectType::TERRAINBODY)) {
const TerrainBody* terrain = static_cast<const TerrainBody*>(relTo);
vector3d surface_pos = pos.Normalized();
double radius;
if (altType != AltitudeType::DEFAULT)
{
radius = altType == AltitudeType::SEA_LEVEL ? terrain->GetSystemBody()->GetRadius() :
terrain->GetTerrainHeight(surface_pos);
}
else
{
radius = terrain->GetSystemBody()->GetRadius();
if (center_dist <= 3.0 * terrain->GetMaxFeatureRadius()) {
radius = terrain->GetTerrainHeight(surface_pos);
}
}
double altitude = center_dist - radius;
if (altitude < 0)
altitude = 0;
return altitude;
}
else {
return center_dist;
}
}

void Body::OrientOnSurface(double radius, double latitude, double longitude)
{
vector3d up = vector3d(cos(latitude) * cos(longitude), sin(latitude) * cos(longitude), sin(longitude));
Expand Down
8 changes: 8 additions & 0 deletions src/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ enum class ObjectType { // <enum name=PhysicsObjectType scope='ObjectType' publi
HYPERSPACECLOUD // <enum skip>
};

enum class AltitudeType {
//SEA_LEVEL if distant, ABOVE_TERRAIN otherwise
DEFAULT,
SEA_LEVEL,
ABOVE_TERRAIN
};

#define OBJDEF(__thisClass, __parentClass, __TYPE) \
static constexpr ObjectType StaticType() { return ObjectType::__TYPE; } \
static constexpr ObjectType SuperType() { return __parentClass::StaticType(); } \
Expand Down Expand Up @@ -175,6 +182,7 @@ class Body : public DeleteEmitter, public PropertiedObject {
vector3d GetInterpPositionRelTo(FrameId relToId) const;
vector3d GetInterpPositionRelTo(const Body *relTo) const;
matrix3x3d GetInterpOrientRelTo(FrameId relToId) const;
double GetAltitudeRelTo(const Body* relTo, AltitudeType altType = AltitudeType::DEFAULT);

// should set m_interpolatedTransform to the smoothly interpolated value
// (interpolated by 0 <= alpha <=1) between the previous and current physics tick
Expand Down
125 changes: 70 additions & 55 deletions src/lua/LuaBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "Ship.h"
#include "SpaceStation.h"
#include "Star.h"
#include <unordered_map>

namespace PiGui {
// Declared in LuaPiGuiInternal.h
Expand All @@ -44,20 +45,20 @@ namespace PiGui {
* <IsDynamic>.
*/

/*
* Attribute: label
*
* The label for the body. This is what is displayed in the HUD and usually
* matches the name of the planet, space station, etc if appropriate.
*
* Availability:
*
* alpha 10
*
* Status:
*
* stable
*/
/*
* Attribute: label
*
* The label for the body. This is what is displayed in the HUD and usually
* matches the name of the planet, space station, etc if appropriate.
*
* Availability:
*
* alpha 10
*
* Status:
*
* stable
*/

/*
* Attribute: seed
Expand Down Expand Up @@ -102,7 +103,6 @@ static int l_body_attr_seed(lua_State *l)
*
* stable
*/

static int l_body_attr_path(lua_State *l)
{
Body *b = LuaObject<Body>::CheckFromLua(1);
Expand Down Expand Up @@ -222,7 +222,6 @@ static int l_body_set_component(lua_State *l)
*
* stable
*/

static int l_body_get_velocity_rel_to(lua_State *l)
{
Body *b = LuaObject<Body>::CheckFromLua(1);
Expand Down Expand Up @@ -336,6 +335,7 @@ static int l_body_is_more_important_than(lua_State *l)
LuaPush<bool>(l, PiGui::first_body_is_more_important_than(body, other));
return 1;
}

/*
* Method: GetPositionRelTo
*
Expand All @@ -355,7 +355,6 @@ static int l_body_is_more_important_than(lua_State *l)
*
* stable
*/

static int l_body_get_position_rel_to(lua_State *l)
{
Body *b = LuaObject<Body>::CheckFromLua(1);
Expand All @@ -365,6 +364,13 @@ static int l_body_get_position_rel_to(lua_State *l)
return 1;
}

static std::unordered_map<std::string, AltitudeType> altitudeTypesStringMap =
{
{"default", AltitudeType::DEFAULT},
{"sea-level", AltitudeType::SEA_LEVEL},
{"above-ground", AltitudeType::ABOVE_TERRAIN}
};

/*
* Method: GetAltitudeRelTo
*
Expand All @@ -375,6 +381,8 @@ static int l_body_get_position_rel_to(lua_State *l)
* Parameters:
*
* other - the other body
* (optional) altType - what altitude to calculate (sea-level, above-ground)
* if not specified, sea-level for distant bodies, above-ground otherwise
*
* Availability:
*
Expand All @@ -384,28 +392,26 @@ static int l_body_get_position_rel_to(lua_State *l)
*
* stable
*/

static int l_body_get_altitude_rel_to(lua_State *l)
{
Body *b = LuaObject<Body>::CheckFromLua(1);
const Body *other = LuaObject<Body>::CheckFromLua(2);
vector3d pos = Pi::player->GetPositionRelTo(other);
double center_dist = pos.Length();
if (other && other->IsType(ObjectType::TERRAINBODY)) {
const TerrainBody *terrain = static_cast<const TerrainBody *>(other);
vector3d surface_pos = pos.Normalized();
double radius = terrain->GetSystemBody()->GetRadius();
if (center_dist <= 3.0 * terrain->GetMaxFeatureRadius()) {
radius = terrain->GetTerrainHeight(surface_pos);
std::string typeString = LuaPull<const char*>(l, 3, "default");
AltitudeType altType = AltitudeType::DEFAULT;
if (typeString.compare("default"))
{
if (auto str = altitudeTypesStringMap.find(typeString); str != altitudeTypesStringMap.end())
{
altType = str->second;
}
else
{
return luaL_error(l, "invalid altitude type: %s", typeString.c_str());
}
double altitude = center_dist - radius;
if (altitude < 0)
altitude = 0;
LuaPush(l, altitude);
return 1;
} else {
LuaPush(l, center_dist);
return 1;
}
double altitude = b->GetAltitudeRelTo(other, altType);
LuaPush(l, altitude);
return 1;
}

/*
Expand Down Expand Up @@ -493,6 +499,13 @@ static int l_body_attr_frame_body(lua_State *l)
}

Frame *f = Frame::GetFrame(b->GetFrame());

if (!f)
{
lua_pushnil(l);
return 1;
}

LuaObject<Body>::PushToLua(f->GetBody());
return 1;
}
Expand Down Expand Up @@ -522,6 +535,12 @@ static int l_body_attr_frame_rotating(lua_State *l)
}

Frame *f = Frame::GetFrame(b->GetFrame());
if (!f)
{
lua_pushnil(l);
return 1;
}

lua_pushboolean(l, f->IsRotFrame());
return 1;
}
Expand Down Expand Up @@ -601,8 +620,7 @@ static int l_body_distance_to(lua_State *l)
/*
* Method: GetGroundPosition
*
* Get latitude, longitude and altitude of a dynamic body close to the ground or nil the body is not a dynamic body
* or is not close to the ground.
* Get latitude, longitude and altitude of frame of ref of a dynamic body or nil if the body is not a dynamic body
*
* > latitude, longitude, altitude = body:GetGroundPosition()
*
Expand Down Expand Up @@ -636,22 +654,20 @@ static int l_body_get_ground_position(lua_State *l)
}

Frame *f = Frame::GetFrame(b->GetFrame());
if (!f->IsRotFrame())
return 0;

if (!f)
{
lua_pushnil(l);
return 1;
}
vector3d pos = b->GetPosition();
double latitude = atan2(pos.y, sqrt(pos.x * pos.x + pos.z * pos.z));
double longitude = atan2(pos.x, pos.z);
lua_pushnumber(l, latitude);
lua_pushnumber(l, longitude);
Body *astro = f->GetBody();
if (astro->IsType(ObjectType::TERRAINBODY)) {
double radius = static_cast<TerrainBody *>(astro)->GetTerrainHeight(pos.Normalized());
double altitude = pos.Length() - radius;
lua_pushnumber(l, altitude);
} else {
lua_pushnil(l);
}
double altitude = b->GetAltitudeRelTo(astro);
lua_pushnumber(l, altitude);
return 3;
}

Expand Down Expand Up @@ -711,7 +727,6 @@ static int l_body_find_nearest_to(lua_State *l)
*
* stable
*/

static int l_body_get_phys_radius(lua_State *l)
{
Body *b = LuaObject<Body>::CheckFromLua(1);
Expand Down Expand Up @@ -752,31 +767,31 @@ static bool push_body_to_lua(Body *body)
LuaObject<Body>::PushToLua(body);
break;
case ObjectType::MODELBODY:
LuaObject<Body>::PushToLua(dynamic_cast<ModelBody *>(body));
LuaObject<ModelBody>::PushToLua(static_cast<ModelBody *>(body));
break;
case ObjectType::SHIP:
LuaObject<Ship>::PushToLua(dynamic_cast<Ship *>(body));
LuaObject<Ship>::PushToLua(static_cast<Ship *>(body));
break;
case ObjectType::PLAYER:
LuaObject<Player>::PushToLua(dynamic_cast<Player *>(body));
LuaObject<Player>::PushToLua(static_cast<Player *>(body));
break;
case ObjectType::SPACESTATION:
LuaObject<SpaceStation>::PushToLua(dynamic_cast<SpaceStation *>(body));
LuaObject<SpaceStation>::PushToLua(static_cast<SpaceStation *>(body));
break;
case ObjectType::PLANET:
LuaObject<Planet>::PushToLua(dynamic_cast<Planet *>(body));
LuaObject<Planet>::PushToLua(static_cast<Planet *>(body));
break;
case ObjectType::STAR:
LuaObject<Star>::PushToLua(dynamic_cast<Star *>(body));
LuaObject<Star>::PushToLua(static_cast<Star *>(body));
break;
case ObjectType::CARGOBODY:
LuaObject<Star>::PushToLua(dynamic_cast<CargoBody *>(body));
LuaObject<CargoBody>::PushToLua(static_cast<CargoBody *>(body));
break;
case ObjectType::MISSILE:
LuaObject<Missile>::PushToLua(dynamic_cast<Missile *>(body));
LuaObject<Missile>::PushToLua(static_cast<Missile *>(body));
break;
case ObjectType::HYPERSPACECLOUD:
LuaObject<HyperspaceCloud>::PushToLua(dynamic_cast<HyperspaceCloud *>(body));
LuaObject<HyperspaceCloud>::PushToLua(static_cast<HyperspaceCloud *>(body));
break;
default:
return false;
Expand Down
Loading

0 comments on commit 9bb464e

Please sign in to comment.