示例#1
0
//ZZZ unpleasant
static void hitCallback(CollisionContact* c)
{
	auto& ent1 = *static_cast<Entity*>(c->userData1);
	auto& ent2 = *static_cast<Entity*>(c->userData2);

	auto dc1 = ent1.component<DynamicsComponent>();
	auto dc2 = ent2.component<DynamicsComponent>();
	auto poc1 = ent1.component<PosOrientComponent>();
	auto poc2 = ent2.component<PosOrientComponent>();
	auto mc1 = ent1.component<MassComponent>();
	auto mc2 = ent2.component<MassComponent>();

	const double coeff_rest = 0.5;

	const double invMass1 = 1.0 / mc1->mass;
	const double invMass2 = 1.0 / mc2->mass;
	const vector3d hitPos1 = c->pos - poc1->pos;
	const vector3d hitPos2 = c->pos - poc2->pos;
	const vector3d hitVel1 = dc1->vel + dc1->angVel.Cross(hitPos1);
	const vector3d hitVel2 = dc2->vel + dc2->angVel.Cross(hitPos2);
	const double relVel = (hitVel1 - hitVel2).Dot(c->normal);

	// moving away so no collision
	if (relVel > 0) return;

	const double invAngInert1 = 1.0 / dc1->angInertia;
	const double invAngInert2 = 1.0 / dc2->angInertia;
	const double numerator = -(1.0 + coeff_rest) * relVel;
	const double term1 = invMass1;
	const double term2 = invMass2;
	const double term3 = c->normal.Dot((hitPos1.Cross(c->normal) * invAngInert1).Cross(hitPos1));
	const double term4 = c->normal.Dot((hitPos2.Cross(c->normal) * invAngInert2).Cross(hitPos2));

	const double j = numerator / (term1 + term2 + term3 + term4);
	const vector3d force = j * c->normal;

	dc1->vel += force * invMass1;
	dc1->angVel += hitPos1.Cross(force) * invAngInert1;
	dc2->vel -= force * invMass2;
	dc2->angVel -= hitPos2.Cross(force) * invAngInert2;
}
示例#2
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);
}
示例#3
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);
}
示例#4
0
static void hitCallback(CollisionContact *c)
{
    //printf("OUCH! %x (depth %f)\n", SDL_GetTicks(), c->depth);

    Object *po1 = static_cast<Object*>(c->userData1);
    Object *po2 = static_cast<Object*>(c->userData2);

    const bool po1_isDynBody = po1->IsType(Object::DYNAMICBODY);
    const bool po2_isDynBody = po2->IsType(Object::DYNAMICBODY);
    // collision response
    assert(po1_isDynBody || po2_isDynBody);

    if (po1_isDynBody && po2_isDynBody) {
        DynamicBody *b1 = static_cast<DynamicBody*>(po1);
        DynamicBody *b2 = static_cast<DynamicBody*>(po2);
        const vector3d linVel1 = b1->GetVelocity();
        const vector3d linVel2 = b2->GetVelocity();
        const vector3d angVel1 = b1->GetAngVelocity();
        const vector3d angVel2 = b2->GetAngVelocity();

        const double coeff_rest = 0.5;
        // step back
//		mover->UndoTimestep();

        const double invMass1 = 1.0 / b1->GetMass();
        const double invMass2 = 1.0 / b2->GetMass();
        const vector3d hitPos1 = c->pos - b1->GetPosition();
        const vector3d hitPos2 = c->pos - b2->GetPosition();
        const vector3d hitVel1 = linVel1 + angVel1.Cross(hitPos1);
        const vector3d hitVel2 = linVel2 + angVel2.Cross(hitPos2);
        const double relVel = (hitVel1 - hitVel2).Dot(c->normal);
        // moving away so no collision
        if (relVel > 0) return;
        if (!OnCollision(po1, po2, c, -relVel)) return;
        const double invAngInert1 = 1.0 / b1->GetAngularInertia();
        const double invAngInert2 = 1.0 / b2->GetAngularInertia();
        const double numerator = -(1.0 + coeff_rest) * relVel;
        const double term1 = invMass1;
        const double term2 = invMass2;
        const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert1).Cross(hitPos1));
        const double term4 = c->normal.Dot((hitPos2.Cross(c->normal)*invAngInert2).Cross(hitPos2));

        const double j = numerator / (term1 + term2 + term3 + term4);
        const vector3d force = j * c->normal;

        b1->SetVelocity(linVel1 + force*invMass1);
        b1->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert1);
        b2->SetVelocity(linVel2 - force*invMass2);
        b2->SetAngVelocity(angVel2 - hitPos2.Cross(force)*invAngInert2);
    } else {
        // one body is static
        vector3d hitNormal;
        DynamicBody *mover;

        if (po1_isDynBody) {
            mover = static_cast<DynamicBody*>(po1);
            hitNormal = c->normal;
        } else {
            mover = static_cast<DynamicBody*>(po2);
            hitNormal = -c->normal;
        }

        const double coeff_rest = 0.5;
        const vector3d linVel1 = mover->GetVelocity();
        const vector3d angVel1 = mover->GetAngVelocity();

        // step back
//		mover->UndoTimestep();

        const double invMass1 = 1.0 / mover->GetMass();
        const vector3d hitPos1 = c->pos - mover->GetPosition();
        const vector3d hitVel1 = linVel1 + angVel1.Cross(hitPos1);
        const double relVel = hitVel1.Dot(c->normal);
        // moving away so no collision
        if (relVel > 0 && !c->geomFlag) return;
        if (!OnCollision(po1, po2, c, -relVel)) return;
        const double invAngInert = 1.0 / mover->GetAngularInertia();
        const double numerator = -(1.0 + coeff_rest) * relVel;
        const double term1 = invMass1;
        const double term3 = c->normal.Dot((hitPos1.Cross(c->normal)*invAngInert).Cross(hitPos1));

        const double j = numerator / (term1 + term3);
        const vector3d force = j * c->normal;

        mover->SetVelocity(linVel1 + force*invMass1);
        mover->SetAngVelocity(angVel1 + hitPos1.Cross(force)*invAngInert);
    }
}
示例#5
0
{
	GeoSphere::UpdateAllGeoSpheres();
	GasGiant::UpdateAllGasGiants();
}

//static 
void BaseSphere::OnChangeDetailLevel()
{
	GeoSphere::OnChangeDetailLevel();
}

void BaseSphere::DrawAtmosphereSurface(Graphics::Renderer *renderer,
	const matrix4x4d &modelView, const vector3d &campos, float rad,
	Graphics::RenderState *rs, RefCountedPtr<Graphics::Material> mat)
{
	PROFILE_SCOPED()
	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);

	if(!m_atmos)
		m_atmos.reset( new Drawables::Sphere3D(renderer, mat, rs, 4, 1.0f, ATTRIB_POSITION));
	m_atmos->Draw(renderer);

	renderer->GetStats().AddToStatCount(Graphics::Stats::STAT_ATMOSPHERES, 1);
}
示例#6
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);
}
示例#7
0
static void raytraceCollMesh(vector3d camPos, vector3d camera_up, vector3d camera_forward, CollisionSpace *space)
{
	memset(wank, 0, sizeof(float)*TEXSIZE*TEXSIZE);

	vector3d toPoint, xMov, yMov;

	vector3d topLeft, topRight, botRight, cross;
	topLeft = topRight = botRight = camera_forward * camera_zoom;
	cross = camera_forward.Cross(camera_up) * aspectRatio;
	topLeft = topLeft + camera_up - cross;
	topRight = topRight + camera_up + cross;
	botRight = botRight - camera_up + cross;

	xMov = topRight - topLeft;
	yMov = botRight - topRight;
	float xstep = 1.0f / TEXSIZE;
	float ystep = 1.0f / TEXSIZE;
	float xpos, ypos;
	ypos = 0.0f;
	GeomTree::stats_rayTriIntersections = 0;

	Uint32 t = SDL_GetTicks();
	for (int y=0; y<TEXSIZE; y++, ypos += ystep) {
		xpos = 0.0f;
		for (int x=0; x<TEXSIZE; x++, xpos += xstep) {
			toPoint = (topLeft + (xMov * xpos) + (yMov * ypos)).Normalized();
			
			CollisionContact c;
			space->TraceRay(camPos, toPoint, 1000000.0f, &c);

			if (c.triIdx != -1) {
				wank[x][y] = 100.0/(10*c.dist);
			} else {
				wank[x][y] = 0;
			}
		}
	}
	printf("%.3f million rays/sec, %.2f tri isect tests per ray\n", (TEXSIZE*TEXSIZE)/(1000.0*(SDL_GetTicks()-t)),
				GeomTree::stats_rayTriIntersections/(float)(TEXSIZE*TEXSIZE));
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, mytexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE, TEXSIZE, 0, GL_LUMINANCE, GL_FLOAT, wank);

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 1, 0, 1, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	//glActiveTexture(GL_TEXTURE0);
	glDisable(GL_LIGHTING);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glBegin(GL_TRIANGLE_FAN);
		glTexCoord2i(0,1);
		glVertex3f(1,1,0);

		glTexCoord2i(0,0);
		glVertex3f(0,1,0);
		
		glTexCoord2i(1,0);
		glVertex3f(0,0,0);
		
		glTexCoord2i(1,1);
		glVertex3f(1,0,0);
	glEnd();
	glDisable(GL_TEXTURE_2D);
}