#include <clustered_sound.h>
Nevrax France
Definition at line 58 of file clustered_sound.h.
Public Types | |
typedef std::map< NL3D::CCluster *, CClusterSoundStatus > | TClusterStatusMap |
Container for audible cluster status. | |
typedef std::map< NL3D::CCluster *, CSoundTravContext > | TClusterTravContextMap |
Container for the next traversal step. | |
Public Member Functions | |
CClusteredSound () | |
Constructor. | |
const TClusterStatusMap & | getAudibleClusters () |
const std::vector< std::pair< NLMISC::CVector, NLMISC::CVector > > & | getAudioPath () |
const CClusterSoundStatus * | getClusterSoundStatus (NL3D::CCluster *cluster) |
NL3D::CCluster * | getRootCluster () |
void | init (NL3D::CScene *scene, float portalInterpolate, float maxEarDistance, float minGain) |
void | update (const NLMISC::CVector &listenerPos, const NLMISC::CVector &view, const NLMISC::CVector &up) |
Private Member Functions | |
bool | addAudibleCluster (NL3D::CCluster *cluster, CClusterSoundStatus &soundStatus) |
Add a cluster into the list of audible cluster. | |
void | addNextTraverse (NL3D::CCluster *cluster, CSoundTravContext &travContext) |
Add a cluster for the next traversal step. | |
NLMISC::CVector | interpolateSourceDirection (const CSoundTravContext &context, float portalDist, const NLMISC::CVector &nearPoint, const NLMISC::CVector &realListener, NLMISC::CVector &d1, NLMISC::CVector &d2, float &alpha) |
Compute a positional blending depending on context. | |
void | soundTraverse (const std::vector< NL3D::CCluster * > &clusters, CSoundTravContext &travContext) |
Traverse the cluster system to build/update the audible cluster set and theire respective status. | |
float | getAABoxNearestPos (const NLMISC::CAABBox &box, const NLMISC::CVector &pos, NLMISC::CVector &nearPos) |
float | getPolyNearestPos (const std::vector< NLMISC::CVector > &poly, const NLMISC::CVector &pos, NLMISC::CVector &nearPoint) |
Private Attributes | |
TClusterStatusMap | _AudibleClusters |
The current audible cluster. | |
std::vector< std::pair< NLMISC::CVector, NLMISC::CVector > > | _AudioPath |
The segment of all the audio path. | |
std::hash_map< NLMISC::TStringId, uint > | _IdToEaxEnv |
The mapping for env name Id to EAX environement number. | |
std::hash_map< NLMISC::TStringId, uint > | _IdToMaterial |
The mapping for occlusion material name to material number. | |
uint | _LastEnv |
The last setted environement. | |
float | _MaxEarDistance |
Maximum earing distance. | |
float | _MinGain |
Minimum gain. | |
TClusterTravContextMap | _NextTraversalStep |
The cluster for the next travesal step. | |
float | _PortalInterpolate |
Interpolation distance when listener is near a portal. | |
NL3D::CCluster * | _RootCluster |
The root cluster of the scene. | |
NL3D::CScene * | _Scene |
The scene of interest. | |
std::hash_map< NLMISC::TStringId, NLMISC::TStringId > | _SoundGroupToSound |
The sound_group to sound assoc. | |
std::hash_map< NLMISC::TStringId, CClusterSound > | _Sources |
The current cluster playing source indexed with sound group id. | |
Static Private Attributes | |
char * | _EnvironmentNames [] |
The environment name table for init. | |
char * | _MaterialNames [] |
The material name table for init. |
|
Container for audible cluster status.
Definition at line 87 of file clustered_sound.h. Referenced by getAudibleClusters(). |
|
Container for the next traversal step.
Definition at line 175 of file clustered_sound.h. |
|
Constructor.
Definition at line 222 of file clustered_sound.cpp. References _EnvironmentNames, _IdToEaxEnv, _IdToMaterial, _MaterialNames, and uint.
00223 : _Scene(0), 00224 _RootCluster(0), 00225 _LastEnv(0xffffffff) 00226 { 00227 // fill the env name table 00228 uint i; 00229 for (i=0; _EnvironmentNames[i] != 0; ++i) 00230 { 00231 _IdToEaxEnv.insert(make_pair(CStringMapper::map(string(_EnvironmentNames[i])), i)); 00232 } 00233 // fill the material name table 00234 for (i=0; _MaterialNames[i] != 0; ++i) 00235 { 00236 _IdToMaterial.insert(make_pair(CStringMapper::map(string(_MaterialNames[i])), i)); 00237 } 00238 00239 } |
|
Add a cluster into the list of audible cluster.
Definition at line 957 of file clustered_sound.cpp. References _AudibleClusters, _MaxEarDistance, NLSOUND::CClusteredSound::CClusterSoundStatus::Direction, NLSOUND::CClusteredSound::CClusterSoundStatus::Dist, nlassert, and NLMISC::CVector::norm(). Referenced by soundTraverse().
00958 { 00959 TClusterStatusMap::iterator it(_AudibleClusters.find(cluster)); 00960 nlassert(soundStatus.Dist < _MaxEarDistance); 00961 nlassert(soundStatus.Direction.norm() <= 1.01f); 00962 00963 if (it != _AudibleClusters.end()) 00964 { 00965 // get the best one (for now, based on shortest distance) 00966 if (soundStatus.Dist < it->second.Dist) 00967 { 00968 it->second = soundStatus; 00969 00970 return true; 00971 } 00972 } 00973 else 00974 { 00975 _AudibleClusters.insert(make_pair(cluster, soundStatus)); 00976 return true; 00977 } 00978 00979 return false; 00980 } |
|
Add a cluster for the next traversal step.
Definition at line 941 of file clustered_sound.cpp. References _NextTraversalStep, and NLSOUND::CClusteredSound::CSoundTravContext::Dist. Referenced by soundTraverse().
00942 { 00943 std::map<CCluster*, CSoundTravContext>::iterator it = _NextTraversalStep.find(cluster); 00944 00945 if (it != _NextTraversalStep.end()) 00946 { 00947 if (it->second.Dist > travContext.Dist) 00948 { 00949 it->second = travContext; 00950 } 00951 } 00952 else 00953 _NextTraversalStep.insert(make_pair(cluster, travContext)); 00954 00955 } |
|
Compute the point in the bounding box that is the nearest from a given position. This point can be in the volume of the box, on a segment of one of the vertex. In addition, the method also return the distance from the nearest point to the reference position.
Definition at line 1155 of file clustered_sound.cpp. References NLMISC::clamp(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. Referenced by soundTraverse().
01156 { 01157 CVector vMin, vMax; 01158 box.getMin(vMin); 01159 box.getMax(vMax); 01160 01161 01162 nearPos = pos; 01163 // X 01164 clamp(nearPos.x, vMin.x, vMax.x); 01165 // Y 01166 clamp(nearPos.y, vMin.y, vMax.y); 01167 // Z 01168 clamp(nearPos.z, vMin.z, vMax.z); 01169 01170 return (pos-nearPos).norm(); 01171 } |
|
Definition at line 198 of file clustered_sound.h. References _AudibleClusters, and TClusterStatusMap.
00198 {return _AudibleClusters;} |
|
Definition at line 200 of file clustered_sound.h. References _AudioPath.
00200 { return _AudioPath;} |
|
Definition at line 459 of file clustered_sound.cpp. References _AudibleClusters. Referenced by NLSOUND::CAudioMixerUser::update(), and NLSOUND::CBackgroundSoundManager::updateBackgroundStatus().
00460 { 00461 TClusterStatusMap::iterator it(_AudibleClusters.find(cluster)); 00462 00463 if (it == _AudibleClusters.end()) 00464 { 00465 return 0; 00466 } 00467 else 00468 return &(it->second); 00469 } |
|
Compute the point on the poly that is the nearest from a given position. This point can be on the surface of the poly, on a segment or on one of the vertex. In addition, the method also return the distance from the nearest point to the reference position.
Definition at line 1098 of file clustered_sound.cpp. References NLMISC::CPlane::getNormal(), NLMISC::CPlane::make(), NLMISC::CVector::norm(), NLMISC::CPlane::project(), NLMISC::CVector::sqrnorm(), and uint. Referenced by soundTraverse().
01099 { 01100 CPlane plane; 01101 plane.make(poly[0], poly[1], poly[2]); 01102 CVector proj = plane.project(pos); 01103 float minDist = FLT_MAX; 01104 bool projIn = true; 01105 uint nbVertex = poly.size(); 01106 01107 // loop throw all vertex 01108 for (uint j=0; j<nbVertex; ++j) 01109 { 01110 float d = (pos-poly[j]).sqrnorm(); 01111 // check if the vertex is the nearest point 01112 if (d < minDist) 01113 { 01114 nearPoint = poly[j]; 01115 minDist = d; 01116 } 01117 // if (projIn /*&& j<poly.size()-1*/) 01118 { 01119 // check each segment 01120 if (plane.getNormal()*((poly[(j+1)%nbVertex] - poly[j]) ^ (proj - poly[j])) < 0) 01121 { 01122 // the point is not inside the poly surface ! 01123 projIn = false; 01124 // check if the nearest point is on this segment 01125 CVector v1 = (poly[(j+1)%nbVertex] - poly[j]); 01126 float v1Len = v1.norm(); 01127 v1 = v1 / v1Len; 01128 CVector v2 = proj - poly[j]; 01129 // project v2 on v1 01130 float p = v1 * v2; 01131 if (p>=0 && p<=v1Len) 01132 { 01133 // the nearest point is on the segment! 01134 nearPoint = poly[j] + v1 * p; 01135 minDist = (nearPoint-pos).sqrnorm(); 01136 break; 01137 } 01138 } 01139 } 01140 } 01141 if (projIn) 01142 { 01143 float d = (proj-pos).sqrnorm(); 01144 if (d < minDist) 01145 { 01146 // the nearest point is on the surface 01147 nearPoint = proj; 01148 minDist = d; 01149 } 01150 } 01151 01152 return sqrtf(minDist); 01153 } |
|
Definition at line 472 of file clustered_sound.cpp. References NL3D::CScene::getClipTrav(). Referenced by NLSOUND::CBackgroundSoundManager::updateBackgroundStatus().
00473 { 00474 if (_Scene == 0) 00475 return 0; 00476 00477 return _Scene->getClipTrav().RootCluster; 00478 } |
|
Initialize the class
Definition at line 242 of file clustered_sound.cpp. References _MaxEarDistance, _MinGain, _PortalInterpolate, _RootCluster, _SoundGroupToSound, NLSOUND::Container, and NL3D::CScene::getClipTrav(). Referenced by NLSOUND::CAudioMixerUser::initClusteredSound().
00243 { 00244 // load the sound_group sheets 00245 ::loadForm("sound_group", CAudioMixerUser::instance()->getPackedSheetPath()+"sound_groups.packed_sheets", Container, CAudioMixerUser::instance()->getPackedSheetUpdate(), false); 00246 00247 // copy the container data into internal structure 00248 std::map<std::string, CSoundGroupSerializer>::iterator first(Container.begin()), last(Container.end()); 00249 for (; first != last; ++first) 00250 { 00251 _SoundGroupToSound.insert(first->second._SoundGroupAssoc.begin(), first->second._SoundGroupAssoc.end()); 00252 } 00253 00254 // and clear the temporary Container 00255 Container.clear(); 00256 00257 00258 _Scene = scene; 00259 _PortalInterpolate = portalInterpolate; 00260 _MaxEarDistance = maxEarDist; 00261 _MinGain = minGain; 00262 if(scene != 0) 00263 { 00264 _RootCluster = _Scene->getClipTrav().RootCluster; 00265 } 00266 else 00267 _RootCluster = 0; 00268 } |
|
Compute a positional blending depending on context.
Definition at line 982 of file clustered_sound.cpp. References _PortalInterpolate, alpha, NLSOUND::CClusteredSound::CSoundTravContext::NbPortal, nlassert, NLMISC::CVector::norm(), and NLMISC::CVector::normed(). Referenced by soundTraverse().
00983 { 00984 CVector direction;// (context.Direction); 00985 00986 if (portalDist > _PortalInterpolate || alpha >= 1.0f) 00987 { 00988 // the portal is too far, no interpolation. 00989 if (context.NbPortal == 0) 00990 { 00991 // it's the first portal, compute the initial virtual sound direction 00992 direction = d1 = (nearPoint-realListener).normed(); 00993 } 00994 else 00995 { 00996 direction = (nearPoint-realListener).normed(); 00997 direction = (direction * (1-alpha) + d1 * (alpha)).normed(); 00998 d1 = direction; 00999 } 01000 alpha = 1; 01001 } 01002 else 01003 { 01004 // the portal is near the listener, interpolate the direction 01005 if (context.NbPortal == 0) 01006 { 01007 // It's the first portal, compute the initial direction 01008 alpha = (portalDist / _PortalInterpolate); 01009 // alpha = alpha*alpha*alpha; 01010 direction = d1 = (nearPoint-realListener).normed(); 01011 } 01012 /* else if (context.NbPortal == 1) 01013 { 01014 float factor = (1-alpha); 01015 // factor = factor*factor*factor; 01016 direction = (nearPoint-realListener).normed(); 01017 direction = d1 = (direction * factor + d1 * (1-factor)).normed(); 01018 01019 // alpha = 1-factor; 01020 alpha = factor; 01021 } 01022 */ else 01023 { 01024 // two or more portal 01025 float factor = (portalDist / _PortalInterpolate) * (1-alpha); 01026 // factor = factor*factor*factor; 01027 direction = (nearPoint-realListener).normed(); 01028 direction = d1 = (direction * factor + d1 * alpha).normed(); 01029 01030 // alpha = 1-factor; 01031 alpha = factor; 01032 } 01033 } 01034 01035 nlassert(direction.norm() <= 1.01f); 01036 return direction; 01037 /* 01038 CVector direction (context.Direction); 01039 d1 = context.Direction1; 01040 d2 = context.Direction2; 01041 01042 01043 if (portalDist < _PortalInterpolate) 01044 { 01045 if (context.NbPortal == 0) 01046 { 01047 alpha = (portalDist / _PortalInterpolate); 01048 direction = d1 = (nearPoint-realListener).normed() * alpha; 01049 direction.normalize(); 01050 } 01051 else if (context.NbPortal == 1) 01052 { 01053 alpha = alpha * (portalDist / _PortalInterpolate); 01054 // d2 = (nearPoint-realListener).normed() * alpha; 01055 d2 = (nearPoint-context.ListenerPos).normed() * (1-alpha); 01056 direction = d1 + d2; 01057 direction.normalize(); 01058 } 01059 else 01060 { 01061 alpha = alpha * (portalDist / _PortalInterpolate); 01062 // d1 = d1+d2; 01063 d2 = (nearPoint-context.ListenerPos).normed() * (1-alpha); 01064 // direction = d1 + d2 + (nearPoint-context.ListenerPos).normed() * (1-alpha); 01065 direction = d1 + d2; 01066 direction.normalize(); 01067 } 01068 } 01069 else 01070 { 01071 // alpha = 0.0f 01072 if (context.NbPortal == 0) 01073 { 01074 direction = d1 = (nearPoint-realListener).normed(); 01075 } 01076 else if (context.NbPortal == 1) 01077 { 01078 d2 = (nearPoint-context.ListenerPos).normed() * (1-alpha); 01079 // d2 = d1; //(nearPoint-context.ListenerPos).normed(); // * (1-alpha); 01080 direction = d1+d2; 01081 direction.normalize(); 01082 } 01083 else 01084 { 01085 // d2 = (nearPoint-context.ListenerPos).normed() * (1-alpha); 01086 d1 = d1+d2; 01087 // d2 = (nearPoint-realListener).normed(); 01088 // direction = d1+d2+(nearPoint-context.ListenerPos).normed() * (1-alpha); 01089 direction.normalize(); 01090 } 01091 } 01092 01093 return direction; 01094 */ 01095 } |
|
Traverse the cluster system to build/update the audible cluster set and theire respective status.
Definition at line 481 of file clustered_sound.cpp. References _AudibleClusters, _AudioPath, _IdToMaterial, _MaxEarDistance, _MinGain, _NextTraversalStep, _PortalInterpolate, _RootCluster, addAudibleCluster(), addNextTraverse(), NLSOUND::CClusteredSound::CSoundTravContext::Alpha, alpha, NLSOUND::CClusteredSound::CSoundTravContext::Direction, NLSOUND::CClusteredSound::CClusterSoundStatus::Direction, NLSOUND::CClusteredSound::CSoundTravContext::Direction1, NLSOUND::CClusteredSound::CSoundTravContext::Direction2, NLSOUND::CClusteredSound::CSoundTravContext::Dist, NLSOUND::CClusteredSound::CClusterSoundStatus::Dist, NLSOUND::CClusteredSound::CClusterSoundStatus::DistFactor, NLSOUND::EAX_MATERIAL_PARAM, NL3D::CCluster::FatherAudible, NLSOUND::CClusteredSound::CSoundTravContext::FilterUnvisibleChild, NLSOUND::CClusteredSound::CSoundTravContext::FilterUnvisibleFather, NLSOUND::CClusteredSound::CSoundTravContext::Gain, NLSOUND::CClusteredSound::CClusterSoundStatus::Gain, getAABoxNearestPos(), getPolyNearestPos(), H_AUTO, interpolateSourceDirection(), NLSOUND::CClusteredSound::CSoundTravContext::ListenerPos, min, NLSOUND::CClusteredSound::CSoundTravContext::NbPortal, nlassert, nlwarning, NLMISC::CVector::normed(), NLSOUND::CClusteredSound::CSoundTravContext::Obstruction, NLSOUND::CClusteredSound::CClusterSoundStatus::Obstruction, NLSOUND::CClusteredSound::CSoundTravContext::Occlusion, NLSOUND::CClusteredSound::CClusterSoundStatus::Occlusion, NLSOUND::CClusteredSound::CSoundTravContext::OcclusionLFFactor, NLSOUND::CClusteredSound::CClusterSoundStatus::OcclusionLFFactor, NLSOUND::CClusteredSound::CSoundTravContext::OcclusionRoomRatio, NLSOUND::CClusteredSound::CClusterSoundStatus::OcclusionRoomRatio, NLSOUND::CClusteredSound::CClusterSoundStatus::PosAlpha, NLSOUND::CClusteredSound::CClusterSoundStatus::Position, NLSOUND::CClusteredSound::CSoundTravContext::PreviousCluster, NLSOUND::CClusteredSound::CSoundTravContext::PreviousVector, sint32, and uint. Referenced by update().
00482 { 00483 H_AUTO(NLSOUND_soundTraverse) 00484 // std::map<CCluster*, CSoundTravContext> nextTraverse; 00485 std::vector<std::pair<const CCluster*, CSoundTravContext> > curClusters; 00486 CVector realListener (travContext.ListenerPos); 00487 00488 _AudioPath.clear(); 00489 00490 // fill the initial cluster liste 00491 CClusterSoundStatus css; 00492 css.Direction = CVector::Null; 00493 css.DistFactor = 0.0f; 00494 css.Dist = 0.0f; 00495 css.Gain = 1.0f; 00496 css.Occlusion = 0; 00497 css.OcclusionLFFactor = 1.0f; 00498 css.OcclusionRoomRatio = 1.0f; 00499 css.Obstruction = 0; 00500 css.PosAlpha = 0; 00501 // css.Position = CVector::Null; 00502 css.Position = realListener; 00503 00504 for (uint i=0; i<clusters.size(); ++i) 00505 { 00506 bool valid = true; 00507 // eliminate cluster when listener is behind their portals AND inside the other cluster 00508 for (uint j=0; j<clusters[i]->getNbPortals(); j++) 00509 { 00510 CPortal *portal = clusters[i]->getPortal(j); 00511 const std::vector<CVector> &poly = portal->getPoly(); 00512 00513 if (poly.size() < 3) 00514 { 00515 // only warn once, avoid log flooding ! 00516 static std::set<std::string> warned; 00517 if (warned.find(clusters[i]->Name) == warned.end()) 00518 { 00519 nlwarning("Cluster [%s] contains a portal [%s] with less than 3 vertex !", 00520 clusters[i]->Name.c_str(), portal->getName().empty() ? "no name" : portal->getName().c_str()); 00521 warned.insert(clusters[i]->Name); 00522 } 00523 valid = false; 00524 continue; 00525 } 00526 CVector normal = (poly[0] - poly[1]) ^ (poly[2] - poly[1]); 00527 00528 float dist = (realListener - poly[0]) * normal; 00529 float dist2 = (clusters[i]->getBBox().getCenter() - poly[0]) * normal; 00530 00531 if ((dist < 0 && dist2 > 0) || (dist > 0 && dist2 < 0)) 00532 { 00533 if (portal->getCluster(0) == clusters[i]) 00534 { 00535 if (find(clusters.begin(), clusters.end(), portal->getCluster(1)) != clusters.end()) 00536 { 00537 valid = false; 00538 continue; 00539 } 00540 } 00541 else if (find(clusters.begin(), clusters.end(), portal->getCluster(0)) != clusters.end()) 00542 { 00543 valid = false; 00544 continue; 00545 } 00546 00547 } 00548 00549 /* 00550 if (portal->getCluster(0) == clusters[i] && dist > 0) 00551 // if (!portal->isInFront(realListener)) 00552 { 00553 valid = false; 00554 continue; 00555 } 00556 else if (portal->getCluster(1) == clusters[i] && dist < 0) 00557 // if (portal->isInFront(realListener)) 00558 { 00559 valid = false; 00560 continue; 00561 } 00562 */ 00563 } 00564 if( valid) 00565 { 00566 curClusters.push_back(make_pair(clusters[i], travContext)); 00567 addAudibleCluster(clusters[i], css); 00568 } 00569 } 00570 00571 do 00572 { 00573 // add the next traverse (if any) 00574 std::copy(_NextTraversalStep.begin(), _NextTraversalStep.end(), std::back_inserter(curClusters)); 00575 _NextTraversalStep.clear(); 00576 00577 while (!curClusters.empty()) 00578 { 00579 CCluster * cluster = const_cast<CCluster*>(curClusters.back().first); 00580 CSoundTravContext &travContext = curClusters.back().second; 00581 00582 CClusterSoundStatus css; 00583 css.Gain = travContext.Gain; 00584 css.Dist = travContext.Dist; 00585 css.Direction = travContext.Direction; 00586 css.Occlusion = travContext.Occlusion; 00587 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00588 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00589 css.Obstruction = travContext.Obstruction; 00590 00591 // store this cluster and it's parameters 00592 _AudibleClusters.insert(make_pair(cluster, css)); 00593 00594 // 1st, look each portal 00595 uint i; 00596 for (i=0; i<cluster->getNbPortals(); ++i) 00597 { 00598 CPortal *portal = cluster->getPortal(i); 00599 // get the other cluster 00600 CCluster *otherCluster = portal->getCluster(0); 00601 bool clusterInFront = true; 00602 if (otherCluster == cluster) 00603 { 00604 otherCluster = portal->getCluster(1); 00605 clusterInFront = false; 00606 } 00607 nlassert(otherCluster != cluster); 00608 00609 if (otherCluster && travContext.PreviousCluster != otherCluster) // && (!travContext.FilterUnvisibleChild || otherCluster->AudibleFromFather)) 00610 { 00611 const vector<CVector> &poly = portal->getPoly(); 00612 00613 // a security test 00614 if (poly.size() < 3) 00615 { 00616 // only warn once, avoid log flooding ! 00617 static std::set<std::string> warned; 00618 if (warned.find(cluster->Name) == warned.end()) 00619 { 00620 nlwarning("Cluster [%s] contains a portal [%s] with less than 3 vertex !", 00621 cluster->Name.c_str(), portal->getName().empty() ? "no name" : portal->getName().c_str()); 00622 warned.insert(cluster->Name); 00623 } 00624 } 00625 else 00626 { 00627 00628 // Test to skip portal with suface > 40 m2 (aprox) 00629 float surface = ((poly[2]-poly[1]) ^ (poly[0]-poly[1])).norm(); 00630 if (surface > 340 /* && otherCluster->isIn(travContext.ListenerPos, travContext.MaxDist-travContext.Dist)*/) 00631 { 00632 float minDist; 00633 CVector nearPos; 00634 CAABBox box = otherCluster->getBBox(); 00635 00636 minDist = getAABoxNearestPos(box, travContext.ListenerPos, nearPos); 00637 00638 if (travContext.Dist + minDist < _MaxEarDistance) 00639 { 00640 CVector soundDir = (nearPos - travContext.ListenerPos).normed(); 00641 CClusterSoundStatus css; 00642 css.Gain = travContext.Gain; 00643 css.Dist = travContext.Dist + minDist; 00644 css.Occlusion = travContext.Occlusion; 00645 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00646 css.Obstruction = travContext.Obstruction; 00647 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00648 css.DistFactor = css.Dist / _MaxEarDistance; 00649 css.Direction = travContext.Direction; 00650 00651 float alpha = travContext.Alpha; 00652 CVector d1(travContext.Direction1), d2; 00653 00654 css.Direction = interpolateSourceDirection(travContext, css.Dist+travContext.Dist, nearPos, travContext.ListenerPos /*realListener*/, d1, d2, alpha); 00655 css.Position = nearPos + css.Dist * css.Direction; 00656 css.PosAlpha = min(1.0f, css.Dist / _PortalInterpolate); 00657 00658 if (addAudibleCluster(otherCluster, css)) 00659 { 00660 // debugLines.push_back(CLine(travContext.ListenerPos, nearPos)); 00661 CSoundTravContext stc(travContext); 00662 stc.FilterUnvisibleChild = true; 00663 stc.Direction1 = d1; 00664 stc.Direction2 = d2; 00665 stc.Direction = css.Direction; 00666 stc.PreviousCluster = cluster; 00667 stc.Alpha = alpha; 00668 stc.PreviousVector = (nearPos - travContext.ListenerPos).normed(); 00669 addNextTraverse(otherCluster, stc); 00670 _AudioPath.push_back(make_pair(travContext.ListenerPos, nearPos)); 00671 } 00672 } 00673 } 00674 else 00675 { 00676 // find the nearest point of this portal (either on of the perimeter vertex or a point on the portal surface) 00677 float minDist; 00678 CVector nearPos; 00679 00680 minDist = getPolyNearestPos(poly, travContext.ListenerPos, nearPos); 00681 00682 if (travContext.Dist+minDist < _MaxEarDistance) 00683 { 00684 // TODO : compute relative gain according to portal behavior. 00685 CClusterSoundStatus css; 00686 css.Gain = travContext.Gain; 00687 CVector soundDir = (nearPos - travContext.ListenerPos).normed(); 00688 uint occId = portal->getOcclusionModelId(); 00689 std::hash_map<NLMISC::TStringId, uint>::iterator it(_IdToMaterial.find(occId)); 00690 00691 #if EAX_AVAILABLE == 1 00692 if (it != _IdToMaterial.end()) 00693 { 00694 // found an occlusion material for this portal 00695 uint matId = it->second; 00696 css.Occlusion = max(sint32(EAXBUFFER_MINOCCLUSION), sint32(travContext.Occlusion + EAX_MATERIAL_PARAM[matId][0])); //- 1800); //EAX_MATERIAL_THINDOOR; 00697 css.OcclusionLFFactor = travContext.OcclusionLFFactor * EAX_MATERIAL_PARAM[matId][1]; //EAX_MATERIAL_THICKDOORLF; //0.66f; //0.0f; //min(EAX_MATERIAL_THINDOORLF, travContext.OcclusionLFFactor); 00698 css.OcclusionRoomRatio = EAX_MATERIAL_PARAM[matId][2] * travContext.OcclusionRoomRatio; 00699 } 00700 else 00701 { 00702 // the id does not match any know material 00703 css.Occlusion = travContext.Occlusion; 00704 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00705 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00706 } 00707 #else // EAX_AVAILABLE 00708 if (it != _IdToMaterial.end()) 00709 { 00710 // found an occlusion material for this portal 00711 uint matId = it->second; 00712 css.Gain *= EAX_MATERIAL_PARAM[matId]; 00713 } 00714 #endif // EAX_AVAILABLE 00715 /* if (portal->getOcclusionModel() == "wood door") 00716 { 00717 // css.Gain *= 0.5f; 00718 #if EAX_AVAILABLE == 1 00719 css.Occlusion = max(EAXBUFFER_MINOCCLUSION, travContext.Occlusion + EAX_MATERIAL_THICKDOOR); //- 1800); //EAX_MATERIAL_THINDOOR; 00720 css.OcclusionLFFactor = 0.1f * travContext.OcclusionLFFactor; //EAX_MATERIAL_THICKDOORLF; //0.66f; //0.0f; //min(EAX_MATERIAL_THINDOORLF, travContext.OcclusionLFFactor); 00721 css.OcclusionRoomRatio = EAX_MATERIAL_THICKDOORROOMRATION * travContext.OcclusionRoomRatio; 00722 #else 00723 css.Gain *= 0.5f; 00724 #endif 00725 } 00726 else if (portal->getOcclusionModel() == "brick door") 00727 { 00728 #if EAX_AVAILABLE == 1 00729 css.Occlusion = max(EAXBUFFER_MINOCCLUSION, travContext.Occlusion + EAX_MATERIAL_BRICKWALL); 00730 css.OcclusionLFFactor = min(EAX_MATERIAL_BRICKWALLLF, travContext.OcclusionLFFactor); 00731 css.OcclusionRoomRatio = EAX_MATERIAL_BRICKWALLROOMRATIO * travContext.OcclusionRoomRatio; 00732 #else 00733 css.Gain *= 0.2f; 00734 #endif 00735 } 00736 else 00737 { 00738 #if EAX_AVAILABLE == 1 00739 css.Occlusion = travContext.Occlusion; 00740 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00741 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00742 #endif 00743 } 00744 00745 */ // compute obstruction 00746 if (travContext.NbPortal >= 1) 00747 { 00748 float h = soundDir * travContext.PreviousVector; 00749 float obst; 00750 00751 if (h < 0) 00752 { 00753 // obst = float(2000 + asinf(-(soundDir ^ travContext.PreviousVector).norm()) / (Pi/2) * 2000); 00754 obst = float(4000 - (soundDir ^ travContext.PreviousVector).norm() * 2000); 00755 } 00756 else 00757 { 00758 // obst = float(asinf((soundDir ^ travContext.PreviousVector).norm()) / (Pi/2) * 2000); 00759 obst = float((soundDir ^ travContext.PreviousVector).norm() * 2000); 00760 } 00761 00762 // float sqrdist = (realListener - nearPoint).sqrnorm(); 00763 if (travContext.Dist < 2.0f) // interpolate a 2 m 00764 obst *= travContext.Dist / 2.0f; 00765 #if EAX_AVAILABLE == 1 00766 css.Obstruction = max(sint32(EAXBUFFER_MINOBSTRUCTION), sint32(travContext.Obstruction - sint32(obst))); 00767 css.OcclusionLFFactor = 0.50f * travContext.OcclusionLFFactor; 00768 #else 00769 css.Gain *= float(pow(10, -(obst/4)/2000)); 00770 #endif 00771 } 00772 else 00773 css.Obstruction = travContext.Obstruction; 00774 // css.Dist = travContext.Dist + float(sqrt(minDist)); 00775 css.Dist = travContext.Dist + minDist; 00776 css.DistFactor = css.Dist / _MaxEarDistance; 00777 float portalDist = css.Dist; 00778 float alpha = travContext.Alpha; 00779 CVector d1(travContext.Direction1), d2(travContext.Direction2); 00780 00781 css.Direction = interpolateSourceDirection(travContext, portalDist+travContext.Dist, nearPos, travContext.ListenerPos /*realListener*/, d1, d2, alpha); 00782 css.Position = nearPos + css.Dist * css.Direction; 00783 css.PosAlpha = min(1.0f, css.Dist / _PortalInterpolate); 00784 00785 if (addAudibleCluster(otherCluster, css)) 00786 { 00787 // debugLines.push_back(CLine(travContext.ListenerPos, nearPoint)); 00788 CSoundTravContext tc(nearPos, travContext.FilterUnvisibleChild, !cluster->AudibleFromFather); 00789 tc.Dist = css.Dist; 00790 tc.Gain = css.Gain; 00791 tc.Occlusion = css.Occlusion; 00792 tc.OcclusionLFFactor = css.OcclusionLFFactor; 00793 tc.OcclusionRoomRatio = css.OcclusionRoomRatio; 00794 tc.Obstruction = css.Obstruction; 00795 tc.Direction1 = d1; 00796 tc.Direction2 = d2; 00797 tc.NbPortal = travContext.NbPortal+1; 00798 tc.Direction = css.Direction; 00799 tc.PreviousCluster = cluster; 00800 tc.Alpha = alpha; 00801 tc.PreviousVector = soundDir; 00802 00803 addNextTraverse(otherCluster, tc); 00804 _AudioPath.push_back(make_pair(travContext.ListenerPos, nearPos)); 00805 } 00806 } 00807 } 00808 } 00809 } 00810 } 00811 00812 // 2nd, look each child cluster 00813 for (i=0; i<cluster->Children.size(); ++i) 00814 { 00815 CCluster *c = cluster->Children[i]; 00816 00817 // dont redown into an upstream 00818 if (c != travContext.PreviousCluster) 00819 { 00820 // clip on distance. 00821 if (c->AudibleFromFather && c->isIn(travContext.ListenerPos, _MaxEarDistance-travContext.Dist)) 00822 { 00823 float minDist; 00824 CVector nearPos; 00825 CAABBox box = c->getBBox(); 00826 00827 minDist = getAABoxNearestPos(box, travContext.ListenerPos, nearPos); 00828 00829 if (travContext.Dist + minDist < _MaxEarDistance) 00830 { 00831 CClusterSoundStatus css; 00832 css.Gain = travContext.Gain; 00833 css.Dist = travContext.Dist + minDist; 00834 css.DistFactor = css.Dist / _MaxEarDistance; 00835 css.Occlusion = travContext.Occlusion; 00836 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00837 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00838 css.Obstruction = travContext.Obstruction; 00839 /* if (travContext.NbPortal == 0) 00840 css.Direction = (nearPos - travContext.ListenerPos).normed(); 00841 else 00842 css.Direction = travContext.Direction1; 00843 */ 00844 float alpha = travContext.Alpha; 00845 CVector d1(travContext.Direction1), d2; 00846 00847 css.Direction = interpolateSourceDirection(travContext, css.Dist+travContext.Dist, nearPos, travContext.ListenerPos /*realListener*/, d1, d2, alpha); 00848 css.Position = nearPos + css.Dist * css.Direction; 00849 css.PosAlpha = min(1.0f, css.Dist / _PortalInterpolate); 00850 00851 if (addAudibleCluster(c, css)) 00852 { 00853 // debugLines.push_back(CLine(travContext.ListenerPos, nearPos)); 00854 CSoundTravContext stc(travContext); 00855 stc.FilterUnvisibleChild = true; 00856 stc.Direction1 = d1; 00857 stc.Direction2 = d2; 00858 stc.Direction = css.Direction; 00859 stc.PreviousCluster = cluster; 00860 stc.Alpha = alpha; 00861 stc.PreviousVector = (nearPos - travContext.ListenerPos).normed(); 00862 addNextTraverse(c, stc); 00863 _AudioPath.push_back(make_pair(travContext.ListenerPos, nearPos)); 00864 } 00865 } 00866 } 00867 } 00868 } 00869 00870 // 3nd, look in father cluster 00871 if (cluster->Father && cluster->Father != travContext.PreviousCluster && cluster->FatherAudible) 00872 { 00873 // if (!travContext.FilterUnvisibleFather || ((1.0f-travContext.Alpha) > travContext.MinGain)) 00874 { 00875 CCluster *c = cluster->Father; 00876 float minDist; 00877 CVector nearPos; 00878 CAABBox box = c->getBBox(); 00879 00880 if (c != _RootCluster) 00881 minDist = getAABoxNearestPos(box, travContext.ListenerPos, nearPos); 00882 else 00883 { 00884 // special case for root cluster coz it have a zero sized box and a zero position. 00885 nearPos = travContext.ListenerPos; 00886 minDist = 0; 00887 } 00888 00889 CClusterSoundStatus css; 00890 css.Gain = travContext.Gain; 00891 /* if (travContext.FilterUnvisibleFather) 00892 { 00893 // compute a gain 00894 float alpha = 1-(travContext.Dist / _PortalInterpolate); 00895 alpha = alpha * alpha * alpha; 00896 css.Gain = max(0.0f, alpha); 00897 } 00898 else 00899 css.Gain = travContext.Gain; 00900 */ 00901 // if (c->Name == "cluster_1") 00902 // nldebug("Cluster 1 : gain = %f", css.Gain); 00903 float alpha = travContext.Alpha; 00904 CVector d1(travContext.Direction1), d2; 00905 00906 css.Direction = interpolateSourceDirection(travContext, travContext.Dist, nearPos, travContext.ListenerPos /*realListener*/, d1, d2, alpha); 00907 00908 if (css.Gain > _MinGain) 00909 { 00910 css.Dist = travContext.Dist; 00911 // css.Direction = CVector::Null; 00912 css.DistFactor = css.Dist / _MaxEarDistance; 00913 css.Occlusion = travContext.Occlusion; 00914 css.OcclusionLFFactor = travContext.OcclusionLFFactor; 00915 css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; 00916 css.Obstruction = travContext.Obstruction; 00917 css.Position = nearPos + css.Dist * css.Direction; 00918 css.PosAlpha = min(1.0f, css.Dist / _PortalInterpolate); 00919 00920 if (addAudibleCluster(c, css)) 00921 { 00922 CSoundTravContext stc(travContext); 00923 stc.FilterUnvisibleFather = true; 00924 stc.PreviousCluster = cluster; 00925 stc.Direction1 = d1; 00926 stc.Direction2 = d2; 00927 stc.Direction = css.Direction; 00928 stc.Alpha = alpha; 00929 stc.PreviousVector = (nearPos - travContext.ListenerPos).normed(); 00930 _NextTraversalStep.insert(make_pair(c, stc)); 00931 } 00932 } 00933 } 00934 } 00935 curClusters.pop_back(); 00936 } 00937 } 00938 while (!_NextTraversalStep.empty()); 00939 } |
|
Update the cluster sound system. css.DistFactor*css.DistFactor Definition at line 270 of file clustered_sound.cpp. References _AudibleClusters, _IdToEaxEnv, _RootCluster, _SoundGroupToSound, NLSOUND::CClusteredSound::CClusterSoundStatus::Direction, NLSOUND::CClusteredSound::CClusterSoundStatus::Dist, NLSOUND::CClusteredSound::CClusterSound::Distance, NLSOUND::CClusteredSound::CClusterSoundStatus::DistFactor, EAXLISTENER_MAXENVIRONMENTSIZE, NLSOUND::CClusteredSound::CClusterSoundStatus::Gain, NL3D::CScene::getClipTrav(), NLMISC::CAABBox::getHalfSize(), NLSOUND::CAudioMixerUser::getListener(), H_AUTO, min, NLMISC::minof(), nldebug, nlwarning, NLSOUND::IListener::setEnvironment(), NLSOUND::USource::setLooping(), NLSOUND::USource::setPos(), NLSOUND::USource::setRelativeGain(), size, soundTraverse(), NLSOUND::CClusteredSound::CClusterSound::Source, uint, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. Referenced by NLSOUND::CAudioMixerUser::update().
00271 { 00272 H_AUTO(NLSOUND_ClusteredSoundUpdate) 00273 if (_Scene == 0) 00274 { 00275 // hum... what to do ? 00276 static bool bDisplayOnce = false; 00277 if (!bDisplayOnce) 00278 { 00279 nlwarning("CClusteredSound::update : no scene specified !"); 00280 bDisplayOnce = true; 00281 } 00282 return; 00283 } 00284 00285 CClipTrav &clipTrav = _Scene->getClipTrav (); 00286 00287 // Retreive the list of cluster where the listener is 00288 vector<CCluster*> vCluster; 00289 clipTrav.fullSearch (vCluster, clipTrav.RootCluster->Group, listenerPos); 00290 00291 00292 // reset the audible cluster map 00293 _AudibleClusters.clear(); 00294 00295 // create the initial travesal context 00296 CSoundTravContext stc(listenerPos, false, false); 00297 00298 // and start the cluster traversal to find out what cluster is audible and how we ear it 00299 soundTraverse(vCluster, stc); 00300 00301 //----------------------------------------------------- 00302 // update the clustered sound (create and stop sound) 00303 //----------------------------------------------------- 00304 00305 std::hash_map<uint, CClusterSound> newSources; 00306 00307 { 00308 // fake the distance for all playing source 00309 // std::map<std::string, CClusterSound>::iterator first(_Sources.begin()), last(_Sources.end()); 00310 std::hash_map<NLMISC::TStringId, CClusterSound>::iterator first(_Sources.begin()), last(_Sources.end()); 00311 for (; first != last; ++first) 00312 { 00313 first->second.Distance = FLT_MAX; 00314 } 00315 } 00316 00317 00318 TClusterStatusMap::const_iterator first(_AudibleClusters.begin()), last(_AudibleClusters.end()); 00319 for (; first != last; ++first ) 00320 { 00321 static NLMISC::TStringId NO_SOUND_GROUP = CStringMapper::emptyId(); 00322 const CClusterSoundStatus &css = first->second; 00323 CCluster *cluster = first->first; 00324 NLMISC::TStringId soundGroup; 00325 00326 soundGroup = cluster->getSoundGroupId(); 00327 00328 00329 if (soundGroup != NO_SOUND_GROUP) 00330 { 00331 // search an associated sound name 00332 std::hash_map<NLMISC::TStringId, CClusterSound>::iterator it(_Sources.find(soundGroup)); 00333 if (it != _Sources.end()) 00334 { 00335 // the source is already playing, check and replace if needed 00336 CClusterSound &cs = it->second; 00337 00338 if (cs.Distance >= css.Dist) 00339 { 00340 // this one is better ! 00341 cs.Distance = css.Dist; 00342 cs.Source->setPos(listenerPos + css.Direction * css.Dist + CVector(0,0,2)); 00343 if (css.DistFactor < 1.0f) 00344 cs.Source->setRelativeGain(css.Gain * (1.0f - (css.DistFactor*css.DistFactor*css.DistFactor*css.DistFactor))); 00345 else 00346 cs.Source->setRelativeGain(css.Gain); 00347 } 00348 newSources.insert(make_pair(soundGroup, cs)); 00349 } 00350 else 00351 { 00352 // create a new source 00353 00354 // nldebug("Searching sound assoc for group [%s]", CStringMapper::unmap(soundGroup).c_str()); 00355 00356 std::hash_map<NLMISC::TStringId, NLMISC::TStringId>::iterator it2(_SoundGroupToSound.find(soundGroup)); 00357 if (it2 != _SoundGroupToSound.end()) 00358 { 00359 NLMISC::TStringId soundName = it2->second; 00360 CClusterSound cs; 00361 00362 nldebug("Found the sound [%s] for sound group [%s]", CStringMapper::unmap(soundName).c_str(), CStringMapper::unmap(soundGroup).c_str()); 00363 00364 cs.Distance = css.Dist; 00365 cs.Source = CAudioMixerUser::instance()->createSource(soundName, false, NULL, NULL, cluster); 00366 if (cs.Source != 0) 00367 { 00368 cs.Source->setPos(listenerPos + css.Direction * css.Dist + CVector(0,0,2)); 00369 if (css.DistFactor < 1.0f) 00370 cs.Source->setRelativeGain(css.Gain * (1.0f - (css.DistFactor*css.DistFactor))); 00371 else 00372 cs.Source->setRelativeGain(css.Gain); 00373 cs.Source->setLooping(true); 00374 newSources.insert(make_pair(soundGroup, cs)); 00375 } 00376 } 00377 } 00378 } 00379 } 00380 // check for source to stop 00381 { 00382 #if _STLPORT_VERSION >= 0x450 00383 std::hash_map<NLMISC::TStringId, CClusterSound> oldSources; 00384 oldSources.swap(_Sources); 00385 #else 00386 // there is a bug in the swap methode in stlport 4.5, so fallback to a 00387 // very less effective create by copy and clear. 00388 std::hash_map<NLMISC::TStringId, CClusterSound> oldSources(_Sources); 00389 _Sources.clear(); 00390 #endif 00391 00392 std::hash_map<uint, CClusterSound>::iterator first(newSources.begin()), last(newSources.end()); 00393 for (; first != last; ++first) 00394 { 00395 _Sources.insert(*first); 00396 if (!first->second.Source->isPlaying()) 00397 first->second.Source->play(); 00398 00399 oldSources.erase(first->first); 00400 } 00401 00402 while (!oldSources.empty()) 00403 { 00404 CClusterSound &cs = oldSources.begin()->second; 00405 delete cs.Source; 00406 oldSources.erase(oldSources.begin()); 00407 } 00408 } 00409 00410 // update the environnement effect (if any) 00411 if (!vCluster.empty()) 00412 { 00413 H_AUTO(NLSOUND_ClusteredSound_updateEnvFx) 00414 CAudioMixerUser *mixer = CAudioMixerUser::instance(); 00415 TStringId fxId = vCluster[0]->getEnvironmentFxId(); 00416 00417 IListener *drvListener = static_cast<CListenerUser*>(mixer->getListener())->getListener(); 00418 const CAABBox &box = vCluster[0]->getBBox(); 00419 CVector vsize = box.getHalfSize(); 00420 float size = NLMISC::minof(vsize.x, vsize.y, vsize.z) * 2; 00421 00422 // special case for root cluster (ie, external) 00423 if (vCluster[0] == _RootCluster) 00424 { 00425 // this is the root cluster. This cluster have a size of 0 ! 00426 size = EAXLISTENER_MAXENVIRONMENTSIZE; 00427 } 00428 else 00429 { 00430 // else, clip the env size to max eax supported size 00431 size = min(size, EAXLISTENER_MAXENVIRONMENTSIZE); 00432 } 00433 00434 uint newEnv; 00435 00436 // retreive the EAX environment number 00437 std::hash_map<NLMISC::TStringId, uint>::iterator it(_IdToEaxEnv.find(fxId)); 00438 if (it != _IdToEaxEnv.end()) 00439 { 00440 // there is an EAX effect 00441 newEnv = it->second; 00442 } 00443 else 00444 { 00445 // no effect, default to "PLAIN" effect 00446 static TStringId plain = CStringMapper::map("PLAIN"); 00447 newEnv = _IdToEaxEnv[plain]; 00448 } 00449 00450 // only update environement if there is some change. 00451 if (newEnv != _LastEnv) 00452 { 00453 drvListener->setEnvironment(newEnv, size); 00454 _LastEnv = newEnv; 00455 } 00456 } 00457 } |
|
The current audible cluster.
Definition at line 252 of file clustered_sound.h. Referenced by addAudibleCluster(), getAudibleClusters(), getClusterSoundStatus(), soundTraverse(), and update(). |
|
The segment of all the audio path.
Definition at line 258 of file clustered_sound.h. Referenced by getAudioPath(), and soundTraverse(). |
|
Initial value: { "GENERIC", "PADDEDCELL", "ROOM", "BATHROOM", "LIVINGROOM", "STONEROOM", "AUDITORIUM", "CONCERTHALL", "CAVE", "ARENA", "HANGAR", "CARPETEDHALLWAY", "HALLWAY", "STONECORRIDOR", "ALLEY", "FOREST", "CITY", "MOUNTAINS", "QUARRY", "PLAIN", "PARKINGLOT", "SEWERPIPE", "UNDERWATER", "DRUGGED", "DIZZY", "PSYCHOTIC", NULL }
Definition at line 51 of file clustered_sound.cpp. Referenced by CClusteredSound(). |
|
The mapping for env name Id to EAX environement number.
Definition at line 267 of file clustered_sound.h. Referenced by CClusteredSound(), and update(). |
|
The mapping for occlusion material name to material number.
Definition at line 269 of file clustered_sound.h. Referenced by CClusteredSound(), and soundTraverse(). |
|
The last setted environement.
Definition at line 256 of file clustered_sound.h. |
|
Initial value: { "SINGLEWINDOW", "DOUBLEWINDOW", "THINDOOR", "THICKDOOR", "WOODWALL", "BRICKWALL", "STONEWALL", "CURTAIN", NULL }
Definition at line 81 of file clustered_sound.cpp. Referenced by CClusteredSound(). |
|
Maximum earing distance.
Definition at line 244 of file clustered_sound.h. Referenced by addAudibleCluster(), init(), and soundTraverse(). |
|
Minimum gain.
Definition at line 246 of file clustered_sound.h. Referenced by init(), and soundTraverse(). |
|
The cluster for the next travesal step.
Definition at line 254 of file clustered_sound.h. Referenced by addNextTraverse(), and soundTraverse(). |
|
Interpolation distance when listener is near a portal.
Definition at line 242 of file clustered_sound.h. Referenced by init(), interpolateSourceDirection(), and soundTraverse(). |
|
The root cluster of the scene.
Definition at line 248 of file clustered_sound.h. Referenced by init(), soundTraverse(), and update(). |
|
The scene of interest.
Definition at line 240 of file clustered_sound.h. |
|
The sound_group to sound assoc.
Definition at line 264 of file clustered_sound.h. |
|
The current cluster playing source indexed with sound group id.
Definition at line 261 of file clustered_sound.h. |