コード例 #1
0
void StarSystem::UpdateUnitPhysics( bool firstframe )
{
    static bool phytoggle  = true;
    static int  batchcount = SIM_QUEUE_SIZE-1;
    double aitime = 0;
    double phytime = 0;
    double collidetime     = 0;
    double flattentime     = 0;
    double bolttime = 0;
    targetpick   = 0;
    aggfire      = 0;
    numprocessed = 0;
    stats.CheckVitals( this );
    if (phytoggle) {
        for (++batchcount; batchcount > 0; --batchcount) {
            //BELOW COMMENTS ARE NO LONGER IN SYNCH
            //NOTE: Randomization is necessary to preserve scattering - otherwise, whenever a
            //unit goes from low-priority to high-priority and back to low-priority, they
            //get synchronized and start producing peaks.
            //NOTE2: But... randomization must come only on priority changes. Otherwise, it may
            //interfere with subunit scheduling. Luckily, all units that make use of subunit
            //scheduling also require a constant base priority, since otherwise priority changes
            //will wreak havoc with subunit interpolation. Luckily again, we only need
            //randomization on priority changes, so we're fine.
            try {
                Unit *unit = NULL;
                for (un_iter iter = physics_buffer[current_sim_location].createIterator(); (unit = *iter); ++iter) {
                    int priority  = UnitUtil::getPhysicsPriority( unit );
                    //Doing spreading here and only on priority changes, so as to make AI easier
                    int predprior = unit->predicted_priority;
                    //If the priority has really changed (not an initial scattering, because prediction doesn't match)
                    if (priority != predprior) {
                        if (predprior == 0)
                            //Validate snapshot of current interpolated state (this is a reschedule)
                            unit->curr_physical_state = unit->cumulative_transformation;
                        //Save priority value as prediction for next scheduling, but don't overwrite yet.
                        predprior = priority;
                        //Scatter, so as to achieve uniform distribution
                        priority  = 1+( ( (unsigned int) vsrandom.genrand_int32() )%priority );
                    }
                    float backup = SIMULATION_ATOM;
                    theunitcounter   = theunitcounter+1;
                    SIMULATION_ATOM *= priority;
                    unit->sim_atom_multiplier = priority;
                    double aa = queryTime();
                    unit->ExecuteAI();
                    double bb = queryTime();
                    unit->ResetThreatLevel();
                    //FIXME "firstframe"-- assume no more than 2 physics updates per frame.
                    unit->UpdatePhysics( identity_transformation, identity_matrix, Vector( 0,
                                                                                           0,
                                                                                           0 ), priority
                                         == 1 ? firstframe : true, &this->gravitationalUnits(), unit );
                    double cc = queryTime();
                    aitime  += bb-aa;
                    phytime += cc-bb;
                    SIMULATION_ATOM = backup;
                    unit->predicted_priority = predprior;
                }
            }
            catch (const boost::python::error_already_set) {
                if ( PyErr_Occurred() ) {
                    PyErr_Print();
                    PyErr_Clear();
                    fflush( stderr );
                    fflush( stdout );
                } throw;
            }
            double c0  = queryTime();
            Bolt::UpdatePhysics( this );
            double cc  = queryTime();
            last_collisions.clear();
            double fl0 = queryTime();
            collidemap[Unit::UNIT_BOLT]->flatten();
            if (Unit::NUM_COLLIDE_MAPS > 1)
                collidemap[Unit::UNIT_ONLY]->flatten( *collidemap[Unit::UNIT_BOLT] );
            flattentime = queryTime()-fl0;
            Unit *unit;
            for (un_iter iter = physics_buffer[current_sim_location].createIterator(); (unit = *iter);) {
                int   priority = unit->sim_atom_multiplier;
                float backup   = SIMULATION_ATOM;
                SIMULATION_ATOM *= priority;
                unsigned int newloc = (current_sim_location+priority)%SIM_QUEUE_SIZE;
                unit->CollideAll();
                SIMULATION_ATOM = backup;
                if (newloc == current_sim_location)
                    ++iter;
                else
                    iter.moveBefore( physics_buffer[newloc] );
            }
            double dd = queryTime();
            collidetime += dd-cc;
            bolttime    += cc-c0;
            current_sim_location = (current_sim_location+1)%SIM_QUEUE_SIZE;
            ++physicsframecounter;
            totalprocessed += theunitcounter;
            theunitcounter  = 0;
        }
    } else {
        Unit *unit = NULL;
        for (un_iter iter = getUnitList().createIterator(); (unit = *iter); ++iter) {
            unit->ExecuteAI();
            last_collisions.clear();
            unit->UpdatePhysics( identity_transformation, identity_matrix, Vector( 0,
                                                                                   0,
                                                                                   0 ), firstframe,
                                 &this->gravitationalUnits(), unit );
            unit->CollideAll();
        }
    }
}
コード例 #2
0
//client
void StarSystem::Update( float priority, bool executeDirector )
{
    bool   firstframe = true;
    double pythontime = 0;
    ///this makes it so systems without players may be simulated less accurately
    for (unsigned int k = 0; k < _Universe->numPlayers(); ++k)
        if (_Universe->AccessCockpit( k )->activeStarSystem == this)
            priority = 1;
    float normal_simulation_atom = SIMULATION_ATOM;
    SIMULATION_ATOM /= ( priority/getTimeCompression() );
    ///just be sure to restore this at the end
    time += GetElapsedTime();
    _Universe->pushActiveStarSystem( this );
    //WARNING PERFORMANCE HACK!!!!!
    if (time > 2*SIMULATION_ATOM)
        time = 2*SIMULATION_ATOM;
    double bolttime = 0;
    if ( time/SIMULATION_ATOM >= (1./PHY_NUM) ) {
        //Chew up all SIMULATION_ATOMs that have elapsed since last update
        while ( time/SIMULATION_ATOM >= (1./PHY_NUM) ) {
            if (current_stage == MISSION_SIMULATION) {
                TerrainCollide();
                UpdateAnimatedTexture();
                Unit::ProcessDeleteQueue();
                double pythonidea = queryTime();
                if ( (run_only_player_starsystem
                      && _Universe->getActiveStarSystem( 0 ) == this) || !run_only_player_starsystem )
                    if (executeDirector)
                        ExecuteDirector();
                pythontime = queryTime()-pythonidea;
                static int dothis = 0;
                if ( this == _Universe->getActiveStarSystem( 0 ) )
                    if ( (++dothis)%2 == 0 )
                        AUDRefreshSounds();
                for (unsigned int i = 0; i < active_missions.size(); ++i)
                    //waste of farkin time
                    active_missions[i]->BriefingUpdate();
                current_stage = PROCESS_UNIT;
            } else if (current_stage == PROCESS_UNIT) {
                UpdateUnitPhysics( firstframe );
                UpdateMissiles(); //do explosions
                collidetable->Update();
                if ( this == _Universe->getActiveStarSystem( 0 ) )
                    UpdateCameraSnds();
                bolttime      = queryTime();
                bolttime      = queryTime()-bolttime;
                current_stage = MISSION_SIMULATION;
                firstframe    = false;
            }
            time -= (1./PHY_NUM)*SIMULATION_ATOM;
        }
        unsigned int i = _Universe->CurrentCockpit();
        for (unsigned int j = 0; j < _Universe->numPlayers(); ++j)
            if (_Universe->AccessCockpit( j )->activeStarSystem == this) {
                _Universe->SetActiveCockpit( j );
                _Universe->AccessCockpit( j )->updateAttackers();
                if ( _Universe->AccessCockpit( j )->Update() ) {
                    SIMULATION_ATOM = normal_simulation_atom;
                    _Universe->SetActiveCockpit( i );
                    _Universe->popActiveStarSystem();
                    return;
                }
            }
        _Universe->SetActiveCockpit( i );
    }
    if ( sigIter.isDone() )
        sigIter = drawList.createIterator();
    else
        ++sigIter;
    while ( !sigIter.isDone() && !UnitUtil::isSignificant( *sigIter) )
        ++sigIter;
    //If it is done, leave it NULL for this frame then.
    //WARNING cockpit does not get here...
    SIMULATION_ATOM = normal_simulation_atom;
    //WARNING cockpit does not get here...
    _Universe->popActiveStarSystem();
}
コード例 #3
0
//#define UPDATEDEBUG  //for hard to track down bugs
void GameStarSystem::Draw(bool DrawCockpit)
{
	double starttime=queryTime();
	GFXEnable (DEPTHTEST);
	GFXEnable (DEPTHWRITE);
	saved_interpolation_blend_factor=interpolation_blend_factor = (1./PHY_NUM)*((PHY_NUM*time)/SIMULATION_ATOM+current_stage);
	GFXColor4f(1,1,1,1);
	if (DrawCockpit) {
		AnimatedTexture::UpdateAllFrame();
	}
	for (unsigned int i=0;i<contterrains.size();++i) {
		contterrains[i]->AdjustTerrain(this);
	}

	Unit * par;
	bool alreadysetviewport=false;
	if ((par=_Universe->AccessCockpit()->GetParent())==NULL) {
		_Universe->AccessCamera()->UpdateGFX (GFXTRUE);
	}
	else {
		if (!par->isSubUnit()) {
			//now we can assume world is topps
			par-> cumulative_transformation = linear_interpolate (par->prev_physical_state,par->curr_physical_state,interpolation_blend_factor);
			Unit * targ = par->Target();
			if (targ&&!targ->isSubUnit()) {
				targ-> cumulative_transformation = linear_interpolate (targ->prev_physical_state,targ->curr_physical_state,interpolation_blend_factor);
			}
			_Universe->AccessCockpit()->SetupViewPort(true);
			alreadysetviewport=true;
		}

	}
	double setupdrawtime=queryTime();
	{
		cam_setup_phase=true;

		//int numships=0;
		Unit * saveparent=_Universe->AccessCockpit()->GetSaveParent();
		Unit * targ=NULL;
		if (saveparent) {
			targ=saveparent->Target();
		}
		//Array containing the two interesting units, so as not to have to copy-paste code
		Unit * camunits[2]={saveparent,targ};
		float backup=SIMULATION_ATOM;
		unsigned int cur_sim_frame = _Universe->activeStarSystem()->getCurrentSimFrame();
		for(int i=0;i<2;++i) {
			Unit *unit=camunits[i];
			// Make sure unit is not null;
			if(unit&&!unit->isSubUnit()) {
				interpolation_blend_factor=calc_blend_factor(saved_interpolation_blend_factor,unit->sim_atom_multiplier,unit->cur_sim_queue_slot,cur_sim_frame);
				SIMULATION_ATOM = backup*unit->sim_atom_multiplier;
				((GameUnit<Unit> *)unit)->GameUnit<Unit>::Draw();
			}
		}
		interpolation_blend_factor=saved_interpolation_blend_factor;
		SIMULATION_ATOM=backup;

		//printf("Number of insystem ships: %d (%d FPS)\n",numships,(int)(1.f/GetElapsedTime()));

								 ///this is the final, smoothly calculated cam
		_Universe->AccessCockpit()->SetupViewPort(true);

		cam_setup_phase=false;
	}
	setupdrawtime=queryTime()-setupdrawtime;
	GFXDisable (LIGHTING);
	bg->Draw();
	double drawtime=queryTime();

	double maxdrawtime=0;

	//Ballpark estimate of when an object of configurable size first becomes one pixel

	QVector drawstartpos=_Universe->AccessCamera()->GetPosition();
        
	Collidable key_iterator(0,1,drawstartpos);
	UnitWithinRangeOfPosition<UnitDrawer> drawer(game_options.precull_dist,0,key_iterator);
	//Need to draw really big stuff (i.e. planets, deathstars, and other mind-bogglingly big things that shouldn't be culled despited extreme distance
	Unit* unit;
        if ((drawer.action.parent=_Universe->AccessCockpit()->GetParent())!=NULL) {
          drawer.action.parenttarget=drawer.action.parent->Target();
        }
	for(un_iter iter=this->GravitationalUnits.createIterator();(unit=*iter)!=NULL;++iter) {
		float distance = (drawstartpos-unit->Position()).Magnitude()-unit->rSize();
		if(distance < game_options.precull_dist) {
			drawer.action.grav_acquire(unit);
		}
		else {
			drawer.action.draw(unit);
		}
	}

	// Need to get iterator to approx camera position
	CollideMap::iterator parent=collidemap[Unit::UNIT_ONLY]->lower_bound(key_iterator);
	findObjectsFromPosition(this->collidemap[Unit::UNIT_ONLY],parent,&drawer,drawstartpos,0,true);
        drawer.action.drawParents();//draw units targeted by camera
	//FIXME  maybe we could do bolts & units instead of unit only--and avoid bolt drawing step

#if 0
	for (unsigned int sim_counter=0;sim_counter<=SIM_QUEUE_SIZE;++sim_counter) {
		double tmp=queryTime();
		Unit *unit;
		UnitCollection::UnitIterator iter = physics_buffer[sim_counter].createIterator();
		float backup=SIMULATION_ATOM;
		unsigned int cur_sim_frame = _Universe->activeStarSystem()->getCurrentSimFrame();
		while((unit = iter.current())!=NULL) {
			interpolation_blend_factor=calc_blend_factor(saved_interpolation_blend_factor,unit->sim_atom_multiplier,unit->cur_sim_queue_slot,cur_sim_frame);
			//if (par&&par->Target()==unit) {
			//printf ("i:%f s:%f m:%d c:%d l:%d\n",interpolation_blend_factor,saved_interpolation_blend_factor,unit->sim_atom_multiplier,sim_counter,current_sim_location);
			//}
			SIMULATION_ATOM = backup*unit->sim_atom_multiplier;
			((GameUnit<Unit> *)unit)->Draw();
			iter.advance();
		}
		interpolation_blend_factor=saved_interpolation_blend_factor;
		SIMULATION_ATOM=backup;
		tmp=queryTime()-tmp;
		if (tmp>maxdrawtime)maxdrawtime=tmp;
	}
#endif
	drawtime=queryTime()-drawtime;
	WarpTrailDraw();

	GFXFogMode (FOG_OFF);

	GFXColor tmpcol (0,0,0,1);
	GFXGetLightContextAmbient(tmpcol);
	double processmesh=queryTime();
	if (!game_options.draw_near_stars_in_front_of_planets) stars->Draw();
	Mesh::ProcessZFarMeshes();
	if (game_options.draw_near_stars_in_front_of_planets) stars->Draw();

	GFXEnable (DEPTHTEST);
	GFXEnable (DEPTHWRITE);
	//need to wait for lights to finish
	GamePlanet::ProcessTerrains();
	Terrain::RenderAll();
	Mesh::ProcessUndrawnMeshes(true);
	processmesh=queryTime()-processmesh;
	Nebula * neb;

	Matrix ident;
	Identity(ident);

	//Atmosphere::ProcessDrawQueue();
	GFXPopGlobalEffects();
	GFXLightContextAmbient(tmpcol);

	if ((neb = _Universe->AccessCamera()->GetNebula())) {
		neb->SetFogState();
	}
	Beam::ProcessDrawQueue();
	Bolt::Draw();

	//  if (_Universe->AccessCamera()->GetNebula()!=NULL)
	GFXFogMode (FOG_OFF);
	Animation::ProcessDrawQueue();
	Halo::ProcessDrawQueue();
	particleTrail.DrawAndUpdate();
	GameStarSystem::DrawJumpStars();
	ConditionalCursorDraw(false);
	//  static bool doInputDFA = XMLSupport::parse_bool (vs_config->getVariable ("graphics","MouseCursor","false"));
	if (DrawCockpit) {
		_Universe->AccessCockpit()->Draw();
		//    if (doInputDFA) {
		//      GFXHudMode (true);
		//      systemInputDFA->Draw();
		//      GFXHudMode (false);
		//    }
	}
	double fintime=queryTime()-starttime;
	if (debugPerformance()) {
		printf("draw: %f setup %f units %f maxunit %f processmesh %f ",fintime,setupdrawtime,drawtime,maxdrawtime,processmesh);
	}
}