Beispiel #1
0
void OnSolver::CreateModel(){
  // delete old model
  DeleteModel();

  // clear system body IDs (primer for traversal algorithm)
  system->ClearBodyIDs();
  

  // error check for inertial frame
  Body* sysbasebody = system->bodies.GetHeadElement()->value;
  if( sysbasebody->GetType() != INERTIALFRAME ){
    cerr << "ERROR: inertial frame not at head of bodies list" << endl;
    exit(1);
  }

  // setup the O(n) spanning tree
  numbodies = inertialframe.RecursiveSetup( (InertialFrame*) sysbasebody );
  if(!numbodies){
    cerr << "ERROR: unable to create O(n) model" << endl;
    exit(1);
  }
  
  
  
  bodyarray = new OnBody* [numbodies];
  
  CreateTopologyArray(0,&inertialframe);	  
  
  CreateStateMatrixMaps();  
}
Beispiel #2
0
bool Tweaker::Update()
{
	if(s_isInit && s_enabled) {
		if(s_monitorMode && Pi::player) {
			Body* nt = Pi::player->GetNavTarget();
			Body* ct = Pi::player->GetCombatTarget();
			//Body* target = nt != nullptr ? nt : ct; // Prioritize navtarget over combat target
			Body* target = ct != nullptr ? ct : nt; // Prioritize combattarget since we only care about ships now
			// Check if target changed
			if(target != s_monitorCurrentTarget) {
				// Target changed.
				// Remove active monitor if necessary
				if( s_activeMonitor && target && s_monitorCurrentTarget &&
				    target->GetType() == s_monitorCurrentTarget->GetType()) 
				{
					// Keep the same monitor
				} else {
					// Change monitor
					TwDeleteBar(s_activeMonitor);
					s_activeMonitor = nullptr;
					if(target) { // Only add new monitor if there is a valid target
						s_activeMonitor = CreateMonitor(target);
					}
				}
				s_monitorCurrentTarget = target;
			}
			// Updated monitors
			UpdateMonitor(target);
		}
		return true;
	} else {
		return false;
	}
}
Beispiel #3
0
Game::Game(const SystemPath &path, double time) :
	m_galaxy(GalaxyGenerator::Create()),
	m_time(time),
	m_state(STATE_NORMAL),
	m_wantHyperspace(false),
	m_timeAccel(TIMEACCEL_1X),
	m_requestedTimeAccel(TIMEACCEL_1X),
	m_forceTimeAccel(false)
{
	// Now that we have a Galaxy, check the starting location
	if (!path.IsBodyPath())
		throw InvalidGameStartLocation("SystemPath is not a body path");
	RefCountedPtr<const Sector> s = m_galaxy->GetSector(path);
	if (size_t(path.systemIndex) >= s->m_systems.size()) {
		char buf[128];
		std::sprintf(buf, "System %u in sector <%d,%d,%d> does not exist",
			unsigned(path.systemIndex), int(path.sectorX), int(path.sectorY), int(path.sectorZ));
		throw InvalidGameStartLocation(std::string(buf));
	}
	RefCountedPtr<StarSystem> sys = m_galaxy->GetStarSystem(path);
	if (path.bodyIndex >= sys->GetNumBodies()) {
		char buf[256];
		std::sprintf(buf, "Body %d in system <%d,%d,%d : %d ('%s')> does not exist", unsigned(path.bodyIndex),
			int(path.sectorX), int(path.sectorY), int(path.sectorZ), unsigned(path.systemIndex), sys->GetName().c_str());
		throw InvalidGameStartLocation(std::string(buf));
	}

	m_space.reset(new Space(this, m_galaxy, path));

	Body *b = m_space->FindBodyForPath(&path);
	assert(b);

	m_player.reset(new Player("kanara"));

	m_space->AddBody(m_player.get());

	m_player->SetFrame(b->GetFrame());

	if (b->GetType() == Object::SPACESTATION) {
		m_player->SetDockedWith(static_cast<SpaceStation*>(b), 0);
	} else {
		const SystemBody *sbody = b->GetSystemBody();
		m_player->SetPosition(vector3d(0, 1.5*sbody->GetRadius(), 0));
		m_player->SetVelocity(vector3d(0,0,0));
	}
	Polit::Init(m_galaxy);

	CreateViews();

	EmitPauseState(IsPaused());
}
Beispiel #4
0
static int l_body_is_hyperspace_cloud(lua_State *l)
{
	Body *body = LuaObject<Body>::CheckFromLua(1);
	LuaPush<bool>(l, body->GetType() == Object::Type::HYPERSPACECLOUD);
	return 1;
}
Beispiel #5
0
static int l_body_is_ship(lua_State *l)
{
	Body *body = LuaObject<Body>::CheckFromLua(1);
	LuaPush<bool>(l, body->GetType() == Object::Type::SHIP);
	return 1;
}
Beispiel #6
0
static int l_body_is_cargo_container(lua_State *l)
{
	Body *body = LuaObject<Body>::CheckFromLua(1);
	LuaPush<bool>(l, body->GetType() == Object::Type::CARGOBODY);
	return 1;
}
Beispiel #7
0
static int l_body_is_missile(lua_State *l)
{
	Body *body = LuaObject<Body>::CheckFromLua(1);
	LuaPush<bool>(l, body->GetType() == Object::Type::MISSILE);
	return 1;
}
Beispiel #8
0
void Island::Solve(Profile* profile, const PTimeStep& step, const glm::vec2& gravity, bool allowSleep)
{
	Time timer;

	real32 h = step.delta;

	// Integrate velocities and apply damping. Initialize the body state.
	for (s32 i = 0; i < m_bodyCount; ++i)
	{
		Body* b = m_bodies[i];

		glm::vec2 c = b->m_sweep.c;
		real32 a = b->m_sweep.a;
		glm::vec2 v = b->m_linearVelocity;
		real32 w = b->m_angularVelocity;

		// Store positions for continuous collision.
		b->m_sweep.c0 = b->m_sweep.c;
		b->m_sweep.a0 = b->m_sweep.a;

		if (b->m_type == dynamicBody)
		{
			// Integrate velocities.
			v += h * (b->m_gravityScale * gravity + b->m_invMass * b->m_force);
			w += h * b->m_invI * b->m_torque;

			// Apply damping.
			// ODE: dv/dt + c * v = 0
			// Solution: v(t) = v0 * exp(-c * t)
			// Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
			// v2 = exp(-c * dt) * v1
			// Pade approximation:
			// v2 = v1 * 1 / (1 + c * dt)
			v *= 1.0f / (1.0f + h * b->m_linearDamping);
			w *= 1.0f / (1.0f + h * b->m_angularDamping);
		}

		m_positions[i].c = c;
		m_positions[i].a = a;
		m_velocities[i].v = v;
		m_velocities[i].w = w;
	}

	auto captureTimer = Services::getPlatform()->getTime();

	// Solver data
	SolverData solverData;
	solverData.step = step;
	solverData.positions = m_positions;
	solverData.velocities = m_velocities;

	// Initialize velocity constraints.
	ContactSolverDef contactSolverDef;
	contactSolverDef.step = step;
	contactSolverDef.contacts = m_contacts;
	contactSolverDef.count = m_contactCount;
	contactSolverDef.positions = m_positions;
	contactSolverDef.velocities = m_velocities;
	contactSolverDef.allocator = m_allocator;

	ContactSolver contactSolver(&contactSolverDef);
	contactSolver.InitializeVelocityConstraints();

	if (step.warmStarting)
	{
		contactSolver.WarmStart();
	}

	for (s32 i = 0; i < m_jointCount; ++i)
	{
		m_joints[i]->InitVelocityConstraints(solverData);
	}

	profile->solveInit = Services::getPlatform()->getTime()-captureTimer;

	// Solve velocity constraints
	captureTimer = Services::getPlatform()->getTime();
	for (s32 i = 0; i < step.velocityIterations; ++i)
	{
		for (s32 j = 0; j < m_jointCount; ++j)
		{
			m_joints[j]->SolveVelocityConstraints(solverData);
		}

		contactSolver.SolveVelocityConstraints();
	}

	// Store impulses for warm starting
	contactSolver.StoreImpulses();
	profile->solveVelocity = Services::getPlatform()->getTime()-captureTimer;

	// Integrate positions
	for (s32 i = 0; i < m_bodyCount; ++i)
	{
		glm::vec2 c = m_positions[i].c;
		real32 a = m_positions[i].a;
		glm::vec2 v = m_velocities[i].v;
		real32 w = m_velocities[i].w;

		// Check for large velocities
		glm::vec2 translation = h * v;
		if (glm::dot(translation, translation) > maxTranslationSquared)
		{
			real32 ratio = maxTranslation / translation.length();
			v *= ratio;
		}

		real32 rotation = h * w;
		if (rotation * rotation > maxRotationSquared)
		{
			real32 ratio = maxRotation / glm::abs(rotation);
			w *= ratio;
		}

		// Integrate
		c += h * v;
		a += h * w;

		m_positions[i].c = c;
		m_positions[i].a = a;
		m_velocities[i].v = v;
		m_velocities[i].w = w;
	}

	// Solve position constraints
	captureTimer = Services::getPlatform()->getTime();
	bool positionSolved = false;
	for (s32 i = 0; i < step.positionIterations; ++i)
	{
		bool contactsOkay = contactSolver.SolvePositionConstraints();

		bool jointsOkay = true;
		for (s32 i = 0; i < m_jointCount; ++i)
		{
			bool jointOkay = m_joints[i]->SolvePositionConstraints(solverData);
			jointsOkay = jointsOkay && jointOkay;
		}

		if (contactsOkay && jointsOkay)
		{
			// Exit early if the position errors are small.
			positionSolved = true;
			break;
		}
	}

	// Copy state buffers back to the bodies
	for (s32 i = 0; i < m_bodyCount; ++i)
	{
		Body* body = m_bodies[i];
		body->m_sweep.c = m_positions[i].c;
		body->m_sweep.a = m_positions[i].a;
		body->m_linearVelocity = m_velocities[i].v;
		body->m_angularVelocity = m_velocities[i].w;
		body->SynchronizeTransform2D();
	}

	profile->solvePosition = Services::getPlatform()->getTime()-captureTimer;

	Report(contactSolver.m_velocityConstraints);

	if (allowSleep)
	{
		real32 minSleepTime = FLT_MAX;

		const real32 linTolSqr = linearSleepTolerance * linearSleepTolerance;
		const real32 angTolSqr = angularSleepTolerance * angularSleepTolerance;

		for (s32 i = 0; i < m_bodyCount; ++i)
		{
			Body* b = m_bodies[i];
			if (b->GetType() == staticBody)
			{
				continue;
			}

			if ((b->m_flags & Body::autoSleepFlag) == 0 ||
				b->m_angularVelocity * b->m_angularVelocity > angTolSqr ||
				glm::dot(b->m_linearVelocity, b->m_linearVelocity) > linTolSqr)
			{
				b->m_sleepTime = 0.0f;
				minSleepTime = 0.0f;
			}
			else
			{
				b->m_sleepTime += h;
				minSleepTime = glm::min(minSleepTime, b->m_sleepTime);
			}
		}

		if (minSleepTime >= timeToSleep && positionSolved)
		{
			for (s32 i = 0; i < m_bodyCount; ++i)
			{
				Body* b = m_bodies[i];
				b->SetAwake(false);
			}
		}
	}
}
Beispiel #9
0
static int l_body_is_more_important_than(lua_State *l)
{
	Body *body = LuaObject<Body>::CheckFromLua(1);
	Body *other = LuaObject<Body>::CheckFromLua(2);

	// compare body and other
	// push true if body is "more important" than other
	// the most important body is shown on the hud and
	// bodies are sorted by importance in menus

	if(body == other)
	{
		LuaPush<bool>(l, false);
		return 1;
	}

	Object::Type a = body->GetType();
	const SystemBody *sb_a = body->GetSystemBody();
	bool a_gas_giant = sb_a && sb_a->GetSuperType() == SystemBody::SUPERTYPE_GAS_GIANT;
	bool a_planet = sb_a && sb_a->IsPlanet();
	bool a_moon = sb_a && sb_a->IsMoon();

	Object::Type b = other->GetType();
	const SystemBody *sb_b = other->GetSystemBody();
	bool b_gas_giant = sb_b && sb_b->GetSuperType() == SystemBody::SUPERTYPE_GAS_GIANT;
	bool b_planet = sb_b && sb_b->IsPlanet();
	bool b_moon = sb_b && sb_b->IsMoon();

	bool result = false;

	// if type is the same, just sort alphabetically
	// planets are different, because moons are
	// less important (but don't have their own type)
	if(a == b && a != Object::Type::PLANET) result = body->GetLabel() < other->GetLabel();
	// a star is larger than any other object
	else if(a == Object::Type::STAR) result = true;
	// any (non-star) object is smaller than a star
	else if(b == Object::Type::STAR) result = false;
	// a gas giant is larger than anything but a star,
	// but remember to keep total order in mind: if both are
	// gas giants, order alphabetically
	else if(a_gas_giant) result = !b_gas_giant || body->GetLabel() < other->GetLabel();
	// any (non-star, non-gas giant) object is smaller than a gas giant
	else if(b_gas_giant) result = false;
	// between two planets or moons, alphabetic
	else if(a_planet && b_planet) result = body->GetLabel() < other->GetLabel();
	else if(a_moon && b_moon) result = body->GetLabel() < other->GetLabel();
	// a planet is larger than any non-planet
	else if(a_planet) result = true;
	// a non-planet is smaller than any planet
	else if(b_planet) result = false;
	// a moon is larger than any non-moon
	else if(a_moon) result = true;
	// a non-moon is smaller than any moon
	else if(b_moon) result = false;
	// spacestation > city > ship > hyperspace cloud > cargo body > missile > projectile
	else if(a == Object::Type::SPACESTATION) result = true;
	else if(b == Object::Type::SPACESTATION) result = false;
    else if(a == Object::Type::CITYONPLANET) result = true;
    else if(b == Object::Type::CITYONPLANET) result = false;
	else if(a == Object::Type::SHIP) result = true;
	else if(b == Object::Type::SHIP) result = false;
	else if(a == Object::Type::HYPERSPACECLOUD) result = true;
	else if(b == Object::Type::HYPERSPACECLOUD) result = false;
	else if(a == Object::Type::CARGOBODY) result = true;
	else if(b == Object::Type::CARGOBODY) result = false;
	else if(a == Object::Type::MISSILE) result = true;
	else if(b == Object::Type::MISSILE) result = false;
	else if(a == Object::Type::PROJECTILE) result = true;
	else if(b == Object::Type::PROJECTILE) result = false;
	else Error("don't know how to compare %i and %i\n", a, b);

	LuaPush<bool>(l, result);
	return 1;
}
Beispiel #10
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtol(pos, const_cast<char**>(&end), 0);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}

		case 't': {
			lua_newtable(l);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			pos = unpickle(l, pos);
			lua_pushvalue(l, -3);
			lua_rawset(l, -3);
			lua_pop(l, 1);

			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;

			break;
		}

		case 'r': {
			pos = unpickle(l, pos);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			lua_pushvalue(l, -2);
			lua_rawget(l, -2);

			if (lua_isnil(l, -1))
				throw SavedGameCorruptException();

			lua_insert(l, -3);
			lua_pop(l, 2);

			break;
		}

		case 'u': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) {
				pos = end;

				Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId);
				LuaSystemPath::PushToLuaGC(sbp);

				break;
			}

			if (len == 4 && strncmp(pos, "Body", 4) == 0) {
				pos = end;

				Uint32 n = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Body *body = Pi::game->GetSpace()->GetBodyByIndex(n);
				if (pos == end) throw SavedGameCorruptException();

				switch (body->GetType()) {
					case Object::BODY:
						LuaBody::PushToLua(body);
						break;
					case Object::SHIP:
						LuaShip::PushToLua(dynamic_cast<Ship*>(body));
						break;
					case Object::SPACESTATION:
						LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body));
						break;
					case Object::PLANET:
						LuaPlanet::PushToLua(dynamic_cast<Planet*>(body));
						break;
					case Object::STAR:
						LuaStar::PushToLua(dynamic_cast<Star*>(body));
						break;
					case Object::PLAYER:
						LuaPlayer::PushToLua(dynamic_cast<Player*>(body));
						break;
					default:
						throw SavedGameCorruptException();
				}

				break;
			}

			throw SavedGameCorruptException();
		}

		case 'o': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			const char *cl = pos;

			// unpickle the object, and insert it beneath the method table value
			pos = unpickle(l, end);

			// get _G[typename]
			lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
			lua_pushlstring(l, cl, len);
			lua_gettable(l, -2);
			lua_remove(l, -2);

			if (lua_isnil(l, -1)) {
				lua_pop(l, 2);
				break;
			}

			lua_getfield(l, -1, "Unserialize");
			if (lua_isnil(l, -1)) {
				lua_pushlstring(l, cl, len);
				luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1));
			}

			lua_insert(l, -3);
			lua_pop(l, 1);

			pi_lua_protected_call(l, 1, 1);

			break;
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}
Beispiel #11
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}
			
		case 't': {
			lua_newtable(l);
			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;
			break;
		}

		case 'u': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) {
				pos = end;

				Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 systemNum = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sbodyId = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId);
				LuaSystemPath::PushToLuaGC(sbp);

				break;
			}

			if (len == 4 && strncmp(pos, "Body", 4) == 0) {
				pos = end;

				int n = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Body *body = Serializer::LookupBody(n);
				if (pos == end) throw SavedGameCorruptException();

				switch (body->GetType()) {
					case Object::BODY:
						LuaBody::PushToLua(body);
						break;
					case Object::SHIP:
						LuaShip::PushToLua(dynamic_cast<Ship*>(body));
						break;
					case Object::SPACESTATION:
						LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body));
						break;
					case Object::PLANET:
						LuaPlanet::PushToLua(dynamic_cast<Planet*>(body));
						break;
					case Object::STAR:
						LuaStar::PushToLua(dynamic_cast<Star*>(body));
						break;
					case Object::PLAYER:
						LuaPlayer::PushToLua(dynamic_cast<Player*>(body));
						break;
					default:
						throw SavedGameCorruptException();
				}

				break;
			}

			throw SavedGameCorruptException();
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}