Skip to content
Snippets Groups Projects
Commit c3c0297d authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Algorithm restructuring, still no detections ...

parent 367bf207
No related branches found
No related tags found
No related merge requests found
......@@ -96,6 +96,9 @@ namespace ITAPropagationPathSim
float m_tEnergyThreshold;
ITAGeo::Halfedge::CMeshModel m_oMeshModel; //!< Geometrical mesh model (halfedges)
private:
};
}
}
......
......@@ -69,163 +69,104 @@ void CEngine::Run( std::shared_ptr< ITAGeo::CPropagationAnchor > pSource, std::s
cout << "Number of Rays: " << GetNumberOfRays() << endl;
// Define Ray
struct SoundParticle
{
VistaRay rCurrentRay;
VistaVector3D v3RandomDirection;
// Required pre-allocated variables for the algorithm
VistaRay rRay;
double dEnergy = 1.0f;
VistaVector3D v3IntersectionPoint;
VistaVector3D v3LastIntersectionPoint;
VistaVector3D v3DetectionPoint;
CITAMesh::FaceHandle hLastIntersectedFace;
CITAMesh::FaceHandle hLastReflectionFace = CITAMesh::InvalidFaceHandle;
bool bRayDirectionChanged = true;
ITAGeo::CPropagationPath oPropagationPath;
// hidden internal variables
float tCurrentEnergy;
float tAbsorbtionLossFactor; // accumulated absorbtion losses
void init()
{
tCurrentEnergy = 1.0f;
tAbsorbtionLossFactor = 1.0f;
oPropagationPath.clear();
}
void updateEnergy(const float tAbsobrtionOfFace)
// Generate rays
for( unsigned long int n = 0; n < GetNumberOfRays(); n++ )
{
// update absorbtion losses
tAbsorbtionLossFactor *= (1.0f - tAbsobrtionOfFace);
if (oPropagationPath.GetLength() != 0)
tCurrentEnergy = tAbsorbtionLossFactor * (1.0f / powf(oPropagationPath.GetLength(), 2));
}
// Initialize current ray with origin at source position and random direction using uniform spherical probability distribution
rRay.SetOrigin( pSource->v3InteractionPoint );
rRay.SetDir( ITAGeoUtils::GetUniformlyDistributedSphericalRandomDirection() );
bool bEnergyBelowThreshold(const float tEnergyThreshold)
{
return tCurrentEnergy < tEnergyThreshold;
}
ITAGeo::CPropagationPath oPropagationPath;
oPropagationPath.push_back( pSource );
void setRandomDirection()
// Run energy model for each ray
while( dEnergy > GetEnergyThreshold() )
{
ITAGeoUtils::SetUniformlyDistributedSphericalRandomDirection(v3RandomDirection);
rCurrentRay.SetDir(v3RandomDirection);
}
struct Reflection
// Check for receiver hit by ray
if( ITAGeoUtils::RayDetectionSphereIntersectionTest( rRay, pDestination, m_tDetectionSphereRadius, v3DetectionPoint ) )
{
VistaVector3D v3Point;
CITAMesh::FaceHandle hFace;
//std::vector<VistaVector3D> v3FaceInterections; // Store all Intersections from which the nearest to the current ray origin is the actual point of reflection
//std::vector<CITAMesh::FaceHandle> hIntersectedFaces; // Store all handles of the intersected faces in order to be able to get the face handle of the actual reflecting face
VistaVector3D v3NearestPoint;
CITAMesh::FaceHandle hNearestFace;
float tAbsorbtionOfFace;
int iReflectionOrder;
// Update path
auto pDetection = std::make_shared<ITAGeo::CDetectionPoint>( v3DetectionPoint );
void init()
{
//v3FaceInterections.clear();
//hIntersectedFaces.clear();
tAbsorbtionOfFace = 0.0f;
iReflectionOrder = 0;
}
auto oNewPropagationPath = oPropagationPath; // Make a copy of the current path and finalize it
oNewPropagationPath.push_back( pDetection );
oNewPropagationPath.push_back( pDestination );
void updateNearestPoint(VistaRay& rCurrentRay, CITAMesh::FaceHandle hCurrentFace)
{
if (iReflectionOrder == 0)
{
v3NearestPoint = v3Point;
hNearestFace = hCurrentFace;
}
else
{
if ((v3Point - rCurrentRay.GetOrigin()).GetLength() < (v3NearestPoint - rCurrentRay.GetOrigin()).GetLength())
{
v3NearestPoint = v3Point;
hNearestFace = hCurrentFace;
}
}
iReflectionOrder++;
// Store path of ray in path list for histogram evaluation
lPropagationPaths.push_back( oNewPropagationPath );
}
} Reflection;
} Ray;
for (unsigned long int n = 0; n < GetNumberOfRays(); n++)
{
// Initialize current ray with origin at source position and random direction using uniform spherical probability distribution
Ray.rCurrentRay.SetOrigin(pSource->v3InteractionPoint);
Ray.setRandomDirection();
// Initialize variables of current ray
Ray.init();
// Store source position as start point of the propagation path
Ray.oPropagationPath.push_back(pSource);
while( !Ray.bEnergyBelowThreshold(m_tEnergyThreshold) )
{
// Initialize reflection list
Ray.Reflection.init();
hLastIntersectedFace = CITAMesh::InvalidFaceHandle;
// Check ray propagation for each face of the mesh
auto it = pMesh->faces_begin();
while( it != pMesh->faces_end() )
{
// ->siehe MirrorImage->CEngine::AudibilityTest
CITAMesh::FaceHandle hFace( *it++ );
if( hLastReflectionFace == hFace )
continue;
// Check for intersection of the ray with current face and store intersection point
if (ITAGeoUtils::RayFaceIntersectionTest(Ray.rCurrentRay, pMesh, hFace, Ray.Reflection.v3Point, eCulling))
if( ITAGeoUtils::RayFaceIntersectionTest( rRay, pMesh, hFace, v3IntersectionPoint, eCulling ) )
{
Ray.Reflection.updateNearestPoint(Ray.rCurrentRay, hFace);
/*
//Ray.Reflection.tAbsorbtionOfFace = 0.7f; //@todo: dynamic addaption of absorbtion according to material
Ray.Reflection.v3FaceInterections.push_back(Ray.Reflection.v3Point);
Ray.Reflection.hIntersectedFaces.push_back(hFace);
*/
}
}
if (/*Ray.Reflection.v3FaceInterections.empty()*/ false)
if( bRayDirectionChanged )
{
ITA_EXCEPT1(ITAException::IO_ERROR, "Invalid mesh! Ray could not be reflected on any face!");
hLastIntersectedFace = hFace;
v3LastIntersectionPoint = v3IntersectionPoint;
bRayDirectionChanged = false;
}
else
{
// Choose nearest ray-face-intersection point as current reflection point
//GetNearestReflectionPointAndFaceOfRay(Ray.Reflection.v3Point, Ray.Reflection.hFace, Ray.Reflection.v3FaceInterections, Ray.Reflection.hIntersectedFaces, Ray.rCurrentRay);
const VistaVector3D v3DistLast = v3LastIntersectionPoint - rRay.GetOrigin();
const VistaVector3D v3Dist = v3IntersectionPoint - rRay.GetOrigin();
if( v3DistLast.GetLength() > v3Dist.GetLength() )
{
hLastIntersectedFace = hFace;
v3LastIntersectionPoint = v3IntersectionPoint;
}
}
}
}
// Update propagation path of ray
auto pReflection = std::make_shared<ITAGeo::CSpecularReflection>(Ray.Reflection.v3NearestPoint);
Ray.oPropagationPath.push_back(pReflection);
if( !hLastIntersectedFace.is_valid() )
break;
// Reflect ray on face
ITAGeoUtils::ReflectRayOnFace(Ray.rCurrentRay, pMesh, Ray.Reflection.hNearestFace, Ray.Reflection.v3NearestPoint);
// Nearest reflection point found on face hLastIntersectionFace at v3LastIntersectionPoint
// Update energy of ray
Ray.updateEnergy(Ray.Reflection.tAbsorbtionOfFace); // @todo pReflection->Material = get material from face
}
// Update propagation path of ray
auto pReflection = std::make_shared<ITAGeo::CSpecularReflection>( v3LastIntersectionPoint );
// Check for receiver hit by ray
if (ITAGeoUtils::RayDetectionSphereIntersectionTest(Ray.rCurrentRay, pDestination, m_tDetectionSphereRadius, Ray.v3DetectionPoint))
{
// Update path
auto pDetection = std::make_shared<ITAGeo::CDetectionPoint>(Ray.v3DetectionPoint);
Ray.oPropagationPath.push_back(pDetection);
assert( ( oPropagationPath.back()->v3InteractionPoint - pReflection->v3InteractionPoint ).GetLength() > 0.0f );
oPropagationPath.push_back( pReflection );
Ray.oPropagationPath.push_back(pDestination);
// Store path of ray in path list for histogram evaluation
lPropagationPaths.push_back(Ray.oPropagationPath);
}
// Reflect ray on face
const VistaVector3D v3ReflectedDirection = ITAGeoUtils::GetReflectedDirection( pMesh, hLastIntersectedFace, rRay );
rRay.SetOrigin( v3LastIntersectionPoint );
rRay.SetDir( v3ReflectedDirection );
bRayDirectionChanged = true;
hLastReflectionFace = hLastIntersectedFace;
// Update energy of ray according to spherical spreading loss
if( oPropagationPath.GetLength() != 0 )
dEnergy = 1.0f / pow( oPropagationPath.GetLength(), 2 );
}
}
}
void CEngine::SetNumberOfRays( unsigned long int nRays )
{
m_nNumberOfRays = nRays;
......
......@@ -113,7 +113,7 @@ int main( int iNumInArgs, char* pcInArgs[] )
CPropagationPathList pathList;
ITAStopWatch sw; sw.start();
oRTEngine.Run( pEmitter, pSensor, pathList, ITAGeo::ECulling::NONE );
oRTEngine.Run( pEmitter, pSensor, pathList, ITAGeo::ECulling::BACKFACE );
cout << "Ray tracing calculation time: " << timeToString( sw.stop() ) << endl;
for (auto path : pathList)
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment