示例#1
0
void ProjectileSystem::update(ent_ptr<EntityManager> em, ent_ptr<EventManager> events, double dt)
{
	for (auto entity : em->entities_with_components<ProjectileComponent, FrameComponent>()) {
		ent_ptr<ProjectileComponent> pc = entity.component<ProjectileComponent>();
		pc->lifetime -= dt;

		if (pc->lifetime < 0) {
			entity.destroy();
			continue;
		}

		ent_ptr<PosOrientComponent> poc = entity.component<PosOrientComponent>();
		const vector3d vel = pc->baseVel + pc->dirVel;
		poc->pos += vel * dt;

		//Collide
		auto pfc = entity.component<FrameComponent>();
		CollisionContact c;
		pfc->frame->GetCollisionSpace()->TraceRay(poc->pos, vel.Normalized(), vel.Length(), &c, 0);

		Entity* collEnt = static_cast<Entity*>(c.userData1);
		if (collEnt && *collEnt != pc->owner) {
			Entity clonk = *collEnt;
			//auto gc = clonk.component<CollisionMeshComponent>();
			//auto fc = clonk.component<FrameComponent>();
			//SDL_assert(gc);
			//SDL_assert(fc);
			//clonk.destroy();
			entity.destroy();
		}
	}
}
示例#2
0
vector3d TransferPlanner::GetOffsetVel() const {
	if(m_position.ExactlyEqual(vector3d(0., 0., 0.)))
		return vector3d(0., 0., 0.);

	const vector3d pNormal = m_position.Cross(m_velocity);

	return m_dvPrograde * m_velocity.Normalized() +
		   m_dvNormal   * pNormal.Normalized() +
		   m_dvRadial   * m_position.Normalized();
}
示例#3
0
static void DrawAtmosphereSurface(Graphics::Renderer *renderer,
	const matrix4x4d &modelView, const vector3d &campos, float rad, Graphics::Material *mat)
{
	const int LAT_SEGS = 20;
	const int LONG_SEGS = 20;
	vector3d yaxis = campos.Normalized();
	vector3d zaxis = vector3d(1.0,0.0,0.0).Cross(yaxis).Normalized();
	vector3d xaxis = yaxis.Cross(zaxis);
	const matrix4x4d invrot = matrix4x4d::MakeRotMatrix(xaxis, yaxis, zaxis).InverseOf();

	renderer->SetTransform(modelView * matrix4x4d::ScaleMatrix(rad, rad, rad) * invrot);

	// what is this? Well, angle to the horizon is:
	// acos(planetRadius/viewerDistFromSphereCentre)
	// and angle from this tangent on to atmosphere is:
	// acos(planetRadius/atmosphereRadius) ie acos(1.0/1.01244blah)
	double endAng = acos(1.0/campos.Length())+acos(1.0/rad);
	double latDiff = endAng / double(LAT_SEGS);

	double rot = 0.0;
	float sinCosTable[LONG_SEGS+1][2];
	for (int i=0; i<=LONG_SEGS; i++, rot += 2.0*M_PI/double(LONG_SEGS)) {
		sinCosTable[i][0] = float(sin(rot));
		sinCosTable[i][1] = float(cos(rot));
	}

	/* Tri-fan above viewer */
	Graphics::VertexArray va(Graphics::ATTRIB_POSITION);
	va.Add(vector3f(0.f, 1.f, 0.f));
	for (int i=0; i<=LONG_SEGS; i++) {
		va.Add(vector3f(
			sin(latDiff)*sinCosTable[i][0],
			cos(latDiff),
			-sin(latDiff)*sinCosTable[i][1]));
	}
	renderer->DrawTriangles(&va, mat, Graphics::TRIANGLE_FAN);

	/* and wound latitudinal strips */
	double lat = latDiff;
	for (int j=1; j<LAT_SEGS; j++, lat += latDiff) {
		Graphics::VertexArray v(Graphics::ATTRIB_POSITION);
		float cosLat = cos(lat);
		float sinLat = sin(lat);
		float cosLat2 = cos(lat+latDiff);
		float sinLat2 = sin(lat+latDiff);
		for (int i=0; i<=LONG_SEGS; i++) {
			v.Add(vector3f(sinLat*sinCosTable[i][0], cosLat, -sinLat*sinCosTable[i][1]));
			v.Add(vector3f(sinLat2*sinCosTable[i][0], cosLat2, -sinLat2*sinCosTable[i][1]));
		}
		renderer->DrawTriangles(&v, mat, Graphics::TRIANGLE_STRIP);
	}
}
示例#4
0
文件: Ship.cpp 项目: tomm/pioneer
void Ship::FireWeapon(int num)
{
	if (m_flightState != FLYING)
		return;

	std::string prefix(num?"laser_rear_":"laser_front_");
	int damage = 0;
	Properties().Get(prefix+"damage", damage);
	if (!damage)
		return;

	Properties().PushLuaTable();
	LuaTable prop(Lua::manager->GetLuaState(), -1);

	const matrix3x3d &m = GetOrient();
	const vector3d dir = m * vector3d(m_gun[num].dir);
	const vector3d pos = m * vector3d(m_gun[num].pos) + GetPosition();

	m_gun[num].temperature += 0.01f;

	m_gun[num].recharge = prop.Get<float>(prefix+"rechargeTime");
	const vector3d baseVel = GetVelocity();
	const vector3d dirVel = prop.Get<float>(prefix+"speed") * dir.Normalized();

	const Color c(prop.Get<float>(prefix+"rgba_r"), prop.Get<float>(prefix+"rgba_g"),
			prop.Get<float>(prefix+"rgba_b"), prop.Get<float>(prefix+"rgba_a"));
	const float lifespan = prop.Get<float>(prefix+"lifespan");
	const float width = prop.Get<float>(prefix+"width");
	const float length = prop.Get<float>(prefix+"length");
	const bool mining = prop.Get<int>(prefix+"mining");
	if (prop.Get<int>(prefix+"dual"))
	{
		const vector3d orient_norm = m.VectorY();
		const vector3d sep = 5.0 * dir.Cross(orient_norm).NormalizedSafe();

		Projectile::Add(this, lifespan, damage, length, width, mining, c, pos + sep, baseVel, dirVel);
		Projectile::Add(this, lifespan, damage, length, width, mining, c, pos - sep, baseVel, dirVel);
	} else {
		Projectile::Add(this, lifespan, damage, length, width, mining, c, pos, baseVel, dirVel);
	}

	Sound::BodyMakeNoise(this, "Pulse_Laser", 1.0f);
	lua_pop(prop.GetLua(), 1);
	LuaEvent::Queue("onShipFiring", this);
}
示例#5
0
void Ship::FireWeapon(int num)
{
	const ShipType &stype = GetShipType();
	if (m_flightState != FLYING) return;

	const matrix3x3d &m = GetOrient();
	const vector3d dir = m * vector3d(stype.gunMount[num].dir);
	const vector3d pos = m * vector3d(stype.gunMount[num].pos) + GetPosition();

	m_gunTemperature[num] += 0.01f;

	Equip::Type t = m_equipment.Get(Equip::SLOT_LASER, num);
	const LaserType &lt = Equip::lasers[Equip::types[t].tableIndex];
	m_gunRecharge[num] = lt.rechargeTime;
	vector3d baseVel = GetVelocity();
	vector3d dirVel = lt.speed * dir.Normalized();

	if (lt.flags & Equip::LASER_DUAL)
	{
		const ShipType::DualLaserOrientation orient = stype.gunMount[num].orient;
		const vector3d orient_norm =
				(orient == ShipType::DUAL_LASERS_VERTICAL) ? m.VectorX() : m.VectorY();
		const vector3d sep = stype.gunMount[num].sep * dir.Cross(orient_norm).NormalizedSafe();

		Projectile::Add(this, t, pos + sep, baseVel, dirVel);
		Projectile::Add(this, t, pos - sep, baseVel, dirVel);
	}
	else
		Projectile::Add(this, t, pos, baseVel, dirVel);

	/*
			// trace laser beam through frame to see who it hits
			CollisionContact c;
			GetFrame()->GetCollisionSpace()->TraceRay(pos, dir, 10000.0, &c, this->GetGeom());
			if (c.userData1) {
				Body *hit = static_cast<Body*>(c.userData1);
				hit->OnDamage(this, damage);
			}
	*/

	Polit::NotifyOfCrime(this, Polit::CRIME_WEAPON_DISCHARGE);
	Sound::BodyMakeNoise(this, "Pulse_Laser", 1.0f);
}
示例#6
0
static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos)
{
	Equip::Type t;
	if (20*Pi::rng.Fixed() < asteroid->GetMetallicity()) {
		t = Equip::PRECIOUS_METALS;
	} else if (8*Pi::rng.Fixed() < asteroid->GetMetallicity()) {
		t = Equip::METAL_ALLOYS;
	} else if (Pi::rng.Fixed() < asteroid->GetMetallicity()) {
		t = Equip::METAL_ORE;
	} else if (Pi::rng.Fixed() < fixed(1,2)) {
		t = Equip::WATER;
	} else {
		t = Equip::RUBBISH;
	}
	CargoBody *cargo = new CargoBody(t);
	cargo->SetFrame(f);
	cargo->SetPosition(pos);
	const double x = Pi::rng.Double();
	vector3d dir = pos.Normalized();
	dir.ArbRotate(vector3d(x, 1-x, 0), Pi::rng.Double()-.5);
	cargo->SetVelocity(Pi::rng.Double(100.0,200.0) * dir);
	Pi::game->GetSpace()->AddBody(cargo);
}
示例#7
0
void Camera::DrawSpike(double rad, const vector3d &viewCoords, const matrix4x4d &viewTransform)
{
	glPushMatrix();

	float znear, zfar;
	Render::GetNearFarClipPlane(znear, zfar);
	double newdist = znear + 0.5f * (zfar - znear);
	double scale = newdist / viewCoords.Length();

	glTranslatef(float(scale*viewCoords.x), float(scale*viewCoords.y), float(scale*viewCoords.z));

	Render::State::UseProgram(0);
	// face the camera dammit
	vector3d zaxis = viewCoords.Normalized();
	vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized();
	vector3d yaxis = zaxis.Cross(xaxis);
	matrix4x4d rot = matrix4x4d::MakeInvRotMatrix(xaxis, yaxis, zaxis);
	glMultMatrixd(&rot[0]);

	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);

	// XXX WRONG. need to pick light from appropriate turd.
	GLfloat col[4];
	glGetLightfv(GL_LIGHT0, GL_DIFFUSE, col);
	glColor4f(col[0], col[1], col[2], 1);
	glBegin(GL_TRIANGLE_FAN);
	glVertex3f(0,0,0);
	glColor4f(col[0], col[1], col[2], 0);

	const float spikerad = float(scale*rad);

	// bezier with (0,0,0) control points
	{
		vector3f p0(0,spikerad,0), p1(spikerad,0,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			glVertex3fv(&p[0]);
		}
	}
	{
		vector3f p0(spikerad,0,0), p1(0,-spikerad,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			glVertex3fv(&p[0]);
		}
	}
	{
		vector3f p0(0,-spikerad,0), p1(-spikerad,0,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			glVertex3fv(&p[0]);
		}
	}
	{
		vector3f p0(-spikerad,0,0), p1(0,spikerad,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			glVertex3fv(&p[0]);
		}
	}
	glEnd();
	glDisable(GL_BLEND);
	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);
	glPopMatrix();
}
示例#8
0
void Camera::DrawSpike(double rad, const vector3d &viewCoords, const matrix4x4d &viewTransform)
{
	// draw twinkly star-thing on faraway objects
	// XXX this seems like a good case for drawing in 2D - use projected position, then the
	// "face the camera dammit" bits can be skipped
	if (!m_renderer) return;

	const double newdist = m_zNear + 0.5f * (m_zFar - m_zNear);
	const double scale = newdist / viewCoords.Length();

	matrix4x4d trans = matrix4x4d::Identity();
	trans.Translate(scale*viewCoords.x, scale*viewCoords.y, scale*viewCoords.z);

	// face the camera dammit
	vector3d zaxis = viewCoords.Normalized();
	vector3d xaxis = vector3d(0,1,0).Cross(zaxis).Normalized();
	vector3d yaxis = zaxis.Cross(xaxis);
	matrix4x4d rot = matrix4x4d::MakeInvRotMatrix(xaxis, yaxis, zaxis);
	trans = trans * rot;

	m_renderer->SetDepthTest(false);
	m_renderer->SetBlendMode(BLEND_ALPHA_ONE);

	// XXX this is supposed to pick a correct light colour for the object twinkle.
	// Not quite correct, since it always uses the first light
	GLfloat col[4];
	glGetLightfv(GL_LIGHT0, GL_DIFFUSE, col);
	col[3] = 1.f;

	static VertexArray va(ATTRIB_POSITION | ATTRIB_DIFFUSE);
	va.Clear();

	const Color center(col[0], col[1], col[2], col[2]);
	const Color edges(col[0], col[1], col[2], 0.f);

	//center
	va.Add(vector3f(0.f), center);

	const float spikerad = float(scale*rad);

	// bezier with (0,0,0) control points
	{
		const vector3f p0(0,spikerad,0), p1(spikerad,0,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			va.Add(p, edges);
		}
	}
	{
		const vector3f p0(spikerad,0,0), p1(0,-spikerad,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			va.Add(p, edges);
		}
	}
	{
		const vector3f p0(0,-spikerad,0), p1(-spikerad,0,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			va.Add(p, edges);
		}
	}
	{
		const vector3f p0(-spikerad,0,0), p1(0,spikerad,0);
		float t=0.1f; for (int i=1; i<10; i++, t+= 0.1f) {
			const vector3f p = (1-t)*(1-t)*p0 + t*t*p1;
			va.Add(p, edges);
		}
	}

	glPushMatrix();
	m_renderer->SetTransform(trans);
	m_renderer->DrawTriangles(&va, Graphics::vtxColorMaterial, TRIANGLE_FAN);
	m_renderer->SetBlendMode(BLEND_SOLID);
	m_renderer->SetDepthTest(true);
	glPopMatrix();
}
示例#9
0
void BaseSphere::DrawAtmosphereSurface(Graphics::Renderer *renderer,
	const matrix4x4d &modelView, const vector3d &campos, float rad,
	Graphics::RenderState *rs, Graphics::Material *mat)
{
	using namespace Graphics;
	const vector3d yaxis = campos.Normalized();
	const vector3d zaxis = vector3d(1.0, 0.0, 0.0).Cross(yaxis).Normalized();
	const vector3d xaxis = yaxis.Cross(zaxis);
	const matrix4x4d invrot = matrix4x4d::MakeRotMatrix(xaxis, yaxis, zaxis).Inverse();

	renderer->SetTransform(modelView * matrix4x4d::ScaleMatrix(rad, rad, rad) * invrot);

	// what is this? Well, angle to the horizon is:
	// acos(planetRadius/viewerDistFromSphereCentre)
	// and angle from this tangent on to atmosphere is:
	// acos(planetRadius/atmosphereRadius) ie acos(1.0/1.01244blah)
	const double endAng = acos(1.0 / campos.Length()) + acos(1.0 / rad);
	const double latDiff = endAng / double(LAT_SEGS);

	double rot = 0.0;
	float sinTable[LONG_SEGS + 1];
	float cosTable[LONG_SEGS + 1];
	for (int i = 0; i <= LONG_SEGS; i++, rot += 2.0*M_PI / double(LONG_SEGS)) {
		sinTable[i] = float(sin(rot));
		cosTable[i] = float(cos(rot));
	}

	// Tri-fan above viewer
	if(!m_TriFanAbove.Valid())
	{
		// VertexBuffer
		VertexBufferDesc vbd;
		vbd.attrib[0].semantic = ATTRIB_POSITION;
		vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3;
		vbd.numVertices = LONG_SEGS + 2;
		vbd.usage = BUFFER_USAGE_STATIC;
		m_TriFanAbove.Reset(renderer->CreateVertexBuffer(vbd));
	}
#pragma pack(push, 4)
	struct PosVert {
		vector3f pos;
	};
#pragma pack(pop)
	PosVert* vtxPtr = m_TriFanAbove->Map<PosVert>(Graphics::BUFFER_MAP_WRITE);
	vtxPtr[0].pos = vector3f(0.f, 1.f, 0.f);
	for (int i = 0; i <= LONG_SEGS; i++)
	{
		vtxPtr[i + 1].pos = vector3f(
			sin(latDiff)*sinTable[i],
			cos(latDiff),
			-sin(latDiff)*cosTable[i]);
	}
	m_TriFanAbove->Unmap();
	renderer->DrawBuffer(m_TriFanAbove.Get(), rs, mat, Graphics::TRIANGLE_FAN);

	// and wound latitudinal strips
	if (!m_LatitudinalStrips[0].Valid())
	{
		VertexBufferDesc vbd;
		vbd.attrib[0].semantic = ATTRIB_POSITION;
		vbd.attrib[0].format = ATTRIB_FORMAT_FLOAT3;
		vbd.numVertices = (LONG_SEGS + 1) * 2;
		vbd.usage = BUFFER_USAGE_DYNAMIC;
		for (int j = 0; j < LAT_SEGS; j++) {
			// VertexBuffer
			m_LatitudinalStrips[j].Reset(renderer->CreateVertexBuffer(vbd));
		}
	}
	double lat = latDiff;
	for (int j=1; j<LAT_SEGS; j++, lat += latDiff) {
		const float cosLat = cos(lat);
		const float sinLat = sin(lat);
		const float cosLat2 = cos(lat+latDiff);
		const float sinLat2 = sin(lat+latDiff);
		vtxPtr = m_LatitudinalStrips[j]->Map<PosVert>(Graphics::BUFFER_MAP_WRITE);
		vtxPtr[0].pos = vector3f(0.f, 1.f, 0.f);
		for (int i=0; i<=LONG_SEGS; i++) {
			vtxPtr[(i*2)+0].pos = vector3f(sinLat*sinTable[i], cosLat, -sinLat*cosTable[i]);
			vtxPtr[(i*2)+1].pos = vector3f(sinLat2*sinTable[i], cosLat2, -sinLat2*cosTable[i]);
		}
		m_LatitudinalStrips[j]->Unmap();
		renderer->DrawBuffer(m_LatitudinalStrips[j].Get(), rs, mat, Graphics::TRIANGLE_STRIP);
	}

	renderer->GetStats().AddToStatCount(Graphics::Stats::STAT_ATMOSPHERES, 1);
}