void updateEdgeLevels(ISPCScene* scene_in, const Vec3fa& cam_pos) { /* first update small meshes */ #if defined(ISPC) parallel_for(size_t(0),size_t( scene_in->numGeometries ),[&](const range<size_t>& range) { const int threadIndex = (int)TaskScheduler::threadIndex(); for (size_t i=range.begin(); i<range.end(); i++) updateMeshEdgeLevelBufferTask((int)i,threadIndex,scene_in,cam_pos); }); #endif /* now update large meshes */ for (size_t g=0; g<scene_in->numGeometries; g++) { ISPCGeometry* geometry = g_ispc_scene->geometries[g]; if (geometry->type != SUBDIV_MESH) continue; ISPCSubdivMesh* mesh = (ISPCSubdivMesh*) geometry; #if defined(ISPC) if (mesh->numFaces < 10000) continue; parallel_for(size_t(0),size_t( (mesh->numFaces+4095)/4096 ),[&](const range<size_t>& range) { const int threadIndex = (int)TaskScheduler::threadIndex(); for (size_t i=range.begin(); i<range.end(); i++) updateSubMeshEdgeLevelBufferTask((int)i,threadIndex,mesh,cam_pos); }); #else updateEdgeLevelBuffer(mesh,cam_pos,0,mesh->numFaces); #endif rtcUpdateBuffer(g_scene,mesh->geom.geomID,RTC_LEVEL_BUFFER); } }
void updateMeshEdgeLevelBufferTask (int taskIndex, int threadIndex, ISPCScene* scene_in, const Vec3fa& cam_pos ) { ISPCGeometry* geometry = g_ispc_scene->geometries[taskIndex]; if (geometry->type != SUBDIV_MESH) return; ISPCSubdivMesh* mesh = (ISPCSubdivMesh*) geometry; unsigned int geomID = mesh->geom.geomID; if (mesh->numFaces < 10000) { updateEdgeLevelBuffer(mesh,cam_pos,0,mesh->numFaces); rtcUpdateBuffer(g_scene,mesh->geom.geomID,RTC_LEVEL_BUFFER); } }
/*! updates the tessellation level for each edge */ void updateEdgeLevelBuffer( RTCScene scene_i, unsigned geomID, const Vec3fa& cam_pos ) { float* level = (float* ) rtcMapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); int* faces = (int* ) rtcMapBuffer(scene_i, geomID, RTC_INDEX_BUFFER); Vec3fa* vertices = (Vec3fa*) rtcMapBuffer(scene_i, geomID, RTC_VERTEX_BUFFER); for (size_t f=0; f<NUM_FACES; f++) { for (size_t i=0; i<FACE_SIZE; i++) { const Vec3fa v0 = Vec3fa(vertices[faces[FACE_SIZE*f+(i+0)%FACE_SIZE]]); const Vec3fa v1 = Vec3fa(vertices[faces[FACE_SIZE*f+(i+1)%FACE_SIZE]]); const float l = LEVEL_FACTOR*length(v1-v0)/length(cam_pos-0.5f*(v1+v0)); level[FACE_SIZE*f+i] = max(min(l,MAX_EDGE_LEVEL),MIN_EDGE_LEVEL); } } rtcUnmapBuffer(scene_i, geomID, RTC_VERTEX_BUFFER); rtcUnmapBuffer(scene_i, geomID, RTC_INDEX_BUFFER); rtcUnmapBuffer(scene_i, geomID, RTC_LEVEL_BUFFER); rtcUpdateBuffer(scene_i,geomID,RTC_LEVEL_BUFFER); }
extern "C" void ispcUpdateBuffer (RTCScene scene, unsigned geomID, RTCBufferType type) { rtcUpdateBuffer(scene,geomID,type); }