Since this has got a fair amount of positive feedbacks, I decided to try and help the best I know how to get it to a wider public. (Your only way to have this is to compile it or get it to official release as far as I know) But I’m going to need your help with that.
So I assume, to give it the best chances from the start we need: well thought-out concept (down to details), specifics and community support. From a workflow point: 1) gathering inputs here and IG; 2) Implement as good as I can; 3) Link this thread with a flyspray feature request + sit back and wait patiently for the devs to revise/rework/scrap/implement it. (Or I might just delegate this to someone who wants it ASAP and would keep nagging the devs about it. )
There are three pillars I can think of that could get main closer to RL hearing.
- Damping with squared distance
(The first post. This is in line with physics.)
- Amplify voices based on facing
actor->GetLastPosition(pos,yrot,sector);
me->GetLastPosition(myPos,myYrot,mySector);
csVector3 diff=pos-myPos;
float r=(atan2(-diff.x,-diff.z))-myYrot; //-x -z for opposite (facing)
r=(r>PI) ? TWO_PI-r : r;
r=(r<-PI) ? TWO_PI+r : r;
r=abs(r);
This results in a coefficient ranging from 0 (you are facing the source) to PI (source is behind you). It is 2d deliberately since I assume players use third person view the most, but this can be argued with. It is also possible to use this the other way around too (someone talking with their backs facing you) so to try to simulate something more complex than a point source of waves.
- Clear line of sight
csVector3 isect,start,end,norm;
csRef<iCollideSystem> cdsys = csQueryRegistry<iCollideSystem> (psengine->GetObjectRegistry ());
start= myPos+ csVector3(0, 1.8f, 0);//1,8.. I'm sorry dwarven friends... Is there a way to tell character height?
end = pos+ csVector3(0, 1.8f, 0);
norm=end-start;norm.Normalize();
csIntersectingTriangle closest_tri;
iMeshWrapper* sel;
float dist,maxRad=0;
do
{
sel = 0;
dist = csColliderHelper::TraceBeam (cdsys, sector,start, end, false, closest_tri, isect, &sel);
if (sel && dist>0)
{
csSphere cssph=sel->GetRadius();
if (cssph.GetRadius()>=maxRad)
{
maxRad=cssph.GetRadius();
}
float lastStep=(isect-start).Norm();
if (lastStep<0,1) //Sometimes TraceBeam gets stuck in objects (almost endless loop) so needs a kick
{
start+=norm;
}
else
{
start=csVector3(isect);
}
}
} while (dist>0);
if (maxRad>4.25f)
{
//different floor – other side
}
In this maxRad(ius) returns with the size of the biggest object blocking. Some sizes from next to KadaEl’s: chimney 0,18; jug 0,18; chair 0,6; large barrel; table 0,83; bar 3,08; bench 3,62, forge 4,25, a piece of wall 4,5, a piece of ceiling 4,53-5,42, floor 8; roof 10,82; guard tower 12,51
Might not be fully accurate at all times, but tests shows it is doable. There also is the possibility to redo calculations from a slightly different point of view too (something like start+=csVector3(0.3, 0, 0.3)). My aim here would be to being able to tell if the source is on another floor in KadaEl’s or it is originating from behind a whole smithy.
What I want you to do is: form an opinion and share it with me here or IG. Could be about anything like: which can be useful at all, how many colors should we use, what their default values should be, how and in what order to use the numbers from the functions above. And any insights are welcome too like: why not just leave it alone? PS is slow enough already, your code has errors here and here, that can be solved easily like this, uses cases where it should be tested first, hints on how RL biology/physics work, etc.
PS: I did the mods in cmdusers.cpp to test with additional includes as follows:
#include <csgeom/math3d.h>
#include "meshattach.h"
#include "csgeom/sphere.h"