Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

AutoBahn, Rotation math problem.

grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
12-23-2006 12:37
Edit: fixed below, but I don't know why.

I have been working on a scripted system that lets vehicles "see" the road and then drive by themselves. The road script replicates, sets the name with the key to the next prim and then removes itself from the prim. The vehicle can then use llKey2Name calls to get the road position and the next key.
http://www.lslwiki.com/lslwiki/wakka.php?wakka=AutobahnRoad

The problem is that I suck at math.

This script works fine when the prim is made so that ZERO_ROTATION points east, but I built my test road with the prims at 90,0,180 so that I could use the taper functions.

The problem is with m_RotationAdjustment in the UpdateDescr() function

CODE

//public Road configuration script
//
//Released into the public domain by grumble Loudon and LaserFur Leonov
//
//V0.4 (not done)
//
//defaults are used if not in notecard
integer m_Channel = 65;

integer m_lane = 1;
string m_RoadName = "TestRoad";

//Rotate the road prim east and touch to get "Actual Prim rotation"
rotation m_RotationAdjustment = <-0.70711, 0.00000, 0.00000, 0.70711>;

vector m_LaneAdjustment = <0.0,0.0,1.5>; //adjust to 1m above surface

//****************************************************************************************
integer m_DetectedScan = -1;
integer m_UpdateScript = 0;

integer m_MessageTimer = 0;
integer m_reSendMessage = 0;
string m_reSendMessageStr = "";

//current data
key m_lane1Key;

vector m_LanePos;
rotation m_LaneRot;

vector m_testPos;
//****************************************************************************************
UpdateFloatText()
{
string Text;
Text ="";
Text += "Lane " + (string)m_lane + "\n";

if (m_DetectedScan >= 0){
Text += "Road is sensing " + (string)m_DetectedScan + " Road Prims";
};
Text += "\n Actual Prim rotation = " + (string)llGetRot();
Text += "\n Lane pos = " + (string)m_LanePos;
Text += "\n Lane Rot = " + (string)m_LaneRot;
Text += "\n Adj pos = " + (string)m_testPos;
llSetText(Text ,<1,1,1>,1);
}
//*******************************************************************************
UpdateDescr(){

//object name = PublicRoad;0;Lane;speed;name;<pos 1m Up>;<Rotation>;key1;key2 ect...

vector myPos = llGetPos();
rotation myRot = llGetRot();

// rotation tRot = m_RotationAdjustment; //inverse //ZERO_ROTATION /
m_LaneRot = myRot;// * tRot; // adjust for custom direction from prims view

vector LaneAdj = m_LaneAdjustment * m_LaneRot ; //adjust the lane surface
m_testPos = LaneAdj;

m_LanePos = myPos + LaneAdj; //1m above road surface

string name;
name = "PublicRoad;0;"; //prim name and version
name += (string)m_lane + ";"; // Lane number
name += "20;"; //recomended Speed limit in m/sec
name += m_RoadName + ";"; //road name
name += (string)m_LanePos + ";"; // X,y,z Lane position
name += (string)m_LaneRot + ";"; // rotation.
//<0,0,0,1> points east,
//<0,0,-1,0> points west
//<0,0, 0.707, 0.707 points north
//<0,0, -0.707, 0.707 points south
name += (string)m_lane1Key; //Key to next prim


llSetObjectName(name);
UpdateFloatText();

}// update
//********************************************************************************
integer ProcessCommand(string message,integer FromNotecard) // from either chat or notecard
{// processes message
//returns true if message should be re sent on chat
integer resend = -1;

if (message == "Scan"){
llSensorRepeat("",NULL_KEY,PASSIVE|ACTIVE,18,0.5,3.1);
resend = 0;

}else if (message == "stop"){
llSensorRemove();
m_DetectedScan = -1;
if (!FromNotecard){
llSleep(.2);
llWhisper(m_Channel,message);
};

}else if (message == "remove"){
if (!FromNotecard){
llSetText("" ,<1,1,1>,1);
llSleep(.2);
llWhisper(m_Channel,message);
llRemoveInventory(llGetScriptName());
};
resend = 0;
}else if (message == "update"){
if (!FromNotecard){
m_UpdateScript = TRUE; //rez start pram tells next script
};
}else{
UpdateDescr();
};//

return resend ;

}//ProcessCommand

//********************************************************************************
default
{
state_entry()
{

//used to get m_RotationAdjustment
//llOwnerSay( (string) (ZERO_ROTATION / llGetRot()));

llSetRemoteScriptAccessPin(123);
llListen(m_Channel,"",NULL_KEY,"");

UpdateDescr();

m_lane1Key = NULL_KEY;

if (llGetStartParameter() == 1) m_UpdateScript = TRUE; //replicate

llSensorRepeat("",NULL_KEY,PASSIVE|ACTIVE,18,0.5,2.4);

llSetTimerEvent(1.2);
} //Entry
//*****************************************************************************
on_rez(integer Reznumber){
if (Reznumber == 1){
// replicate
m_UpdateScript = TRUE;
}else{
llResetScript();
};
}

//*****************************************************************************
timer(){

if (m_MessageTimer != 0) --m_MessageTimer;


} //timer
//*****************************************************************************
touch(integer num){
llOwnerSay(" Actual Prim rotation = " + (string)llGetRot());
}
//*****************************************************************************
listen(integer channel, string name, key id, string message){

if (m_MessageTimer == 0) //we only respond to one command every 3 seconds
{
m_MessageTimer = 2;
if ( m_reSendMessageStr != message ) //repeating message?
{
m_reSendMessageStr = message;
m_reSendMessage = ProcessCommand(message,FALSE);
}; //same
}; //timer

}// listen
//*****************************************************************************
sensor(integer Num_Detected)
{
m_DetectedScan = 0;

integer useNum = -1;
vector myPos = llGetPos();
float closest = 100;

integer i;
for (i = 0 ; i < Num_Detected; ++i){
string name = llDetectedName(i);
key dKey = llDetectedKey(i);

if (llGetSubString(name,0,10) == "PublicRoad;"){
if ( llDetectedOwner(i) == llGetOwner()){

//does it need upating
if (m_UpdateScript){
if (llDetectedType(i) == PASSIVE){ //no script running
if ( llDetectedOwner(i) == llGetOwner()){

llRemoteLoadScriptPin(dKey, llGetScriptName(), 123, TRUE, 1);
jump ExitFor; //rescan
};//owner
};//passive
}; // update


//is it my lane?
list Prams = llParseStringKeepNulls(name,[";"],[]);
integer listLenght = llGetListLength(Prams);
if (listLenght >= 7 ){
//0 PublicRoad
//1 version
integer DetLane = (integer)llList2String(Prams,2);//2 Lane
//3 speed
//m_DetectedRoadName = llList2String(Prams,4); //4 Name

if (DetLane == m_lane){

//is it ahead of me?
vector NextPos = llDetectedPos(i);
float dist = llVecDist(myPos , NextPos);

// check angle
// To do

if (dist < closest ){
useNum = i;
closest = dist;
};
++m_DetectedScan;
};//lane
};//list

}; // owner
};//name
}; //sensor for


if (useNum != -1){
key nearestKey = llDetectedKey(useNum);
if (m_lane1Key != nearestKey){
m_lane1Key = nearestKey;
UpdateDescr();
};

m_UpdateScript = FALSE;
};
@ExitFor;
//UpdateDescr(); //test
UpdateFloatText();
}//sensor

no_sensor()
{
m_DetectedScan = 0;
//UpdateDescr(); //test
UpdateFloatText();

}//no sensor
//*****************************************************************************
} //default
//*****************************************************************************
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
12-24-2006 10:38
I don't have time to study this now. Cool idea though. I can point you at another thread that has discussed similar problems.

As I understand you, you have a piece of road. You are trying to compute the position of the next piece of road, relative to the first?

Link to discussion
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
12-25-2006 07:22
I need to compute a position 1m above the road surface, but the objects rotation is user selectable to make it easier to update existing roads and to take advantage of taper, twist, ect..

If the user makes the object so that Zero_Rotation points east, then the script works.

The problem is that the prim rotation must be rotated by some other measured rotation.

I have the following information
1. The prims rotation when it is pointed east. (m_RotationAdjustment)
2. The prims current rotation (llGetRot())
3. The vector to offset the prim location. (m_LaneAdjustment)

Here is a cut down version with just the math in question.
This comes closest, but it flips the car upside down and into the ground when traveling east.
CODE

//Rotate the road prim east and touch to get the"Actual Prim rotation"
rotation m_RotationAdjustment = <-0.70711, 0.00000, 0.00000, 0.70711>;

//adjust to 1m above surface
vector m_LaneAdjustment = <0.0, 0.0, 1.5>;

//math
rotation tRot = ZERO_ROTATION / m_RotationAdjustment; //try inverse?
rotation m_LaneRot = llGetRot() * tRot; // (does not work!)

vector LaneAdj = m_LaneAdjustment * m_LaneRot ; //adjust the lane (works)

//output
//vector Pos = LaneAdj + llGetPos();
//rotation Rot = m_LaneRot;

Simply changing m_LaneAdjustment does not work since the vehicle needs the rotation to orientate itself.

The test road is in Charissa 10,10,95.
I am building the test rollercoaster in a private sim.
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
12-26-2006 10:34
This works, but I don't know why.

Edit: corection below

Users can now rotate the prim east and touch it to get the RotationAdjustment

Here is the math
CODE

rotation m_RotationAdjustment =<-0.70711, 0.00000, 0.00000, 0.70711>;
vector m_LaneAdjustment = <1.0,2.0,3.5>;

vector myPos = llGetPos();
rotation myRot = llGetRot();
rotation tRot1 = ZERO_ROTATION /myRot;
rotation tRot2 = m_RotationAdjustment;
m_LaneRot = tRot1 * tRot2 ; // adjust for custom direction from prims view

vector LaneAdj = m_LaneAdjustment * m_LaneRot ; //adjust the lane surface
vector m_LanePos = myPos + LaneAdj; //1m above road surface