void CAOGenerator::GenerateNodeByTexel(CConversionSceneNode* pNode, raytrace::CRaytracer* pTracer, size_t& iRendered) { for (size_t c = 0; c < pNode->GetNumChildren(); c++) GenerateNodeByTexel(pNode->GetChild(c), pTracer, iRendered); for (size_t m = 0; m < pNode->GetNumMeshInstances(); m++) { CConversionMeshInstance* pMeshInstance = pNode->GetMeshInstance(m); CConversionMesh* pMesh = pMeshInstance->GetMesh(); if (!pMesh->GetNumUVs()) continue; for (size_t f = 0; f < pMesh->GetNumFaces(); f++) { CConversionFace* pFace = pMesh->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; } tvector<Vector> avecPoints; tvector<size_t> aiPoints; 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; } }
void CAOGenerator::ShadowMapSetupSceneNode(CConversionSceneNode* pNode, tvector<float>& aflVerts, bool bDepth) { if (!pNode) return; for (size_t c = 0; c < pNode->GetNumChildren(); c++) ShadowMapSetupSceneNode(pNode->GetChild(c), aflVerts, bDepth); for (size_t m = 0; m < pNode->GetNumMeshInstances(); m++) { CConversionMeshInstance* pMeshInstance = pNode->GetMeshInstance(m); CConversionMesh* pMesh = pMeshInstance->GetMesh(); for (size_t f = 0; f < pMesh->GetNumFaces(); f++) { CConversionFace* pFace = pMesh->GetFace(f); if (!bDepth) { // Allow this in the depth model so that it still projects a shadow, but we don't produce a map for it. if (pFace->m != ~0 && pMeshInstance->GetMappedMaterial(pFace->m)) { if (!pMeshInstance->GetMappedMaterial(pFace->m)->IsVisible()) continue; CConversionMaterial* pMaterial = m_pScene->GetMaterial(pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial); if (pMaterial && !pMaterial->IsVisible()) continue; } } CConversionVertex* pVertex0 = pFace->GetVertex(0); for (size_t k = 2; k < pFace->GetNumVertices(); k++) { CConversionVertex* pVertex1 = pFace->GetVertex(k-1); CConversionVertex* pVertex2 = pFace->GetVertex(k); AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex0->v), pMeshInstance->GetNormal(pVertex0->vn), pMesh->GetUV(pVertex0->vu)); AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex1->v), pMeshInstance->GetNormal(pVertex1->vn), pMesh->GetUV(pVertex1->vu)); AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex2->v), pMeshInstance->GetNormal(pVertex2->vn), pMesh->GetUV(pVertex2->vu)); } } } }
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(); }