Dear visitor, welcome to krpano.com Forum.
If this is your first visit here, please read the Help. It explains in detail how this page works.
To use all features of this page, you should consider registering.
Please use the registration form, to register here or read more information about the registration process.
If you are already registered, please login here.

A Tutorial on Krpano Action Arguments (pt 1)

Hi ,
i try to understand this for a while but i get crazy with tha %1 etc thing..
what does that exactely mean?..

Hi Tuur,

Ah. I'd like to have an argument, please -- Michael Palin, The Argument Clinic

As you know krpano actions are of the form:

Source code

1
2
3

<action name="action_name">
body
</action>

where body is the action code.

The actions may be called in the following manner:

Source code

1

action_name(arg1,arg2,arg3,...,argN);

or

Source code

1

action(action_name,arg1,arg2,arg3,...,argN);

where N is 99 or less. In other words, you may have up to 99 arguments (krpano versions less than 1.0.8.10 supported only 9 arguments).

krpano actions allow you to access arguments from within the body of your code via the %N reference, where N is a number from 1 to 99. %0 may be used to reference the name of the action from within the action's body.

In other words:

%0 is the name of the action that is being called

%1 is the first argument passed to that function, null if no first argument

%2 is the second argument passed to that action, null if no second argument

....

%9 is the ninth argument passed to that action, null if no ninth argument

For the new version 1.0.8.10 of krpano you can now have up to 99 arguments.

%10 is the tenth argument passed to that action, null if no tenth argument

%11 is the tenth argument passed to that action, null if no eleventh argument

Quoted

This code snippet includes two actions: hello which prints the string hello followed by whatever the user passes in as the first argument, and main which calls the hello function four times with different arguments. Note that the fourth call passes no arguments: hello();. This produces the output INFO: hello null.

ARGUMENT SUBSTITUTION
Krpano's action language is different from other programming languages in that the arguments do not become local variables within the code body, rather arguments are substituted into the code prior to the execution of the code body. You can think of it as if you are using a text editor on the body of the code, and doing a search and replace for each argument, replacing all occurrences of %1 with the string that is the first argument, replacing all occurrences of %2 with the string that is the second argument, etc. If no argument has been provided for a given %N, then a global replace of null is performed for that particular %N.

This substitution occurs after the action is called, but before the action is executed. Consider this example:

In the main action, the first call to test is test(abc,def,123,456);. When this line of the program is reached, then the arguments are substituted into the body of test. That is, before the test action is executed,

Source code

Source code

. After the substitution, the body is executed and produces the output:

Quoted

action test arg1 is abc, arg2 is def, args 3 and 4 are 123456

.
We then proceed to the next line in main where test is called again with different arguments: test(krpano,is,#,1). Here the action name "test" replaces %0, "krpano" replaces %1, "is" replaces %2, "#" replaces %3, and "1" replaces %4. Thus, before execution, the code body

Source code

Quoted

action test arg1 is krpano, arg2 is is, args 3 and 4 are #1

One interesting thing to note, is that in this example, the replacement of arguments %3 and %4 occur within a quoted string. Krpano's handles argument through a simple substitution mechanism, without regard for syntax. The resulting code of course must be syntactically correct, but substitutions can occur within quoted strings, in or out of argument lists, in function names, really anywhere within the body of the code. In fact, entire code segments may be passed through the argument list as in the following example.

Suppose we want to add debugging code which is only executed when the global variable debug is set to true. We can create such an action, let's call it dbg, through which we can pass a code fragment that can be conditionally executed:

Source code

Source code

This code now executes, and since debug has previously been set to true the nested if statement is executed where a is compared to b and is found to be greater resulting in the trace("a is ",a) code being executed which produces the (only) output a is 2000.

A Tutorial on Krpano Action Arguments (pt 2)

To use a variable's value as an argument, you must extract the value using the get() command. The get() command is one of the few krpano commands that returns a value, and it can only be used as an argument or (for version 1.0.8.10) in an index array.

Quoted

INFO: called test(a,b,c);
INFO: called test(1,2,3);
INFO: called test(100,200,300);
INFO: called test(d,null,null);

In the main action, we first set a to 1, b to 2, and c to 3. We then call test(a,b,c) which prints called test(a,b,c). Note that we did not use the get function, so the value of the variables are not passed to the test action. In this case, we pass the strings "a" "b" and "c" rather than their values 1 2 and 3.

In the second call, test(get(a),get(b),get(c)); we dereference the variables a,b and c using the get() command. Thus in this case the values of the variables are passed through the arguments and the output is called test(1,2,3). It is important to note that the get function dereferences the variables before the argument substitutions are made. So the call

Source code

1

test(get(a),get(b),get(c));

first gets converted to

Source code

1

test(1,2,3);

next the argument substitions are made to the body of test causing

Source code

1

trace("called %0(%1,%2,%3)");

to be converted to

Source code

1

trace("called test(1,2,3)");

and lastly the body is executed producing the output

Quoted

INFO: called test(1,2,3);

In the third call, test(100,200,300);, we pass the scalar values 100, 200 and 300 as arguments and we get the predictable result called test(100,200,300).

In the fourth call, test(d,get(d)); we pass only two arguments. This means the third argument will be passed as null. The first argument d is passed as the string "d". The second argument is get(d). Since d is not a defined variable, this gets passed as null. So the output is called test(d,null,null).

RETURNING VALUES THROUGH ARGUMENT VARIABLES

krpano actions do not return values via a return(value); call. As such, the only way to pass values computed within an action back to the calling action is either through global variables (krpano does not support local variables) or "by reference" (through variables whose names are provided as arguments). While global variables would work, the use of globals is considered a bad programming practice and can lead to un-maintainable code. So it is preferable to pass values back through arguments.

Built in functions such as add, sub, etc use this argument passing method:

Source code

1
2

add(x,1,2);
trace("result is ",x);

produces:

Quoted

INFO: result is 3

Note here that the name of a variable, x is the first argument passed to add. The second and third arguments are the numbers to be added, 1 and 2. The add function sums 1 and 2 and sets the variable x to the result, in this case 3.
We can use variables with add in the following way:

Source code

1
2
3

set(a,10);
set(b,20);
add(sum,get(a),get(b));

Here we pass the variable namesum to the add function, but we pass the values of the addend variables a and b to the function. (Actually, add is one of only a handful functions that doesn't require the get() to extract the value of it's arguments. The other math functions, copy(), as well as trace() and the predicates for if statements automatically dereference variables passed to them. Nonetheless, user defined actions must always use get() to pass the values of variables.)

We can use the same approach as add uses to return values in a simple action of our own creation:

In this example we have an action named coord_string which takes one argument--the name of a variable that will be set to a string containing the coordinates. The action calls the txtadd function which composes a string in the format "(h,v)". The first argument is the variable namexyz, which means that the coord_string action sets the variable xyz to the string "(0,0)". Note that we do not use the get function on xyz because that would pass xyz's value, we want to pass its name so its value can be changed within the action.

In the following slightly more complicated example we calculate an (approximation) of the distance between two points.

First we look at the absolute value action abs. This function takes the name of a variable which contains a value, computes the absolute value and sets the variable to the result. Thus, it uses the only one argument both to provide input and return output. The action checks to see if the value for the variable is negative, and if so it subtracts the value from zero and writes the result back into the variable. If the value was positive, then the contents of the variable are unchanged.

The dist function uses the octagonal approximation to compute the distance between the two points. We use this approximation because krpano does not provide a square root function. The dist action takes five arguments, the first is the variable name into which to return the result, followed by the x y coordinates for the first point and finally the x and y coordinates for the second point. It computes the differences for the x's and y's and then applies the absolute value function to each difference. It then multiplies the greater of these two differences by the magic number 0.941246 and the lesser by 0.41. These are then added and the result is copied into the variable whose name was provided as the first argument.

AN IMPORTANT (SUBTLE) DIFFERENCE IN BEHAVIOR BETWEEN 1.0.8.10 AND PREVIOUS VERSIONS
Previous to krpano 1.0.8.10, the number of actions were limited to 9. With 1.0.8.10 the number of arguments was extended to 99. While this is a great improvement, it does create a small backward compatibility problem.

Prior to 1.0.8.10 this code would produce the output: a0. With 1.0.8.10 the output would be j. This is because krpano now looks at two digits past the % rather than one, so in the pre 1.0.8.10 case it substitutes the first argument "a" for %1 and in the 1.0.8.10 case "j" is substituted for %10.

Hope this helps

steveedited 5/30/10--corrected an error in the prose found by Michel, thanks Michel!

This post has been edited 2 times, last edit by "pinsane" (May 31st 2010, 3:00am)

Source code

I've tried, but I'm not sure the operation can be combined ... thanks !

Unfortunately, get() is the only function that returns a value in line, and thus can be used to pass a value into an argument list. Klaus recently introduced the ability to provide two arguments to a math function (as you did with mul in your example), but what this does is multiply the contents of the first variable argument by the second argument. The result is returned in the first variable argument.

Klaus, "recursive" calls could be great, and avoid unnecessary line of codes !

Hi Nelk,
Recursive calls are supported. Anytime you see someone doing anything that requires looping (resetting an attribute on every hotspot for instance) they are using recursion.

One limitation for recursion, is that Klaus prevents the call stack from getting too long, so if you're doing something that requires deep recursion (such as looping across a large number of plugins or traversing a large complex array) then you can get an action overflow error. I believe Klaus limits the number of single actions that can be called at any given time to 2000. You can get around this restriction by having your recursive function occasionally call wait(0); which internally breaks the action queue. Don't call wait(0);too many times however, as it will noticeably slow down the performance of your action.

Understanding the usage of those codes

Hi to everyone, this is one of my first post here, but the first of a big list I think,

I'm coming from flashpanoramas, so I know how the xml is working in order to configure the pano engine.

But with krpano, I have seen there are much more possibilities, and it seems to me that also there's much more performance, and so I have a lot of work to study the way of organizing files projects declaring actions, ...

Is there any post talking about the best architecture / workflow / files order....??

The other question would be, what this code would be used for in the real world ??

I have to build a similar project to this http://rcdespanyol.visita3d.com/en.html but in krpano, any suggestions ?? is better to have an xml file for every pano or is better to use scenes .....??

RE: Understanding the usage of those codes

But with krpano, I have seen there are much more possibilities, and it seems to me that also there's much more performance, and so I have a lot of work to study the way of organizing files projects declaring actions, ...
Is there any post talking about the best architecture / workflow / files order....??
The other question would be, what this code would be used for in the real world ??
I have to build a similar project to this http://rcdespanyol.visita3d.com/en.html but in krpano, any suggestions ?? is better to have an xml file for every pano or is better to use scenes .....??

As for one file per panorama or using separate files for each panorama, it really depends on the amount of different panoramas you will have at the tour. If there's tens of scenes in the same file, it can really slow down loading time at least in some older iOS devices so dividing things to different files improves at least initial loading performance quite a bit. Also, have tried using bunch of scenes in multiple files but got to trouble with it. Depending on what you do with things (and how you handle navigation), you could actually use both separate files and bunch of scenes inside them.

Still, you have to note that even while krpano has quite bit of documentation, there are usage/implementation cases that aren't always as clear as they could be. Documentation is improving slowly but you should invest some of your time on browsing forum as there's quite bit of interesting ideas and tips around here. :) Welcome to the game.

This post has been edited 1 times, last edit by "autiomaa" (Mar 9th 2011, 12:32pm)