Beispiel #1
0
void leafpushdown(Leaf *leaf, unsigned int depth)
{
  float xmid = halfway(leaf->extents.xmin, leaf->extents.xmax);
  float ymid = halfway(leaf->extents.ymin, leaf->extents.ymax);

  Qnode *newnode = calloc(1, sizeof(Qnode));
  if(newnode) {
    LeafData *cur = leaf->contents.payload;
    
    newnode->depth = depth;
    
    newnode->ul.extents = BUILD_EXTENTS(leaf->extents.xmin, leaf->extents.ymin, 
                                        xmid, ymid);
    
    newnode->ur.extents = BUILD_EXTENTS(xmid, leaf->extents.ymin, 
                                        leaf->extents.xmax, ymid);
    
    newnode->ll.extents = BUILD_EXTENTS(leaf->extents.xmin, ymid, 
                                        xmid, leaf->extents.ymax);
    
    newnode->lr.extents = BUILD_EXTENTS(xmid, ymid, 
                                        leaf->extents.xmax, leaf->extents.ymax);
    while(cur) {
      DO_CORNERS(cur->x, cur->y, MOVE_CORNER, newnode);
    }
    leaf->size = 0;
    leaf->contents.leaf = newnode;
  }
}
Beispiel #2
0
void subdivide (std::vector<vector>& vertices,
                std::vector<triangle>& triangles)
{
    std::vector<triangle> new_tris;

    for (const triangle& tri : triangles)
    {
        unsigned int a(tri[0]), b(tri[1]), c(tri[2]);
        unsigned int d, e, f;

        vector n1 (normalize(halfway(vertices[a], vertices[b])));
        auto f1 (std::find (vertices.begin(), vertices.end(), n1));
        if (f1 == vertices.end())
        {
            d = vertices.size();
            vertices.push_back(n1);
        }
        else
        {
            d = std::distance(vertices.begin(), f1);
        }

        vector n2 (normalize(halfway(vertices[b], vertices[c])));
        auto f2 (std::find (vertices.begin(), vertices.end(), n2));
        if (f2 == vertices.end())
        {
            e = vertices.size();
            vertices.push_back(n2);
        }
        else
        {
            e = std::distance(vertices.begin(), f2);
        }

        vector n3 (normalize(halfway(vertices[c], vertices[a])));
        auto f3 (std::find (vertices.begin(), vertices.end(), n3));
        if (f3 == vertices.end())
        {
            f = vertices.size();
            vertices.push_back(n3);
        }
        else
        {
            f = std::distance(vertices.begin(), f3);
        }

        new_tris.push_back(make_triangle(a, d, f));
        new_tris.push_back(make_triangle(d, b, e));
        new_tris.push_back(make_triangle(f, e, c));
        new_tris.push_back(make_triangle(d, e, f));
    }

    triangles.swap(new_tris);
}
Beispiel #3
0
void newtree(QuadTree *qt, 
             unsigned int maxsize,
             unsigned int maxdepth,
             Extent extents)
{
  float xmid = halfway(extents.xmin,extents.xmax); 
  float ymid = halfway(extents.ymin,extents.ymax);
  
  qt->head     = NULL;
  qt->maxsize  = maxsize;
  qt->maxdepth = maxdepth;
  qt->extents  = extents;
    
  qt->head = calloc(1,sizeof(Qnode));
 
  qt->head->depth = 1;

  qt->head->ul.extents = BUILD_EXTENTS(qt->extents.xmin, 
                                      qt->extents.ymin, 
                                      xmid, 
                                      ymid);
  qt->head->ur.extents = BUILD_EXTENTS(xmid, 
                                      qt->extents.ymin, 
                                      qt->extents.xmax, 
                                      ymid);
  qt->head->ll.extents = BUILD_EXTENTS(qt->extents.xmin, 
                                      ymid, 
                                      xmid, 
                                      qt->extents.ymax);
  qt->head->lr.extents = BUILD_EXTENTS(xmid, 
                                      ymid, 
                                      qt->extents.xmax, 
                                      qt->extents.ymax);
  if (!qt->head) {     // calloc has thrown a hizzy!
    return;
  }
  
}
 optional<cache_iterator_type> advance(const tangent_vector& tangent, const double& from_t, const double& to_t, size_t recursion = 1) const
 {
   if (recursion > max_recursion_)
     return optional<cache_iterator_type>();
   
   //log_cout << "  Parallel transport: " << from_t << " -> " << to_t << endl;
   
   for (set<std::shared_ptr<chart> >::const_iterator i = charts().begin(); i != charts().end(); ++i)
     if (tangent[*i])
     {
       optional<cache_iterator_type> result(advance_on_chart(*i, *tangent[*i], from_t, to_t));
       if (result)
         return result;
     }
   
   optional<cache_iterator_type> halfway(advance(tangent, from_t, (from_t + to_t) / 2, recursion + 1));
   return halfway ? advance(*(*halfway)->second, (from_t + to_t) / 2, to_t, recursion + 1) : optional<cache_iterator_type>();
 }
Beispiel #5
0
const HTMLEntityTableEntry* HTMLEntitySearch::findLast(UChar nextCharacter) const
{
    const HTMLEntityTableEntry* left = m_first;
    const HTMLEntityTableEntry* right = m_last;
    if (left == right)
        return right;
    CompareResult result = compare(right, nextCharacter);
    if (result == Prefix)
        return right;
    if (result == Before)
        return left;
    while (left + 1 < right) {
        const HTMLEntityTableEntry* probe = halfway(left, right);
        result = compare(probe, nextCharacter);
        if (result == After)
            right = probe;
        else {
            ASSERT(result == Before || result == Prefix);
            left = probe;
        }
    }
    ASSERT(left + 1 == right);
    return left;
}
Beispiel #6
0
/*
 * zero or positive weight is the number of interesting commits it can
 * reach, including itself.  Especially, weight = 0 means it does not
 * reach any tree-changing commits (e.g. just above uninteresting one
 * but traversal is with pathspec).
 *
 * weight = -1 means it has one parent and its distance is yet to
 * be computed.
 *
 * weight = -2 means it has more than one parent and its distance is
 * unknown.  After running count_distance() first, they will get zero
 * or positive distance.
 */
static struct commit_list *do_find_bisection(struct commit_list *list,
					     int nr, int *weights,
					     int find_all)
{
	int n, counted;
	struct commit_list *p;

	counted = 0;

	for (n = 0, p = list; p; p = p->next) {
		struct commit *commit = p->item;
		unsigned flags = commit->object.flags;

		p->item->util = &weights[n++];
		switch (count_interesting_parents(commit)) {
		case 0:
			if (!(flags & TREESAME)) {
				weight_set(p, 1);
				counted++;
				show_list("bisection 2 count one",
					  counted, nr, list);
			}
			/*
			 * otherwise, it is known not to reach any
			 * tree-changing commit and gets weight 0.
			 */
			break;
		case 1:
			weight_set(p, -1);
			break;
		default:
			weight_set(p, -2);
			break;
		}
	}

	show_list("bisection 2 initialize", counted, nr, list);

	/*
	 * If you have only one parent in the resulting set
	 * then you can reach one commit more than that parent
	 * can reach.  So we do not have to run the expensive
	 * count_distance() for single strand of pearls.
	 *
	 * However, if you have more than one parents, you cannot
	 * just add their distance and one for yourself, since
	 * they usually reach the same ancestor and you would
	 * end up counting them twice that way.
	 *
	 * So we will first count distance of merges the usual
	 * way, and then fill the blanks using cheaper algorithm.
	 */
	for (p = list; p; p = p->next) {
		if (p->item->object.flags & UNINTERESTING)
			continue;
		if (weight(p) != -2)
			continue;
		weight_set(p, count_distance(p));
		clear_distance(list);

		/* Does it happen to be at exactly half-way? */
		if (!find_all && halfway(p, nr))
			return p;
		counted++;
	}

	show_list("bisection 2 count_distance", counted, nr, list);

	while (counted < nr) {
		for (p = list; p; p = p->next) {
			struct commit_list *q;
			unsigned flags = p->item->object.flags;

			if (0 <= weight(p))
				continue;
			for (q = p->item->parents; q; q = q->next) {
				if (q->item->object.flags & UNINTERESTING)
					continue;
				if (0 <= weight(q))
					break;
			}
			if (!q)
				continue;

			/*
			 * weight for p is unknown but q is known.
			 * add one for p itself if p is to be counted,
			 * otherwise inherit it from q directly.
			 */
			if (!(flags & TREESAME)) {
				weight_set(p, weight(q)+1);
				counted++;
				show_list("bisection 2 count one",
					  counted, nr, list);
			}
			else
				weight_set(p, weight(q));

			/* Does it happen to be at exactly half-way? */
			if (!find_all && halfway(p, nr))
				return p;
		}
	}

	show_list("bisection 2 counted all", counted, nr, list);

	if (!find_all)
		return best_bisection(list, nr);
	else
		return best_bisection_sorted(list, nr);
}
Beispiel #7
0
Color Shade(
    int                 hitObj,         // which object was hit
    Ray			        R,              // the ray that hit
    RayHit              hit,            // result of intersection test
    int                 lev)            // level in trace recursion
{
	Vector temp = R.v.clone();
	temp.scale(hit.tValue);
	Point poc = ptPlusVec(R.p, temp);
	Vector norm = hit.norm;
 
	Pigment* p = thePigs[theShapes[hitObj]->pig];
	Finish* f = theFins[theShapes[hitObj]->fin];
    
	Color col(0, 0, 0);

	for (int i = 0; i < nLgts; i++) {
		if (i == 0)
			col.accumulate((theLgts[i]->col).dotWith(p->getColorAt(poc)).scaleBy(f->amb));
		else {
			Ray LightRay = Ray(poc, ptToPt(poc, theLgts[i]->loc));
			LightRay.tValue = ptToPt(poc, theLgts[i]->loc).length();
			if (!Hit(LightRay)) {

				Light* l = theLgts[i];
				Scalar d = dist(poc, l->loc);
				Scalar atten = 1/(l->a + l->b*d + l->c*d*d);

				//diff
				Color temp = p->getColorAt(poc);
				temp = temp.scaleBy(f->diff);
				temp = temp.scaleBy(max(0, dotProd(norm, LightRay.v)));
				temp = temp.scaleBy(atten);
				temp = temp.dotWith(l->col);
				col.accumulate(temp);

				//spec
				temp = l->col;
				temp = temp.scaleBy(f->spec);
				Vector view = R.v.clone();
				view.scale(-1);
				temp = temp.scaleBy(max(0, pow(dotProd(norm, halfway(LightRay.v, view)), f->shiny)));
				temp = temp.scaleBy(atten);
				col.accumulate(temp);

			}
		}
	}

	if (f->refl != 0) {
		Vector v = R.v.clone();
		v.scale(-1);
		Vector n = norm.clone();
		n.scale(2*dotProd(n, v));
		Vector r = Vector(n.x - v.x, n.y - v.y, n.z - v.z);
		Ray R2 = Ray(poc, r);
		Color reflCol = Trace(R2, lev + 1);
		reflCol = reflCol.scaleBy(f->refl);
		col.accumulate(reflCol);
	}

	if (f->trans != 0) {
		Vector v = R.v.clone();
		v.scale(-1);
		Vector n = norm.clone();
	
		Scalar cosI = dotProd(v, n);
		Scalar eta = 1;
		if (hit.insideObj)
			eta = f->ior;
		else
			eta = 1/(f->ior);
		
		if (1 - eta*eta*(1 - cosI*cosI) < 0 && f->refl == 0) {
			n.scale(2*dotProd(n, v));
			Vector r = Vector(n.x - v.x, n.y - v.y, n.z - v.z);
			Ray R2 = Ray(poc, r);
			Color reflCol = Trace(R2, lev + 1);
			reflCol = reflCol.scaleBy(f->refl);
			col.accumulate(reflCol);
		}
		else {
			Scalar cosT = sqrt(1 - eta*eta*(1 - cosI*cosI));
			n.scale(eta*cosI-cosT);
			v.scale(eta);
			Vector r = Vector(n.x - v.x, n.y - v.y, n.z - v.z);
			Ray R2 = Ray(poc, r);
			Color refrCol = Trace(R2, lev + 1);
			refrCol = refrCol.scaleBy(f->trans);
			col.accumulate(refrCol);
		}
	}
	
	return col;

	//naive
	//return p->getColorAt(poc);
}