Jump to content

Follow a path of pre made prims


Dorex Delicioso
 Share

You are about to reply to a thread that has been inactive for 3229 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Lousy subject line because I'm not sure what this would be called

I don't know if this can be done or not, so I thought I'd ask.

I would like to lay down any number of prims in a circut, and have another prim follow them, picking up each prims information as it goes.

For example, I lay down a bunch of prims in a circle, all with different orientations. The main prim moves to one and gets that prims position and rotation info, then it moves to the next and collects that, all the way around. Sort of like laying down railroad track and having the prim follow them.

What I don't know is how to make one prim detect another one I guess.

I know i can make a prim do a circut with KeyFrame, but this is to teach a prim the location values to use in a KeyFrame script.  I want to put down the prims, have one follow them and get the data, then I can test and rerun until I'm happy with it instead of having to manually place the prim in each position and read the data that way.

Is this even possilbe ?

Thanks for your advice and help

Dorex D.

Link to comment
Share on other sites

Sure you can do that
Give all the prims the same name and let your moving prim use llSensor() to sense them
The first one returned (number 0) out of max 16 is the nearest one

In the sensor event you have access to all returned prim positions and rotations at the same time
Use llDetectedPos() and llDetectedRot() for that

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

Is it safe to assume that llDetectedPos(0) is always going to be the nearest one (assuming the sensor is using a reasonably narrow arc, like PI/4) or is it best to compare distances too?   

I ask because it will simplify my life a lot in a forthcoming project if I don't need always to be checking llVecDist.

Link to comment
Share on other sites

So after posting this, I read the replies and came up with this code. It works, it's not particularly fancy and I'm sure some top-notch scripter can rewrite it in 1/2 the code, but it works.

 

//// Follow a path of target prims// Because sensor only returns 16 objects, the targets have to // be fairly close to make sure each is found (sensorDistance)//// Each target prim has to be named 'Link xx.xx' where xx.xx is any sequential float number// Link 1, Link 2, Link 2.2, Link 3. Floats were used so you can insert additional targets as needed.// Each next target can be in any position, ahead, behind, etc. so we can't just use the next closest target.//float		sensorDistance=32.0;float		lastTargetId;string		namePrefix="Link";float		SEARCHID=9999.9;vector		startPosition;rotation	startRotation;default{    touch_start(integer total_number) {		//		// remember where we started		//		startRotation=llGetRot();		startPosition=llGetPos();		lastTargetId=-1;		llSensorRepeat("", "", PASSIVE, sensorDistance, PI, 1.0);    }     sensor( integer detected ){			float 	selectedTargetId=SEARCHID;		integer	detectedId;		float 	targetId;		        while(detected--)        {			// filter only for the prim names we are searching for			string name = llDetectedName(detected);			//llOwnerSay("Looking at: " + name);						if(llSubStringIndex(name, namePrefix)>-1){							// get the targetId from the target prim				targetId = (float)llGetSubString(name, llSubStringIndex(name," "), -1);				//				// search all targets found for the next lowest id				//				if(targetId>lastTargetId && targetId<selectedTargetId){					selectedTargetId=targetId;					detectedId=detected;						}			}                 }				lastTargetId=selectedTargetId;		if(selectedTargetId<SEARCHID){			//			// found a prim to follow, move to it's location and read it's position/rotation			//			list details = llGetObjectDetails(llDetectedKey(detectedId), ([OBJECT_POS, OBJECT_ROT, OBJECT_DESC]));			vector pos=llList2Vector(details,0);			rotation rot=llList2Rot(details,1);			llSetRegionPos(pos);			llSetRot(rot);			// save pos/rot here for other uses					} else {			// couldn't find any more targets 			llSensorRemove( );			llSetRegionPos(startPosition);			llSetRot(startRotation);					}			    }}
Link to comment
Share on other sites

It has probably occurred to you that if the target prims are all numbered like that, you don't need to have your scripted object visit each one to get its position and rotation. After all, once your sensor finds them all you need to do is save llDetectedPos and llDetectedPos for each one in a strided list, in order by their ID number.

Link to comment
Share on other sites

Hi,

 

Yes, the prims are along the outter edge of a whole region which is why I had to number them and visit them individually so the next one would be in range. Seems to work pretty good so far, better than placing the object there for each point manually and getting the data points from it.. The biggest issue I'm having is when getting near a lot of unrealated objects that clog up the sensor limit.

thanks a lot

Dorex

Link to comment
Share on other sites

To meet that issue you may consider naming all your way points identically and use the name as filter in llSensorRepeat()

Say:

llSensorRepeat("waypoint", "", PASSIVE, sensorDistance, PI, 1.0);

The number can be placed in the description and you can get it by:

list L = llGetObjectDetails( llDetectedKey( detected), [OBJECT_DESC]);integer number = llList2Integer( L, 0);

As a bonus you can remove the filtering you have in the sensor event handler

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

Hi Dora

I took your advice and rename all the marker prims with the same name and moved the index into the description.

Made for smaller, cleaner code, which is always a good thing.

Thanks everyone for your help, here's how it ended up


default{ touch_start(integer total_number) { lastTargetId=-1; llSensorRepeat("Link", "", PASSIVE, 50.0, PI, 1.0); } sensor( integer detected ) { float selectedTargetId=9999; float targetId; vector targetPos; rotation targetRot; // // do the detect loop this way so we get the closest objects first // integer detectedIndex=0; do{ // find the next prim with our target name 'Link' where the target id in the description // is greater than the lastTargetId, but lower than all remaining // // parse the description field to get a csv list of values {targetId,speed,xxx,xxx} // targetId is required, nothing else is. // list objectValues=llGetObjectDetails(llDetectedKey(detectedIndex),([OBJECT_POS,OBJECT_ROT,OBJECT_DESC])); list descriptionValues=llParseString2List(llList2String(objectValues,2),[","],[]); targetId = llList2Float(descriptionValues,0); if(targetId>lastTargetId && targetId<selectedTargetId){ // possible target, save the info for later selectedTargetId=targetId; targetPos=llList2Vector(objectValues,0); targetRot=llList2Rot(objectValues,1); } }while(++detectedIndex<detected); lastTargetId=selectedTargetId; if(selectedTargetId<9999){ llSetRegionPos(targetPos); llSetRot(targetRot); llOwnerSay("Moving to: " + namePrefix + " " + (string) selectedTargetId); } else { // couldn't find anymore prims llSensorRemove( ); } }}

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3229 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...