Example #1
0
	Int32 Quadratic( Real x2, Real x, Real k, Real roots[2] )
	{
		if( IsZero( x2 ) )
			return Linear( x, k, roots );

		Real d = x * x - 4 * x2 * k;
		if( IsClose( d, 0.0f ) )
		{
			roots[0] = roots[1] = -x / ( 2 * x2 );
			return 1;	// One Root
		}
		else if( d > 0.0f )
		{
			Real fSqrD = SQRT( d );
			Real f2A = 2.0f * x2;
			roots[0] = ( -x + fSqrD ) / f2A;
			roots[1] = ( -x - fSqrD ) / f2A;
			return 2;	// Two Roots
		}
		return 0;
	}
int BroadCollisionStrategy::Calculate(
	int nLayer, 
	Player * player, 
	Stack * stack,
	list<Space *> * retVal)
{
	int numLayers = stack->GetNumLayers();

	std::vector<Space *>::const_iterator iterator;

	for (iterator = stack->Get(nLayer)->GetSpaces()->begin();
		iterator != stack->Get(nLayer)->GetSpaces()->end();
		iterator++)
	{
		if (IsClose(player, *(iterator)))
		{
			retVal->push_back(*(iterator));
		}
	}

	return 1;
}
Example #3
0
bool FractoriumEmberController<T>::Render()
{
	m_Rendering = true;

	bool success = true;
	GLWidget* gl = m_Fractorium->ui.GLDisplay;
	RendererCL<T, float>* rendererCL = nullptr;
	eProcessAction qualityAction, action;

	//Quality is the only parameter we update inside the timer.
	//This is to allow the user to rapidly increase the quality spinner
	//without fully resetting the render. Instead, it will just keep iterating
	//where it last left off in response to an increase.
	T d = T(m_Fractorium->m_QualitySpin->value());

	if (d < m_Ember.m_Quality)//Full restart if quality decreased.
	{
		m_Ember.m_Quality = d;
		qualityAction = eProcessAction::FULL_RENDER;
	}
	else if (d > m_Ember.m_Quality && ProcessState() == ACCUM_DONE)//If quality increased, keep iterating after current render finishes.
	{
		m_Ember.m_Quality = d;
		qualityAction = eProcessAction::KEEP_ITERATING;
	}
	else if (IsClose(d, m_Ember.m_Quality))
		qualityAction = eProcessAction::NOTHING;

	if (qualityAction == eProcessAction::FULL_RENDER)
		Update([&] {});//Stop the current render, a full restart is needed.
	else if (qualityAction == eProcessAction::KEEP_ITERATING)
		m_ProcessActions.push_back(qualityAction);//Special, direct call to avoid resetting the render inside Update() because only KEEP_ITERATING is needed.

	action = CondenseAndClearProcessActions();//Combine with all other previously requested actions.

	if (m_Renderer->RendererType() == OPENCL_RENDERER)
		rendererCL = dynamic_cast<RendererCL<T, float>*>(m_Renderer.get());

	//Force temporal samples to always be 1. Perhaps change later when animation is implemented.
	m_Ember.m_TemporalSamples = 1;

	//Take care of solo xforms and set the current ember and action.
	if (action != NOTHING)
	{
		int i, solo = m_Fractorium->ui.CurrentXformCombo->property("soloxform").toInt();

		if (solo != -1)
		{
			m_TempOpacities.resize(m_Ember.TotalXformCount());

			for (i = 0; i < m_Ember.TotalXformCount(); i++)
			{
				m_TempOpacities[i] = m_Ember.GetTotalXform(i)->m_Opacity;
				m_Ember.GetTotalXform(i)->m_Opacity = i == solo ? 1 : 0;
			}
		}

		m_Renderer->SetEmber(m_Ember, action);

		if (solo != -1)
		{
			for (i = 0; i < m_Ember.TotalXformCount(); i++)
			{
				m_Ember.GetTotalXform(i)->m_Opacity = m_TempOpacities[i];
			}
		}
	}

	//Ensure sizes are equal and if not, update dimensions.
	if (SyncSizes())
	{
		action = FULL_RENDER;
		return true;
	}

	//Determining if a completely new rendering process is being started.
	bool iterBegin = ProcessState() == NONE;

	if (iterBegin)
	{
		if (m_Renderer->RendererType() == CPU_RENDERER)
			m_SubBatchCount = m_Fractorium->m_Settings->CpuSubBatch();
		else if (m_Renderer->RendererType() == OPENCL_RENDERER)
			m_SubBatchCount = m_Fractorium->m_Settings->OpenCLSubBatch();

		m_Fractorium->m_ProgressBar->setValue(0);
		m_Fractorium->m_RenderStatusLabel->setText("Starting");
	}

	//If the rendering process hasn't finished, render with the current specified action.
	if (ProcessState() != ACCUM_DONE)
	{
		//if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging.
		if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, (iterBegin || m_Fractorium->m_Settings->ContinuousUpdate())) == RENDER_OK)//Force output on iterBegin or if the settings specify to always do it.
		{
			//The amount to increment sub batch while rendering proceeds is purely empirical.
			//Change later if better values can be derived/observed.
			if (m_Renderer->RendererType() == OPENCL_RENDERER)
			{
				if (m_SubBatchCount < (4 * m_Devices.size()))//More than 3 with OpenCL gives a sluggish UI.
					m_SubBatchCount += m_Devices.size();
			}
			else
			{
				if (m_SubBatchCount < 5)
					m_SubBatchCount++;
				else if (m_SubBatchCount < 105)//More than 105 with CPU gives a sluggish UI.
					m_SubBatchCount += 25;
			}

			//Rendering has finished, update final stats.
			if (ProcessState() == ACCUM_DONE)
			{
				EmberStats stats = m_Renderer->Stats();
				QString iters = ToString<qulonglong>(stats.m_Iters);
				QString scaledQuality = ToString(uint(m_Renderer->ScaledQuality()));
				string renderTime = m_RenderElapsedTimer.Format(m_RenderElapsedTimer.Toc());

				m_Fractorium->m_ProgressBar->setValue(100);

				//Only certain stats can be reported with OpenCL.
				if (m_Renderer->RendererType() == OPENCL_RENDERER)
				{
					m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Total time: " + QString::fromStdString(renderTime) + ".");
				}
				else
				{
					double percent = double(stats.m_Badvals) / double(stats.m_Iters);
					QString badVals = ToString<qulonglong>(stats.m_Badvals);
					QString badPercent = QLocale::system().toString(percent * 100, 'f', 2);

					m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Bad values: " + badVals + " (" + badPercent + "%). Total time: " + QString::fromStdString(renderTime) + ".");
				}
				
				if (m_LastEditWasUndoRedo && (m_UndoIndex == m_UndoList.size() - 1))//Traversing through undo list, reached the end, so put back in regular edit mode.
				{
					m_EditState = REGULAR_EDIT;
				}
				else if (m_EditState == REGULAR_EDIT)//Regular edit, just add to the end of the undo list.
				{
					m_UndoList.push_back(m_Ember);
					m_UndoIndex = m_UndoList.size() - 1;
					m_Fractorium->ui.ActionUndo->setEnabled(m_UndoList.size() > 1);
					m_Fractorium->ui.ActionRedo->setEnabled(false);

					if (m_UndoList.size() >= UNDO_SIZE)
						m_UndoList.pop_front();
				}
				else if (!m_LastEditWasUndoRedo && m_UndoIndex < m_UndoList.size() - 1)//They were anywhere but the end of the undo list, then did a manual edit, so clear the undo list.
				{
					Ember<T> ember(m_UndoList[m_UndoIndex]);

					ClearUndo();
					m_UndoList.push_back(ember);
					m_UndoList.push_back(m_Ember);
					m_UndoIndex = m_UndoList.size() - 1;
					m_Fractorium->ui.ActionUndo->setEnabled(true);
					m_Fractorium->ui.ActionRedo->setEnabled(false);
				}

				m_LastEditWasUndoRedo = false;
				m_Fractorium->UpdateHistogramBounds();//Mostly of engineering interest.
				FillSummary();//Only update summary on render completion since it's not the type of thing the user needs real-time updates on.
			}
			
			//Update the GL window on start because the output will be forced.
			//Update it on finish because the rendering process is completely done.
			if (iterBegin || ProcessState() == ACCUM_DONE)
			{
				if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed.
					gl->update();
					//gl->repaint();
				
				//m_Fractorium->update();
				//m_Fractorium->ui.GLParentScrollArea->update();
				//Uncomment for debugging kernel build and execution errors.
				//m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo()));
				//if (rendererCL)
				//{
				//	string s = "OpenCL Kernels: \r\n" + rendererCL->IterKernel() + "\r\n" + rendererCL->DEKernel() + "\r\n" + rendererCL->FinalAccumKernel();
				//
				//	QMetaObject::invokeMethod(m_Fractorium->ui.InfoRenderingTextEdit, "setText", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(s)));
				//}
			}
		}
		else//Something went very wrong, show error report.
		{
			vector<string> errors = m_Renderer->ErrorReport();
			
			success = false;
			m_FailedRenders++;
			m_Fractorium->m_RenderStatusLabel->setText("Rendering failed, see info tab. Try changing parameters.");
			m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoRenderingTextEdit);
			m_Renderer->ClearErrorReport();
		
			if (m_FailedRenders >= 3)
			{
				m_Rendering = false;
				StopRenderTimer(true);
				m_Fractorium->m_RenderStatusLabel->setText("Rendering failed 3 or more times, stopping all rendering, see info tab. Try changing renderer types.");
				ClearFinalImages();
				m_GLController->ClearWindow();

				if (rendererCL)
				{
					//string s = "OpenCL Kernels: \r\n" + rendererCL->IterKernel() + "\r\n" + rendererCL->DEKernel() + "\r\n" + rendererCL->FinalAccumKernel();

					rendererCL->ClearFinal();
					//QMetaObject::invokeMethod(m_Fractorium->ui.InfoRenderingTextEdit, "setText", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(s)));
				}
			}
		}
	}
	
	//Upon finishing, or having nothing to do, rest.
	if (ProcessState() == ACCUM_DONE)
		QThread::msleep(1);
		//QApplication::processEvents();

	m_Rendering = false;
	return success;
}
Example #4
0
//---------------------------------------------------------------------------
void __fastcall TfrmEditLightAnim::FormCloseQuery(TObject *Sender,
      bool &CanClose)
{
	if (!bFinalClose) 	CanClose	= IsClose();
    else                CanClose	= true;
}