Пример #1
0
void Timer::_set_process(bool p_process, bool p_force) {
	switch (timer_process_mode) {
		case TIMER_PROCESS_FIXED: set_fixed_process_internal(p_process && !paused); break;
		case TIMER_PROCESS_IDLE: set_process_internal(p_process && !paused); break;
	}
	processing = p_process;
}
Пример #2
0
void AudioStreamPlayer2D::stop() {

	if (stream_playback.is_valid()) {
		active = false;
		set_fixed_process_internal(false);
		setplay = -1;
	}
}
Пример #3
0
void AudioStreamPlayer2D::play(float p_from_pos) {

	if (stream_playback.is_valid()) {
		setplay = p_from_pos;
		output_ready = false;
		set_fixed_process_internal(true);
	}
}
Пример #4
0
void Timer::set_timer_process_mode(TimerProcessMode p_mode) {

	if (timer_process_mode == p_mode)
		return;

	switch (timer_process_mode) {
		case TIMER_PROCESS_FIXED:
			if (is_fixed_processing_internal()) {
				set_fixed_process_internal(false);
				set_process_internal(true);
			}
			break;
		case TIMER_PROCESS_IDLE:
			if (is_processing_internal()) {
				set_process_internal(false);
				set_fixed_process_internal(true);
			}
			break;
	}
	timer_process_mode = p_mode;
}
Пример #5
0
void AudioStreamPlayer2D::_notification(int p_what) {

	if (p_what == NOTIFICATION_ENTER_TREE) {

		AudioServer::get_singleton()->add_callback(_mix_audios, this);
		if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
			play();
		}
	}

	if (p_what == NOTIFICATION_EXIT_TREE) {

		AudioServer::get_singleton()->remove_callback(_mix_audios, this);
	}

	if (p_what == NOTIFICATION_INTERNAL_FIXED_PROCESS) {

		//update anything related to position first, if possible of course

		if (!output_ready) {
			List<Viewport *> viewports;
			Ref<World2D> world_2d = get_world_2d();
			ERR_FAIL_COND(world_2d.is_null());

			int new_output_count = 0;

			Vector2 global_pos = get_global_position();

			int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);

			//check if any area is diverting sound into a bus

			Physics2DDirectSpaceState *space_state = Physics2DServer::get_singleton()->space_get_direct_state(world_2d->get_space());

			Physics2DDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS];

			int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, Physics2DDirectSpaceState::TYPE_MASK_AREA);

			for (int i = 0; i < areas; i++) {

				Area2D *area2d = Object::cast_to<Area2D>(sr[i].collider);
				if (!area2d)
					continue;

				if (!area2d->is_overriding_audio_bus())
					continue;

				StringName bus_name = area2d->get_audio_bus_name();
				bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
				break;
			}

			world_2d->get_viewport_list(&viewports);
			for (List<Viewport *>::Element *E = viewports.front(); E; E = E->next()) {

				Viewport *vp = E->get();
				if (vp->is_audio_listener_2d()) {

					//compute matrix to convert to screen
					Transform2D to_screen = vp->get_global_canvas_transform() * vp->get_canvas_transform();
					Vector2 screen_size = vp->get_visible_rect().size;

					//screen in global is used for attenuation
					Vector2 screen_in_global = to_screen.affine_inverse().xform(screen_size * 0.5);

					float dist = global_pos.distance_to(screen_in_global); //distance to screen center

					if (dist > max_distance)
						continue; //cant hear this sound in this viewport

					float multiplier = Math::pow(1.0f - dist / max_distance, attenuation);
					multiplier *= Math::db2linear(volume_db); //also apply player volume!

					//point in screen is used for panning
					Vector2 point_in_screen = to_screen.xform(global_pos);

					float pan = CLAMP(point_in_screen.x / screen_size.width, 0.0, 1.0);

					float l = 1.0 - pan;
					float r = pan;

					outputs[new_output_count].vol = AudioFrame(l, r) * multiplier;
					outputs[new_output_count].bus_index = bus_index;
					outputs[new_output_count].viewport = vp; //keep pointer only for reference
					new_output_count++;
					if (new_output_count == MAX_OUTPUTS)
						break;
				}
			}

			output_count = new_output_count;
			output_ready = true;
		}

		//start playing if requested
		if (setplay >= 0.0) {
			setseek = setplay;
			active = true;
			setplay = -1;
			//do not update, this makes it easier to animate (will shut off otherise)
			//_change_notify("playing"); //update property in editor
		}

		//stop playing if no longer active
		if (!active) {
			set_fixed_process_internal(false);
			//do not update, this makes it easier to animate (will shut off otherise)
			//_change_notify("playing"); //update property in editor
			emit_signal("finished");
		}
	}
}