|
shaqq Korobase
Registered User
Join date: 17 Jun 2008
Posts: 3
|
09-22-2008 03:57
I need a general script that I could attach to any building object and it will use a listener to determine which avatars are entering and exiting the building. Spent the whole day trying to figure out how to solve this problem and failed miserably  Please help!!!
|
|
Jodie Suisei
Lost In LSL Code
Join date: 6 Oct 2006
Posts: 66
|
09-22-2008 04:46
A listener for telling if people going in and out of your building wouldnt do much on its own. You would either need to use a Scripted prim set to volume detect (Phantom) and put a visitor greeter in it so when an avi walked through it would keep count then you could pass that to a listen script. The other solution would be to use a sensor repeat to see who is within 96m of the prim with the script in and then relay to that listen script. There is a place SL Free Scripts Library dont have the SLURL but they have for free in there basic visitor greeter scripts and i believe one with email that you could get your hands on with a little time finding them. They should put you on at least a starting point  Oooh i will do one better i happen to have a free one in my inventory //This script will count everyone that visits //But it can only remember the last 100 unique visitors //people will be counted more than once if they visit often.
//Owner can Touch object anytime for the current totals.
//It will send owner an Instant Message each day like a //Voting Station, to tell you yesterday's count.
//Rez object around midnight for best results
// Edit these variables only ___________________________ integer displaytext = TRUE; //FALSE for no floating text float range = 40.0; // sq. meters to scan float rate = 60.0; // seconds between scanning for new visitors (higher is less lag) //______________________________________________________
// Global variables integer seconds = 86400; //24 hours string startdate; list visitor_list; integer today = 0; integer totalcount = 0; string ts; list now; list lstParcelName;
//Functions integer isNameOnList( string name ) { integer len = llGetListLength( visitor_list ); integer i; for( i = 0; i < len; i++ ) { if( llList2String(visitor_list, i) == name ) { return TRUE; } } return FALSE; }
//States default { on_rez( integer param ) { llResetScript(); } state_entry() { list lstParcelDetails = [PARCEL_DETAILS_NAME]; lstParcelName=llGetParcelDetails(llGetPos(),lstParcelDetails); ts = llGetDate(); now = llParseString2List( ts, ["-"], [] ) ; integer nyear = (integer)llList2String( now, 0 ) ; integer nmonth = (integer)llList2String( now, 1 ) ; integer nday = (integer)llList2String( now, 2 ) ; if (nmonth == 1) { string smonth = "January"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 2) { string smonth = "February"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 3) { string smonth = "March"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 4) { string smonth = "April"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 5) { string smonth = "May"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 6) { string smonth = "June"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 7) { string smonth = "July"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 8) { string smonth = "August"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 9) { string smonth = "September"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 10) { string smonth = "October"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 11) { string smonth = "November"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } else if (nmonth == 12) { string smonth = "December"; startdate = smonth + " " + (string)nday + ", " + (string)nyear; } if (displaytext) { llSetText( "0 Visitors Today\n 0 since " + startdate, <1,1,1>, 0.8 ); } else { llSetText( "", <1,1,1>, 1.0 ); } llOwnerSay("Now Ready. Scanning " + (string)range + " meters every " + (string)rate + " seconds for new visitors."); llOwnerSay("Please wait " + (string)rate + " seconds for the first count."); llSetTimerEvent(seconds); llSensorRepeat( "", "", AGENT, range, TWO_PI, rate ); } sensor( integer number_detected ) { integer i; for( i = 0; i < number_detected; i++ ) { if( llDetectedKey( i ) != llGetOwner() ) { key detected_key = llDetectedKey( i ); string detected_name = llDetectedName( i ); if( isNameOnList( detected_name ) == FALSE ) { visitor_list += detected_name; today += 1; totalcount += 1; integer len = llGetListLength( visitor_list ); if (len == 100) { visitor_list = []; } else if (len > 100) { visitor_list = []; } if (displaytext) { llSetText( (string)today + " Visitors Today\n " + (string)totalcount + " since " + startdate, <1,1,1>, 0.8 ); } } } } } touch_start (integer total_number) { if (llDetectedKey(0) != llGetOwner()) //anyone { //nothing happens } else if (llDetectedKey(0) == llGetOwner()) //owner { integer len = llGetListLength( visitor_list ); llOwnerSay((string)today + " people have been here so far today."); llOwnerSay((string)totalcount + " total visitors since " + (string)startdate +"."); } } timer() //EVERY 24 HOURS { llInstantMessage(llGetOwner(), "There was " + (string)today + " visitors yesterday at " + (string)lstParcelName + ". " + (string)totalcount + " total visitors since " + (string)startdate +"."); today = 0; if (displaytext) { llSetText( (string)today + " Visitors Today\n " + (string)totalcount + " since " + startdate, <1,1,1>, 0.8 ); } } }
Hope that helps 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
09-22-2008 17:04
Define "inside". 
|
|
shaqq Korobase
Registered User
Join date: 17 Jun 2008
Posts: 3
|
Still need help
09-23-2008 01:02
Hi guyz,
The problem is still not solved. The code suggested by Jodie doesn't quite do the job. So I'll start with defining "inside", following Hewees advice.
I have a building with walls and one entrance doors. Being inside this building means entering it through the door and being within the area surrounded by building's walls, ceiling and the ground.
I'm ready to accept some simplifications. 1. There could be a floor in every building that I'm concerned with 2. I would agree to start with just determining whether the avatar is within the bounding box of the building.
After reading the LSL manual I had a clear impression that the sensor will be acceptable for the beginning as on all the images it seems to be placed in the center of mass of the object and I just have to calculate the correct range, so that I get a sphere that tightly encloses the building. But on practice the sensor is associated with the starting coordinate, not with the center.
Then I followed the approach with scanning every avatar in 96 m surrounding and determining whether this avatar is inside the bounding box of the building. That's where I got stuck. I can't find a right way to calculate the bounding box. It seems that I also have to take the object rotation into account, which is not clear to me yet how to calculate.
So, any help would be very much appreciated. I expected there would be an easy method call like isInside(vector point), but it doesn't seem to be the case in LSL.
|
|
Zhenya Vlodovic
Registered User
Join date: 23 Sep 2008
Posts: 40
|
09-23-2008 07:04
If you want to do this with sensors you'll need to get the XYZ coordinates of any avatar within range and compare those against the bounds of your building, i.e.
if ( pos.x >= lowerboundX && pos.x <= upperboundX && pos.y >= lowerboundY && pos.y <= upperboundY && pos.z >= lowerboundZ && pos.z <= upperboundZ)
There's no way to get the bounds of the building automatically, though you could create a bounding prim (perhaps invisible and phantom) and calculate its bounds.
To get the coordinates of an avatar you'd use llDetectedPos in your sensor event.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
09-23-2008 10:00
If a simple bounding box check is adequate, you should be able to do something like this: (Note: Not yet compiled; may need a few minor syntax fixes.) // Returns TRUE iff point (in region coords) is inside this object's bounding box integer isPointInsideBounds(vector point) { key rootPrim; if (llGetNumberOfPrims() > 1) { rootPrim = llGetLinkKey(1); } else { rootPrim = llGetKey(); }
list details = llGetLinkPrimitiveParams(rootPrim, [ OBJECT_POSITION, OBJECT_ROTATION ]); if (llGetListLength(details) < 2) { return FALSE; }
vector pos = llList2Vector(details, 0); vector rot = llList2Vector(details, 1); vector relPos = (point-pos)/rot;
list bbox = llGetBoundingBox(rootPrim); vector bboxMin = llList2Vector(bbox, 0); vector bboxMax = llList2Vector(bbox, 1);
return relPos.x > bboxMin.x && relPos.x < bboxMax.x && relPos.y > bboxMin.y && relPos.y < bboxMax.y && relPos.z > bboxMin.z && relPos.z < bboxMax.z; }
|
|
Moundsa Mayo
Registered User
Join date: 21 May 2007
Posts: 16
|
09-23-2008 19:17
If you decide to try the phantom invisible building-sized prim (prolly a megaprim would be required), just implement CollisionFilter and VolumeDetect for that prim and you're done - no need for calculations.
|
|
Destiny Niles
Registered User
Join date: 23 Aug 2006
Posts: 949
|
09-23-2008 19:35
I've just finished doing a project that did just what you describe. Use a prim the size of the room and use llVolumeDetect use collision_start to detect inside and the collision_end is trigger when they leave default { state_entry() { llVolumeDetect(TRUE); // Starts llVolumeDetect } collision_start(integer total_number) { llSay(0, llDetectedName(0)+" has entered the building"  ; // Tells you when something penetrates the prim } collision_end(integer num) { llSay(0,llDetectedName(0)+" has exited the building"  ; } }
|
|
shaqq Korobase
Registered User
Join date: 17 Jun 2008
Posts: 3
|
Thanx
09-24-2008 22:21
Thanx a lot for your help, guyz!!! I plan to use a combination of the both proposed approaches. As I need a general script that I intend to apply to many different buildings it is not acceptable for me to create a phantom for every building. All of my buildings will have a single entry door, so here is what I came up with.
I will track the bounds of the room and will have a door phantom that will give me some extra precision.
Thanx again for your help!
|
|
Alicia Sautereau
if (!social) hide;
Join date: 20 Feb 2007
Posts: 3,125
|
09-24-2008 22:35
if the rooms or atleast scanning area can be square, you should be able to get the 4 corner cordinates and do some math magic if the avi is still in the "box"
don`t ask me as i`m bad with math but maybe some one can?
|