Thanks Stephan, you answer was very helpful. After some headbanging I have it 
working seemingly flawless. Here is the code for reference:


Code:


osg::Vec3d  rayIntersectWithXYPlane(float x, float y, osg::Node* widget) {
    // flip mouse y axis
    y = ofGetHeight() - y;  //important
    
    osg::Vec3d isect = osg::Vec3d(0,0,0);

    // compute model to window transform
    // Model*View*Projection*WindowMatrix
    osg::Matrixd matrix;
    matrix.postMult(widget->getWorldMatrices()[0]);
    matrix.postMult(camera->getViewMatrix());
    matrix.postMult(camera->getProjectionMatrix());                  
    matrix.postMult(camera->getViewport()->computeWindowMatrix());
    
    osg::Matrixd inverse;
    inverse.invert(matrix);
    
    // Transform ray from window to model coordinates
    osg::Vec3d startRay = osg::Vec3d(x,y,0) * inverse;
    osg::Vec3d endRay = osg::Vec3d(x,y,1) * inverse;
    
    // Intersect ray with XY-plane
    // (0,0,1,0) is plane in hess normal form
    getPlaneLineIntersection(osg::Vec4d(0,0,1,0), startRay, endRay, isect);

    return isect;
}    
bool getPlaneLineIntersection(const osg::Vec4d& plane, 
                              const osg::Vec3d& lineStart, const osg::Vec3d& 
lineEnd, 
                              osg::Vec3d& isect)
{
    // intersects an infinite line with an infinite plane
    // in hesse normal form  Ax + By + Cz + D = 0
    // A,B,C is the normal vector of the plane, D the distance to the origin    
    const double deltaX = lineEnd.x() - lineStart.x();
    const double deltaY = lineEnd.y() - lineStart.y();
    const double deltaZ = lineEnd.z() - lineStart.z();

    const double denominator = (plane[0]*deltaX + plane[1]*deltaY + 
plane[2]*deltaZ);
    if (! denominator) return false;

    const double C = (plane[0]*lineStart.x() + plane[1]*lineStart.y() + 
plane[2]*lineStart.z() + plane[3]) / denominator;

    isect.x() = lineStart.x() - deltaX * C;
    isect.y() = lineStart.y() - deltaY * C;
    isect.z() = lineStart.z() - deltaZ * C;

    return true;
}





Instead of osg::computeLocalToWorld(...) I use getWorldMatrices(...) which I 
believe does pretty much the same. I also use this 
getPlaneLineIntersection(...) for doing the actual intersection.

I have one more quick question. What is generally meant in osg with world 
coordinates? For example in computeLocalToWorldMatrix(). Is it simply the 
coordinates in the parent or all the way up to the root node? I would assume 
it's all the way up to the root but I read some code that makes me think 
otherwise.

Thanks again,

/stefanix

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=13960#13960





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to