Notifications
Clear all
[Closed] DotNet/SDK IntersectRay co-ordinate space issues
Jul 01, 2016 12:58 am
Greetings, still struggling with an SDK port of a heavy lifting IntersectRay loop, and running into some trouble with the difference between the coordinate space maxScript IntersectRayEx works in, and the C# or C++ equivalents…
After some googling, I realised I needed the ray in my hit test to be in object space, but Can’t seem to get it back out again… I’m not quite sure where I’m going wrong?
Code sample here:
Thanks for the help!
Mikie
Edit: Adding the solution I found…
This didn’t work:
// cast as tri-object, as we know it will work by this point
var triOriginal = objOriginal as ITriObject;
// get various cooridnate spaces
var TTM = Target.GetNodeTM(Ip.Time, intv);
var InvTTM = Target.GetNodeTM(Ip.Time, intv);
var STM = Source.GetNodeTM(Ip.Time, intv);
var InvSTM = Source.GetNodeTM(Ip.Time, intv);
InvTTM.Invert();
InvSTM.Invert();
// ray in world space (Source is always in world space, rayDir = (0,0,-1, or 0,0,1))
Rhey = Global.Ray.Create(STM.Trans, RayDir);
// put ray in target object space
Rhey.P = InvTTM.Multiply(STM).Trans;
Rhey.Dir = Global.VectorTransform(Rhey.Dir, InvTTM);
Global.Normalize(Rhey.Dir);
var res = triOriginal.Mesh.IntersectRay(Rhey, ref dist, nor, ref fi, bary);
HitPos.X = Rhey.P.X + Rhey.Dir.X * dist; // broken out for quicker debug in attached process
HitPos.Y = Rhey.P.Y + Rhey.Dir.Y * dist;
HitPos.Z = Rhey.P.Z + Rhey.Dir.Z * dist;
// Back into world space?
HitPos = Global.VectorTransform(HitPos, TTM);
Autodesk.Max.GlobalInterface.Instance.TheListener.EditStream.Printf($"Source: {Source.Name} | ");
Autodesk.Max.GlobalInterface.Instance.TheListener.EditStream.Printf($"HitPos X: {HitPos.X} Y: {HitPos.Y} Z: {HitPos.Z}
");
This did work… Good old trial and error to the rescue. I kind of (but not completely) understand where I went wrong, and hopefully others can learn as well…
// cast as tri-object, as we know it will work by this point
var triOriginal = objOriginal as ITriObject;
// get various cooridnate spaces
var TTM = Target.GetObjectTM(Ip.Time, intv);
var InvTTM = Target.GetObjectTM(Ip.Time, intv);
var STM = Source.GetNodeTM(Ip.Time, intv);
var InvSTM = Source.GetNodeTM(Ip.Time, intv);
InvTTM.Invert();
InvSTM.Invert();
// ray in world space (Source is always in world space, rayDir = (0,0,-1, or 0,0,1))
Rhey = Global.Ray.Create(STM.Trans, RayDir);
// put ray in target object space
Rhey.P = STM.Multiply(InvTTM).Trans;
Rhey.Dir = Global.VectorTransform(Rhey.Dir, InvTTM);
Global.Normalize(Rhey.Dir);
var res = triOriginal.Mesh.IntersectRay(Rhey, ref dist, nor, ref fi, bary);
// Hit position in Object space
HitPos = Rhey.P.Add(Rhey.Dir.MultiplyBy(dist));
// Back into World Space
var resMat = Global.Matrix3.Create(true);
resMat.Trans = HitPos;
resMat = resMat.Multiply(TTM);
HitPos = resMat.Trans;
// Debug to 3ds Max Listener
Autodesk.Max.GlobalInterface.Instance.TheListener.EditStream.Printf($"Source: {Source.Name} | ");
Autodesk.Max.GlobalInterface.Instance.TheListener.EditStream.Printf($"HitPos X: {HitPos.X} Y: {HitPos.Y} Z: {HitPos.Z}
");