00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <math.h>
00023
00024 #include "Trace.h"
00025 #include "Vec3d.h"
00026 #include "XForm3d.h"
00027 #include "Camera.h"
00028 #include "Sound3d.h"
00029
00030
00031 typedef struct geSound3d_Cfg
00032 {
00033 geFloat Volume;
00034 geFloat Pan;
00035 geFloat Frequency;
00036 } geSound3d_Cfg;
00037
00038
00039
00040
00041
00042
00043
00044
00045 static void geSound3D_RollOut(geSound3d_Cfg *Cfg, geFloat Dist, geFloat Min, geFloat Max)
00046 {
00047 geFloat Volume;
00048 assert( Cfg != NULL );
00049
00050 if( Dist > Max )
00051 {
00052 Volume = 0.0f;
00053 }
00054 else if( Dist < Min )
00055 {
00056 Volume = 1.0f;
00057 }
00058 else
00059 Volume = 1.0f - (Dist/Min - 1)*0.1f;
00060 Cfg->Volume = Volume;
00061 }
00062
00063
00064
00065
00066 static void geSound3D_Pan(geSound3d_Cfg *Cfg, geFloat FaceOffset )
00067 {
00068 assert(Cfg != NULL);
00069 Cfg->Pan = (geFloat)sin((double)FaceOffset )*0.1f;
00070 }
00071
00072
00073
00074
00075 static void geSound3D_Doppler(geSound3d_Cfg *Cfg, geFloat Mps )
00076 {
00077
00078 assert(Cfg != NULL);
00079 Cfg->Frequency = 1.0f + (Mps/ 331.0f );
00080 }
00081
00082
00083
00084
00085
00086
00087 GENESISAPI void geSound3D_GetConfig(
00088 const geWorld *World,
00089 const geXForm3d *MXForm,
00090 const geVec3d *SndPos,
00091 geFloat Min,
00092 geFloat Ds,
00093 geFloat *Volume,
00094 geFloat *Pan,
00095 geFloat *Frequency)
00096 {
00097 geVec3d ViewPos, LocalPos, Dist;
00098 geSound3d_Cfg Cfg;
00099 geFloat Magnitude;
00100 geVec3d Origin = {0.0f, 0.0f, 0.0f};
00101 geXForm3d CXForm;
00102 int32 Leaf1, Leaf2;
00103
00104 assert( World != NULL );
00105 assert( MXForm != NULL );
00106 assert( SndPos != NULL );
00107 assert( Volume != NULL );
00108 assert( Pan != NULL );
00109 assert( Frequency != NULL );
00110
00111
00112 LocalPos = MXForm->Translation;
00113
00114 geCamera_ConvertWorldSpaceToCameraSpace(MXForm, &CXForm);
00115 geXForm3d_Transform( &CXForm, SndPos, &ViewPos);
00116
00117 if( !geWorld_GetLeaf((geWorld*)World, &LocalPos, &Leaf1) )
00118 return;
00119 if( !geWorld_GetLeaf((geWorld*)World, SndPos, &Leaf2) )
00120 return;
00121
00122 if (!geWorld_LeafMightSeeLeaf((geWorld*)World, Leaf1, Leaf2, 0))
00123 {
00124 Magnitude = 0.0f;
00125 Dist.X = 0.0f;
00126 Cfg.Volume = 0.0f;
00127 }
00128 else
00129 {
00130 GE_Collision Col;
00131
00132
00133 geVec3d_Subtract(&LocalPos, SndPos, &Dist);
00134
00135 Magnitude = geVec3d_Length(&Dist);
00136
00137 if (Trace_GEWorldCollision((geWorld*)World, NULL, NULL, &LocalPos, SndPos, GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_MODELS, 0, NULL, NULL, &Col))
00138 Magnitude *= 1.5f;
00139
00140 geSound3D_RollOut(&Cfg, Magnitude, Min, Min*10);
00141 }
00142
00143 geSound3D_Pan(&Cfg, (geFloat)atan2( (double)ViewPos.X, (double)ViewPos.Z ) );
00144
00145 geSound3D_Doppler(&Cfg, Ds);
00146
00147 *Volume = Cfg.Volume;
00148 *Pan = Cfg.Pan;
00149 *Frequency = Cfg.Frequency;
00150 }
00151
00152
00153
00154
00155
00156 GENESISAPI void geSound3D_GetConfigIgnoreObstructions(
00157 const geWorld *World,
00158 const geXForm3d *MXForm,
00159 const geVec3d *SndPos,
00160 geFloat Min,
00161 geFloat Ds,
00162 geFloat *Volume,
00163 geFloat *Pan,
00164 geFloat *Frequency)
00165 {
00166 geVec3d ViewPos, LocalPos, Dist;
00167 geSound3d_Cfg Cfg;
00168 geFloat Magnitude;
00169 geVec3d Origin = {0.0f, 0.0f, 0.0f};
00170 geXForm3d CXForm;
00171 int32 Leaf1, Leaf2;
00172
00173 assert( World != NULL );
00174 assert( MXForm != NULL );
00175 assert( SndPos != NULL );
00176 assert( Volume != NULL );
00177 assert( Pan != NULL );
00178 assert( Frequency != NULL );
00179
00180
00181 LocalPos = MXForm->Translation;
00182
00183 geCamera_ConvertWorldSpaceToCameraSpace(MXForm, &CXForm);
00184 geXForm3d_Transform( &CXForm, SndPos, &ViewPos);
00185
00186 if( !geWorld_GetLeaf((geWorld*)World, &LocalPos, &Leaf1) )
00187 return;
00188 if( !geWorld_GetLeaf((geWorld*)World, SndPos, &Leaf2) )
00189 return;
00190
00191 if (!geWorld_LeafMightSeeLeaf((geWorld*)World, Leaf1, Leaf2, 0))
00192 {
00193 Magnitude = 0.0f;
00194 Dist.X = 0.0f;
00195 Cfg.Volume = 0.0f;
00196 }
00197 else
00198 {
00199
00200 geVec3d_Subtract(&LocalPos, SndPos, &Dist);
00201
00202 Magnitude = geVec3d_Length(&Dist);
00203
00204 geSound3D_RollOut(&Cfg, Magnitude, Min, Min*10);
00205 }
00206
00207 geSound3D_Pan(&Cfg, (geFloat)atan2( (double)ViewPos.X, (double)ViewPos.Z ) );
00208
00209 geSound3D_Doppler(&Cfg, Ds);
00210
00211 *Volume = Cfg.Volume;
00212 *Pan = Cfg.Pan;
00213 *Frequency = Cfg.Frequency;
00214 }