示例#1
0
void SimState::run() {
	
	double simStartTime;
	double simCurrentTime;
	double timeDif;
	double previousFrameStart = glfwGetTime();
	double deltaT;

	while (!shouldStopStateLoop) {
		simStartTime = glfwGetTime();
		deltaT = simStartTime - previousFrameStart;
		
		updateSim(deltaT);

		//main thread only
		glfwPollEvents();
		keyOps();

		//clamp rate
		simCurrentTime = glfwGetTime();
		timeDif = simCurrentTime - simStartTime;
		if (SIM_TIME > timeDif) {
			std::chrono::milliseconds duration((int)((SIM_TIME - timeDif) * 1000));
			std::this_thread::sleep_for(duration);
		}

		previousFrameStart = simStartTime;

		updateUpdateThreadState();

		//std::cout << "sim step" << std::endl;

		//pausing
		if (shouldPause) {
			//wait for the second thread to signal that it has completed a step and is pausing
			std::unique_lock<std::mutex> l(secondThreadDoneLock);
			secondShouldPause = true;
			while (!secondThreadDone) {
				secondThreadIsDone.wait(l);
			}

			glfwMakeContextCurrent(window);
			nonifyKeys();
			//std::cout << "pausing done" << std::endl;
		}
	}
}
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), d_numViewPorts(0)
{
    d_qSimTimer = new QTimer(this);
    connect(d_qSimTimer, SIGNAL(timeout()), this, SLOT(updateSim()));

    d_qDrawTimer = new QTimer(this);
    connect(d_qDrawTimer, SIGNAL(timeout()), this, SLOT(drawViewPorts()));
    d_qDrawTimer->start(30);

    QDockWidget *dock = new QDockWidget("Simulation Commands", this);
    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);

    // Create the simulation control buttons
    Button *startButton = createButton(tr("Start"), SLOT(startSim()));
    Button *stopButton = createButton(tr("Stop"), SLOT(stopSim()));
    Button *initButton = createButton(tr("Initialize"), SLOT(initializeSim()));

    QGroupBox *controlGroupBox = new QGroupBox(tr("Simulation Control"));
    QVBoxLayout *vControlBox = new QVBoxLayout;
    vControlBox->addWidget(startButton);
    vControlBox->addWidget(stopButton);
    vControlBox->addWidget(initButton);
    vControlBox->addStretch(1);
    controlGroupBox->setLayout(vControlBox);
    mainLayout->addWidget(controlGroupBox, 0, 0);

    // Add other buttons here

    // Add the mainlayout to the dock widget
    QWidget *wi = new QWidget;
    wi->setLayout(mainLayout);
    dock->setWidget(wi);
    addDockWidget(Qt::LeftDockWidgetArea, dock);

    setWindowTitle("Cloth Simulation");

    d_cloth = new C_Cloth();
    d_cloth->initialize(10.0f, 10.0f, 30, 30, 200, 550.0, 400.0, 0.005, ZAXIS);
    d_cloth->lockParticle(0, 0);
    d_cloth->lockParticle(0, 19);
    d_cloth->setGravity(vector3f(0.0, -32.0, 0));
}
示例#3
0
void CcustomSim::beforeEnd(double newTime) {
   updateSim(newTime);
}
示例#4
0
void CcustomSim::beforeMiddle(double newTime) {
   updateSim(newTime);
}
示例#5
0
/*******************************************************************
  Submits all relevant run information to the run table
*******************************************************************/
bool commitSimulation( Simulation* s )
{
	// do nothing if database is not configured
	if( DB::connectionInfo.dbname == "" ){
		return true;
	}

	// set up thread-dependent db connection
	QSqlDatabase* db;
	dbLock.lock();
	if( !dbStore.contains(QThread::currentThreadId()) ){
		db = new QSqlDatabase();
		*db = QSqlDatabase::addDatabase("QMYSQL", QString::number(QThread::currentThreadId()));
		db->setHostName(DB::connectionInfo.host);
		db->setDatabaseName(DB::connectionInfo.dbname);
		db->setUserName(DB::connectionInfo.user);
		db->setPassword(DB::connectionInfo.password);
		dbStore.insert(QThread::currentThreadId(), db);

		// make sure the database exists and the credentials are good
		if( !db->open() ){
			qCritical() << "Could not open database";
			return false;
		}
	}
	else {
		db = dbStore[QThread::currentThreadId()];
	}
	dbLock.unlock();

	// prepare queries
	QSqlQuery testState(*db), addState(*db), addSim(*db), updateSim(*db);
	QSqlQuery addLoop(*db), incrementLoop(*db), termLoopFromState(*db);

	testState.prepare(
		"SELECT COUNT(state_def) AS count, loop_id, sim_id FROM states "
		"WHERE state_def=:id;");
	addState.prepare(
		"INSERT INTO states (state_def, next_state, stepnum, sim_id, loop_id) "
		"VALUES (:statedef, :nextstate, :stepnum, :simid, :loopid);");
	addSim.prepare(
		"INSERT INTO simulations (sim_id, length) VALUES (:simid, :length);");
	updateSim.prepare(
		"UPDATE simulations SET final_state=:final, term_loop_id=:termloopid "
		"WHERE sim_id=:id;");
	addLoop.prepare(
		"INSERT INTO loops (loop_id, length, instance_cnt) "
		"VALUES (:loopid, :length, 0);");
	incrementLoop.prepare(
		"UPDATE loops SET instance_cnt=instance_cnt+1 WHERE loop_id=:id;");
	termLoopFromState.prepare(
		"SELECT simulations.term_loop_id AS termloop FROM states JOIN simulations "
		"ON states.sim_id=simulations.sim_id WHERE states.state_def=:id;");

	State* i;
	State* initial = s->getInitialState();
	ull loopState = 0;
	bool loopFlag = false;

	// make sure the simulation has been run
	if( initial == NULL || initial->next == NULL ){
		qCritical() << "Cannot commit an incomplete simulation.";
		return false;
	}

	// lock simulation
	//QMutexLocker locker( &DB::simLock );

	// start transaction
	db->transaction();

	// loop over states
	for( i = initial; i!=NULL; i = i->next )
	{
		// check if current state is in the db
		testState.bindValue( ":id", QVariant(i->pack()) );
		if( !testState.exec() ){
			qCritical() << "Cannot query state table!" << endl
				<< testState.lastError().text();
			db->rollback();
			return false;
		}
		testState.first();

		// if state IS NOT in db
		if( testState.record().value("count").toInt() == 0 )
		{
			// initial state is fresh
			if( i == initial )
			{
				// commit new simulation entry
				addSim.bindValue(":simid", QVariant(initial->pack()));
				addSim.bindValue(":length", QVariant(s->getTotalLength()));
				if( !addSim.exec() ){
					qCritical() << "Cannot add new simulation to database!" << endl
						<< addSim.lastError().text();
					db->rollback();
					return false;
				}
			}

			// state is the start of the loop
			if( *i == *(s->getLoopState()) )
			{
				// set the loop id flag for future commits
				loopFlag = true;
				loopState = i->pack();

				// create new entry in the loop table
				addLoop.bindValue(":id", QVariant(loopState));
				addLoop.bindValue(":length", QVariant(s->getLoopLength()));
				if( !addLoop.exec() ){
					qCritical() << "Cannot add new loop to database!" << endl
						<< addLoop.lastError().text();
					db->rollback();
					return false;
				}

			}

			// commit state to db
			addState.bindValue(":statedef", QVariant(i->pack()));
			addState.bindValue(":nextstate", QVariant(i->next->pack()));
			addState.bindValue(":stepnum", QVariant(i->stepNum));
			addState.bindValue(":simid", QVariant(initial->pack()));
			addState.bindValue(":loopid", loopFlag ? QVariant(loopState) : QVariant() );
			if( !addState.exec() ){
				qCritical() << "Cannot add new state to database!" << endl
					<< addState.lastError().text();
				db->rollback();
				return false;
			}
		}

		// state IS in db
		else
		{
			// initial state has already been checked
			if( i == initial )
			{
				// our work here is done
				db->rollback();
				return true;
			}

			// get the db state's loop id
			ull termLoop = 0;
			if( testState.record().value("loop_id").isNull() )
			{
				// join a non-loop state
				termLoopFromState.bindValue(":id", QVariant(i->pack()));
				if( !termLoopFromState.exec() ){
					qCritical() << "Cannot retrieve terminal loop from state!" << endl
						<< termLoopFromState.lastError().text();
					db->rollback();
					return false;
				}
				termLoop = termLoopFromState.record().value("termloop").toLongLong();
			}
			else
			{
				// join a loop state
				termLoop = testState.record().value("loop_id").toLongLong();
			}

			// update simulation table with merger point and term loop id
			updateSim.bindValue(":final", QVariant(i->pack()));
			updateSim.bindValue(":termloopid", QVariant(termLoop));
			updateSim.bindValue(":id", QVariant(initial->pack()));
			if( !updateSim.exec() ){
				qCritical() << "Cannot update sim with terminal info!" << endl
					<< updateSim.lastError().text();
				db->rollback();
				return false;
			}

			// increment term loop instance count
			incrementLoop.bindValue(":id", termLoop);
			if( !incrementLoop.exec() ){
				qCritical() << "Cannot increment loop instance count!" << endl
					<< incrementLoop.lastError().text();
				db->rollback();
				return false;
			}

			// default case: break, complete the transaction, return true
			// includes self-looping state case
			break;

		} // end state presence branch

	} // end state loop


	// commit transaction
	db->commit();

	// unlock simulation
	//locker.unlock();

	return true;
}