// temporary one-point version static void CollideWithTerrain(Body *body) { if (!body->IsType(Object::DYNAMICBODY)) return; DynamicBody *dynBody = static_cast<DynamicBody*>(body); if (!dynBody->IsMoving()) return; Frame *f = body->GetFrame(); if (!f || !f->GetBody() || f != f->GetBody()->GetFrame()) return; if (!f->GetBody()->IsType(Object::TERRAINBODY)) return; TerrainBody *terrain = static_cast<TerrainBody*>(f->GetBody()); const Aabb &aabb = dynBody->GetAabb(); double altitude = body->GetPosition().Length() + aabb.min.y; if (altitude >= terrain->GetMaxFeatureRadius()) return; double terrHeight = terrain->GetTerrainHeight(body->GetPosition().Normalized()); if (altitude >= terrHeight) return; CollisionContact c; c.pos = body->GetPosition(); c.normal = c.pos.Normalized(); c.depth = terrHeight - altitude; c.userData1 = static_cast<void*>(body); c.userData2 = static_cast<void*>(f->GetBody()); hitCallback(&c); }
static int l_get_gps(lua_State *l) { Player *player = LuaObject<Player>::CheckFromLua(1); vector3d pos = Pi::player->GetPosition(); double center_dist = pos.Length(); auto frame = player->GetFrame(); if(frame) { Body *astro = frame->GetBody(); if(astro && astro->IsType(Object::TERRAINBODY)) { TerrainBody* terrain = static_cast<TerrainBody*>(astro); if (!frame->IsRotFrame()) frame = frame->GetRotFrame(); vector3d surface_pos = pos.Normalized(); double radius = 0.0; if (center_dist <= 3.0 * terrain->GetMaxFeatureRadius()) { radius = terrain->GetTerrainHeight(surface_pos); } double altitude = center_dist - radius; vector3d velocity = player->GetVelocity(); double vspeed = velocity.Dot(surface_pos); if (fabs(vspeed) < 0.05) vspeed = 0.0; // Avoid alternating between positive/negative zero // RefreshHeadingPitch(); if (altitude < 0) altitude = 0; LuaPush(l, altitude); LuaPush(l, vspeed); const float lat = RAD2DEG(asin(surface_pos.y)); const float lon = RAD2DEG(atan2(surface_pos.x, surface_pos.z)); LuaPush(l, lat); LuaPush(l, lon); return 4; // } } } return 0; }