function [p,e0]=mmcraytrace(node,elem,p0,v0,e0)
%
% [p,e0]=mmcraytrace(node,elem,p0,v0,e0)
%
% Determine the entry position and element for a ray to intersect a mesh
%
% author: Qianqian Fang (q.fang <at> neu.edu)
%
% input:
%     node: the mesh coordinate list
%     elem: the tetrahedral mesh element list, 4 columns
%     p0: origin of the ray
%     v0: direction vector of the ray
%     e0: search direction: '>' forward search, '<' backward search, '-' bidirectional
%
% output:
%     p: the intersection position
%     e0: if found, the index of the intersecting element ID
%
% this file is part of Mesh-based Monte Carlo (MMC)
%
% License: GPLv3, see http://mcx.sf.net/mmc/ for details
%

p=p0;
face=volface(elem);
[t,u,v,idx]=raytrace(p0,v0,node,face);
if(isempty(idx))
    error('ray does not intersect with the mesh');
else
    t=t(idx);
    if(e0=='>')
        idx1=find(t>=0);
    elseif(e0=='<')
        idx1=find(t<=0);
    elseif(isnan(e0) || e0=='-')
        idx1=1:length(t);
    else
        error('ray direction specifier is not recognized');
    end
    if(isempty(idx1))
        error('no intersection is found along the ray direction');
    end
    t0=abs(t(idx1));
    [tmin,loc]=min(t0);
    faceidx=idx(idx1(loc));

    % update source position
    p=p0+t(idx1(loc))*v0;

    % find initial element id
    felem=sort(face(faceidx,:));
    f=elem;
    f=[f(:,[1,2,3]);
       f(:,[2,1,4]);
       f(:,[1,3,4]);
       f(:,[2,4,3])];
    [tf,loc]=ismember(felem,sort(f,2),'rows');
    loc=mod(loc,size(elem,1));
    if(loc==0) loc=size(elem,1); end
    e0=loc;
end
