Jump to content

Does PQS.RayIntersection actually work?


Recommended Posts

What the subject says. I can't get the thing to work at all, and I suspect it's because unlike what the parameter arguments say, it's not *really* expecting me to use coordinates in in Unity world coords, but in some other system it's not telling me what it is.

When I use the exact same coordinates that work for local raycast collisions, which are supposedly using world coords, the same coordinates don't work with the pqs controller attached to a CelestialBody. They keep finding hits where there are no hits, and failing to find hits where there are.

I was wondering if there was anyone, anywhere, who had used this method before. Every place I expected I might see an example of it working, the mod in question wasn't using it but using something not quite right. Most mods that do a similar thing to what I'm trying to do seem to get an intersection with the SPHERE of the planet, and then get the altitude at that location, which isn't quite right, as the diagram below shows:

ZH7mzHa.png

Link to comment
Share on other sites

I think the question can be expanded to include how the terrain and/or PQS system works when the detail is reduced for distance.

The reason I ask is that I do a raycast to terrain for my Landing Height mod (using a plain raycast, not the PQSintersection method) but I was not able to get it to work reliably outside the 2.5km physics sphere.

I know there is nothing that ties the physics sphere to terrain detail, but I can see the programmer at Squad who did the terrain decide to use the same distance to start reducing terrain detail as the 2.5km limit already exists anyway.

I don't know a thing about the PQS system however, I am assuming that when terrain detail gets reduced for distance, the PQS objects available to hit with a raycast change as well.

D.

Edited by Diazo
Link to comment
Share on other sites

The problem I'm having isn't detail level, it's aim. It's hitting kerbin when not even aimed anywhere near kerbin. I can aim the ray up 60 degrees above the horizon from an orbit of 100km and still get a "hit" on kerbin, and not get any hits when aimed right at kerbin from there. This is making me think the coordinate reference frame the function call expects its arguments to be using is not really the Unity World coords they're named as if they use.

This is where Squad's insistence on not documenting their API, combined with their insistence on making it illegal to decompile the DLL, makes some mods nearly impossible to write. You have nothing to go on for what an API call does other than it's name, and the types of its arguments, and the hope that another modder has already worked out what it does through trial and error, so they might have documented it on one of the fan-made API documentation sites. In this case those clearly aren't telling me what the call actually does.

I had a good search through other mod code available in github to see if anyone else is using this method and nobody seems to be.

Link to comment
Share on other sites

Okay, I just got home and was able to take a look at the method in the Object Browser and will admit I'm not clear on what it does.

My reading of the method seems to match yours. I will list my interpretation in case it gives you some inspiration into what is going on, but I don't think I have an answer for you.

public bool RayIntersection(UnityEngine.Vector3 worldStart, UnityEngine.Vector3 worldDirection, out Vector3d intersection)

first bool from left: return true if hit pqs, false otherswise

Vector3 worldStart: Origin point for the ray in world co-ordinates

Vector3 worldDirection: Direction of ray from origin point as defined by previous variable

out Vector3d intersection: the Vector3 point returned by the method of where the ray intersects the pqs layer.

Assuming the method actually does what it looks like it does, I'm suspicious of the world co-ordinates conversion. I have yet to find the co-ordinates I need smoothly, I've only worked with transforms a few times but it has always been a huge pain.

I realize that is not really helpful but that's the extent of my knowledge on this subject.

D.

Link to comment
Share on other sites

Okay, I just got home and was able to take a look at the method in the Object Browser and will admit I'm not clear on what it does.

My reading of the method seems to match yours. I will list my interpretation in case it gives you some inspiration into what is going on, but I don't think I have an answer for you.

public bool RayIntersection(UnityEngine.Vector3 worldStart, UnityEngine.Vector3 worldDirection, out Vector3d intersection)

first bool from left: return true if hit pqs, false otherswise

Vector3 worldStart: Origin point for the ray in world co-ordinates

Vector3 worldDirection: Direction of ray from origin point as defined by previous variable

out Vector3d intersection: the Vector3 point returned by the method of where the ray intersects the pqs layer.

Assuming the method actually does what it looks like it does, I'm suspicious of the world co-ordinates conversion. I have yet to find the co-ordinates I need smoothly, I've only worked with transforms a few times but it has always been a huge pain.

I realize that is not really helpful but that's the extent of my knowledge on this subject.

D.

The problem is that I already have proof that I have the world coordinates correctly because I'm drawing a line using Unity's LineRenderer using the same coordinates so I can see on screen that my idea of the ray described by the world coordinates is matching what I think it is. Also, I'm able to use those same numbers while low to the ground in a physics.raycast to find ground polygons and it works them. and Physics raycast is supposedly also using world coordinates too. That's the 'proof' that it's not using the same coordinates system as the one called "world coordinates".

I also tried scaling the coordinates to map scale using scaledspace to see if the intersection presumes it must take place in mapview space, but that doesn't seem to make any difference. The problem is *still* that the aim is in the wrong direction and finds hits that aren't hits.

I wish I had an example that actually worked to go from. You can use inductive reasoning to work out what a thing is doing only if you have both examples of it working and examples of it not working to derive from.

Link to comment
Share on other sites

Well, I messed around a bit with this code:

PQS testPQS = FlightGlobals.ActiveVessel.mainBody.pqsController;
double testing = 0;
bool testhit = testPQS.RayIntersection(FlightGlobals.ActiveVessel.rootPart.transform.position, (FlightGlobals.ActiveVessel.mainBody.position - FlightGlobals.ActiveVessel.rootPart.transform.position), out testing);
if (testhit)
{
print("Hit " + testing + " " + FlightGlobals.ActiveVessel.altitude);
}
else
{
print("Miss");
}

Now, this just fires straight down to world center of mass and I was using the distance result to monitor distance.

Watching the log, it does look like my example method returns valid data as the number changed as expected with altitude.

The two caveats were that:

a) It returned a number that was about 5.7 to 5.9 times larger then my altitude as reported by FlightGlobals.ActiveVessel.altitude

B) The number returned seemed to be the distance to sea level, not the 70 meters or so higher that the pad at KSC should report.

To add to the strangeness, my first try I got my direction vector backwards and was firing the Ray straight up, it was returning a value of about 210,000, which when divided by the 5.9 from my previous example comes out to almost exactly 35k above the launchpad.

All my test were from a vessel fresh from launch, I did not put anything into orbit because I stopped my tests and I'm not actually getting anywhere and I wanted to get some work in on my mod tonight.

That's what I found for what it is worth.

D.

Link to comment
Share on other sites

I found the problem with a LOT of trial and error and frustration. With the function call:

public bool RayIntersection(UnityEngine.Vector3 worldStart, UnityEngine.Vector3 worldDirection, out Vector3d intersection)

The 'worldStart' parameter is correct, but the 'worldDirection' parameter is being read utterly wrong by the function.

The problem is that it seems to be always rotating it off the wrong direction. To overcompensate for that I have to rotate it twice the correct way, to compensate for the fact that it rotates it once the wrong way, like so:

Vector3d useWorldDir = pqs.transformRotation * ( pqs.transformRotation * worldDir );

And then pass in useWorldDir as the second argument to RayIntersection.

I'm fairly sure this has got to be a bug. I now suspect the API call isn't being used anywhere by SQUAD themselves because there's no way they could be using it the way it is now without it being discovered to be wrong.

Link to comment
Share on other sites

[ addendum ]

I also found out after all this work that despite the implications of the name, the RayIntersection function doesn't even calculate intersections with the terrain *anyway*. It just finds the intersection with the sea level sphere, which I could have easily done with my own math. (Making me wonder why on earth it's part of the PQScontroller when the information it needs to find the sea level sphere intersection is just position and radius of the body - surely it's got nothing to do with the PQS terrain and thus belongs just in CelestialBody....grumble.)

That was a lot of work for nothing. It turns out I'll still have to write a homemade terrain intersect solver anyway. It will be a numerical approximation by slices, which can be computationally expensive. So I'll have to find a tricky way to allow it to store the state of the partially complete numerical algorithm between Unity updates so it can take, say, 2 or 3 updates to finish the algorithm - otherwise I'll be starving other mods of CPU time.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...