Esempio n. 1
0
	void World::updateNaviMap(bool full_recompute) {
		FWK_PROFILE("updateNaviMap");
			
		//TODO: what about static entities that are added during the game?

		if(full_recompute) {
			vector<IBox> bboxes, blockers;
			bboxes.reserve(m_tile_map.size() + m_entity_map.size());

			for(int n = 0; n < m_tile_map.size(); n++) {
				const Tile *tile = m_tile_map[n].ptr;
				if(!tile || !Flags::test(tile->flags(), Flags::all | Flags::colliding))
					continue;

				bool is_walkable = Flags::test(tile->flags(), Flags::walkable_tile | Flags::wall_tile);
				(is_walkable? bboxes : blockers).push_back((IBox)m_tile_map[n].bbox);
			}


			for(int n = 0; n < m_entity_map.size(); n++)
				if(m_entity_map[n].ptr && Flags::test(m_entity_map[n].flags, Flags::static_entity | Flags::colliding))
					blockers.push_back(enclosingIBox(m_entity_map[n].ptr->boundingBox()));

			NaviHeightmap heightmap(m_tile_map.dimensions());
			heightmap.update(bboxes, blockers);
			//heightmap.saveLevels();
			//heightmap.printInfo();

			for(int m = 0; m < (int)m_navi_maps.size(); m++) {
				m_navi_maps[m].update(heightmap);
				//m_navi_maps[m].printInfo();
			}
		}

		for(int m = 0; m < (int)m_navi_maps.size(); m++) {
			NaviMap &navi_map = m_navi_maps[m];
			navi_map.removeColliders();

			for(int n = 0; n < m_entity_map.size(); n++) {
				auto &object = m_entity_map[n];
				if(!object.ptr)
					continue;

				if(Flags::test(object.flags, Flags::dynamic_entity | Flags::colliding)) {
					const IBox &box = enclosingIBox(object.ptr->boundingBox());
					navi_map.addCollider(box, n);
				}
			}
			navi_map.updateReachability();
		}
	}
Esempio n. 2
0
	void WorldViewer::update(double time_diff) {
		FWK_PROFILE("WorldViewer::update");
		Actor *spectator = m_world->refEntity<Actor>(m_spectator);

		if((int)m_entities.size() != m_world->entityCount())
			m_entities.resize(m_world->entityCount());
		
		if(!m_spectator) {
			for(int n = 0; n < (int)m_entities.size(); n++) {
				Entity *entity = m_world->refEntity(n);
				VisEntity &vis_entity = m_entities[n];
				vis_entity.ref = entity? entity->ref() : EntityRef();
				vis_entity.mode = entity? VisEntity::visible : VisEntity::invisible;
				vis_entity.occluder_id = -1;
			}
			return;
		}

		if(!spectator)
			return;

		FBox bbox = spectator->boundingBox();
		m_cur_pos = bbox.center();
		m_eye_pos = asXZY(m_cur_pos.xz(), bbox.min.y + bbox.height() * 0.75f);

		for(int n = 0; n < (int)m_entities.size(); n++) {
			Entity *entity = m_world->refEntity(n);
			VisEntity &vis_entity = m_entities[n];

			if(!entity) {
				vis_entity = VisEntity();
				continue;
			}
			
			const auto *desc = m_world->refEntityDesc(n);
			DASSERT(desc);

			bool is_visible = m_see_all || spectator == entity || spectator->canSee(entity->ref(), !isMovable(*entity));

			if(vis_entity.ref != entity->ref()) {
				vis_entity = VisEntity();
				vis_entity.ref = entity->ref();
				vis_entity.mode = is_visible? VisEntity::visible : VisEntity::invisible;
			}

			if(is_visible) {
				vis_entity.occluder_id = desc->occluder_id;

				if(vis_entity.mode == VisEntity::visible)
					continue;

				if(vis_entity.mode == VisEntity::shadowed || vis_entity.mode == VisEntity::pre_blending_out) {
					vis_entity.shadow.reset();
					vis_entity.mode = VisEntity::visible;
				}
				else {
					float blend_value = 0.0;
					if(vis_entity.mode == VisEntity::blending_in)
						blend_value = vis_entity.blend_value;
					else if(vis_entity.mode == VisEntity::blending_out)
						blend_value = blend_time - vis_entity.blend_value;

					blend_value += time_diff;
					vis_entity.mode = blend_value > blend_time? VisEntity::visible : VisEntity::blending_in;
					vis_entity.blend_value = blend_value;
				}
			}
			else {
				if(vis_entity.mode == VisEntity::shadowed || vis_entity.mode == VisEntity::invisible)
					continue;

				if(vis_entity.mode == VisEntity::visible) {
					vis_entity.blend_value = 0.0f;
					vis_entity.mode = VisEntity::pre_blending_out;
				}

				if(vis_entity.mode == VisEntity::pre_blending_out) {
					vis_entity.blend_value += time_diff;

					if(vis_entity.blend_value > blend_time) {
						if(isMovable(*entity)) {
							vis_entity.mode = VisEntity::blending_out;
							vis_entity.blend_value = vis_entity.blend_value - blend_time;
						}
						else {
							vis_entity.mode = VisEntity::shadowed;
							vis_entity.occluder_id = desc->occluder_id;
							vis_entity.shadow.reset(entity->clone());
						}
					}
				}
				else {
					float blend_value = 0.0f;

					if(vis_entity.mode == VisEntity::blending_in)
						blend_value = blend_time - vis_entity.blend_value;
					else if(vis_entity.mode == VisEntity::blending_out)
						blend_value = vis_entity.blend_value;

					vis_entity.blend_value = blend_value + time_diff;
					vis_entity.mode = VisEntity::blending_out;

					if(vis_entity.blend_value > blend_time)
						vis_entity.mode = VisEntity::invisible;
				}
			}
		}

		if(m_occluder_config.update(spectator->boundingBox()))
			m_world->tileMap().updateVisibility(m_occluder_config);
	}