-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: The relation between the source and the listener is unclear #182
Comments
Hi @chrisnorman7,
I think you mean OpenGL coordinate system which is right handed ;) Here the SoLoud lib documentation for 3D sound for further information, even if I think you read it already. The So for this test, I just move the position of the sound and let the listener stay still "looking" always forward (the same could be done by moving the listener). I would also tend to use Unfortunately, I think you should manage both vectors and angles :) code (add vector_math: ^2.1.4 to pubspec)import 'package:flutter/material.dart';
import 'package:flutter_soloud/flutter_soloud.dart';
import 'package:vector_math/vector_math_64.dart' as v;
import 'dart:math' show pi;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
/// Create an instance.
const MyHomePage({
super.key,
});
/// Create state for this widget.
@override
MyHomePageState createState() => MyHomePageState();
}
/// State for [MyHomePage].
class MyHomePageState extends State<MyHomePage> {
/// The current listener coordinates.
late v.Vector3 listenerCoord;
/// The current sound coordinates.
late v.Vector3 soundCoord;
/// The current sound handle.
SoundHandle? _handle;
final center = v.Vector3.zero();
final north = v.Vector3(0, 1, 0);
final west = v.Vector3(-1, 0, 0);
final east = v.Vector3(1, 0, 0);
final south = v.Vector3(0, -1, 0);
/// Initialise state.
@override
void initState() {
super.initState();
listenerCoord = center;
soundCoord = center;
}
void updateSoundCoordinates() {
SoLoud.instance.set3dSourcePosition(
_handle!,
soundCoord.x,
soundCoord.y,
soundCoord.z,
);
/// Let the listener "look" at the sound.
/// This makes the sound to be always in front of the listener and I think
/// it's not what you want.
// SoLoud.instance.set3dListenerAt(soundCoord.x, soundCoord.y, soundCoord.z);
}
/// Rotate the sound by [angleDegrees] degrees with [pivot] as origin.
void rotateAroundPoint(v.Vector3 pivot, double angleDegrees) {
// Convert angle to radians (15 degrees clockwise)
final angleRadians = v.radians(-15); // Negative for clockwise rotation
// Translate point to origin
final translated = soundCoord - pivot;
// Create rotation matrix
final rotationMatrix = Matrix4.rotationZ(angleRadians);
// Rotate point
final rotated = rotationMatrix.transform3(translated);
// Translate back to original position
soundCoord = rotated + pivot;
updateSoundCoordinates();
}
/// Build a widget.
@override
Widget build(BuildContext context) {
final soLoud = SoLoud.instance;
return Scaffold(
appBar: AppBar(
title: const Text('Example'),
),
body: Column(
children: [
if (_handle == null)
TextButton(
onPressed: () async {
await soLoud.init();
soLoud
..set3dListenerPosition(
listenerCoord.x,
listenerCoord.y,
listenerCoord.z,
)
..set3dListenerAt(
soundCoord.x,
soundCoord.y,
soundCoord.z,
)
..set3dListenerUp(0, 1, 0);
final source =
await soLoud.loadAsset('assets/audio/IveSeenThings.mp3');
final handle = await soLoud.play3d(
source,
soundCoord.x,
soundCoord.y,
soundCoord.z,
looping: true,
);
soLoud.setInaudibleBehavior(handle, true, false);
if (mounted) {
setState(() {
_handle = handle;
});
}
},
autofocus: true,
child: const Text('Play sound'),
)
else
Focus(
autofocus: true,
child: Text('listener: $listenerCoord\nsound: $soundCoord'),
),
const SizedBox(height: 30),
Center(
child: TextButton(
onPressed: () {
/// Move the sound to the north.
soundCoord = north;
updateSoundCoordinates();
setState(() {});
},
child: const Text('Move north'),
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () {
/// Move the sound to the west.
soundCoord = west;
updateSoundCoordinates();
setState(() {});
},
child: const Text('Move west'),
),
TextButton(
onPressed: () {
/// Move the sound to the east.
soundCoord = east;
updateSoundCoordinates();
setState(() {});
},
child: const Text('Move east'),
),
],
),
Center(
child: TextButton(
onPressed: () {
/// Move the sound to the south.
soundCoord = south;
updateSoundCoordinates();
setState(() {});
},
child: const Text('Move south'),
),
),
const SizedBox(height: 30),
Center(
child: TextButton(
onPressed: () {
rotateAroundPoint(center, 15.0 * pi / 180.0); // 15 degrees
setState(() {});
},
child: const Text('Rotate listener'),
),
),
],
),
);
}
} |
@alnitak This moves the sound how I'd like. How can I rotate the listener instead please? The head will never tilt, so it's just swivelling on the neck. I'm sorry this has turned more into a maths question than a SoLoud issue. Feel free to tell me to JFGI. Thanks for your help and patience. |
I think that if you swap Glad to be of any help! |
What about when your player is moving through a space and walking past sound sources? What about when the player is moving past sound sources and there are other sound sources moving in the opposite direction? |
Well, everything is relative (cit. :) ). Anyway, it all depends on what you are trying to do and how you are feeling with 3D space. I would suggest replicating what the environment is and if the listener is moving, you should move it according, and the same for the sound around. I think your example is a good start to experiencing this. |
When moving the listener position, the location of sound handles seems to jump around unpredictably.
When I run this code, the sound starts off to the right (and hopefully slightly in front, although that could be confirmation bias), then moves to the centre. When I move east, the sound goes to the right and west to the left which seems backwards.
Now I see from the website that the 3d stuff uses OpenAl algorithms, so it's entirely possible I'm setting this up wrong. If that's the case, can you direct me somewhere a non-maths person can copy-and-paste code to swirl the listener around according to simple things like angles rather than vectors?
Sorry there's no accompanying video. Microsoft GameBar refused to assist.
Cheers,
The text was updated successfully, but these errors were encountered: