void CAOGenerator::GenerateByTexel() { if (m_eAOMethod == AOMETHOD_RAYTRACE) RaytraceSetupThreads(); float flTotalArea = 0; for (size_t m = 0; m < m_pScene->GetNumMeshes(); m++) { CConversionMesh* pMesh = m_pScene->GetMesh(m); for (size_t f = 0; f < pMesh->GetNumFaces(); f++) { CConversionFace* pFace = pMesh->GetFace(f); flTotalArea += pFace->GetUVArea(); } } raytrace::CRaytracer* pTracer = NULL; if (m_eAOMethod == AOMETHOD_RAYTRACE) { m_pWorkListener->SetAction("Building tree", 0); pTracer = new raytrace::CRaytracer(m_pScene); pTracer->AddMeshesFromNode(m_pScene->GetScene(0)); pTracer->BuildTree(); srand((unsigned int)time(0)); } if (m_eAOMethod == AOMETHOD_RAYTRACE && GetNumberOfProcessors() > 1) m_pWorkListener->SetAction("Dispatching jobs", (size_t)(flTotalArea*m_iWidth*m_iHeight)); else m_pWorkListener->SetAction("Rendering", (size_t)(flTotalArea*m_iWidth*m_iHeight)); size_t iRendered = 0; if (m_pScene->GetNumScenes()) GenerateNodeByTexel(m_pScene->GetScene(0), pTracer, iRendered); if (m_eAOMethod == AOMETHOD_RAYTRACE) { RaytraceJoinThreads(); RaytraceCleanupThreads(); delete pTracer; } }
void CTexelGenerator::Generate() { for (size_t i = 0; i < m_apMethods.size(); i++) m_apMethods[i]->PreGenerate(); if (m_pWorkListener) { m_pWorkListener->BeginProgress(); m_pWorkListener->SetAction("Building tree", 0); } if (SMAKWindow()) SMAKWindow()->ClearDebugLines(); memset(&m_abTexelMask[0], 0, m_iWidth*m_iHeight*sizeof(bool)); m_bIsGenerating = true; m_bStopGenerating = false; m_bDoneGenerating = false; raytrace::CRaytracer* pTracer = NULL; pTracer = new raytrace::CRaytracer(m_pScene); for (size_t m = 0; m < m_apHiRes.size(); m++) pTracer->AddMeshInstance(m_apHiRes[m]); pTracer->BuildTree(); m_pWorkParallelizer = new CParallelizer((JobCallback)::ComputeAtTexel); m_pWorkParallelizer->Start(); float flTotalArea = 0; for (size_t m = 0; m < m_pScene->GetNumMeshes(); m++) { CConversionMesh* pMesh = m_pScene->GetMesh(m); for (size_t f = 0; f < pMesh->GetNumFaces(); f++) { CConversionFace* pFace = pMesh->GetFace(f); flTotalArea += pFace->GetUVArea(); } } if (m_pWorkListener) m_pWorkListener->SetAction("Dispatching jobs", (size_t)(flTotalArea*m_iWidth*m_iHeight)); size_t iRendered = 0; tvector<Vector> avecPoints; tvector<size_t> aiPoints; for (size_t i = 0; i < m_apLoRes.size(); i++) { CConversionMeshInstance* pMeshInstance = m_apLoRes[i]; if (!pMeshInstance->GetMesh()->GetNumUVs()) continue; for (size_t f = 0; f < pMeshInstance->GetMesh()->GetNumFaces(); f++) { CConversionFace* pFace = pMeshInstance->GetMesh()->GetFace(f); if (pFace->m != ~0) { if (!pMeshInstance->GetMappedMaterial(pFace->m)->IsVisible()) continue; CConversionMaterial* pMaterial = m_pScene->GetMaterial(pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial); if (pMaterial && !pMaterial->IsVisible()) continue; } avecPoints.clear(); aiPoints.clear(); for (size_t t = 0; t < pFace->GetNumVertices(); t++) { avecPoints.push_back(pMeshInstance->GetVertex(pFace->GetVertex(t)->v)); aiPoints.push_back(t); } while (avecPoints.size() > 3) { size_t iEar = FindEar(avecPoints); size_t iLast = iEar==0?avecPoints.size()-1:iEar-1; size_t iNext = iEar==avecPoints.size()-1?0:iEar+1; GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[iLast], aiPoints[iEar], aiPoints[iNext], pTracer, iRendered); avecPoints.erase(avecPoints.begin()+iEar); aiPoints.erase(aiPoints.begin()+iEar); if (m_bStopGenerating) break; } GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[0], aiPoints[1], aiPoints[2], pTracer, iRendered); if (m_bStopGenerating) break; } if (m_bStopGenerating) break; } m_pWorkParallelizer->FinishJobs(); if (m_pWorkListener) m_pWorkListener->SetAction("Rendering", m_pWorkParallelizer->GetJobsTotal()); while (true) { if (m_pWorkParallelizer->AreAllJobsDone()) break; if (m_pWorkListener) m_pWorkListener->WorkProgress(m_pWorkParallelizer->GetJobsDone()); if (m_bStopGenerating) break; } delete m_pWorkParallelizer; delete pTracer; for (size_t i = 0; i < m_apMethods.size(); i++) m_apMethods[i]->PostGenerate(); if (!m_bStopGenerating) m_bDoneGenerating = true; m_bIsGenerating = false; // One last call to let them know we're done. if (m_pWorkListener) m_pWorkListener->EndProgress(); }