]> git.itanic.dy.fi Git - sdl-planets/commitdiff
Merge branch 'master' into dirty_work dirty_work
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Mon, 7 Feb 2011 19:58:14 +0000 (21:58 +0200)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Mon, 7 Feb 2011 19:58:14 +0000 (21:58 +0200)
Conflicts:
planet.c
quadtree.c

1  2 
planet.c
quadtree.c
quadtree.h

diff --cc planet.c
index 1441fc33e729534c8f622834090ddb35ee759391,2c7d1435ff09fe8df676735e29f4ba2c3fe445d5..7a75f0a0d1adb4515b3bab2c48361fff5e300aeb
+++ b/planet.c
@@@ -287,23 -243,18 +287,18 @@@ static struct planet *_merge_planets(st
        vector_add(&pa, &pb, &p);
        mass = a->mass + b->mass;
  
-       if (a->mass < b->mass) {
-               rem = a;
-               nr = a;
-       } else {
-               rem = b;
-               nr = a;
-       }
-       nr->r = (a->r * a->mass + b->r * b->mass) / mass;
-       nr->g = (a->g * a->mass + b->g * b->mass) / mass;
-       nr->b = (a->b * a->mass + b->b * b->mass) / mass;
+       if (a->mass < b->mass)
+               parent = quadtree_move(&a->tree, b->tree.pos, &planet_ops);
  
 -      a->r = (a->r * a->mass + b->r * b->mass) / mass;
 -      a->g = (a->g * a->mass + b->g * b->mass) / mass;
 -      a->b = (a->b * a->mass + b->b * b->mass) / mass;
 +      nr->mass = mass;
 +      reshape_planet(nr);
 +      vector_div(&p, nr->mass, &nr->speed);
  
-       return rem;
+       a->mass = mass;
+       reshape_planet(a);
+       vector_div(&p, a->mass, &a->speed);
+       return tree_to_planet(quadtree_find_parent(parent));
  }
  
  /*
   */
  struct planet *merge_planets(struct planet *a, struct planet *b)
  {
-       struct planet *r;
-       r = _merge_planets(a, b);
+       struct quadtree *p;
+       _merge_planets(a, b);
  
-       //list_del(&b->list);
-       //quadtree_del(&b->tree, &planet_ops);
+       list_del(&b->list);
+       p = quadtree_del(&b->tree, &planet_ops);
  
-       //free(b);
-       if (r == a)
-               a->to_be_deleted = 1;
-       else
-               b->to_be_deleted = 1;
-       return r;
+       free(b);
+       return tree_to_planet(p);
  }
  
- static int planet_search_when_moving(struct quadtree *node,
-                                    struct quadtree_iterator *itr)
- {
-       struct planet *p = tree_to_planet(node);
-       struct planet_search_iterator *it = qt_itr_to_planet_itr(itr);
-       int direction = 0, i;
-       int up = 0, left = 0, right = 0, down = 0;
-       for (i = 0; i < 2; i++) {
-               if (it->limit[i].x < p->tree.pos.x)
-                       left = 1;
-               else
-                       right = 1;
-               if (it->limit[i].y < p->tree.pos.y)
-                       up = 1;
-               else
-                       down = 1;
-       }
-       if (left || up)
-               direction |= QUADTREE_UPLEFT;
-       if (right || up)
-               direction |= QUADTREE_UPRIGHT;
-       if (left || down)
-               direction |= QUADTREE_DOWNLEFT;
-       if (right || down)
-               direction |= QUADTREE_DOWNRIGHT;
-       if ((left && right) || (up && down))
-               direction |= QUADTREE_SELF;
-       return direction;
- }
- void planet_move_iterator(struct quadtree *node, struct quadtree_iterator *it)
- {
-       struct planet_search_iterator *itr = qt_itr_to_planet_itr(it);
-       if (node == it->head)
-               return;
- /*
-       parent = quadtree_del(node, &planet_ops);
-       quadtree_add(parent, node, &planet_ops);
- */
-       itr->modify++;
- }
 +static void gravitize_planet(struct planet *p, struct planet *pt, double time)
 +{
 +      struct vector vect;
 +      float dist;
 +      int i;
 +
 +      vector_sub(&p->tree.pos, &pt->tree.pos, &vect);
 +      dist = vector_abs(&vect);
 +
 +      if (p != pt)
 +              gravitize_planet_with_planet(p, pt, time);
 +
 +      if (dist > pt->tree_area * 8) {
 +              /*
 +               * OK, the node is far enough. We can approximate the
 +               * entire tree as a single entity.
 +               */
 +              optimizations += pt->tree.children;
 +              gravitize_planet_with_tree(p, pt, time);
 +              return;
 +      }
 +
 +      /* Otherwise, gravitize with each of the child */
 +      for (i = 0; i < 4; i++) {
 +              if (!pt->tree.child[i])
 +                      continue;
 +
 +              gravitize_planet(p, tree_to_planet(pt->tree.child[i]),
 +                               time);
 +      }
 +}
 +
 +void gravitize_planet_tree(struct planet *p, double time)
 +{
 +      int i;
 +
 +      for (i = 0; i < 4; i++) {
 +              if (!p->tree.child[i])
 +                      continue;
 +
 +              gravitize_planet_tree(tree_to_planet(p->tree.child[i]),
 +                                    time);
 +      }
 +
 +      gravitize_planet(p,
 +                       tree_to_planet(quadtree_find_parent(&p->tree)),
 +                       time);
 +}
 +
  struct planet *move_planet(struct planet *p, const double time)
  {
        struct vector tmp, new_pos;
        vector_scale(&p->speed, time, &tmp);
        vector_add(&p->tree.pos, &tmp, &new_pos);
  
-       /* Check if we have crossed any of the parents */
-       parent = p->tree.parent;
-       while (parent) {
-               pa = tree_to_planet(parent);
-               if (p->tree.pos.x < pa->tree.pos.x && new_pos.x > pa->tree.pos.x)
-                       modify = 1;
-               if (p->tree.pos.x > pa->tree.pos.x && new_pos.x < pa->tree.pos.x)
-                       modify = 1;
-               if (p->tree.pos.y < pa->tree.pos.y && new_pos.y > pa->tree.pos.y)
-                       modify = 1;
-               if (p->tree.pos.y > pa->tree.pos.y && new_pos.y < pa->tree.pos.y)
-                       modify = 1;
-               if (!modify) {
-                       parent = parent->parent;
-                       continue;
-               }
-               tree_parent = quadtree_del(&p->tree, &planet_ops);
-               p->tree.pos = new_pos;
-               quadtree_add(tree_parent, &p->tree, &planet_ops);
-               return tree_to_planet(tree_parent);
-       }
-       if(p->tree.children) {
-               /*
-                * Now, search the subtree for any crossed children and move
-                * them into correct place within the tree.
-                */
-               it.qt_iterator.head = &p->tree;
-               it.limit[0] = p->tree.pos;
-               it.limit[1] = new_pos;
-               it.qt_iterator.direction = planet_search_when_moving;
-               it.qt_iterator.callback = planet_move_iterator;
-               walk_quadtree(&it.qt_iterator);
-       }
-       if (it.modify) {  
-               tree_parent = quadtree_del(&p->tree, &planet_ops);
-               p->tree.pos = new_pos;
-               quadtree_add(tree_parent, &p->tree, &planet_ops);
-               goto out;
-       }
-       p->tree.pos = new_pos;
-       tree_parent = quadtree_find_parent(&p->tree);
- out:
-       quadtree_validate_tree(&p->tree);
-       return tree_to_planet(tree_parent);
+       return tree_to_planet(quadtree_move(&p->tree, new_pos, &planet_ops));
  }
  
 +int propagate_tree_movement(struct planet *p)
 +{
 +      int i, count = 1;
 +
 +      for (i = 0; i < 4; i++) {
 +              if (!p->tree.child[i])
 +                      continue;
 +
 +              vector_add(&tree_to_planet(p->tree.child[i])->speed,
 +                      &p->tree_speed,
 +                      &tree_to_planet(p->tree.child[i])->speed);
 +
 +              count += propagate_tree_movement(
 +                      tree_to_planet(p->tree.child[i]));
 +      }
 +
 +      vector_add(&p->tree_speed, &p->speed, &p->speed);
 +
 +      p->tree_speed.x = 0;
 +      p->tree_speed.y = 0;
 +
 +      return count;
 +}
 +
 +struct planet *prune_planet_tree(struct planet *p)
 +{
 +      struct quadtree *tree_parent = &p->tree;
 +      int i;
 +/*
 +      while (head != start) {
 +              p = list_to_planet(head);
 +              if (p->to_be_deleted) {
 +                      if (head == start)
 +                              start = head->next;
 +                      list_del(&p->list);
 +                      tree_parent = quadtree_del(&p->tree, &planet_ops);
 +                      head = head->next;
 +                      free(p);
 +                      continue;
 +              }
 +
 +              head = head->next;
 +      }
 +
 +      return tree_to_planet(tree_parent);
 +*/
 +      for (i = 0; i < 4; i++) {
 +              if (!p->tree.child[i])
 +                      continue;
 +
 +              prune_planet_tree(tree_to_planet(p->tree.child[i]));
 +      }
 +
 +      if (p->to_be_deleted) {
 +              list_del(&p->list);
 +              tree_parent = quadtree_del(&p->tree, &planet_ops);
 +              free(p);
 +              return tree_to_planet(tree_parent);
 +      }
 +
 +      planet_ops.recalculate_stats(&p->tree);
 +
 +      return tree_to_planet(quadtree_find_parent(&p->tree));
 +}
 +
  void print_planet(const struct planet *p)
  {
        printf("pos: (%f,%f), speed: (%f,%f), mass: %f, radius %f\n",
diff --cc quadtree.c
Simple merge
diff --cc quadtree.h
Simple merge