@@ -41,8 +41,7 @@ struct Source {
4141 float outerAngle ;
4242 float outerAngleVolume ;
4343 float innerDistance ;
44- float outerDistance ;
45- float outerDistanceVolume ;
44+ float minFalloffVolume ;
4645 uint32_t occlusionRays ;
4746 uint32_t transmissionRays ;
4847 float reverb ;
@@ -576,8 +575,7 @@ Source* lovrSourceClone(Source* source) {
576575 clone -> outerAngle = source -> outerAngle ;
577576 clone -> outerAngleVolume = source -> outerAngleVolume ;
578577 clone -> innerDistance = source -> innerDistance ;
579- clone -> outerDistance = source -> outerDistance ;
580- clone -> outerDistanceVolume = source -> outerDistanceVolume ;
578+ clone -> minFalloffVolume = source -> minFalloffVolume ;
581579 clone -> occlusionRays = source -> occlusionRays ;
582580 clone -> transmissionRays = source -> transmissionRays ;
583581 clone -> reverb = source -> reverb ;
@@ -764,16 +762,14 @@ void lovrSourceSetCone(Source* source, float innerAngle, float outerAngle, float
764762 source -> outerAngleVolume = outerVolume ;
765763}
766764
767- void lovrSourceGetFalloff (Source * source , float * innerDistance , float * outerDistance , float * outerVolume ) {
765+ void lovrSourceGetFalloff (Source * source , float * innerDistance , float * minVolume ) {
768766 * innerDistance = source -> innerDistance ;
769- * outerDistance = source -> outerDistance ;
770- * outerVolume = source -> outerDistanceVolume ;
767+ * minVolume = source -> minFalloffVolume ;
771768}
772769
773- void lovrSourceSetFalloff (Source * source , float innerDistance , float outerDistance , float outerVolume ) {
770+ void lovrSourceSetFalloff (Source * source , float innerDistance , float minVolume ) {
774771 source -> innerDistance = innerDistance ;
775- source -> outerDistance = outerDistance ;
776- source -> outerDistanceVolume = outerVolume ;
772+ source -> minFalloffVolume = minVolume ;
777773}
778774
779775void lovrSourceGetOcclusion (Source * source , uint32_t * occlusionRays , uint32_t * transmissionRays ) {
@@ -874,14 +870,32 @@ static void convertPose(float* position, float* orientation, IPLCoordinateSpace3
874870 vec3_init (& basis -> origin .x , position );
875871}
876872
877- static void applyAttenuation (IPLfloat32 distance , void * userdata ) {
873+ static float applyAttenuation (IPLfloat32 distance , void * userdata ) {
878874 Source * source = userdata ;
879- return 1.f ; // TODO
875+ if (distance <= source -> innerDistance ) {
876+ return 1.f ;
877+ } else {
878+ return MAX (source -> innerDistance / distance , source -> minFalloffVolume );
879+ }
880880}
881881
882- static float applyDirectivity (IPLVector3 direction , void * userdata ) {
882+ static float applyDirectivity (IPLVector3 sourceDirection , void * userdata ) {
883883 Source * source = userdata ;
884- return 1.f ; // TODO
884+
885+ float listenerDirection [3 ];
886+ vec3_init (listenerDirection , & state .listenerBasis [state .backbuffer ].origin .x );
887+ vec3_sub (listenerDirection , source -> position );
888+ vec3_normalize (listenerDirection );
889+ float angle = acosf (vec3_dot (& sourceDirection .x , listenerDirection ));
890+
891+ if (angle < source -> innerAngle ) {
892+ return 1.f ;
893+ } else if (angle >= source -> outerAngle ) {
894+ return source -> outerAngleVolume ;
895+ } else {
896+ float t = (angle - source -> innerAngle ) / (source -> outerAngle - source -> innerAngle );
897+ return source -> outerAngleVolume + (1.f - source -> outerAngleVolume ) * t ;
898+ }
885899}
886900
887901static void onSpatializerLog (IPLLogLevel iplLevel , const char * message ) {
@@ -1048,9 +1062,9 @@ static void phonon_update(float dt) {
10481062 vec3_sub (vec3_init (& source -> relativeDirection [backbuffer ].x , source -> position ), state .position );
10491063
10501064 source -> inputs .directFlags = 0 ;
1051- if (source -> outerDistanceVolume < 1.f ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_AIRABSORPTION ;
10521065 if (vec3_dot (source -> absorption , source -> absorption ) > 1e-5 ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_AIRABSORPTION ;
10531066 if (source -> innerAngle < (float ) M_PI ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_DIRECTIVITY ;
1067+ if (source -> minFalloffVolume < 1.f ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_DISTANCEATTENUATION ;
10541068 if (source -> occlusionRays > 0 ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_OCCLUSION ;
10551069 if (source -> occlusionRays > 0 && source -> transmissionRays > 0 ) source -> inputs .directFlags |= IPL_DIRECTSIMULATIONFLAGS_TRANSMISSION ;
10561070
@@ -1213,7 +1227,7 @@ static bool phonon_mix_source(Source* source, float* _src, float* dst, float* _t
12131227
12141228 // Direct effects, applied in-place
12151229 IPLDirectEffectParams * directParams = & source -> outputs [index ].direct ;
1216- if (directParams . flags ) {
1230+ if (directParams -> flags ) {
12171231 tail |= !iplDirectEffectApply (source -> directEffect , directParams , & src , & src );
12181232 }
12191233
0 commit comments