#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. |
1.3.6