Esempio n. 1
0
GeomTree::GeomTree(Serializer::Reader &rd)
{
	Profiler::Timer timer;
	timer.Start();

	m_numVertices = rd.Int32();
	m_numEdges = rd.Int32();
	m_numTris = rd.Int32();
	m_radius = rd.Double();

	m_aabb.max = rd.Vector3d();
	m_aabb.min = rd.Vector3d();
	m_aabb.radius = rd.Double();

	const Uint32 numAabbs = rd.Int32();
	m_aabbs.resize(numAabbs);
	for (Uint32 iAabb = 0; iAabb < numAabbs; ++iAabb) {
		m_aabbs[iAabb].max = rd.Vector3d();
		m_aabbs[iAabb].min = rd.Vector3d();
		m_aabbs[iAabb].radius = rd.Double();
	}

	m_edges.resize(m_numEdges);
	for (Sint32 iEdge = 0; iEdge < m_numEdges; ++iEdge) {
		m_edges[iEdge].Load(rd);
	}

	m_vertices.resize(m_numVertices);
	for (Sint32 iVert = 0; iVert < m_numVertices; ++iVert) {
		m_vertices[iVert] = rd.Vector3f();
	}

	const int numIndicies(m_numTris * 3);
	m_indices.resize(numIndicies);
	for (Sint32 iIndi = 0; iIndi < numIndicies; ++iIndi) {
		m_indices[iIndi] = rd.Int16();
	}

	m_triFlags.resize(m_numTris);
	for (Sint32 iTri = 0; iTri < m_numTris; ++iTri) {
		m_triFlags[iTri] = rd.Int32();
	}

	// activeTris = tris we are still trying to put into leaves
	std::vector<int> activeTris;
	activeTris.reserve(m_numTris);
	// So, we ignore tris with flag >= 0x8000
	for (int i = 0; i<m_numTris; i++)
	{
		if (m_triFlags[i] >= IGNORE_FLAG) continue;
		activeTris.push_back(i * 3);
	}
	// regenerate the aabb data
	Aabb *aabbs = new Aabb[activeTris.size()];
	for (unsigned int i = 0; i<activeTris.size(); i++)
	{
		const vector3d v1 = vector3d(m_vertices[m_indices[activeTris[i] + 0]]);
		const vector3d v2 = vector3d(m_vertices[m_indices[activeTris[i] + 1]]);
		const vector3d v3 = vector3d(m_vertices[m_indices[activeTris[i] + 2]]);
		aabbs[i].min = aabbs[i].max = v1;
		aabbs[i].Update(v2);
		aabbs[i].Update(v3);
	}
	m_triTree.reset(new BVHTree(activeTris.size(), &activeTris[0], aabbs));
	delete[] aabbs;

	// 
	int *edgeIdxs = new int[m_numEdges];
	memset(edgeIdxs, 0, sizeof(int)*m_numEdges);
	for (int i = 0; i<m_numEdges; i++) {
		edgeIdxs[i] = i;
	}
	m_edgeTree.reset(new BVHTree(m_numEdges, edgeIdxs, &m_aabbs[0]));

	timer.Stop();
	//Output(" - - GeomTree::GeomTree(Serializer::Reader &rd) took: %lf milliseconds\n", timer.millicycles());
}
Esempio n. 2
0
void Pi::Init(const std::map<std::string, std::string> &options, bool no_gui)
{
#ifdef PIONEER_PROFILER
	Profiler::reset();
#endif

	Profiler::Timer timer;
	timer.Start();

	OS::EnableBreakpad();
	OS::NotifyLoadBegin();

	FileSystem::Init();
	FileSystem::userFiles.MakeDirectory(""); // ensure the config directory exists
#ifdef PIONEER_PROFILER
	FileSystem::userFiles.MakeDirectory("profiler");
	profilerPath = FileSystem::JoinPathBelow(FileSystem::userFiles.GetRoot(), "profiler");
#endif
	PROFILE_SCOPED()

	Pi::config = new GameConfig(options);

	if (config->Int("RedirectStdio"))
		OS::RedirectStdio();

	std::string version(PIONEER_VERSION);
	if (strlen(PIONEER_EXTRAVERSION)) version += " (" PIONEER_EXTRAVERSION ")";
	const char *platformName = SDL_GetPlatform();
	if (platformName)
		Output("ver %s on: %s\n\n", version.c_str(), platformName);
	else
		Output("ver %s but could not detect platform name.\n\n", version.c_str());

	Output("%s\n", OS::GetOSInfoString().c_str());

	ModManager::Init();

	Lang::Resource res(Lang::GetResource("core", config->String("Lang")));
	Lang::MakeCore(res);

	Pi::SetAmountBackgroundStars(config->Float("AmountOfBackgroundStars"));
	Pi::detail.planets = config->Int("DetailPlanets");
	Pi::detail.cities = config->Int("DetailCities");

	// Initialize SDL
	Uint32 sdlInitFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK;
#if defined(DEBUG) || defined(_DEBUG)
	sdlInitFlags |= SDL_INIT_NOPARACHUTE;
#endif
	if (SDL_Init(sdlInitFlags) < 0) {
		Error("SDL initialization failed: %s\n", SDL_GetError());
	}

	OutputVersioningInfo();

	Graphics::RendererOGL::RegisterRenderer();

	// determine what renderer we should use, default to Opengl 3.x
	const std::string rendererName = config->String("RendererName", Graphics::RendererNameFromType(Graphics::RENDERER_OPENGL_3x));
	Graphics::RendererType rType = Graphics::RENDERER_OPENGL_3x;
	//if(rendererName == Graphics::RendererNameFromType(Graphics::RENDERER_OPENGL_3x))
	//{
	//	rType = Graphics::RENDERER_OPENGL_3x;
	//}

	// Do rest of SDL video initialization and create Renderer
	Graphics::Settings videoSettings = {};
	videoSettings.rendererType = rType;
	videoSettings.width = config->Int("ScrWidth");
	videoSettings.height = config->Int("ScrHeight");
	videoSettings.fullscreen = (config->Int("StartFullscreen") != 0);
	videoSettings.hidden = no_gui;
	videoSettings.requestedSamples = config->Int("AntiAliasingMode");
	videoSettings.vsync = (config->Int("VSync") != 0);
	videoSettings.useTextureCompression = (config->Int("UseTextureCompression") != 0);
	videoSettings.useAnisotropicFiltering = (config->Int("UseAnisotropicFiltering") != 0);
	videoSettings.enableDebugMessages = (config->Int("EnableGLDebug") != 0);
	videoSettings.gl3ForwardCompatible = (config->Int("GL3ForwardCompatible") != 0);
	videoSettings.iconFile = OS::GetIconFilename();
	videoSettings.title = "Pioneer";

	Pi::renderer = Graphics::Init(videoSettings);

	Pi::CreateRenderTarget(videoSettings.width, videoSettings.height);
	Pi::rng.IncRefCount(); // so nothing tries to free it
	Pi::rng.seed(time(0));

	input.Init();
	input.onKeyPress.connect(sigc::ptr_fun(&Pi::HandleKeyDown));

	// we can only do bindings once joysticks are initialised.
	if (!no_gui) // This re-saves the config file. With no GUI we want to allow multiple instances in parallel.
		KeyBindings::InitBindings();

	RegisterInputBindings();

	navTunnelDisplayed = (config->Int("DisplayNavTunnel")) ? true : false;
	speedLinesDisplayed = (config->Int("SpeedLines")) ? true : false;
	hudTrailsDisplayed = (config->Int("HudTrails")) ? true : false;

	TestGPUJobsSupport();

	EnumStrings::Init();

	// get threads up
	Uint32 numThreads = config->Int("WorkerThreads");
	const int numCores = OS::GetNumCores();
	assert(numCores > 0);
	if (numThreads == 0) numThreads = std::max(Uint32(numCores) - 1, 1U);
	asyncJobQueue.reset(new AsyncJobQueue(numThreads));
	Output("started %d worker threads\n", numThreads);
	syncJobQueue.reset(new SyncJobQueue);

	Output("ShipType::Init()\n");
	// XXX early, Lua init needs it
	ShipType::Init();

	// XXX UI requires Lua  but Pi::ui must exist before we start loading
	// templates. so now we have crap everywhere :/
	Output("Lua::Init()\n");
	Lua::Init();

	Pi::pigui.Reset(new PiGui);
	Pi::pigui->Init(Pi::renderer->GetSDLWindow());

	float ui_scale = config->Float("UIScaleFactor", 1.0f);
	if (Graphics::GetScreenHeight() < 768) {
		ui_scale = float(Graphics::GetScreenHeight()) / 768.0f;
	}

	Pi::ui.Reset(new UI::Context(
		Lua::manager,
		Pi::renderer,
		Graphics::GetScreenWidth(),
		Graphics::GetScreenHeight(),
		ui_scale));

#ifdef ENABLE_SERVER_AGENT
	Pi::serverAgent = 0;
	if (config->Int("EnableServerAgent")) {
		const std::string endpoint(config->String("ServerEndpoint"));
		if (endpoint.size() > 0) {
			Output("Server agent enabled, endpoint: %s\n", endpoint.c_str());
			Pi::serverAgent = new HTTPServerAgent(endpoint);
		}
	}
	if (!Pi::serverAgent) {
		Output("Server agent disabled\n");
		Pi::serverAgent = new NullServerAgent();
	}
#endif

	LuaInit();

	Gui::Init(renderer, Graphics::GetScreenWidth(), Graphics::GetScreenHeight(), 800, 600);

	// twice, to initialize the font correctly
	draw_progress(0.01f);
	draw_progress(0.01f);

	Output("GalaxyGenerator::Init()\n");
	if (config->HasEntry("GalaxyGenerator"))
		GalaxyGenerator::Init(config->String("GalaxyGenerator"),
			config->Int("GalaxyGeneratorVersion", GalaxyGenerator::LAST_VERSION));
	else
		GalaxyGenerator::Init();

	draw_progress(0.1f);

	Output("FaceParts::Init()\n");
	FaceParts::Init();
	draw_progress(0.2f);

	Output("new ModelCache\n");
	modelCache = new ModelCache(Pi::renderer);
	draw_progress(0.3f);

	Output("Shields::Init\n");
	Shields::Init(Pi::renderer);
	draw_progress(0.4f);

	//unsigned int control_word;
	//_clearfp();
	//_controlfp_s(&control_word, _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE, _MCW_EM);
	//double fpexcept = Pi::timeAccelRates[1] / Pi::timeAccelRates[0];

	Output("BaseSphere::Init\n");
	BaseSphere::Init();
	draw_progress(0.5f);

	Output("CityOnPlanet::Init\n");
	CityOnPlanet::Init();
	draw_progress(0.6f);

	Output("SpaceStation::Init\n");
	SpaceStation::Init();
	draw_progress(0.7f);

	Output("NavLights::Init\n");
	NavLights::Init(Pi::renderer);
	draw_progress(0.75f);

	Output("Sfx::Init\n");
	SfxManager::Init(Pi::renderer);
	draw_progress(0.8f);

	if (!no_gui && !config->Int("DisableSound")) {
		Output("Sound::Init\n");
		Sound::Init();
		Sound::SetMasterVolume(config->Float("MasterVolume"));
		Sound::SetSfxVolume(config->Float("SfxVolume"));
		GetMusicPlayer().SetVolume(config->Float("MusicVolume"));

		Sound::Pause(0);
		if (config->Int("MasterMuted")) Sound::Pause(1);
		if (config->Int("SfxMuted")) Sound::SetSfxVolume(0.f);
		if (config->Int("MusicMuted")) GetMusicPlayer().SetEnabled(false);
	}
	draw_progress(0.9f);

	OS::NotifyLoadEnd();
	draw_progress(0.95f);

#if 0
	// frame test code

	Frame *root = new Frame(0, "root", 0);
	Frame *p1 = new Frame(root, "p1", Frame::FLAG_HAS_ROT);
	Frame *p1r = new Frame(p1, "p1r", Frame::FLAG_ROTATING);
	Frame *m1 = new Frame(p1, "m1", Frame::FLAG_HAS_ROT);
	Frame *m1r = new Frame(m1, "m1r", Frame::FLAG_ROTATING);
	Frame *p2 = new Frame(root, "p2", Frame::FLAG_HAS_ROT);
	Frame *p2r = new Frame(p2, "pr2", Frame::FLAG_ROTATING);

	p1->SetPosition(vector3d(1000,0,0));
	p1->SetVelocity(vector3d(0,1,0));
	p2->SetPosition(vector3d(0,2000,0));
	p2->SetVelocity(vector3d(-2,0,0));
	p1r->SetAngVelocity(vector3d(0,0,0.0001));
	p1r->SetOrient(matrix3x3d::BuildRotate(M_PI/4, vector3d(0,0,1)));
	p2r->SetAngVelocity(vector3d(0,0,-0.0004));
	p2r->SetOrient(matrix3x3d::BuildRotate(-M_PI/2, vector3d(0,0,1)));
	root->UpdateOrbitRails(0, 0);

	CargoBody *c1 = new CargoBody(Equip::Type::SLAVES);
	c1->SetFrame(p1r);
	c1->SetPosition(vector3d(0,180,0));
//	c1->SetVelocity(vector3d(1,0,0));
	CargoBody *c2 = new CargoBody(Equip::Type::SLAVES);
	c2->SetFrame(p1r);
	c2->SetPosition(vector3d(0,200,0));
//	c2->SetVelocity(vector3d(1,0,0));

	vector3d pos = c1->GetPositionRelTo(p1);
	vector3d vel = c1->GetVelocityRelTo(p1);
	double speed = vel.Length();
	vector3d pos2 = c2->GetPositionRelTo(p1);
	vector3d vel2 = c2->GetVelocityRelTo(p1);
	double speed2 = vel2.Length();

	double speed3 = c2->GetVelocityRelTo(c1).Length();
	c2->SwitchToFrame(p1);
	vector3d vel4 = c2->GetVelocityRelTo(c1);
	double speed4 = c2->GetVelocityRelTo(c1).Length();

	root->UpdateOrbitRails(0, 1.0);

	//buildrotate test

	matrix3x3d m = matrix3x3d::BuildRotate(M_PI/2, vector3d(0,0,1));
	vector3d v = m * vector3d(1,0,0);

/*	vector3d pos = p1r->GetPositionRelTo(p2r);
	vector3d vel = p1r->GetVelocityRelTo(p2r);
	matrix3x3d o1 = p1r->GetOrientRelTo(p2r);
	double speed = vel.Length();
	vector3d pos2 = p2r->GetPositionRelTo(p1r);
	vector3d vel2 = p2r->GetVelocityRelTo(p1r);
	matrix3x3d o2 = p2r->GetOrientRelTo(p1r);
	double speed2 = vel2.Length();
*/	root->UpdateOrbitRails(0, 1.0/60);

	delete p2r; delete p2; delete m1r; delete m1; delete p1r; delete p1; delete root;
	delete c1; delete c2;

#endif

#if 0
	// test code to produce list of ship stats

	FILE *pStatFile = fopen("shipstat.csv","wt");
	if (pStatFile)
	{
		fprintf(pStatFile, "name,modelname,hullmass,capacity,fakevol,rescale,xsize,ysize,zsize,facc,racc,uacc,sacc,aacc,exvel\n");
		for (auto iter : ShipType::types)
		{
			const ShipType *shipdef = &(iter.second);
			SceneGraph::Model *model = Pi::FindModel(shipdef->modelName, false);

			double hullmass = shipdef->hullMass;
			double capacity = shipdef->capacity;

			double xsize = 0.0, ysize = 0.0, zsize = 0.0, fakevol = 0.0, rescale = 0.0, brad = 0.0;
			if (model) {
				std::unique_ptr<SceneGraph::Model> inst(model->MakeInstance());
				model->CreateCollisionMesh();
				Aabb aabb = model->GetCollisionMesh()->GetAabb();
				xsize = aabb.max.x-aabb.min.x;
				ysize = aabb.max.y-aabb.min.y;
				zsize = aabb.max.z-aabb.min.z;
				fakevol = xsize*ysize*zsize;
				brad = aabb.GetRadius();
				rescale = pow(fakevol/(100 * (hullmass+capacity)), 0.3333333333);
			}

			double simass = (hullmass + capacity) * 1000.0;
			double angInertia = (2/5.0)*simass*brad*brad;
			double acc1 = shipdef->linThrust[Thruster::THRUSTER_FORWARD] / (9.81*simass);
			double acc2 = shipdef->linThrust[Thruster::THRUSTER_REVERSE] / (9.81*simass);
			double acc3 = shipdef->linThrust[Thruster::THRUSTER_UP] / (9.81*simass);
			double acc4 = shipdef->linThrust[Thruster::THRUSTER_RIGHT] / (9.81*simass);
			double acca = shipdef->angThrust/angInertia;
			double exvel = shipdef->effectiveExhaustVelocity;

			fprintf(pStatFile, "%s,%s,%.1f,%.1f,%.1f,%.3f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%f,%.1f\n",
				shipdef->name.c_str(), shipdef->modelName.c_str(), hullmass, capacity,
				fakevol, rescale, xsize, ysize, zsize, acc1, acc2, acc3, acc4, acca, exvel);
		}
		fclose(pStatFile);
	}
#endif

	luaConsole = new LuaConsole();
	KeyBindings::toggleLuaConsole.onPress.connect(sigc::mem_fun(Pi::luaConsole, &LuaConsole::Toggle));

	planner = new TransferPlanner();

	draw_progress(1.0f);

	timer.Stop();
#ifdef PIONEER_PROFILER
	Profiler::dumphtml(profilerPath.c_str());
#endif
	Output("\n\nLoading took: %lf milliseconds\n", timer.millicycles());
}
Esempio n. 3
0
GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector<vector3f> &vertices, const Uint16 *indices, const unsigned int *triflags)
: m_numVertices(numVerts)
, m_numTris(numTris)
, m_vertices(vertices)
{
	Profiler::Timer timer;
	timer.Start();

	const int numIndices = numTris * 3;
	m_indices.reserve(numIndices);
	for (int i = 0; i < numIndices; ++i) {
		m_indices.push_back(indices[i]);
	}

	m_triFlags.reserve(numTris);
	for (int i = 0; i < numTris; ++i) {
		m_triFlags.push_back(triflags[i]);
	}

	m_aabb.min = vector3d(FLT_MAX,FLT_MAX,FLT_MAX);
	m_aabb.max = vector3d(-FLT_MAX,-FLT_MAX,-FLT_MAX);

	// activeTris = tris we are still trying to put into leaves
	std::vector<int> activeTris;
	activeTris.reserve(numTris);
	// So, we ignore tris with flag >= 0x8000
	for (int i=0; i<numTris; i++) 
	{
		if (triflags[i] >= IGNORE_FLAG) continue;
		activeTris.push_back(i*3);
	}

	typedef std::map< std::pair<int,int>, int > EdgeType;
	EdgeType edges;
#define ADD_EDGE(_i1,_i2,_triflag) \
	if ((_i1) < (_i2)) edges[std::pair<int,int>(_i1,_i2)] = _triflag; \
	else if ((_i1) > (_i2)) edges[std::pair<int,int>(_i2,_i1)] = _triflag;

	// eliminate duplicate vertices
	for (int i=0; i<numVerts; i++) 
	{
		const vector3f &v1 = m_vertices[i];
		for (int j=i+1; j<numVerts; j++) 
		{
			const vector3f &v2 = m_vertices[j];
			if (v2.ExactlyEqual(v1)) 
			{
				for (int k=0; k<numIndices; k++) 
				{
					if ((indices[k] == j) && (triflags[k / 3] < IGNORE_FLAG)) {
						m_indices[k] = i;
					}
				}
			}
		}
	}

	// Get radius, m_aabb, and merge duplicate edges
	m_radius = 0;
	for (int i=0; i<numTris; i++) 
	{
		const unsigned int triflag = m_triFlags[i];
		if (triflag < IGNORE_FLAG) 
		{
			const int vi1 = m_indices[3*i+0];
			const int vi2 = m_indices[3*i+1];
			const int vi3 = m_indices[3*i+2];

			ADD_EDGE(vi1, vi2, triflag);
			ADD_EDGE(vi1, vi3, triflag);
			ADD_EDGE(vi2, vi3, triflag);

			vector3d v[3];
			v[0] = vector3d(m_vertices[vi1]);
			v[1] = vector3d(m_vertices[vi2]);
			v[2] = vector3d(m_vertices[vi3]);
			m_aabb.Update(v[0]);
			m_aabb.Update(v[1]);
			m_aabb.Update(v[2]);
			for (int j=0; j<3; j++) {
				const double rad = v[j].x*v[j].x + v[j].y*v[j].y + v[j].z*v[j].z;
				if (rad>m_radius) m_radius = rad;
			}
		}
	}
	m_radius = sqrt(m_radius);

	{
		Aabb *aabbs = new Aabb[activeTris.size()];
		for (unsigned int i = 0; i < activeTris.size(); i++)
		{
			const vector3d v1 = vector3d(m_vertices[m_indices[activeTris[i] + 0]]);
			const vector3d v2 = vector3d(m_vertices[m_indices[activeTris[i] + 1]]);
			const vector3d v3 = vector3d(m_vertices[m_indices[activeTris[i] + 2]]);
			aabbs[i].min = aabbs[i].max = v1;
			aabbs[i].Update(v2);
			aabbs[i].Update(v3);
		}

		//int t = SDL_GetTicks();
		m_triTree.reset(new BVHTree(activeTris.size(), &activeTris[0], aabbs));
		delete[] aabbs;
	}
	//Output("Tri tree of %d tris build in %dms\n", activeTris.size(), SDL_GetTicks() - t);

	m_numEdges = edges.size();
	m_edges.resize( m_numEdges );
	// to build Edge bvh tree with.
	m_aabbs.resize( m_numEdges );
	int *edgeIdxs = new int[m_numEdges];

	int pos = 0;
	typedef EdgeType::iterator MapPairIter;
	for (MapPairIter i = edges.begin(), iEnd = edges.end();	i != iEnd; ++i, pos++) 
	{
		// precalc some j**z
		const std::pair<int, int> &vtx = (*i).first;
		const int triflag = (*i).second;
		const vector3f &v1 = m_vertices[vtx.first];
		const vector3f &v2 = m_vertices[vtx.second];
		vector3f dir = (v2-v1);
		const float len = dir.Length();
		dir *= 1.0f/len;

		m_edges[pos].v1i = vtx.first;
		m_edges[pos].v2i = vtx.second;
		m_edges[pos].triFlag = triflag;
		m_edges[pos].len = len;
		m_edges[pos].dir = dir;

		edgeIdxs[pos] = pos;
		m_aabbs[pos].min = m_aabbs[pos].max = vector3d(v1);
		m_aabbs[pos].Update(vector3d(v2));
	}

	//t = SDL_GetTicks();
	m_edgeTree.reset(new BVHTree(m_numEdges, edgeIdxs, &m_aabbs[0]));
	delete [] edgeIdxs;
	//Output("Edge tree of %d edges build in %dms\n", m_numEdges, SDL_GetTicks() - t);

	timer.Stop();
	//Output(" - - GeomTree::GeomTree took: %lf milliseconds\n", timer.millicycles());
}