If have played a little bit with Second Life and its ability to access external resources. Inspired by Matt Biddulph’s “flickr screen”, now i wanted to load xml data from an external source into the SL-world and display it on a nice looking screen. Because it is not possible — from my point of view — to display text directly on a SL-primitive, it was necessary to render the text in a first step to an image. I did this using a little RubyOnRails application which also loads and parses the xml-resource. Ok, now i show how i did this.
I used the REXML processor to work with the xml-data and RMagick to create the image. The xml-source is used is a little xml-file provided by LindenLabs which shows the land sales by resident for the last three month (http://secondlife.com/reports/marketplace_stats/2007-03-01/land_sales_by_residents.xml). The whole parsing is specific to this source.
# get the xml via http and read it into a variable and create a XML-Document after that
@content = Net::HTTP.get(URI.parse("
http://secondlife.com/reports/marketplace_stats/2007-03-01/land_sales_by_residents.xml"))
xmlDoc = REXML::Document.new(@content)
# get some attributes and select them with xpath
elRecords = REXML::XPath.first(xmlDoc, "records")
reportTitle = elRecords.attributes['report']
reportDate = elRecords.attributes['date']
# create a new image in the size you need. in my case it was 400 width and 200 height
f = Image.new(400,200) { self.background_color = "white" }# make some settings for the font
drawable = Magick::Draw.new
drawable.pointsize = 15.0
drawable.font_family = 'Helvetica'
drawable.fill = 'gray'
drawable.gravity = Magick::NorthWestGravity
drawable.font_weight = Magick::BoldWeight
drawable.annotate(f, 0, 0, 5, 4, "Second Life #{reportTitle} (#{reportDate})")
drawable.pointsize = 13.0
drawable.fill = 'black'
drawable.font_weight = Magick::NormalWeight
# set some position for the text i want to print
@startTopPos = 24
# go the records in the xml-document and print the values into the new image
REXML::XPath.each( xmlDoc, "records/record") do |element|
element.elements.each("field") do |field|
name = field.attributes['name']
value = field.attributes['value']
drawable.annotate(f, 0, 0, 5, @startTopPos, name)
drawable.annotate(f, 0, 0, 250, @startTopPos, value)
@startTopPos = @startTopPos + 15
end
@startTopPos = @startTopPos + 15
end
# write the image to the disk. i wasnt able to return it directly without saving. :(
f.write("result.png")
# return the image
createdImg = Magick::Image.read("result.png").first
@response.headers["Content-Type"] = "image/png"
@response.headers['Content-Disposition'] = %q{inline; filename="thepicture.png"}
render :text => createdImg.to_blob
This script returns the following image:
To put this image on an primitive i used the following linden script code:
touch_start(integer num_detected) {
llSay(0, "trying...");
if(llGetLandOwnerAt(llGetPos()) != llGetOwner()) {
llSay(0,"Error: Cannot modify parcel media settings.");
}
key video_texture = llList2Key(llParcelMediaQuery( [PARCEL_MEDIA_COMMAND_TEXTURE]), 0);
if(video_texture == NULL_KEY)
{
video_texture = VIDEO_DEFAULT;
llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_TEXTURE, VIDEO_DEFAULT]);
}
llSetTexture(video_texture,ALL_SIDES);
llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_URL,"http://###URL###"]);
llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_PLAY]);
llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_AUTO_ALIGN,TRUE]);
}
###URL### has to be replaced with the URL of the Ruby-Script.
Note: To use this ParcelMedia-feature you have to allow streaming media i think in SL.
No comments:
Post a Comment