16
Dec
08

Motion Capture Second Life Script

Tonight we posted the code for Stereoscopic mode in the Second Life viewer to the SL developer’s list, here: https://jira.secondlife.com/browse/VWR-2972

Also, below is the code for the Second Life scripts that handle our motion capture interface for Becoming Dragon. This script simply reads an XML file over http, extracts the coordinates out and moves the object that contains this script to those coordinates. Then, one only needs to attach the object to your avatar and click on the object to start the motion capture. I left in my comments and debg code. In the next few days we’ll make our code for reading the live Vicon motion capture data out and translating them into XML.

Really, this would be most useful if you use a few objects to represent your avatar and make your avatar invisible. With such a system, by getting the base coordinates right for each body part, you could have full body motion capture. We simply did not have the time to get multiple objects working and mappe into a dragon body, so we only used one coordinate to do position tracking within the room at CRCA, mapping into the room in Second Life.

Since the vicon code is separate, these scripts could easily be used with a Wii, if you use a program like aka.wiimote or Darwiin remote to get the four points of mocap data from the wiibar and translate them to xml. Then these scripts could read that xml over http and viola! wii Second Life motion capture.

Here’s the code:

integer in_world = 0;
key http_request_id;
float timer_secs = 1;
integer moving = 0;
integer moves = 0;
integer max_moves = 60;

//begin xml reading code

list markers;

parseElement(string line)
{
if(line == “<markers>”)
{
//llOwnerSay(“markers line found, starting new markers list”);
markers = [];
return;
}

// determine type of element
string element = llGetSubString(line, 0, llSubStringIndex(line, ” “) – 1);
element = llToLower(element);

// parse known elements

parseMarkerElement(llGetSubString(line, llStringLength(element) + 1, -1));
}

parseMarkerElement(string line) {

//llOwnerSay(“parsing line: “+line);

if(line == “</markers>”) return;

// parse attribute name/value pairs
list parts = llParseString2List(line, [“=\'”, “\’ “, “\'”, “>”, “<\/”, “\'”], []);
integer n = llGetListLength(parts);
integer i;

// set default values
string position_x = “”;
string position_y = “”;
string position_z = “”;
string visibility = “”;
string marker_name = “”;

// loop through name/value pairs
for(i = 0; i < n; i += 2)
{
// read name/value pair

string name = llList2String(parts, i);
name =
name = llToLower(name);
string value = llList2String(parts, i + 1);

//find content of marker node, slightly hackish
if(value == “marker”) {
value = name;
name = “name”;
}

// assign known values
if(name == “position_x”) position_x = value;
if(name == “position_y”) position_y = value;
if(name == “position_z”) position_z = value;
if(name == “visibility”) visibility = value;
if(name == “name”) marker_name = value;
}

// add new item
if(visibility == “true”)
{

markers += [marker_name];
markers += [position_x];
markers += [position_y];
markers += [position_z];
}
}

//end xml reading code

default {

state_entry()  {

if(in_world == 0)
{
llOwnerSay(“Hi, I’m the new movement object xml!”);
in_world = 1;
}

llSetStatus(STATUS_PHYSICS, TRUE);

}

http_response(key request_id, integer status, list metadata, string body)      {

//if ( moves < max_moves ) {

list coords;

//llOwnerSay(“http response received…”);

if (request_id == http_request_id)  {

//llSetText(body, <0,0,1>, 1);
//llOwnerSay(body);

// parse out xml elements
//list lines = llParseString2List(body, [“/>”,”<“, “>”, “\n”], []);
list lines = llParseString2List(body, [“\n”], []);

// loop through elements
integer n = llGetListLength(lines);
integer i;
for(i = 0; i < n; i++)
parseElement(llList2String(lines, i));

//llOwnerSay(“markers: “+(string)markers);

//move by offsets in html body
//= llGetPos();

vector position;
vector offset;
list thiscoord;

if(llGetListLength(markers) > 2) {

//llOwnerSay(“using marker “+llList2String(markers, 0) );

//change these numbers, after the +’s to your origin in your sim
offset.x = (llList2Float(markers, 1)/1000) + 183;

offset.y = (llList2Float(markers, 2)/1000) + 16;

offset.z = (llList2Float(markers, 3)/1000) + 33;

if(offset.x > 0 && offset.y > 0 && offset.z > 0)
{
//llSetPos(offset);

llMoveToTarget(offset, 0.1);

//llOwnerSay(“+++ Moving to “+(string)offset.x+” , “+
// (string)offset.y+” , “+
// (string)offset.z);

llSetText((string)offset.x+”,”+(string)offset.y+”,”+(string)offset.z, <0,0,1>, 1);
}

//moves++;

} //end if coords

} //end if (request_id == http_request_id)

// } else {  //end if moves < 5

// llSetTimerEvent(0);
// llOwnerSay(“Newmove  : “+(string)moves+” moves! Stopping movement.”);
// moving = 0;
// moves = 0;
//}

}

timer() {

//llOwnerSay((string)timer_secs + ” second timer elapsed, sending http request…”);
http_request_id = llHTTPRequest(“http://yourserver.com/coords.php&#8221;, [], “”);

}

touch_start(integer total_number) {

if(moving == 0) {
llSetTimerEvent(timer_secs);
llOwnerSay(“Touched! Timer starting. sending http request…”);
http_request_id = llHTTPRequest(“http://yourserver.com/coords.php&#8221;, [], “”);
moving = 1;
} else {
llSetTimerEvent(0);
llOwnerSay(“Touched! Stopping movement.”);
moving = 0;
moves = 0;
}

}

}

And here’s a sample xml data file…

<?xml version='1.0' encoding='ISO-8859-1'?>
<markers>
		<marker position_x='316.474' position_y='213.859' position_z='42.4289'visibility='true'>Default:Marker1</marker>
		<marker position_x='540.871' position_y='125.609' position_z='44.586'visibility='true'>Default:Marker2</marker>
		<marker position_x='602.447' position_y='263.058' position_z='47.1262'visibility='true'>Default:Marker3</marker>
		<marker position_x='634.26' position_y='337.013' position_z='48.9091'visibility='true'>Default:Marker4</marker>
		<marker position_x='0' position_y='0' position_z='0'visibility='false'>wand:Marker1</marker>
		<marker position_x='0' position_y='0' position_z='0'visibility='false'>wand:Marker2</marker>
		<marker position_x='0' position_y='0' position_z='0'visibility='false'>wand:Marker3</marker>

</markers>
Advertisements

0 Responses to “Motion Capture Second Life Script”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


links

Visit the performance space in SL

Blog Stats

  • 34,784 hits

%d bloggers like this: