Showing posts with label Second Life Scripting. Show all posts
Showing posts with label Second Life Scripting. Show all posts

Monday, March 8, 2010

Evolution Simulation III Devastation in Science Sim!

Well not quite. But I was testing my critters to see how big a population my parcel in Science Sim could hold. Everything was fine until I went to delete them using a listen event with llDie triggered by a chatted command. Guess what, 600 prims dying all at once causes the asset server to have a fit: a bit disconcerting but Mic Bowman got things fixed....




And immediately after Mic's fix:

















Thigs were still loading at this point. What Mic recommended is that I use a random number to determine when a particular critter is going to die so that when I issue the command to die the critters don't all die at once.

In SL this bit of code gives a quite realistic movement for my critters:

vector newpos = newcoodinates(llGetPos() ,3.0);

llSetRot(llEuler2Rot(<0,0,-pi/2>)*llGetRot());

llLookAt(newpos,1,0);

llSetPos(newpos);



But in OpenSim the critters don't seem to turn toward the target in response to llLookAt as they do in SL.


Tuesday, February 23, 2010

SLPro Conference Day 1: A Rocky Start but...

The key note got off to a rocky start with most participants not able to get audio and video for much of the time. But the big announcment is SL's Viewer 2 which we get to preview! Looks like a cleaner interface and my impression is that Viewer 2 renders graphics more rapidly than the current viewer.

But what is really cool is the viewer's shared media feature. One thing that I and other "content devlopers" in Second Life have groused about is the inability to display interactive sorts of media such as, well web pages. With the current Second Life viewer the user can display a web page by replacing using the llLoadUrl function but you can't interact with it. But now you can.

After the keynote we got to play for example with a drawing program and we could all interact with it in real time even though it was displayed as a texture on a prim. If you use a web page as a texture you can not only see the web page but you can scroll through the web page and even open new links just as with a standard browser!

Ahhh but there is more. Currently when you display a web page it uses you're parcel media feature which means only one medium per parcel. So if you are a teacher and want to display say multiple web pages you can't have them all display at the same time unless you subdivide your parcel into smaller parcels. Now you can!

This is a big deal for SL content providers and really integrates SL with the web. I just had to try it and works as advertised. So this image shows two of my blogs on separate prim's and these are all on the same parcel. You can do the same thing with media such as Flash sites opening up a new potential for gaming in SL.

I have just started working with this feature so don't have more to say about it...but it looks like web on a prim is here finally. and I think it is really going to improve the immersive experience in Second Life. I can almost forgive the keynote glitches for this.

Thursday, February 4, 2010

OpenSim Evolution Simulation I

This is the first progress report on what's going on with my OpenSim Artificial Life/Evolution simulation introduced in this post.

Since I am interested in social behavior I think a good place to start is simulating a population where prisoner's dilemma is operating. The term "game" here used in the game theoretic sense, gets its name from the following scenario:

Two suspects are arrested by the police. The police lack enough evidence for a conviction. The prisoners are kept separate and the prosecutor visits each of them with the same deal. If one testifies (defects from the other) against the other, and the other remains silent (cooperates with the other prisoner), the betrayer goes free and the silent accomplice receives the full 10-year sentence. If both remain silent (they cooperate with each other), each gets only six months in jail for a minor charge. If each betrays the other, each receives a five-year sentence. Each prisoner must choose to betray the other or to remain silent. Each one is assured that the other would not know about the betrayal before the end of the investigation.

(modified from http://en.wikipedia.org/wiki/Prisoner%27s_dilemma)

Now this scenario may not seem related to evolution but it turns out that this is exactly the sort of thing that happens when two animals related or not might have choices to cooperate or not with other animals either of the same species or sometimes other species.

A couple of design issues revolve around topics like how to link the organisms' behavor to genetics, represent the genetics of the interacting organisms and how to pass that genetics to offspring. To get a feel for the general strategy I have used in the past, go to this post.

One new technical issue is that unlike my genetics activities and my discrete generation evolution simulation, the organisms I am using here have to be able to replicate themselves independently of some command from me. Now that a scary thought since I don't want to over run a sim with thousands of little evolving critters.

Fortunately the LSL Wiki gives a good rundown on how to make non invasive self replicating critters. For instance have them be killed if they get out of your parcel. Right now my critters are able to detect the parcel boundary and turn away from the boundary....but I will add the kill feature as an additional safety.

One of LSL's safety features isn't going to work in my case. LSL recommends using a counter that is decremented by 1 each time an offspring is replicated from the parent. The value of the counter is passed as the integer parameter in the llRezObject function and when the counter reaches zero say after 10 generations the critter dies rather than replicating. The problem is that I use this parameter to pass the genetics from parent to offspring.

So I need to figure out how to prevent non invasive critters from over running my parcel. My first impulse was to have each critter sense the number of critters in the parcel and stop them from replicating when the parcel count gets to a certain point-kind of a parcel carrying capacity. And that might be a good idea but the simplest way to do it might be to have one object track the number of critters in in the parcel and periodically send that to all the critters using llRegionSay on a private channel and have the critters individually adjust their replication as required.

A more interesting option might be to use a sensor event to get the number of critters in a set radius around the sensing critter and use that to adjust the rate of reproduction, perhaps make it negative. So critters in a region with few others would be able to multiply more rapidly than those at higher densities. I already use a sensor event to let the critters detect each other so I could modify that to do this as well. This would actually be quite realistic since organism's reproductive rates are often affected by density dependent factors.

So here is what I am thinking on the replication issue:

1. Implement a die if beyond land owned by me along with my current boundary detection routine.
2. Implement a central controller that determines how many critters are in my region and either kills them all or stops them from reproducing further if they get too numerous beyond some large population size say 4,000.
3. Implement the sensor option to determine the density of critters and adjust the rate of local reproduction. Should be possible to tweek this so the population's maximum would tend to run at a lower limit than 4,000, say 2,000.

Maybe I am being paranoid but who knows what sort of chaotic things can happen with 2,000 artificial life forms run around a sim unchecked. It would be the equivalent of pythons in the Everglades and probably really annoy my neighbors.


This may be interesting in its own right as a simple population growth model even with out the complication of prisoner's dilemma! If you want to join the fun and see what's going on, IM me as Paul Decelles in ScienceSim or as Simone Gateaux in SL . Remember, you need to configure your client for OpenSim and set up a user account. Also Avatars do not port between SL and Opensim.

The ScienceSim site will get you started.: http://www.sciencesim.com/ Make sure you read and follow the directions and rules carefully.

PS: SLurls don't work in OpenSim as far as I can tell but if you are in OpenSim I am in
Oregon North 47, 184, 23 in the ScienceSim grid.

Tuesday, July 21, 2009

Mitosis I Wigglies



Animated and wiggly duplicated chromosomes (Reddish wormie things*) scripted to separate and behave as they do during anaphase. The green structures are the paired centrioles, the pink box when touched tells the sister chromatids...those are the wigglies... to separate into unduplicated chromosomes.

*notice the precise biological terminology in this post.

Lots of stuff: Part 1

Been busy teaching in first life this summer but also with Second Life as well. In about 2 weeks I in my first life presence as Paul Decelles will be giving a presentation on doing simulations in Second Life to the SIDLIT conference in Kansas City. My topic is Scientific Simulations in Virtual Worlds and I will cover some of the stuff I did on my sabbatical, lots of which is on this blog, and also discuss alternative virtual world systems for doing simulations.




Also, I am part of a group of Second Lifers working over at Nature Magazine's Second Life site at Elucian Omega associated with their Second Nature site. The idea is to have people share lab space to work on their own projects and by sharing space and working in close proximity hopefully the collaboration engendered will lead to greater productivity.

The group includes a bunch of really talented people including Max Chatnoir, whose Genome Island Site I have visited numerous times. Another really talented person doing some exciting work on visualizing proteins is Hiro Sheridan who does lots of really cook stuff on visualizing protein structure. We each have our own project areas, my project is to build a mitosis and meiosis simulation, something I have wanted to do, but it is a bit more complex than the other things I have done and so its only now do I have the background in scripting to attempt this.

Since we have people at different levels of Second Life experience, we are having some basic workshops to get us started. For instance the first week was basic building, given by Hiro. I don't know about the other participants, but I thought it is really valuable to see how another person explains Second Life.

In Second Life there are often several ways to ummm build a cat. So it is easy to get stuck in one way of doing things. For instance, when I duplicate an object I always do it from the pie menu and had forgotten about the little shift and drag trick, which is actually a lot easier. Another example: our first homework assignment is to build a chair and while I have done some building had not built my on chairs-just quickly slapping things together not not being too concerned with the llSitTarget function.




So this morning, I spent some time building a chair and using llSitTarget...and of course it needed a table, and a nice rug. The result is shown here. Now I can replace those lumpy cushions in my lab space!

Friday, May 29, 2009

What's going on at the lab?

My protein synthesis functions, got me thinking about developing an animated model of protein synthesis that actually does transcription and translation and so I have been trying to figure out a good way to do this. The figure shows a animated prototype for an operon that I have been working on. The model loosely mimics the behavior of the repressor protein and inducer of the lac operon as well as the RNA polymerase.

In the picture the repressor protein (red) is sitting on the operator and the RNA polymerase(purple) cannot attach to the promoter to begin transcription of the operon's coding region (teal). The inducer is the green ball. The can see how the system behaves by touching say the inducer which will then bind to the repressor protein, preventing it from blocking the RNA polymerase.

This view shows the repressor protein not on the operator allowing the RNA polymerase to begin transcription. As the polymerase moves down the coding region the transcript (yellow) grows.










When the RNA polymerase reaches the terminator part of the operon the polymerase detaches, the RNA detaches and the small ribosomal subunit (brown) attaches to the start of the start of the transcript.

Obviously there are some simplifications here. For instance in prokaryotes translation can begin while transcription is still on going and I don't bother with the details of how RNA polymerase works.

The goal is to let the students input a short DNA sequence, animate transcription and show the mRNA in local chat (or perhaps as hovering text above the mRNA) and optionally send it as an e-mail. Then as translation proceeds actually have the tRNA's bring in the amino acids and make a short polypeptide. In this scheme the mRNA is a single prim but carries the codons as data inside. But the development of the polypeptide via translation is explicitly animated in terms of what happens at the ribosome, each amino acid shown as a separate object.

In the foreground are some crude tRNA's (orange rectangles) some of which have amino acids represented by balls attached to them. This is going to be a fairly elaborate scripting effort with some neat tricks involved so stay tuned...

My sabbatical is officially over and have already given my sabbatical report. I will be teaching summer school-just two intro biology lecture sections. Also at the end of July I will be speaking on Science simulations in Second Life at SidLit and giving also giving several local talks about Second Life in general.

Thursday, May 14, 2009

Protein synthesis functions

The chromosome module mentioned previously is part of my JCCC evolution build on the agents of evolution. Mutations are any sort of heritable change in the DNA, that is changes in the DNA passed on to future generations of cells. Chromosomal mutations are large scale rearrangements, involving many nucleotide bases. But a discussion of mutations has to include point mutations-changes on the level of a single nucleotide base.

Discussing these means dealing with protein synthesis first. So the last couple of days I have been scripting core functions to do the basic steps in protein synthesis , namely transcription and translation. Max Chatnoir over at Genome Island has a nice little collaborative game related to protein synthesis, (http://slurl.com/secondlife/Genome/119/144/54) but since my focus is on evolution at JCCC, I've decided to build my module around a series of functions that start with a strand of DNA, transcribe that DNA to get a messenger RNA and then translate that DNA.

Doing this involves a series of string manipulations and here are some functions I've written specifically to manipulate DNA and RNA represented as a sequence of letters:

string stringclean(string toclean, string allowed);

This function takes a string toclean and strips out blanks and any characters that are not allowed after converting upper case letters to lower case. Permissible characters are in the string allowed. For instance DNA nucleotide bases are represented as a,t,g or c so the the string allowed is "atgc". Were the string toclean representing RNA then allowed would be "augc". Just to be safe the function trims any leading and trailing spaces. The reason for this function is to try to catch elementary mistakes and strip out extra characters from genetic information copied and pasted from GenBank or FASTA formatted data.

string compdna(string dna);

This function takes a DNA strand and outputs the complementary strand. This is useful because data bases often give a so called sense strand which is like the RNA only with "t" shown instead of "u". For illustrating transcription you need to start with the complement of the the sense strand as happens in the cell. Hence the need for a function to generate the correct DNA strand.

string transcription(string dna);

This function takes what ever DNA strand is given it and mechanically does transcription. It doesn't recognize any sort of promoter region such as a -35 or Pribnow box. If you don't know what those are..well don't worry.

string transcodon(string codon);

Takes an mRNA codon and uses the standard genetic code table to translate the codon into the corresponding amino acid using the standard genetic code, used by most eukaryotes. This function is needed for the translation function:

string translation(string mrna);

This function takes the mRNA string and using the function transcodon, translates the mRNA into the polypeptide that would be produced in the cell at the ribosome. The function does not recognize the Shine-Dalgarno sequence and mRNA's start for simplicity with the start codon, 'aug'. The function terminates the polypeptide when it recognizes a stop codon. Polypeptides are represented by the now standard one letter abbreviations commonly used in protein data bases. Thus it will allow the student to compare the effects of frame shift mutations caused by insertions or deletions to substitutions on the resulting polypeptide.

These functions work for small genes with on the order of 250 nucleotide bases. One frustrating thing is the limited ability of SL to write data to files and for now the easiest way fo the user to save the output, is to e-mail it to themselves.That will be built into the module as an option. Otherwise users would have to cut and paste from the chat window.

Users will have the option of using data they obtain from another source by configuring a note card with the raw data copied from say NCBI, or using a small gene data set preloaded onto a note card.

Three other core functions are being developed:

string makesubstitution(string dna) makes a random base substitution in an original DNA strand.

string makeinsertion(string dna) makes a random insertion while
string makedeletion(string dna) makes a random deletion.

But these will be easy to make. The activities are being designed around a pencil and paper exercise I use in my classes currently, only now the students will be able to use more realistic data and quickly investigate at a number of different mutations.

Monday, April 13, 2009

A Scripting Interlude

While revisiting my genetic drift module and starting my natural selection module, I decided to fix a potentially annoying problem. Since Caminalcules rez as physical objects sometimes they behave really flaky and end up in other regions. Right now they are set to die on their own after a set time but that would be a scant comfort to another land owner who has one of these things appear on her land.

With the help of the good folks in the College of Scripting Music Science group here's the basic strategy...

default {
state_entry()
{
llSetTimerEvent(1.0);
}
timer()
{
// check if the touching person is over the script owner's land

if (llOverMyLand(llGetKey())) {
llSay(0, "the prim is on my land.");
} else {
llSay(0, "the prim is NOT on my land.");
llDie();
}
}
}

Not real hard and experienced scripters probably know about llOverMyLand, but it solves one of life's little mysteries. I can of course shorten this to a single if statement if I just want the critter to die, but I might want different sorts of behavior depending where the critter is, hmmmmm.

By the way, since I have several parcels, I was interested to find that llOverMyLand doesn't care what parcel the object is in just whether or not you own the parcel.

Friday, April 3, 2009

The Cami Lab is up!















The Caminalcules
(camis for short) have been safely installed in a Mendelian Genetics lab module called the Cami Lab. I use my note card configurable camis to illustrate dominance relations, monohybrid crosses, and dihybrid crosses. The evolution module will be directly underneath.

I have had to readjust my land and merge several parcels to give me some prim breathing room. Feel free to come and visit Cami Lab currently at:

http://slurl.com/secondlife/Carmine/128/144/136

As part of this, I rescripted my simple viewer to use Erich Bremer's double buffering script which makes loading much faster. My essentially new viewer uses LSL's way cool llDetectedTouchST function. This function detects where on a prim's surface you are touching and returns that as the x and y terms of a vector.

You can then access, these to do things like change a slide or teleport. What is really cool is that the coordinates are normalized to the size of the prim so they are presented as a float between 0.0 and 1.0, so if you stretch, say a viewer, the detected function still works properly.

Saturday, March 28, 2009

Configurable Caminalcules!















One thing I wanted for my Caminalcules
to is allow for the instructor to configure different genetic systems via a note card rather than a menu system. Turned out to be pretty easy and so in amongst Best Practices Workshops, I've been squeezing out time for this.

So here is an example of a pair of Caminalcules who have indulged in a little bit of dihybrid Mendelian interaction. I'm making little activity pens or corrals (as Max Chatnoir suggests) for them partly to keep them in but because when the pups are "born" sometimes they don't end up right side up. Visitors can move them around with fear that they are going to escape!

I need to give them some sort of movement but that will need to wait and I will probably introduce that option in a couple weeks when I script my Caminalcule evolution activity.

Friday, March 6, 2009

A handy little string function...

For the Caminalcule project I'm finding it easier to represent a genotype as a string because I can easily manipulate strings. But LSL is not real whippy on the string manipulation front.One function I needed was one that would substitute a sub-string starting at a certain position in an original string without making any other changes in the original string.

There are functions that do similar things but they rely on having a recognizable set of characters in the original string as in standard find and replace. But what I wanted was a function that goes to a particular position in the original string where I (or a script) specify where the position starts.

This is important for me because the way I represent genotypes there are some things that change a lot, but somethings may not change very often and yet I want to keep those things together with the more variable stuff-kind of like what happens in a chromosome.

So if I have two sentences:

"The sly big fox is learning scripting." and

"The big sly cat is learning scripting" ,

I might want to change what ever starts at letter 9 with the substring "red". Hence my little function:

replace_string(string original,string sub_string,integer pos).

Try copying the following code and inserting it in to a prim and let me know what you think. Given Blogger's tendency to mess up LSL code, you might have to change a few things by hand. Or IM me (Simone Gateaux) in world and I will send the script to you.


//begin code here
string replace_string(string original,string sub_string,integer pos)
//replaces part of string starting at pos with substring; does not change the original string length
//real handy for me
{

integer orig_length;
integer length;
string new_string;
length = llStringLength(sub_string);
orig_length = llStringLength(original);
if ((orig_length-1) > pos &&( pos >= 0))
{

new_string = llInsertString(original,pos,sub_string);
new_string = llDeleteSubString(new_string,pos+length, pos+length -1+length);

}
else new_string = original;
return new_string;

} //end function

default
{

touch_start(integer num_detected)
{
string newstring;
string oldstring = "The sly big fox is learning how to script.";
string replacement = "red";
integer position = 8; //position start at 0 index so here 8 is the start of "big"
newstring = replace_string(oldstring,replacement,position);
llWhisper(DEBUG_CHANNEL,oldstring);
llWhisper(DEBUG_CHANNEL,newstring);
}
}
//end code



Thursday, March 5, 2009

Caminalcules III Colorful pups...
















This week I implemented a version
of Eloise Pasteure's suggestion to get genetic data into the Caminalcule's offspring, representing the genetic data as a 7 digit integer. This integer has two positions for each locus or allele pair, a dominance term which is 1 position for each locus and an extra flag telling the program whether to process one or both loci when making the phenotype of the offspring. It's a little less compact than what Eloise suggested but easier for me to keep track of.

This version of the Caminalcule will illustrate Mendel's two laws and does not do linkage...yet. The second locus, by the way, has to do with the type and number of black spots on the critter and I just got that implemented today.

Yet to do are some fixes to the menu system- I've had to think carefully how the lldialog function works-and think out the mechanics of Caminalcule mating. How will they communicate and behave? Right now they can detect each other with sensors but I haven't given them an sort of movement. What happens if two encounter each other and they are genetically incompatible? What sort of reproductive system? We already know that some of them are hermaphroditic. Is there also a non hermaphroditic gender? Hmmmm. Stranger things than this happen in nature. You might look up the life cycle of Caenorhabditis elegans, one of the major organisms in modern genetics.

Lots of potential here for getting students thinking about life cycles and gender that go beyond genetics and collaborating with each other. I've also been to several interesting workshops related to Second Life and I will post more on those later.

Thursday, February 26, 2009

Caminalcules II: Mother and her pups

Continuing along with my Caminalcule genetics activity...

Here is a heterozygous Caminalcule mother with 10 of her pups produced by selfing under incomplete dominance. The maternal script produces two gametes at random, the "pup" is rezzed and the genotype along with the degree of dominance communicated to the pup and the pup then changes phenotype.

This is of course not the way it works in the real world; the pups should be rezzed with the genotype in place but there doesn't seem to be an easy way to do that save maybe with some really clever use of llSetPrimativeParams. But my approach seems more flexible.


Here notice that roughly half the "pups" have the heterozygote's phenotype (grey) and roughly half are one of the two phenotypes (black or white) of the homozygotes.

Right now I represent a gene's locus with an SL vector type. The third position is not currently used but it could be used to store some other type of float type information related to the gene say something about its linkage position along a chromosome.

Coming up soon...Caminalcules make nookie.


Tuesday, February 24, 2009

Building the Photosynthesis Engine VI :Calvin cycle

Last night I finished the basic Calvin cycle model. The Calvin cycle is the part of photosynthesis where carbon dioxide is brought into the metabolism of the plant (or other photosynthetic organism).

Next the ATP and NADPH from the light reactions are used to donate energy and hydrogens to the carbon atoms from the carbon dioxide.

The resulting molecule, a three carbon sugar, called G3P then can be used to make glucose or other organic compounds. Making this G3P is the point of photosynthesis!


The model rezzes the molecules involved in the Calvin cycle and it is a real three ring circus to watch. Come visit the model along with the light reactions in Carmine at: http://slurl.com/secondlife/Carmine/116/148/296

There is still more to do in terms of design issues and presentation and particle usage...but as with the Light Reactions, my immediate concern has been with the scripting.

The model can only be toggled on or off but unlike the light reaction model, the molecules move from spot to spot at a more sedate pace.

I want to thank SL educators Azwaldo Villota and Eloise Pasteur for their feedback on this project as well as other visitors who have dropped by from time to time.

Friday, January 23, 2009

Building the Photosynthesis Engine III:Light Reactions

Light Reactions

The light reactions in photosynthesis are where light is absorbed and converted to a flow of electrons. The electrons are used to make energy rich compounds for the rest of photosynthesis. It is also the step where oxygen is produced.

This week I have worked out a way to simulate the light reactions in which all the parts of the model are embedded in a lipid bilayer as in nature (more or less). The model is more detailed model than my more general simulation of the whole photosynthesis process in that the parts are meant to sense each other and communicate with each other. Here both photosystems are glowing purple because they both have absorbed photons. The structures in red or purple are parts of the electron transport systems, the red indicating the passage of electrons.


The user will eventually be able to treat this simulation as a work bench adding or removing parts and putting them in the right order to get their own working model of the light reactions. The parts interact via a series of sensor and listen events. This seems to be an easier approach to implement than the one used in my more general simulation where all the parts are linked into one large object. Again the idea is not to mimic every single detail of the light reactions but allow the user to explore the steps in the light reaction.

Friday, January 16, 2009

Molecular Mayhem in Second Life

Yesterday I visited with Erich Bremer from Stony Brook for a quick tour of Monolith, his Molecular rezzer, discussed in my previous post. He asked me to select a protein from the Protein Data Base(RCSB) so he could test it on his new beta version of Monolith. So many proteins! So I picked three favorites, a cytochrome C (pdb 3CP5), a dicer (2FFL) and a Rubisco (1RXO). The dicer and Rubisco would have required too many prims for the sim-I should have known that- but we had lots of fun rezzing and playing with cytochrome C.



Two big things. First Monolith is fast. It takes roughly one minute to rez a protein. Since a protein such as cytochrome C easily has 5,000 plus atoms, each of which is rezzed as a prim.

Second Monolith provides a fair amount of flexibility to color different regions of the molecule. For instance, cytochrome C has a heme group-this is a set of four carbon rings with an iron atom in the middle, just as in hemoglobin. Erich was able to immediately find the heme group in the pdb format file and color it, just as one might do with a traditional molecular rendering tool such as Cn3D.

Right now Monolith only does space filling models but Erich has plans for ball and stick models, and some ideas for clever use of particles. Monolith is not nearly as powerful as s Cn3D in terms of the types of displays you can use and right now you can't rotate the molecule right now and scaling might be nice, but then these traditional viewers don't let you easily fly through the molecule.

Not quite the holy grail of molecular rendering which for me would be a Cn3D type rendering system in world. But given that Monolith is still in beta, it's pretty impressive given the current constraints of Second Life's environment the Erich has to work around.

Monolith is at http://slurl.com/secondlife/SBU%20Medical%20Center/58/26/28.

Tuesday, January 13, 2009

Building the Photosynthesis Engine II

Here is a working prototype of the Photosynthesis Engine. The Engine consists of eight linked prims, scripted to qualitatively model photosynthesis. This model presented a number of challenges.

First is developing a representation of of photosynthesis that captures qualitative aspects of the process without getting bogged down in heavy model building. I chose to avoid dynamic modeling and and use very general functions to illustrate what is happening in photosynthesis.

The scripting challenge involved getting the parts of the model to talk to each other since the physical model consists of linked prims which pass data to each other. The trick was to develop a system that allows the prims to pass data using SL's llMessageLinked function to send data and the Link_message event to receive data. If you compare this version of the engine, you'll notice it has far fewer parts-important since SL does have limits on how many prims you can have. I also could simply the scripting since each prim has fewer other prims to keep track of.

The next challenge is making the way users interact with the Engine as smooth as possible and this is still being played with along with adjusting the script parameters to give more realistic output.

It is hard to see in this image but the blue horizontal object with the left and right arrows is a tunable lamp. The user can select a particular wavelength of light and "shine" it on the chloroplast to examine the relationship between light wavelength and the rate of photosynthesis. The trick here is to develop a way to represent the spectral color of a wavelength of light in SL's r,g,b color scheme The yellow and light grey boxes show the sugar and oxygen produced by the chloroplast.

The user can also change the level of carbon dioxide and water independently. Note that the user has to manually change the factor she wants to investigate..the engine is not completely automatic.

The model has a thylakoid that receives a wavelength of light from the lamp and uses its own absorption spectrum (input as a notecard) to interact with the wavelength received from the lamp. So the can gets to generate a real action spectrum. I might point out that the thylakoid's color is generated internally with a function based on the its own spectrum. So there is a fair amount of flexible scripting embedded in this innocent looking model!

More details later...

Thursday, December 18, 2008

Simone's Simple Scripts #2 Image maps in SL?

One neat feature of the web is the ability to create image maps. We take for granted that you can often interact with images and get different responses depending on where you click. But until very recently this has not been possible in Second Life.

However now it is, thanks to a new function called llDetectedTouchST. This function allows you to return coordinates you have touched on the face of a prim. If you have a rectangular face the upper left corner is 0,0 and the lower right corner is 1,1.

I have found that with successive calls to this function, you can design rectangular hot spots for a texture. The texture can be anything from an image of a leaf, to menu items or a city map that you want a visitor to interact with. For learning purposes, I decided to set up an interactive leaf using this function. The object tells the visitor what the part is and displays a short text explanation as a texture of an object rezzed when the visitor touches on the appropriate spot on the leaf. I thought about displaying the textures as particles but decided that rezzing objects would give me greater flexibility.

I built in an interesting feature and this came about because I haven't quite mastered how SL handles coordinates. When I rotated the leaf prim, the objects with the explanations often ended up behind or on the wrong side of the leaf. Rather than mess with figuring out the right set of coordinate functions. I decided on a different strategy. I made an invisible prim called "positioner" linked to the leaf object and let it determine where the explanations are rezzed.

This is cool because it allows me to customize where the explanations rezz without with any sort of code. I just move the positioner prim to the right position. To make this little feature I linked the leaf prim to the positioner prim and then used the following set of statements in the Leaf's code to rezz the objects:

puthere = llGetObjectDetails(llGetLinkKey(2),[OBJECT_POS]);
llRezObject(part_name, llList2Vector(puthere,0), <0,0,0>, llGetRot(), 0);

The variable "puthere" is a list and the position of puthere has to be extracted from the list by llList2Vector.

The image shows the invisible prim highlighted (translucent red cube) in the middle of the object for Phloem.

Right now the hot spots and object names for rezzing are written into the code, but it should be easy to have all this be somewhat more automated were I to make this tool generally available. Unfortunately you need to find the prim coordinates for the hot spots by hand via repeated calls to llDetectedTouchST.

If you want to play with the leaf, and assuming SL is installed on your machine, just teleport to my home in Carmine at:
http://slurl.com/secondlife/Carmine/102/143/135