Exemple #1
0
void RayCast2D::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (enabled && !Engine::get_singleton()->is_editor_hint())
				set_physics_process_internal(true);
			else
				set_physics_process_internal(false);

			if (Object::cast_to<CollisionObject2D>(get_parent())) {
				if (exclude_parent_body)
					exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
				else
					exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
			}
		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (enabled)
				set_physics_process_internal(false);

		} break;

		case NOTIFICATION_DRAW: {

			if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
				break;
			Transform2D xf;
			xf.rotate(cast_to.angle());
			xf.translate(Vector2(cast_to.length(), 0));

			//Vector2 tip = Vector2(0,s->get_length());
			Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
			draw_line(Vector2(), cast_to, dcol, 3);
			Vector<Vector2> pts;
			float tsize = 4;
			pts.push_back(xf.xform(Vector2(tsize, 0)));
			pts.push_back(xf.xform(Vector2(0, 0.707 * tsize)));
			pts.push_back(xf.xform(Vector2(0, -0.707 * tsize)));
			Vector<Color> cols;
			for (int i = 0; i < 3; i++)
				cols.push_back(dcol);

			draw_primitive(pts, cols, Vector<Vector2>()); //small arrow

		} break;

		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {

			if (!enabled)
				break;

			_update_raycast_state();

		} break;
	}
}
void AnimationTree::set_active(bool p_active) {

	if (active == p_active)
		return;

	active = p_active;
	started = active;

	if (process_mode == ANIMATION_PROCESS_IDLE) {
		set_process_internal(active);
	} else {

		set_physics_process_internal(active);
	}

	if (!active && is_inside_tree()) {
		for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) {

			if (ObjectDB::get_instance(E->get()->object_id)) {
				E->get()->object->call("stop");
			}
		}

		playing_caches.clear();
	}
}
Exemple #3
0
void Timer::_set_process(bool p_process, bool p_force) {
	switch (timer_process_mode) {
		case TIMER_PROCESS_PHYSICS: set_physics_process_internal(p_process && !paused); break;
		case TIMER_PROCESS_IDLE: set_process_internal(p_process && !paused); break;
	}
	processing = p_process;
}
void AudioStreamPlayer3D::stop() {

	if (stream_playback.is_valid()) {
		active = false;
		set_physics_process_internal(false);
		setplay = -1;
	}
}
void AudioStreamPlayer3D::play(float p_from_pos) {

	if (stream_playback.is_valid()) {
		setplay = p_from_pos;
		output_ready = false;
		set_physics_process_internal(true);
	}
}
Exemple #6
0
void RayCast2D::set_enabled(bool p_enabled) {

	enabled = p_enabled;
	if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
		set_physics_process_internal(p_enabled);
	if (!p_enabled)
		collided = false;
}
Exemple #7
0
void Timer::set_timer_process_mode(TimerProcessMode p_mode) {

	if (timer_process_mode == p_mode)
		return;

	switch (timer_process_mode) {
		case TIMER_PROCESS_PHYSICS:
			if (is_physics_processing_internal()) {
				set_physics_process_internal(false);
				set_process_internal(true);
			}
			break;
		case TIMER_PROCESS_IDLE:
			if (is_processing_internal()) {
				set_process_internal(false);
				set_physics_process_internal(true);
			}
			break;
	}
	timer_process_mode = p_mode;
}
Exemple #8
0
void AnimationPlayer::_set_process(bool p_process, bool p_force) {

	if (processing == p_process && !p_force)
		return;

	switch (animation_process_mode) {

		case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
		case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break;
	}

	processing = p_process;
}
Exemple #9
0
SoftBody::SoftBody() :
		MeshInstance(),
		physics_rid(PhysicsServer::get_singleton()->soft_body_create()),
		mesh_owner(false),
		collision_mask(1),
		collision_layer(1),
		simulation_started(false),
		pinned_points_cache_dirty(true) {

	PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
	//set_notify_transform(true);
	set_physics_process_internal(true);
}
void AudioStreamPlayer3D::_notification(int p_what) {

	if (p_what == NOTIFICATION_ENTER_TREE) {

		velocity_tracker->reset(get_global_transform().origin);
		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_TRANSFORM_CHANGED) {

		if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
			velocity_tracker->update_position(get_global_transform().origin);
		}
	}

	if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {

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

		if (!output_ready) {

			Vector3 linear_velocity;

			//compute linear velocity for doppler
			if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
				linear_velocity = velocity_tracker->get_tracked_linear_velocity();
			}

			Ref<World> world = get_world();
			ERR_FAIL_COND(world.is_null());

			int new_output_count = 0;

			Vector3 global_pos = get_global_transform().origin;

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

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

			PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(world->get_space());

			PhysicsDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS];

			int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask);
			Area *area = NULL;

			for (int i = 0; i < areas; i++) {
				if (!sr[i].collider)
					continue;

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

				if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus())
					continue;

				area = tarea;
				break;
			}

			List<Camera *> cameras;
			world->get_camera_list(&cameras);

			for (List<Camera *>::Element *E = cameras.front(); E; E = E->next()) {

				Camera *camera = E->get();
				Viewport *vp = camera->get_viewport();
				if (!vp->is_audio_listener())
					continue;

				Vector3 local_pos = camera->get_global_transform().orthonormalized().affine_inverse().xform(global_pos);

				float dist = local_pos.length();

				Vector3 area_sound_pos;
				Vector3 cam_area_pos;

				if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
					area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), camera->get_global_transform().origin);
					cam_area_pos = camera->get_global_transform().affine_inverse().xform(area_sound_pos);
				}

				if (max_distance > 0) {

					float total_max = max_distance;

					if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
						total_max = MAX(total_max, cam_area_pos.length());
					}
					if (total_max > max_distance) {
						continue; //cant hear this sound in this camera
					}
				}

				float multiplier = Math::db2linear(_get_attenuation_db(dist));
				if (max_distance > 0) {
					multiplier *= MAX(0, 1.0 - (dist / max_distance));
				}

				Output output;
				output.bus_index = bus_index;
				output.reverb_bus_index = -1; //no reverb by default
				output.viewport = vp;

				float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db;

				if (emission_angle_enabled) {
					Vector3 camtopos = global_pos - camera->get_global_transform().origin;
					float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
					float angle = Math::rad2deg(Math::acos(c));
					if (angle > emission_angle)
						db_att -= -emission_angle_filter_attenuation_db;
				}

				output.filter_gain = Math::db2linear(db_att);

				Vector3 flat_pos = local_pos;
				flat_pos.y = 0;
				flat_pos.normalize();

				unsigned int cc = AudioServer::get_singleton()->get_channel_count();
				if (cc == 1) {
					// Stereo pair
					float c = flat_pos.x * 0.5 + 0.5;

					output.vol[0].l = 1.0 - c;
					output.vol[0].r = c;
				} else {
					Vector3 camtopos = global_pos - camera->get_global_transform().origin;
					float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
					float angle = Math::rad2deg(Math::acos(c));
					float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0;

					if (cc >= 1) {
						// Stereo pair
						float fl = Math::abs(1.0 - Math::abs(-0.8 - av));
						float fr = Math::abs(1.0 - Math::abs(0.8 - av));

						output.vol[0].l = fl;
						output.vol[0].r = fr;
					}

					if (cc >= 2) {
						// Center pair
						float center = 1.0 - Math::sin(Math::acos(c));

						output.vol[1].l = center;
						output.vol[1].r = center;
					}

					if (cc >= 3) {
						// Side pair
						float sl = Math::abs(1.0 - Math::abs(-0.4 - av));
						float sr = Math::abs(1.0 - Math::abs(0.4 - av));

						output.vol[2].l = sl;
						output.vol[2].r = sr;
					}

					if (cc >= 4) {
						// Rear pair
						float rl = Math::abs(1.0 - Math::abs(-0.2 - av));
						float rr = Math::abs(1.0 - Math::abs(0.2 - av));

						output.vol[3].l = rl;
						output.vol[3].r = rr;
					}
				}

				for (int k = 0; k < cc; k++) {
					output.vol[k] *= multiplier;
				}

				bool filled_reverb = false;
				int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;

				if (area) {

					if (area->is_overriding_audio_bus()) {
						//override audio bus
						StringName bus_name = area->get_audio_bus();
						output.bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
					}

					if (area->is_using_reverb_bus()) {

						filled_reverb = true;
						StringName bus_name = area->get_reverb_bus();
						output.reverb_bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);

						float uniformity = area->get_reverb_uniformity();
						float area_send = area->get_reverb_amount();

						if (uniformity > 0.0) {

							float distance = cam_area_pos.length();
							float attenuation = Math::db2linear(_get_attenuation_db(distance));

							//float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life

							float center_val[3] = { 0.5, 0.25, 0.16666 };
							AudioFrame center_frame(center_val[vol_index_max - 1], center_val[vol_index_max - 1]);

							if (attenuation < 1.0) {
								//pan the uniform sound
								Vector3 rev_pos = cam_area_pos;
								rev_pos.y = 0;
								rev_pos.normalize();

								if (cc >= 1) {
									// Stereo pair
									float c = rev_pos.x * 0.5 + 0.5;
									output.reverb_vol[0].l = 1.0 - c;
									output.reverb_vol[0].r = c;
								}

								if (cc >= 3) {
									// Center pair + Side pair
									float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
									float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;

									output.reverb_vol[1].l = xl;
									output.reverb_vol[1].r = xr;
									output.reverb_vol[2].l = 1.0 - xr;
									output.reverb_vol[2].r = 1.0 - xl;
								}

								if (cc >= 4) {
									// Rear pair
									// FIXME: Not sure what math should be done here
									float c = rev_pos.x * 0.5 + 0.5;
									output.reverb_vol[3].l = 1.0 - c;
									output.reverb_vol[3].r = c;
								}

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

									output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
								}
							} else {
								for (int i = 0; i < vol_index_max; i++) {

									output.reverb_vol[i] = center_frame;
								}
							}

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

								output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity);
								output.reverb_vol[i] *= area_send;
							}

						} else {

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

								output.reverb_vol[i] = output.vol[i] * area_send;
							}
						}
					}
				}

				if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {

					Vector3 camera_velocity = camera->get_doppler_tracked_velocity();

					Vector3 local_velocity = camera->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - camera_velocity);

					if (local_velocity == Vector3()) {
						output.pitch_scale = 1.0;
					} else {
						float approaching = local_pos.normalized().dot(local_velocity.normalized());
						float velocity = local_velocity.length();
						float speed_of_sound = 343.0;

						output.pitch_scale = speed_of_sound / (speed_of_sound + velocity * approaching);
						output.pitch_scale = CLAMP(output.pitch_scale, (1 / 8.0), 8.0); //avoid crazy stuff
					}

				} else {
					output.pitch_scale = 1.0;
				}

				if (!filled_reverb) {

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

						output.reverb_vol[i] = AudioFrame(0, 0);
					}
				}

				outputs[new_output_count] = output;
				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_physics_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");
		}
	}
}