Пример #1
0
	void Entity::addToRender(SceneRenderer &out, Color color) const {
		//PROFILE("Entity::addToRender");
		IRect rect = m_sprite.getRect(m_seq_idx, m_frame_idx, m_dir_idx);
		if(!areOverlapping(out.targetRect(), rect + (int2)worldToScreen(m_pos)))
			return;

		FBox bbox = boundingBox() - pos();
		if(shrinkRenderedBBox() && bbox.height() >= 2.0f)
			bbox = {float3(bbox.x(), min(bbox.y() + 1.0f, bbox.ey() - 0.5f), bbox.z()), bbox.max()};

		bool as_overlay = renderAsOverlay();

		FRect tex_rect;
		auto tex = m_sprite.getFrame(m_seq_idx, m_frame_idx, m_dir_idx, tex_rect);
		bool added = out.add(tex, rect, m_pos, bbox, color, tex_rect, as_overlay);
	
	 	if(added && m_oseq_idx != -1 && m_oframe_idx != -1) {
			//TODO: overlay may be visible, while normal sprite is not!
			rect = m_sprite.getRect(m_oseq_idx, m_oframe_idx, m_dir_idx);
			auto ov_tex = m_sprite.getFrame(m_oseq_idx, m_oframe_idx, m_dir_idx, tex_rect);
			out.add(ov_tex, rect, m_pos, bbox, color, tex_rect, true);
		}

//		if(findAny(boundingBox(), {Flags::all | Flags::colliding, ref()}))
//			out.addBox(bbox + pos(), ColorId::red);
	}
Пример #2
0
	bool World::findClosestPos(int3 &out, const int3 &source, const IBox &target_box, EntityRef agent_ref) const {
		const Entity *agent = const_cast<World*>(this)->refEntity(agent_ref);
		if(agent) {
			FBox bbox = agent->boundingBox();
			const NaviMap *navi_map = naviMap(bbox);
			if(navi_map)
				return navi_map->findClosestPos(out, source, bbox.height(), target_box);
		}

		return false;
	}
Пример #3
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);
	}