bool operator() (RoamTriangle *i, RoamTriangle *j) { Vector3 ic = i->incenter + center; Vector3 jc = j->incenter + center; double d = (double)sqrt_approx(cp.distanceSquared(ic)); double f = (double)sqrt_approx(cp.distanceSquared(jc)); double vd = i->calculateVisualError(d); double vf = j->calculateVisualError(f); return vd < vf; }
u32_t fs_bufs_heuristic(int minbufs, u32_t btotal, u32_t bfree, int blocksize, dev_t majordev) { struct vm_stats_info vsi; int bufs; u32_t kbytes_used_fs, kbytes_total_fs, kbcache, kb_fsmax; u32_t kbytes_remain_mem, bused; bused = btotal-bfree; /* but we simply need minbufs no matter what, and we don't * want more than that if we're a memory device */ if(majordev == MEMORY_MAJOR) { return minbufs; } /* set a reasonable cache size; cache at most a certain * portion of the used FS, and at most a certain %age of remaining * memory */ if((vm_info_stats(&vsi) != OK)) { bufs = 1024; printf("fslib: heuristic info fail: default to %d bufs\n", bufs); return bufs; } kbytes_remain_mem = div64u(mul64u(vsi.vsi_free, vsi.vsi_pagesize), 1024); /* check fs usage. */ kbytes_used_fs = div64u(mul64u(bused, blocksize), 1024); kbytes_total_fs = div64u(mul64u(btotal, blocksize), 1024); /* heuristic for a desired cache size based on FS usage; * but never bigger than half of the total filesystem */ kb_fsmax = sqrt_approx(kbytes_used_fs)*40; kb_fsmax = MIN(kb_fsmax, kbytes_total_fs/2); /* heuristic for a maximum usage - 10% of remaining memory */ kbcache = MIN(kbytes_remain_mem/10, kb_fsmax); bufs = kbcache * 1024 / blocksize; /* but we simply need MINBUFS no matter what */ if(bufs < minbufs) bufs = minbufs; return bufs; }
static u32_t fs_bufs_heuristic(int minbufs, u32_t btotal, u64_t bfree, int blocksize, dev_t majordev) { struct vm_stats_info vsi; int bufs; u32_t kbytes_used_fs, kbytes_total_fs, kbcache, kb_fsmax; u32_t kbytes_remain_mem; u64_t bused; bused = btotal-bfree; /* set a reasonable cache size; cache at most a certain * portion of the used FS, and at most a certain %age of remaining * memory */ if(vm_info_stats(&vsi) != OK) { bufs = 1024; if(!quiet) printf("fslib: heuristic info fail: default to %d bufs\n", bufs); return bufs; } /* remaining free memory is unused memory plus memory in used for cache, * as the cache can be evicted */ kbytes_remain_mem = (u64_t)(vsi.vsi_free + vsi.vsi_cached) * vsi.vsi_pagesize / 1024; /* check fs usage. */ kbytes_used_fs = (unsigned long)(((u64_t)bused * blocksize) / 1024); kbytes_total_fs = (unsigned long)(((u64_t)btotal * blocksize) / 1024); /* heuristic for a desired cache size based on FS usage; * but never bigger than half of the total filesystem */ kb_fsmax = sqrt_approx(kbytes_used_fs)*40; kb_fsmax = MIN(kb_fsmax, kbytes_total_fs/2); /* heuristic for a maximum usage - 10% of remaining memory */ kbcache = MIN(kbytes_remain_mem/10, kb_fsmax); bufs = kbcache * 1024 / blocksize; /* but we simply need MINBUFS no matter what */ if(bufs < minbufs) bufs = minbufs; return bufs; }
bool RoamSphere::update(Vector3 cp, Vector3 la, Frustum frustum) { // TODO: fix visualError such that it return 0 if the triangle is behind the camera, even if it is microns away from the camera. Vector3 ncp; bool ret = false; if (splitQueue == NULL) { splitQueue = new std::list<RoamTriangle *>(); } if (mergeQueue == NULL) { mergeQueue = new std::list<RoamTriangle *>(); } if (cameraNode != NULL) { for (std::list<RoamTriangle*>::iterator i = triangles->begin(); i != triangles->end(); i++) { bool isIn = false; RoamTriangle *t = *i; Vector3 ic = t->incenter + center; double d = (double)sqrt_approx(cp.distanceSquared(ic)); double ve = t->calculateVisualError(d); if (frustrumContains(frustum, ic) && angle3Points(cp, ic, center) && ve > maxVisualError) { splitQueue->push_back(t); } else { mergeQueue->push_back(t); } } } splitSorter s; s.cp = cp; s.center = center; splitQueue->sort(s); #ifdef DEBUG assert(confirmAllVertices()); #endif int currentSize = triangles->size(); Frustum frustrum = cameraNode->getCamera()->getFrustum(); if (maxTriangles == 0) maxTriangles = MAX_TRIANGLES; while (triangles->size() < maxTriangles && splitQueue->size() > 0) { ret = true; RoamTriangle *t = splitQueue->front(); split(t); } splitQueue->clear(); mergeQueue->sort(s); mergeQueue->reverse(); while (mergeQueue->size() > 0) { ret = true; RoamTriangle *t = mergeQueue->front(); if (t == NULL) { mergeQueue->pop_front(); continue; } Vector3 ic = t->incenter + center; double d = (double)sqrt_approx(cp.distanceSquared(ic)); double ve = t->calculateVisualError(d); if (ve > minVisualError) break; if (t->diamond != NULL && t->isInDiamond()) merge(t->diamond); else mergeQueue->pop_front(); } mergeQueue->clear(); return ret; }
void RoamSphere::merge(RoamDiamond *d) { RoamTriangle *t, *n, *o, *p; t = d->parent[0]; n = d->child[0]; o = d->parent[1]; p = d->child[1]; #ifdef DEBUG assert(n->parent == t); assert(t->child == n); assert(t->edge1->equals(n)); assert(n->edge2->equals(t)); assert(p->parent == o); assert(o->child == p); assert(o->edge1->equals(p)); assert(p->edge2->equals(o)); assert(t->vertexes[0] == n->vertexes[0]); assert(n->vertexes[0] == p->vertexes[0]); assert(o->vertexes[0] == p->vertexes[0]); assert(t->confirmVertex(n, 1)); assert(o->confirmVertex(p, 1)); assert(t->size == n->size); assert(o->size == p->size); #endif // DEBUG t->child = NULL; o->child = NULL; t->midpoint = sterrain(t->vertexes[0]); o->midpoint = sterrain(t->vertexes[0]); sterrain mp = sterrain((t->vertexes[1] + t->vertexes[2])/2.0); sterrain a = t->midpoint; double error = sqrt_approx(mp.distanceSquared(a)); error *= radius; t->error = error; o->error = error; t->size--; o->size--; t->setEdges(o, t->edge0, n->edge0); t->vertexes[0] = n->vertexes[1]; assert(t->vertexes[0] == t->vertexes[2]); t->vertexes[2] = t->vertexes[1]; t->vertexes[1] = n->vertexes[2]; o->setEdges(t, o->edge0, p->edge0); o->vertexes[0] = p->vertexes[1]; assert(o->vertexes[0] == o->vertexes[2]); o->vertexes[2] = o->vertexes[1]; o->vertexes[1] = p->vertexes[2]; // update the edges... RoamTriangle *e0 = n->edge0; if (e0->edge0->equals(n)) { e0->edge0 = t; } else if (e0->edge1->equals(n)) { e0->edge1 = t; } else if (e0->edge2->equals(n)) { e0->edge2 = t; } else assert(false); e0 = p->edge0; if (e0->edge0->equals(p)) { e0->edge0 = o; } else if (e0->edge1->equals(p)) { e0->edge1 = o; } else if (e0->edge2->equals(p)) { e0->edge2 = o; } else assert(false); #ifdef DEBUG assert(t->edge1->edge0->equals(t) || t->edge1->edge1->equals(t) || t->edge1->edge2->equals(t)); assert(o->edge1->edge0->equals(o) || o->edge1->edge1->equals(o) || o->edge1->edge2->equals(o)); assert(t->edge2->edge0->equals(t) || t->edge2->edge1->equals(t) || t->edge2->edge2->equals(t)); assert(o->edge2->edge0->equals(o) || o->edge2->edge1->equals(o) || o->edge2->edge2->equals(o)); assert(t->edge0->edge0->equals(t)); assert(o->edge0->edge0->equals(o)); assert(t->vertexes[1] == o->vertexes[2]); assert(o->vertexes[1] == t->vertexes[2]); assert(t->midpoint == o->midpoint); assert(t->confirmVertex(t->edge0, 0)); assert(t->confirmVertex(t->edge1, 1)); assert(t->confirmVertex(t->edge2, 2)); assert(o->confirmVertex(o->edge0, 0)); assert(o->confirmVertex(o->edge1, 1)); assert(o->confirmVertex(o->edge2, 2)); assert(!n->containsEdge()); assert(!p->containsEdge()); assert(n->vertexes[1] == t->vertexes[0]); assert(p->vertexes[1] == o->vertexes[0]); #endif // DEBUG triangles->remove(n); triangles->remove(p); mergeQueue->remove(n); mergeQueue->remove(p); mergeQueue->remove(t); mergeQueue->remove(o); removeDiamond(d); delete d; delete n; delete p; d = NULL; n = NULL; p = NULL; if (t->isInDiamond()) RoamDiamond *d = createDiamond(t); if (o->isInDiamond()) RoamDiamond *d = createDiamond(o); }
void RoamSphere::split(RoamTriangle *t) { if (t->size == maxDepth) return; if (!t->edge0->edge0->equals(t)) {// if o is NOT the neighbor... split(t->edge0); } RoamTriangle *o = t->edge0; #ifdef DEBUG assert(t->vertexes[1] == o->vertexes[2]); assert(t->vertexes[2] == o->vertexes[1]); #endif RoamTriangle *n = new RoamTriangle(t, ++t->size, id++); RoamTriangle *p = new RoamTriangle(o, ++o->size, id++); /* t->error /= 2.0f; o->error /= 2.0f; n->error = t->error; p->error = o->error; */ // update position t->midpoint = sterrain((t->vertexes[1] + t->vertexes[2])/2.0); sterrain a = t->midpoint; sterrain mp = body->terrainAlgorithm(t->midpoint, (float)t->size); double error = sqrt_approx(mp.distanceSquared(a)); error *= radius; t->error = error; o->error = error; n->error = error; p->error = error; sterrain t_0 = sterrain(t->vertexes[0]); sterrain t_1 = sterrain(t->vertexes[1]); sterrain t_2 = sterrain(t->vertexes[2]); sterrain o_0 = sterrain(o->vertexes[0]); sterrain o_1 = sterrain(o->vertexes[1]); sterrain o_2 = sterrain(o->vertexes[2]); #ifdef DEBUG assert(o_1 == t_2); assert(o_2 == t_1); #endif t->setPosition(mp, t_2, t_0); n->setPosition(mp, t_0, t_1); o->setPosition(mp, o_2, o_0); p->setPosition(mp, o_0, o_1); // reset edges. RoamTriangle *t_e1 = t->edge1; RoamTriangle *t_e2 = t->edge2; #ifdef DEBUG assert(t_e1 != NULL); assert(t_e2 != NULL); #endif RoamTriangle *o_e1 = o->edge1; RoamTriangle *o_e2 = o->edge2; #ifdef DEBUG assert(o_e1 != NULL); assert(o_e2 != NULL); #endif t->setEdges(t_e1, n, p); n->setEdges(t_e2, o, t); #ifdef DEBUG assert(t->confirmVertex(t_e1, 0)); assert(t->confirmVertex(n, 1)); assert(t->confirmVertex(p, 2)); assert(n->confirmVertex(t_e2, 0)); assert(n->confirmVertex(o, 1)); assert(n->confirmVertex(t, 2)); #endif if (t_e2->edge0->equals(t)) { t_e2->edge0 = n; } else if (t_e2->edge1->equals(t)) { t_e2->edge1 = n; } else if (t_e2->edge2->equals(t)) { t_e2->edge2 = n; } else assert(false); o->setEdges(o_e1, p, n); p->setEdges(o_e2, t, o); #ifdef DEBUG assert(o->confirmVertex(o_e1, 0)); assert(o->confirmVertex(p, 1)); assert(o->confirmVertex(n, 2)); assert(p->confirmVertex(o_e2, 0)); assert(p->confirmVertex(t, 1)); assert(p->confirmVertex(o, 2)); #endif if (o_e2->edge0->equals(o)) { o_e2->edge0 = p; } else if (o_e2->edge1->equals(o)) { o_e2->edge1 = p; } else if (o_e2->edge2->equals(o)) { o_e2->edge2 = p; } else assert(false); if (t->isInDiamond() && t->diamond != NULL) removeDiamond(t->diamond); if (o->isInDiamond() && o->diamond != NULL) removeDiamond(o->diamond); RoamDiamond *d = createDiamond(t); #ifdef DEBUG assert(d != NULL); #endif triangles->push_back(n); triangles->push_back(p); splitQueue->remove(t); splitQueue->remove(o); Vector3 cp = cameraNode->getTranslationWorld(); Frustum frustum = cameraNode->getCamera()->getFrustum(); Vector3 ic = n->incenter + center; double err = (double)sqrt_approx(cp.distanceSquared(ic)); double ve = t->calculateVisualError(err); if (frustrumContains(frustum, ic) && angle3Points(cp, ic, center) && ve > maxVisualError) { splitQueue->push_back(n); } ic = p->incenter + center; err = (double)sqrt_approx(cp.distanceSquared(ic)); ve = t->calculateVisualError(err); if (frustrumContains(frustum, ic) && angle3Points(cp, ic, center) && ve > maxVisualError) { splitQueue->push_back(p); } }