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; }
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; }
//--------------------------------------------------------------------------- void __fastcall TfrmEditLightAnim::FormCloseQuery(TObject *Sender, bool &CanClose) { if (!bFinalClose) CanClose = IsClose(); else CanClose = true; }