Quistess Alpha Posted February 3, 2022 Share Posted February 3, 2022 So, this is one of the worst ways to go about this (1 object+script per point adds up fast) But it's quite fun anyway. // general vars: integer gChan = 297; integer DEBUG = FALSE; vector gPos; // where is the point? string gName; string gDesc; // interpolated variables: vector gPointA; // location of point 'A' string gCodePA; // actual letter may not be 'A' vector gTangentA1; // location of tangent point vector gPointB; // location of point 'B' string gCodePB; // actual letter may not be 'B' vector gTangentB0; // location of tangent point. float gPercent; // percent of the way between 'A' and 'B' // tangent variables: // gCodePA ; will be overused as the point the tangent line passes through. // gPointA ; similarly the position that point is at. integer gTangentNum; // either 0 or 1, which tangent point is this. integer gIgnore; // we need to ignore some messages to prevent an infinite back and forth. // curve_end variables: // none specific. set_interpolation() { float x = gPercent; float nx = 1-gPercent; llSetRegionPos(nx*nx*nx*gPointA + 3*x*nx*nx*gTangentA1 + 3*x*x*nx*gTangentB0 + x*x*x*gPointB); } particle_line(key Target) { llParticleSystem([ PSYS_PART_FLAGS, PSYS_PART_TARGET_LINEAR_MASK| PSYS_PART_EMISSIVE_MASK, PSYS_SRC_TARGET_KEY, Target, PSYS_PART_START_SCALE, <0.1,0.1,0.1>, PSYS_PART_START_COLOR, <0.9,0.9,0.0>, PSYS_SRC_BURST_RATE, 0.2, PSYS_PART_MAX_AGE, 3.0 ]); } default { state_entry() { if(DEBUG) llSay(0,"Boot up"); // set_state(); gName = llGetObjectName(); if (!llSubStringIndex(gName,"Point")) { state curve_end; }else if(!llSubStringIndex(gName,"Tangent")) { state tangent; }else if(!llSubStringIndex(gName,"Interpolated")) { state interpolated; }else { llSay(0,"Name not recognised"); } } } state curve_end { state_entry() { //llListen(gChan,"","",""); llParticleSystem([]); llSetColor(<0,1,0>,0); llSetScale(<0.2,0.2,0.2>); llSetText(gName,<0,1,0>,1.0); } touch_end(integer n) { // set_state(); if(gName!=llGetObjectName()) { llResetScript(); } vector pos = llGetPos(); if(gPos!=pos) { llSay(gChan,(string)pos); gPos=pos; } } } state tangent { state_entry() { llParticleSystem([]); llListen(gChan,"","",""); llSetColor(<0.9,0.9,0>,0); llSetScale(<0.15,0.15,0.15>); llSetText(gName,<1,1,0>,1.0); gCodePA = llGetSubString(gName,-2,-2); gTangentNum = (integer)llGetSubString(gName,-1,-1); llSensor("Point "+gCodePA, "", PASSIVE|SCRIPTED, 12.0, PI); } on_rez(integer i) { llSensor("Point "+gCodePA, "", PASSIVE|SCRIPTED, 12.0, PI); } sensor(integer n) { if(n==1) { gPointA = llDetectedPos(0); particle_line(llDetectedKey(0)); if(DEBUG) llSay(0,"Found point: "+gCodePA); }else { llSay(0,"Error, duplicate points found: "+gCodePA); } } no_sensor() { llSay(0,"Error, Point not found: "+gCodePA); } touch_start(integer n) { if(gName!=llGetObjectName()) { llResetScript(); } vector pos = llGetPos(); if(gPos!=pos) { llSay(gChan,(string)(gPos=pos)); gIgnore = TRUE; vector X = llVecNorm(gPointA-llGetPos()); llSetRot(llRotBetween(<0,0,1>,X)); } } listen(integer Channel, string Name, key ID, string Text) { if(Name=="Point "+gCodePA) { vector pos = ((vector)Text); llSetRegionPos(gPos = (llGetPos()+ pos - gPointA)); llSay(gChan,(string)gPos); gIgnore = TRUE; gPointA = pos; vector X = llVecNorm(gPointA-llGetPos()); llSetRot(llRotBetween(<0,0,1>,X)); }else if(Name=="Tangent "+gCodePA+(string)(!gTangentNum)) { // ^^ could be more efficient by precalculating that as a global variable. if(gIgnore) { gIgnore=FALSE; }else { vector pos2 = (vector)Text; vector norm = llVecNorm(gPointA-pos2); float dist = llVecDist(llGetPos(),gPointA); vector gPos = gPointA+(norm*dist); llSetRegionPos(gPos); llSay(gChan,(string)gPos); } } } } state interpolated { state_entry() { llParticleSystem([]); llListen(gChan,"","",""); llSetColor(<0.2,0.2,0.2>,0); llSetScale(<0.1,0.1,0.1>); gDesc = llGetObjectDesc(); gCodePA = llGetSubString(gName,-2,-2); gCodePB = llGetSubString(gName,-1,-1); llSetText(gCodePA+gCodePB,<0.1,0.1,0.1>,1.0); list parsed = llParseString2List(llGetObjectDesc(),["/"," "],[]); gPercent = (float)llList2String(parsed,0) / (float)llList2String(parsed,1); llSensor("Point "+gCodePA, "", PASSIVE|SCRIPTED, 12.0, PI); } on_rez(integer i) { llSensor("Point "+gCodePA, "", PASSIVE|SCRIPTED, 12.0, PI); } touch_start(integer n) { if(gName!=llGetObjectName() || gDesc!=gDesc) { llResetScript(); } } sensor(integer n) { while(~--n) { string name = llDetectedName(n); if(name == "Point "+gCodePA) { gPointA = llDetectedPos(n); llSensor("Point "+gCodePB, "", PASSIVE|SCRIPTED, 12.0, PI); }else if(name == "Point "+gCodePB) { gPointB = llDetectedPos(n); llSensor("Tangent "+gCodePA+"1", "", PASSIVE|SCRIPTED, 12.0, PI); }else if(name == "Tangent "+gCodePA+"1") { gTangentA1 = llDetectedPos(n); llSensor("Tangent "+gCodePB+"0", "", PASSIVE|SCRIPTED, 12.0, PI); }else if(name == "Tangent "+gCodePB+"0") { gTangentB0 = llDetectedPos(n); set_interpolation(); } if(DEBUG) llSay(0,"Found: "+name); } } no_sensor() { llSay(0,"Not found"); } listen(integer Channel, string name, key ID, string Text) { vector pos = (vector)Text; integer change = FALSE; if(name == "Point "+gCodePA) { gPointA = pos; change = TRUE; }else if(name == "Point "+gCodePB) { gPointB = pos; change = TRUE; }else if(name == "Tangent "+gCodePA+"1") { gTangentA1 = pos; change = TRUE; }else if(name == "Tangent "+gCodePB+"0") { gTangentB0 = pos; change = TRUE; } if(change) { set_interpolation(); } } } It's a bit of a pain to set up (need to type in a lot of repetitive names and descriptions) and to use (need to touch after moving the points or tangents to register a change) but it's workable. Edit-> move a point or 'tangent' then touch it and everything else falls into place in a 'natural' way. You can see it live (I even left move permissions on, so anyone can move the colored points) in my sandbox http://maps.secondlife.com/secondlife/Gilgamesh/36/167/2012 until I decide I need the LI back. (should be a week or two at least) 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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