}
World::~World() {
-
+ for (Entity &e : entities) {
+ e.Kill();
+ }
+ std::size_t removed = 0;
+ do {
+ removed = 0;
+ for (auto e = entities.begin(), end = entities.end(); e != end; ++e) {
+ if (e->CanRemove()) {
+ e = RemoveEntity(e);
+ end = entities.end();
+ ++removed;
+ }
+ }
+ } while (removed > 0 && !entities.empty());
}
bool World::Intersection(
const Ray &ray,
- const glm::mat4 &M,
const ExactLocation::Coarse &reference,
WorldCollision &coll
) {
for (Chunk &cur_chunk : chunks) {
float cur_dist;
- if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(reference), cur_dist)) {
+ if (cur_chunk.Intersection(ray, reference, cur_dist)) {
candidates.push_back({ &cur_chunk, cur_dist });
}
}
for (Candidate &cand : candidates) {
if (cand.dist > coll.depth) continue;
WorldCollision cur_coll;
- if (cand.chunk->Intersection(ray, M * cand.chunk->Transform(reference), cur_coll)) {
+ if (cand.chunk->Intersection(ray, reference, cur_coll)) {
if (cur_coll.depth < coll.depth) {
coll = cur_coll;
}
bool World::Intersection(
const Ray &ray,
- const glm::mat4 &M,
const Entity &reference,
EntityCollision &coll
) {
}
float cur_dist;
glm::vec3 cur_normal;
- if (blank::Intersection(ray, cur_entity.Bounds(), M * cur_entity.Transform(reference.ChunkCoords()), &cur_dist, &cur_normal)) {
+ if (blank::Intersection(ray, cur_entity.Bounds(), cur_entity.Transform(reference.ChunkCoords()), &cur_dist, &cur_normal)) {
// TODO: fine grained check goes here? maybe?
if (cur_dist < coll.depth) {
coll.entity = &cur_entity;
bool World::Intersection(const Entity &e, const EntityState &s, std::vector<WorldCollision> &col) {
// TODO: make special case for entities here and in Chunk::Intersection so entity's bounding radius
// doesn't have to be calculated over and over again (sqrt)
- AABB box = e.Bounds();
glm::ivec3 reference = s.pos.chunk;
glm::mat4 M = s.Transform(reference);
+ ExactLocation::Coarse begin(reference - 1);
+ ExactLocation::Coarse end(reference + 2);
+
bool any = false;
- for (Chunk &cur_chunk : chunks) {
- if (manhattan_radius(cur_chunk.Position() - reference) > 1) {
- // chunk is not one of the 3x3x3 surrounding the entity
- // since there's no entity which can extent over 16 blocks, they can be skipped
- continue;
- }
- if (cur_chunk.Intersection(box, M, cur_chunk.Transform(reference), col)) {
- any = true;
+ for (ExactLocation::Coarse pos(begin); pos.z < end.y; ++pos.z) {
+ for (pos.y = begin.y; pos.y < end.y; ++pos.y) {
+ for (pos.x = begin.x; pos.x < end.x; ++pos.x) {
+ Chunk *chunk = chunks.Get(pos);
+ if (chunk && chunk->Intersection(e, M, chunk->Transform(reference), col)) {
+ any = true;
+ }
+ }
}
}
return any;