Exemplo n.º 1
0
// 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);
}
Exemplo n.º 2
0
void Space::CollideFrame(Frame *f)
{
	if (f->m_astroBody && (f->m_astroBody->IsType(Object::TERRAINBODY))) {
		// this is pretty retarded
		for (BodyIterator i = m_bodies.begin(); i!=m_bodies.end(); ++i) {
			if ((*i)->GetFrame() != f) continue;
			if (!(*i)->IsType(Object::DYNAMICBODY)) continue;
			DynamicBody *dynBody = static_cast<DynamicBody*>(*i);

			Aabb aabb;
			dynBody->GetAabb(aabb);
			const matrix4x4d &trans = dynBody->GetGeom()->GetTransform();

			const vector3d aabbCorners[8] = {
				vector3d(aabb.min.x, aabb.min.y, aabb.min.z),
				vector3d(aabb.min.x, aabb.min.y, aabb.max.z),
				vector3d(aabb.min.x, aabb.max.y, aabb.min.z),
				vector3d(aabb.min.x, aabb.max.y, aabb.max.z),
				vector3d(aabb.max.x, aabb.min.y, aabb.min.z),
				vector3d(aabb.max.x, aabb.min.y, aabb.max.z),
				vector3d(aabb.max.x, aabb.max.y, aabb.min.z),
				vector3d(aabb.max.x, aabb.max.y, aabb.max.z)
			};

			CollisionContact c;

			for (int j=0; j<8; j++) {
				const vector3d &s = aabbCorners[j];
				vector3d pos = trans * s;
				double terrain_height = static_cast<Planet*>(f->m_astroBody)->GetTerrainHeight(pos.Normalized());
				double altitude = pos.Length();
				double hitDepth = terrain_height - altitude;
				if (altitude < terrain_height) {
					c.pos = pos;
					c.normal = pos.Normalized();
					c.depth = hitDepth;
					c.userData1 = static_cast<void*>(dynBody);
					c.userData2 = static_cast<void*>(f->m_astroBody);
					hitCallback(&c);
				}
			}
		}
	}
	f->GetCollisionSpace()->Collide(&hitCallback);
	for (std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
		CollideFrame(*i);
	}
}