Difference between revisions of "Talk:LlCastRay"
Line 71: | Line 71: | ||
Note that clamping is relatively easy, in C++ it shouldn't cost more than a few microseconds. | Note that clamping is relatively easy, in C++ it shouldn't cost more than a few microseconds. | ||
The algorithm would be something like: | The algorithm would be something like: | ||
1) A bounding box can be given with two vectors: ''bbmin'' and ''bbmax'', where ''bbmin'' is the bottom, | 1) A bounding box can be given with two vectors: ''bbmin'' and ''bbmax'', where ''bbmin'' is the bottom, | ||
south/west corner of the sim (0,0,0), and ''bbmax'' the upper, north/east corner of the sim | |||
(256,256,4096). | |||
2) Let the ray begin at vector ''begin'' and end at vector ''end'' (using the same coordinate system as the bounding box). | 2) Let the ray begin at vector ''begin'' and end at vector ''end'' (using the same coordinate system as the bounding box). | ||
3) Calculate bbmine = bbmin - end, and bbmaxe = bbmax - end. Check if end is outside the sim, | 3) Calculate bbmine = bbmin - end, and bbmaxe = bbmax - end. Check if end is outside the sim, | ||
so clamping is needed at all, but checking that at least one coordinate in bbmine is positive | |||
or one coordinate in bbmaxe is negative (set 'clamping_needed'). | |||
4) Shift coordinates so that so that ''begin'' becomes the origin and ''end' becomes the direction | 4) Shift coordinates so that so that ''begin'' becomes the origin and ''end' becomes the direction | ||
(bbmin -= begin; bbmax -= begin; dir = end - begin). Lets call ''end'' ''dir'' from now on. | |||
5) Check that bbmin has three negative coordinates and ''bbmax'' has three positive coordinates. | 5) Check that bbmin has three negative coordinates and ''bbmax'' has three positive coordinates. | ||
If not then ''begin'' is outside the bounding box (if there is a zero, it's on the border | |||
and you can just return ''begin''). Not sure if you should return an error code or return just no results. | |||
Finally, if begin is outside the bounding box, but end was inside, you might want to clamp begin | |||
instead of end. Lets assume that begin is inside the bounding box for now. If end was also inside | |||
it, then no clamping is needed and we stop here. | |||
6) Clamping is needed. Calculate dir.x / bbmin.x, dir.x / bbmax.x, dir.y / bbmin.y, dir.y / bbmax.y, dir.z / bbmin.z and dir.z / bbmax.z. | 6) Clamping is needed. Calculate dir.x / bbmin.x, dir.x / bbmax.x, dir.y / bbmin.y, dir.y / bbmax.y, dir.z / bbmin.z and dir.z / bbmax.z. | ||
7) Find the largest value 'max' of those six and return ''begin'' + dir / max as the collision point of | 7) Find the largest value 'max' of those six and return ''begin'' + dir / max as the collision point of aray in the direction dir. | ||
As you can see, this is a very fast routine. Still, I think it should be added to the server side. | As you can see, this is a very fast routine. Still, I think it should be added to the server side. |
Revision as of 03:27, 3 July 2010
llSonar please?
I would appreciate if you took in consideration my suggestions at http://jira.secondlife.com/browse/SVC-2486 please; any feedback is more than welcome.
ps:llCastRay is already awesome, you rock! Please try the hardest you can to figure out how to get this to come to the maingrid with the least crippling as possible.
--TigroSpottystripes Katsu 03:01, 3 July 2010 (UTC)
Hi Tigro,
If I understand your feature request, it sounds much like the shape cast described in SVC-5381 (http://jira.secondlife.com/browse/SVC-5381) for a sphere or a cylinder cast along its primary axis. Is that correct?
Thanks, Falcon Linden
- I have just skimmed thru the comments there, do shape casting allow for somthing liek for example have a nonphys object recognize the geometry so it could rest against a jumbled pile of prims as if it was laying against them physicly? (in the ASCII art in SVC-2486 it would be having the object represented by the O's resting in the diagonal line as if it was solid) --TigroSpottystripes Katsu 05:44, 3 July 2010 (UTC)
What am I looking at?
A function I just threw in to replace phantom bullets for quickly acquiring a point of interest -- whatever your camera's focused on (in this sim, within 20m) is returned, allowing quicker, more intuitive targeting of other objects. PERMISSION_TRACK_CAMERA must be previously set.
<lsl>key camPing() {
// End points at the camera and 20m in front of it vector camPos = llGetCameraPos(); vector endPos = camPos + ( <20.0, 0., 0.> * llGetCameraRot() );
// Clamp the end position to within the sim // Except what I originally posted was wrong, and I'm too tired to do trig
// Cast the ray; ignore hits on land, otherwise get the root key list contacts = llCastRay( camPos, endPos, RC_REJECT_LAND, RC_GET_ROOT_KEY );
// Return values if ( llList2Integer( contacts, -1 ) > 0 ) { // Got a return return llList2Key( contacts, 0 ); } return NULL_KEY;
} </lsl>
Jack Abraham 04:42, 3 July 2010 (UTC)
RC_GET_LINK_NUM? Not RC_GET_LINK_KEY?
I can't think of a circumstance where knowing the link number of the return would be useful. UUID of the prim hit would be far more useful; is that within the realm of possibility? Jack Abraham 04:47, 3 July 2010 (UTC)
Hi Jack,
The default behavior is to return the UUID of the prim hit. If you want the root key instead, you have to use RC_GET_ROOT_KEY. The intended purpose of RC_GET_LINK_NUM was for scripts like your camera targeting system where it is expected that the camera will be pointed at a child of the linkset performing the cast. For example, suppose you make a minesweeper game where each tile is a prim in the linkset. And suppose you script it so that the use can select a tile by focusing on it and clicking. The script could cast a ray from the camera and determine the link number of the tile in the player's line of sight. Then it could use that link number in an llMessageLinked or some other LSL function to modify the appropriate child prim. Does that make sense? If it turns out no one has any use for RC_GET_LINK_NUM, I'll eliminate it for the sake of simplicity. But the behavior you're looking for is already there by default! Yay.
Cheers, Falcon Linden
Makes perfect sense; I need to read better. Thanks. Jack Abraham 05:44, 3 July 2010 (UTC)
Memory concerns
Dumping all possible avaible information into a list regardless of whether any of them will be used seems severely wasteful. If you really need to dump all the info as soon as the command is called straight into script memory, at least do somthing like adding a parameter to the command that is a list where each item identifies which pieces of information the scripter wants (like with llGetPrimtiveParams ) --TigroSpottystripes Katsu 05:51, 3 July 2010 (UTC)
I think we basically have that, Tigro; we only get UUID and hit position unless we set additional flags. Falcon indicated that we will not get all hits in the final version; that'll further reduce the size of the list. Jack Abraham 07:50, 3 July 2010 (UTC)
Clamping
It would be waste of server resources if every script has to add clamping code to make sure their begin and end are inside the region! Instead, do not return an error code but just stop return only the hits in the region. That might mean you have to add the clamping code in the server, but that would be a hell of a lot more efficient than doing that in the LSL scripts.
Note that clamping is relatively easy, in C++ it shouldn't cost more than a few microseconds. The algorithm would be something like:
1) A bounding box can be given with two vectors: bbmin and bbmax, where bbmin is the bottom, south/west corner of the sim (0,0,0), and bbmax the upper, north/east corner of the sim (256,256,4096).
2) Let the ray begin at vector begin and end at vector end (using the same coordinate system as the bounding box). 3) Calculate bbmine = bbmin - end, and bbmaxe = bbmax - end. Check if end is outside the sim, so clamping is needed at all, but checking that at least one coordinate in bbmine is positive or one coordinate in bbmaxe is negative (set 'clamping_needed'). 4) Shift coordinates so that so that begin becomes the origin and end' becomes the direction (bbmin -= begin; bbmax -= begin; dir = end - begin). Lets call end dir from now on. 5) Check that bbmin has three negative coordinates and bbmax has three positive coordinates. If not then begin is outside the bounding box (if there is a zero, it's on the border and you can just return begin). Not sure if you should return an error code or return just no results. Finally, if begin is outside the bounding box, but end was inside, you might want to clamp begin instead of end. Lets assume that begin is inside the bounding box for now. If end was also inside it, then no clamping is needed and we stop here. 6) Clamping is needed. Calculate dir.x / bbmin.x, dir.x / bbmax.x, dir.y / bbmin.y, dir.y / bbmax.y, dir.z / bbmin.z and dir.z / bbmax.z. 7) Find the largest value 'max' of those six and return begin + dir / max as the collision point of aray in the direction dir.
As you can see, this is a very fast routine. Still, I think it should be added to the server side. I didn't add code in order to avoid and license problems ;)
Aleric Inglewood 12:00, 3 July 2010 (UTC)