Text *Node::text_create(Font *font, Scene &scene) { Assets &assets = scene.assets_get(); std::unique_ptr<Text> text(new Text()); Text *text_ptr = text.get(); text_ptr->font_set(font); text_set(text_ptr); if (!mesh_get()) mesh_create(scene); assets.text_add(std::move(text)); return text_ptr; }
Physics_Rigidbody *Node::physics_rigidbody_create(Scene &scene, bool recursive) { Assets &assets = scene.assets_get(); Physics_Rigidbody *rigidbody_ptr = nullptr; if (!mesh_get()) { POLL_ERROR(std::cerr, "Cannot create rigidbody, no mesh for node: " << name_get()); } else { std::unique_ptr<Physics_Rigidbody> rigidbody(new Physics_Rigidbody()); rigidbody_ptr = rigidbody.get(); rigidbody_ptr->node_ptr_set(this); physics_rigidbody_set(rigidbody_ptr); assets.physics_rigidbody_add(std::move(rigidbody)); } return rigidbody_ptr; }
// resolves collisions between bodies, returning new body count int collide(int n, body bodies[]) { // initialize disjoint set and bodies to include set* bsets[n]; int include[n]; for (int i = 0; i < n; i++) { bsets[i] = make_set(i); include[i] = 1; } // find largest object double maxrad = RADIUS(bodies[0].m); for (int i = 0; i < n; i++) { double rad = RADIUS(bodies[i].m); if (rad > maxrad) maxrad = rad; } // form mesh for collision detection mesh* m = mesh_new(maxrad * 2); for (int i = 0; i < n; i++) mesh_put(m, bodies[i].pos, i); // find collisions for (int i = 0; i < n; i++) { vector ipos = bodies[i].pos; double irad = RADIUS(bodies[i].m); // which bodies are in contact with this one? // look up position in mesh body_list* next = mesh_get(m, ipos, 1); for (body_list* cur = next; cur; cur = next) { // get candidate collider int j = cur->index; vector jpos = bodies[j].pos; double jrad = RADIUS(bodies[j].m); // merge sets of colliding objects if (dist(ipos, jpos) < (irad + jrad) * (irad + jrad)) merge(bsets[i], bsets[j]); // traverse and free next = cur->next; free(cur); } } // free the mesh mesh_free(m); // merge objects for (int i = 0; i < n; i++) { int rootidx = get_value(find(bsets[i])); if (rootidx != i) { include[i] = 0; bodies[rootidx] = body_merge(bodies[rootidx], bodies[i]); } } // free sets for (int i = 0; i < n; i++) free(bsets[i]); // copy down int j = 0; for (int i = 0; i < n; i++) { if (include[i]) bodies[j++] = bodies[i]; } return j; }