Exemplo n.º 1
0
void ObjectViewerView::Update()
{
	if (Pi::KeyState(SDLK_EQUALS)) viewingDist *= 0.99;
	if (Pi::KeyState(SDLK_MINUS)) viewingDist *= 1.01;
	viewingDist = Clamp(viewingDist, 10.0f, 1e12f);

	char buf[128];
	Body *body = Pi::player->GetNavTarget();
	if(body && (body != lastTarget)) {
		// Reset view distance for new target.
		viewingDist = body->GetBoundingRadius() * 2.0f;
		lastTarget = body;

		if (body->IsType(Object::PLANET)) {
			Planet *planet = static_cast<Planet*>(body);
			const SBody *sbody = planet->GetSBody();
			m_sbodyVolatileGas->SetText(stringf("%0{f.3}", sbody->m_volatileGas.ToFloat()));
			m_sbodyVolatileLiquid->SetText(stringf("%0{f.3}", sbody->m_volatileLiquid.ToFloat()));
			m_sbodyVolatileIces->SetText(stringf("%0{f.3}", sbody->m_volatileIces.ToFloat()));
			m_sbodyLife->SetText(stringf("%0{f.3}", sbody->m_life.ToFloat()));
			m_sbodyVolcanicity->SetText(stringf("%0{f.3}", sbody->m_volcanicity.ToFloat()));
			m_sbodyMetallicity->SetText(stringf("%0{f.3}", sbody->m_metallicity.ToFloat()));
			m_sbodySeed->SetText(stringf("%0{d}", sbody->seed));
			m_sbodyMass->SetText(stringf("%0{f}", sbody->mass.ToFloat()));
			m_sbodyRadius->SetText(stringf("%0{f}", sbody->radius.ToFloat()));
		}
	}
	snprintf(buf, sizeof(buf), "View dist: %s     Object: %s", format_distance(viewingDist).c_str(), (body ? body->GetLabel().c_str() : "<none>"));
	m_infoLabel->SetText(buf);
}
Exemplo n.º 2
0
static Frame *MakeFrameFor(SBody *sbody, Body *b, Frame *f)
{
    Frame *orbFrame, *rotFrame;
    double frameRadius;

    if (!sbody->parent) {
        if (b) b->SetFrame(f);
        f->m_sbody = sbody;
        f->m_astroBody = b;
        return f;
    }

    if (sbody->type == SBody::TYPE_GRAVPOINT) {
        orbFrame = new Frame(f, sbody->name.c_str());
        orbFrame->m_sbody = sbody;
        orbFrame->m_astroBody = b;
        orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
        return orbFrame;
    }

    SBody::BodySuperType supertype = sbody->GetSuperType();

    if ((supertype == SBody::SUPERTYPE_GAS_GIANT) ||
            (supertype == SBody::SUPERTYPE_ROCKY_PLANET)) {
        // for planets we want an non-rotating frame for a few radii
        // and a rotating frame in the same position but with maybe 1.05*radius,
        // which actually contains the object.
        frameRadius = std::max(4.0*sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance()*1.05);
        orbFrame = new Frame(f, sbody->name.c_str());
        orbFrame->m_sbody = sbody;
        orbFrame->SetRadius(frameRadius);
        //printf("\t\t\t%s has frame size %.0fkm, body radius %.0fkm\n", sbody->name.c_str(),
        //	(frameRadius ? frameRadius : 10*sbody->GetRadius())*0.001f,
        //	sbody->GetRadius()*0.001f);

        assert(sbody->rotationPeriod != 0);
        rotFrame = new Frame(orbFrame, sbody->name.c_str());
        // rotating frame has size of GeoSphere terrain bounding sphere
        rotFrame->SetRadius(b->GetBoundingRadius());
        rotFrame->SetAngVelocity(vector3d(0,2*M_PI/sbody->GetRotationPeriod(),0));
        rotFrame->m_astroBody = b;
        SetFrameOrientationFromSBodyAxialTilt(rotFrame, sbody);
        b->SetFrame(rotFrame);
        return orbFrame;
    }
    else if (supertype == SBody::SUPERTYPE_STAR) {
        // stars want a single small non-rotating frame
        orbFrame = new Frame(f, sbody->name.c_str());
        orbFrame->m_sbody = sbody;
        orbFrame->m_astroBody = b;
        orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
        b->SetFrame(orbFrame);
        return orbFrame;
    }
    else if (sbody->type == SBody::TYPE_STARPORT_ORBITAL) {
        // space stations want non-rotating frame to some distance
        // and a much closer rotating frame
        frameRadius = 1000000.0; // XXX NFI!
        orbFrame = new Frame(f, sbody->name.c_str());
        orbFrame->m_sbody = sbody;
//		orbFrame->SetRadius(10*sbody->GetRadius());
        orbFrame->SetRadius(frameRadius);

        assert(sbody->rotationPeriod != 0);
        rotFrame = new Frame(orbFrame, sbody->name.c_str());
        rotFrame->SetRadius(1000.0);
//		rotFrame->SetRadius(1.1*sbody->GetRadius());		// enough for collisions?
        rotFrame->SetAngVelocity(vector3d(0.0,double(static_cast<SpaceStation*>(b)->GetDesiredAngVel()),0.0));
        rotFrame->m_astroBody = b;		// hope this doesn't break anything
        b->SetFrame(rotFrame);
        return orbFrame;
    } else if (sbody->type == SBody::TYPE_STARPORT_SURFACE) {
        // just put body into rotating frame of planet, not in its own frame
        // (because collisions only happen between objects in same frame,
        // and we want collisions on starport and on planet itself)
        Frame *frame = *f->m_children.begin();
        b->SetFrame(frame);
        assert(frame->m_astroBody->IsType(Object::PLANET));
        Planet *planet = static_cast<Planet*>(frame->m_astroBody);

        /* position on planet surface */
        double height;
        int tries;
        matrix4x4d rot;
        vector3d pos;
        // first try suggested position
        rot = sbody->orbit.rotMatrix;
        pos = rot * vector3d(0,1,0);
        if (planet->GetTerrainHeight(pos) - planet->GetSBody()->GetRadius() <= 0.0) {
            MTRand r(sbody->seed);
            // position is under water. try some random ones
            for (tries=0; tries<100; tries++) {
                // used for orientation on planet surface
                double r2 = r.Double(); 	// function parameter evaluation order is implementation-dependent
                double r1 = r.Double();		// can't put two rands in the same expression
                rot = matrix4x4d::RotateZMatrix(2*M_PI*r1)
                      * matrix4x4d::RotateYMatrix(2*M_PI*r2);
                pos = rot * vector3d(0,1,0);
                height = planet->GetTerrainHeight(pos) - planet->GetSBody()->GetRadius();
                // don't want to be under water
                if (height > 0.0) break;
            }
        }
        b->SetPosition(pos * planet->GetTerrainHeight(pos));
        b->SetRotMatrix(rot);
        return frame;
    } else {
        assert(0);
    }
    return NULL;
}