Kailye logo

 

Trajectoires Kailyé,
première partie

Dernière mise à jour: 31 Decembre 2009 

 

8 - Trajectories

Trajectories are sets of keys, which contain each a time value, and a position value (or rotation, colour, shape change, etc.). They are sent in advance by a monitoring simulator to the host simulator, and to the viewer. Each Kailye message containing a trajectory will add new values to the trajectory reception buffer of the object, while older values are discarded when they become past.

So each trajectory message is a rectangular table of values, containing one line per time index. Each line contains as much fields as required to animate the object. However, due to the need of compressing data, combined with the huge variety of possible types of data, all the lines of the table are sent in computer format, without separators, while the zero line is sent in ASCII text, telling the significance and format of each field. This is the format line.

We shall see that for an immobile object, we can set its position (or rotation, etc.) using only the format line, as it can contain paddings, this being base values, which can be understood as actual values for an immobile object, when there is only a format line.

 

8.1 - The format line

The idea here is to have a first format line, which contains only formats, but no actual values (unless it is the only one). This first format line will tell the nature of the values, field by field, the format used to code them, and other data.

But at the very first, it will tell the number of fields per line, and the total number of lines. This is important, as values will be coded into computer formats, without line of field separator. The lack of separators may save thousands of octets in a long trajectory, a thing which will highly speed up the overall working of the simulations. The lack of separators also allows to use the whole 0-255 range for all the bytes, but it imposes that all the values have the same length all along the table (but each field in a line may have its own length).

However some fields into the format line will not translate into fields into the data table (the format line has more fields than the others). In this case, these format fields always start with a tilde ~. We can think at it as of comments, but they are functional, not comments. Such ~fields will mostly be used to tell the nature of the data into the following field.

At last, format lines will allow for using only one parameter name for all the possible kinds of trajectories: ?Ktrajectory=table_of_values, for whatever kind of data we need to pass. This, as it was said, will save the resending of cumbersome lists of time values, for the case where the same trajectory requires several different data, such as for instance simultaneous displacement and rotation of a great number of body parts.

 

8.2 - Numbers formats and paddings In the format line

In a trajectory, the coding of time keys arises the same issues as with the KtimeStamp in the messageID Block: it is cumbersome to resend the same fixed high digits, when time keys are sent by hundreds. And we may have trajectories lasting for days, and other running in milliseconds. The same is true with position keys, when we have characters dancing at the metre scale when their position is in the kilometre range. The idea is to resend only the part of the digits which actually changes. We must also reasonably limit accuracy: it is useless to tell the trajectory of a steamer using 32 bits floating points numbers with a nanosecond and nanometre accuracy. Culling useless least digits will most often compress messages at 80%.

 

So, in the format line, the field describing a value may contain two parts:

-a number into text format giving an actual base value for the highest digits: the padding. The padding may be the first position of the trajectory, but there is no reason to impose this. The best seems to provide with a rounded value allowing addition with a simple concatenation. For example, in a trajectory lasting within 100 seconds, the padding may be 1236452300 seconds, while the values will range within 25.89 to 87.45 seconds. The system using the trajectory must perform the addition for each value. For a trajectory lasting into a 100ms range, the padding may be for instance 1236452325.8 Of course the padding will usually be a decimal number, but the scientific notation can too be used, such as 1.236453258e+9 (the confusion with a format can be avoided). It is to be noted that if a trajectory has only the format line, then these paddings can be considered as the values of an unique key for the trajectory. This will be useful to pass the position, orientation, etc... of immobile objects, or when objects are rezzed.

-one or several letters describing the computer format in which the number will be written. We need some definitions:

c tells that we have a char number (Integer running from 0 to 255). Multiple c indicate that we have a longer number, such as int, long int, etc.

Minus sign before the fist c tells that we have a signed number. If we have several c, the sign applies to the whole number, but only the most significant char will be signed (Integer ranging from -128 to 127).

The dot will tell the position of the decimal dot, but it is NOT sent into the values. (Latin decimal coma is forbidden in Kailye)

At last an O letter (upper case) adds an hexadecimal zero (multiplication per 16) to the format. It is a letter instead of a true zero, to save the confusion with the digits of the padding value. It means that the values actually sent need to be multiplied by 16. OO add two hex zeros, while, OOO add three, etc. (In the code format, there is only one character, allowing to add up to 16 zeros).

So we may have, for instance: cc, an int from 0 to 65535, c.c, a number which decimal value is ranging from 0 to 255.996, c0 an integer ranging from 0 to 4095 by steps of 16, etc. In the last case, only one char is send for each value.

We can still further pull insignificant bits out with using the:

h which is an hexadecimal digit (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F), But a signed hexadecimal digit coded on 4 bits can take values only between -8 and +7, so this applies only when it is the greatest digit of a number.

To code number in 4 bits instead of bytes is possible here, because we don't have separators between fields, and this allows us to read and write into the data flow on a bit-wise basis, until we meet an end of table. Eventually the last byte of the whole table may contain some unused bits. However we limit this ability with keeping with groups of 4 bits, to simplify the coding and decoding. Further versions may use coding bit per bit, if this proves to be useful.

Expressing decimal parts as chars arise an issue about rounding, which does not match the decimal rounding, especially with few digits per number. Usually all computer use chars or multiple of chars to code values, so that the decimal formats seem useless, especially when building landscapes and natural shapes (and it is better not to have a square metric grid in mind, when we design these). But builders of houses, machines, etc. will on the contrary want to force decimal values, and thus decimal rounding. So, when true decimal values are required, we need some 256-free true decimal coding:

m tells that we have a hundred (Char running from 0 to 99, coded as a char) (As the h and c letters are already taken, we use the Arabic «mit'a», remembering that the Arabs invented our digits). (This name is defined here, but it is not intended to be specific to Kailye). The signed mita will be coded as a signed char, but with values between -99 and 99. However if the mita is the greatest part of a number, it is very convenient to admit values up to -100 and 100 (-1 or 1 if we have .m)

The use of minus sign and decimal dot is the same as with c and h. And we similarly find the o, but this time it is a lower case letter, which stands for adding a decimal zero (multiplication per 10) with the same rules than the hex O.

d tells that we have a decimal digit, which values are classically 0,1,2,3,4,5,6,7,8,9 (and 10 if it is the greatest part of the number, or 1 if it is .d). However if it is signed, it can range only from -8 to 7. We have the same remarks as above for the h, about 4 bits coding.

 

At last, f stands for a floating point number (PHP conventions). Implicitly, it is a 32 bits float. There were discussions in the VRML normalisation committee to know if 64 bits floats may be of some use, mainly to solve the rounding issues which happen when we have a small scene with very large position coordinates (jitter, deformations... that the Second Life users who were «orbited» know well). This was solved in another way (shifting the zero coordinate of the scene), and thus 64 bits floats were never implemented in any system. We can make provision of them, however, with reserving the F letter (upper case).

As floats cannot be compressed, we must use them only when their accuracy (number of digits) is really required. The formats above allow for some kind of floating points numbers (with the use of o and O), with the only 2-3 significant digits which are enough most of the time in 3D. This makes 12 bits compared to 32 bits.

We can make some provision for arbitrarily long numbers or extra-accurate formats: I-xxx and E-xxx, respectively for integers and scientific notation, where xxx will be a code to be defined in that time. We also already saw the X^Y and the x^y

 

"" in a field tells it is for a free text.

In the mnemonic format, texts have no defined length, so we rely on the "" to discriminate them from their context. This makes that we need an escape character for \", \$, and for itself, \\.

In the code format, there is no other way than doing the same. However using "" into trajectories tables comes in contradiction with the rule here of not having separators. However not having separators would lead to have fixed length texts, a limitative solution which also wastes space with filling blanks. So, as an exception, we shall use the separators indicated here, provided that they work on a byte to byte basis (the byte preceding a text may contain filling zero bits).

A special use of free text will be for URIs, when they appear in parameters, as there is no warranty that these kinds of data will always use Kailye-compatible characters. URIs of resources are used when the data is too large to pass on a Kailye link, or is not appropriate for this (sounds, images...)

 

b is a boolean, coded on one bit. However this arises an issue: if we have only one boolean, the remaining 7 bits are unused. To limit the loss, booleans will be placed into groups of 4 bits. Eventually the free bits could be used as a redundancy, checksum, etc. but this is up to the simulators to attribute other booleans for this purpose. High reliability versions of the Kailye may propose this function in a transparent way to the simulators.

 

The three x y z values of a quaternion arise a special issue, as they can take any value between -1 and +1. So, using a format such as -.c (signed char after the decimal dot) saves bits, but this will miss the +1 value, thus impeding accuracy right when it is useful. So we must use a format such as -.m, which will include the extreme -1 and +1 values.

However in 95% of the time we have the x y z values set to -1,0 or +1. in this case, then four bits are enough to describe x,y and z. This format will be called q, and it is coded as follows, from the least bit to the higher bit: sign, x value (0 or 1), y value, z value. This format can be widely used in building and machines, and it allows to replace the usual lengthy trigonometric calculations with just multiplications by 0, 1 or -1. This format can also be also widely used in houses. Houses usually don't move, but their description can relevantly use trajectories with only a format line.

f,f,f,f will be a general high accuracy quaternion format. (16 bytes)

-h.hc,-h.hc,-h.hc,-h.hc will be a lower accuracy format. (8 bytes)

q,h.hc will be a lower accuracy format for rectangular quaternions (2,5 bytes!)

q,F will be a high accuracy (64 bits) quaternion well fitting for things like moving machine parts, rotating machines, etc. (8.5 bytes)

At last the format Q will work like the q format, more the 5th and 6th bits to tell the number of quadrants of rotation, so that it codes right angle quaternions with less than one byte!

 

Now we can combine a padding and a format, by simply concatenating the padding value (in text) and the format chain. For instance:

1236452300m.m allows for a trajectory from 1236452300.00 to 1236452400.00, with only two bytes per value, instead or 12. The compression ratio is 6, which may save kilobytes in long trajectories, and speed up the simulation accordingly.

-200-d.d sets a -191.1 to -207.9 position range. In this case the first minus sign applies to the padding value, while the second tells that the format is signed.

It is worth to note that the presence of a padding is not mandatory. It is just a convenient mean to compress numbers in a floating point-like system.

But paddings may have uses in the simulation itself, most often for objects which have to move around a base position. For instance a sliding door will move from 1m. But this door was placed in a random position by the builder, for instance 157.335m. In this case, the padding and format will be: 157.335d, the transmitted values will be 0 and 1, and the decoded values will be 157.335 and 158.335. So this door will move accurately, without getting out of its hinges, while transmitting only rounded inaccurate values. This is because in this case the least useful digits are into the padding.

 

At a pinch, in some cases, no format at all tells that no data is transmitted. This may be the case for the same door, moving along the x axis:

,157.335d,225.455,27.000,... In this example values are transmitted only for the first x value of position, which changes, but not for the second y and third z which are constant and use only the padding. Of course in this case the corresponding field is empty (has a zero length).

 

8.3 - The hierarchical naming of fields in the format line

Some field names, such as position, rotation, etc. are obvious. But other may refer at functions which can be implemented into several ways, are not yet normalized, of may have numerous cases. This arises an issue, as different implementation initiatives may lead to varied and non-standardized names. So we need a naming system to allow a freedom of initiative without compromising the standard.

The idea of hierarchical naming is to add several names in the field, in a hierarchy going to the most general to the most peculiar, or also from the most public to the most proprietary or private. Hierarchy levels are separated with a dot. For instance the multiple different systems of random generators may have for syntax:

...,~Random.pseudo.even.BlumBlumShub,...

or:

...,~Random.analog.Poisson,...

The first name tells the basic function, while the second tells a general class of the object. After we enter into peculiarities such as the distribution law, to end with the algorithm used. At last an example of body shape name containing the brand name of the designer:

...,~Body.Google.Human.female,...

In the code version of the Kailye language, the first words will have predefined and coded values. Further versions will have to add for more peculiar codes, as soon as some implementations become popular. The values without code values will remain in ASCII characters. Codes use UTF8-like system, with two character, the first being in the range 128-255.

Codes syntax don't need the dot separator, but its presence should not create an error.

 

8.4 - Field names and data structure in the format line

Some data may have complicated structures, for instance NURBs which have many fields containing integers, numbers, knots, control points, etc. or body shapes with a complex hierarchical geometry. So the receiving simulator has to know in which order the fields arrive. But this order has to be defined in another message, or in a file somewhere on the Internet.

Field $name$ eliminates this need, while introducing some order.

$name$ are part of the hierarchical naming system, and they use the same dot separator. However to differentiate them of standardized key words, they start with $, as in a variety of languages such as C or PHP. However, those names may be imposed by other systems, and thus contain non-Kailye characters. For this reason, they are enclosed between two $, as with the " of free texts, and similarly escaped with \$. Here is a a 3D vector, with each field having a name:

,scope$x$.f,scope$y$.f,scope$z$.f,...

It is to be noted that $name$ always start with the scope.

Same with a non-Kailye text as a name:

,~scope$André$.~position,f,f,f,...

In the code version, the $ is also present. It is to be noted that the $ may enclose a whole hierarchical $name$, with its dots. So something like $.$ should not happen, even in the case we use two $name$ to build a larger name, as a $name$ always start with its scope. However in the case two $name$ are used to build a hierarchical name, then the second must have a narrower scope, included into the scope of the first.

Structuring the data can be done with parenthesis, while giving a name to each parenthesis. In this case, the parenthesis are into special fields of the format line, not containing data and not coding for a field in the data table:

,~NURBCurve.method.Algorithm.parsing.order.u.v,

,~knots(,f,f,f,f...,~),~control points(,f,f,f,f....,~);

Here these names may be standardized Kailye names.

Of course these names must match the ones defined into the 3D description file, where the handling simulator can get their order and create the trajectory fields list. They can also be defined into the standard for a complex NURB description. Structures are not mandatory, but it seems that they are better than defining an order into a standard, or having this order implicit to each object used, such as a given type of NURB. As swapping at random NURB values will produce very noticeable and very ugly results...

 

8.5 - Time values in the format line

Usually the first value transmitted in a trajectory will be the time:

?Ktrajectory=~time,1236452325.c,...

here a time changing from 1236452325.0 to 1236452325.996, by steps of 1/256 seconds.

If a trajectory has only one key, it may be useless to tell a time, as the object is assumed to be motionless. The paddings may then be enough to tell its assigned position, without telling formats for the position, etc.

We can also use the .X^Y or .x^y format for the time padding:

?Ktrajectory=~time.x^y,1236452325.c,...

if we do not need decimal accuracy, then y can be made equal to zero.

 

8.6 - Position values in the format line

To tell that the following values are a position, we just need to add a field into the format line:

,~position,...

Example of a complete position format with float numbers and no padding:

,~position,f,f,f,...

Example of a complete position format with paddings and decimal values comprised between -9.01 and 7,99:

,~position,235-d.m,450-d.m,-2350-d.m,...

An object which is being rezzed must have at least one position indicated. When the trajectory has only one key, with or without a time (only a format line), it tells the position for a motionless object. In the case an object is rezzed, and no past keys are indicated, then it is assigned the position of the closest future key. The reverse is true if it has no future keys.

Simulators may also use non-Kailye parameters such as the X3D: ?translation=x,y,z to tell the position of the object. If no Kailye trajectory is provided, this parameter will be used. It is up to the simulator designers to agree with such parameter names and format. The Kailye language is precisely here to provide such an agreement, independently of existing languages.

Of course the indicated position (or rotation) is within the referential of the geometry hierarchy level where the object is. So this allows for relative movements, such as for instance moving an arm relative to the body, or moving a forearm relative to the arm, or moving a bed relative to the home, and moving the home while keeping the same position of the bed into the home.

 

8.7 - Rotation values in the format line

Rotation trajectories work in the same way as positions, but they use a quaternion instead of a three dimension vector:

,~rotation,q,f;... (with the q format, x,y and z are sent into only one half of a byte)

,~rotation,0,0,1,.c;... These paddings are ideal for a rotating door. Values are sent only for the angle.

The value alpha being an angle, it is usually measured in radians. To avoid some rounding issues, of for practical purposes, we can make provision of formats telling the angle in other units. The same door opening on 90° becomes:

,~rotation.degrees,0,0,1,m;...

,~rotation.grades,0,0,1,m;...

In a very different domain, this one will do well for rotating motors and parts:

,~rotation.turns,0,0,1,f;...

Or for navigation on the surface of a planet:

,~rotation.nautical,f,f,f,f;...

(it is to be reminded that, although we think of nautical miles as a distance, they are in fact defined as a displacement on the surface of a sphere, and thus as an angle). Implicitly, these nautical miles are those on Earth, as it is still the planet we most often have to deal with. But other planets can be specified:

,~rotation.nautical.Moon,f,f,f,f;...

or a general format, telling the radius of the planet (k stands for kms):

,~rotation.nautical.1235k,f,f,f,f;...

 

8.8 - Coordinate systems

Into the 3D description files and languages, there is a need of a rational use of coordinates, in order to rezz any object in an appropriate position and orientation. For instance a body will have its coordinate origins at the level of the floor, looking forward, so that wherever he goes he will always rezz in the appropriate orientation and position. From here the use of coordinate origins for groups of objects, such as the grouping nodes used in VRML, which establish a clear coordinate hierarchical tree into the whole scene, and allow the addition of dependent objects, such as a chair into a house: if we move the house, the chair keeps the same position into the house.

Of course the SI measurement system is mandatory everywhere.

However today 3D languages use coordinate systems with different orientations, such as VRML, Second Life, X3D, CAD, etc. It is important to know which one is used in a trajectory, for instance to allow landmarks to rezz all the bodies looking in the same direction, and not the feet on the walls.

So this field in the format line tells which coordinate system is used by the position or rotation values:

,~coord.xrynzk,...

x,y, z are for the coordinates. Each is followed by a letter telling in which direction the axis is pointing to:

t = top, b = bottom, r = right, l = left, f = front, k = back, n = north, s = south, w = west, e = east.

one of the two system is to be used, depending on which makes sense.

For instance:

,~coord.xrytzk, is for the VRLM coordinate system. We can also use: ,~coord.VRML,...

,~coord.xwynzt is for the Second Life coordinate system. We can also use: ,~coord.SL,...

 

At last there is a problem which appears in large worlds, and that the users of Second Life who were «orbited» know well: when positions with large numbers are involved, the character and close objects show deformities, jitter, coalescing vertexes, etc. This is caused by the limited accuracy of the 32 bits floating point numbers used to code for the position. This issue was solved in VRML with the use of the Geo nodes system, when the coordinate origins of a large scene are translated and made relative to the viewing point (or an object close by). Without this caution, an aircraft flying above a real size Earth would appear as an unique point jumping along its way. But when rendering in a geo coordinate, these coordinates are taken relative to the aircraft, and by a coordinate transformation, the Earth is made to move around the fixed aircraft. This trick eliminates the problem without the need for cumbersome 64 bits floating point numbers.

 

8.9 - Colour values in the format line

Objects can move, but they can also have their internal properties modified. Colour trajectories are used for colour effects and colours changers. They are a specific and different kind of trajectory, due to the specifics of colour coding. So the format will be:

,~colour.rgb,c,c,c;...

In this example, the popular rgb (red Green Blue) colour system is used, with one char value per colour. However colour coding uses a variety of systems for many purposes:

hsl will tell that the Hue Saturation Luminosity system is used.

cmy_k will tell that the Magenta Yellow Cyan _blacK system is used. The underscore tells an inversion of the k (blacK) channel. In this case, four values follow.

Of course we can have cc formats for more colour depth, such as in scientific images. As the format interpreter is a module of the software, we can in fact express colours in any format, even those which don't make sense.

html will tell that the HTML colour coding is used. In this case, only one value is sent in the HTML text format: E0C0FF (without the #, as it is a reserved URI separator).

The a letter adds an alpha channel for transparencies:

rgba

ragaba adds one alpha channel per colour. This was probably never implemented, but it is the only way to realistically filter colours through something like a stained glass. For instance if we have a pixel with red transparent and g and b opaque, the landscape behind appears completely red, not just pink as with only one alpha channel.

 

Derivatives and NURB-controlled trajectories can be used for colours too, and in Second Life colour drifters are not uncommon. The derivative field or NURB is indicated as with position trajectories. There is however an accuracy problem, due to the limited accuracies of the char values, which blocks slow colour drifts to only a few values. So number formats such as h.c add more accuracy for colour derivative value, as they add a decimal part of it. This format allows a drifter to make a turn of the colour space in as long as 18 hours.

Need more? Try h.cccccccccccc. This flexibility of the number formats is achieved with the use of modular software: any field using the Kailye number formats will automatically have all of them available, even if irrelevant. So we won't have bugs or artificial limits such as not allowing for accurate colours like here.

 

8.10 - Vector and scalar values in the format line

,~vector.5,f,f,f,f,f;... is a general purpose trajectories for n dimensions vectors, 5 dimensions in the example. Of course n values are following this format field.

,~scalar,f;... is a scalar trajectory, for single numbers. Of course a vector with one dimension could be used instead, but there is a conceptual difference which may be necessary for automated software design.

Formats, derivative and NURB-control rules are the same as with positions.

 

8.11 - TextureMap, normalMap, shape or colourMap values in the format line

Texture map changers are commonly used in Second Life, for things like flowing water surfaces. The basic ones just offer a linear movement, like a flowing river. But the more elaborated are able to make dance each point of the texture map, offering very realistic wave motions or kaleidoscopes.

Serious modelling languages (VRML, 3DS, CATIA...) are all based on general purpose free shapes (IndexedFaceSet in VRML) composed of vertexes (points) and faces (with normal vectors), which can be modified in runtime by providing them series of key points positions for each vertex. These shapes are also provided with colour maps, per vertex or per faces, and at last normal maps, per face or per vertex, useful for setting appropriate shading effects, such as having an edge appearing rounded or sharp.

Of course the order of values must match the order in the description of the object. This can be deduced easily when the object is known. This is the case when an object is hosted or handled, but not when it is monitored. In this case, such operations have to be done by its host computer.

We can provide with a variety of trajectories for these, which use the same number formats as with the position trajectories:

,~textureMap,f,f,f... is a texture map vector trajectory with 2*n dimensions for n points. The values are pairs of u v coordinates into the texture, modulo 1 (assuming that the texture has a 1 x 1 size).

It is to be noted that texture maps can also be used on NURBs. In this case the map applies to control points instead of vertexes.

,~3DtextureMap,f,f,f... is a 3D texture map vector trajectory with 3*n dimensions for n points. The values are triplets of u v w coordinates into a 3D texture. 3D textures are not yet popular today, due to the size of the graphic file and some adverse effects like the appearance of spurious regular patterns. But they may become important for the realistic rendering of hairs, foliages, disorder, etc.

,~shape,f,f,f... is a vertex coordinate vectors trajectory with 3*n dimensions for n points in the shape. The values are triplets of x y z coordinates into the simulation space. This can also be used for things like the VRML's IndexedLineSets and PointsSets.

,~normalVectors.Face,f,f,f... is a normal vectors trajectory with 3*n dimensions for n vectors. Normal vectors have a 1 length in a volume space, they are borne by the centre of each face, and they are by default normal to the face. Attributing them another value allows to change the rendering of shades.

,~normalVectors.Vertex,f,f,f... is the same as previous, but with normal vectors on vertexes.

,~colorMap.face,r,g,b,r,g,b... can modify the colour of each face. The colour format is usually 3 chars for r,g,b. Others can be specified, such as rgb+alpha, using the Kailye colour formats:

,~colorMap.face.rgba,c,c,c, c,c,c...

 

,~colorMap.Vertex,c,c,c... is the same as previous, but with colours defined on the vertexes. This allows for some automatic gradation of colours without the need for textures, although this usually does not render very good, we often need several vertexes for a nice gradation.

Derivatives and NURB-control may be used for these functions too. But it should be noticed that if check-keys are used, we have not one servomechanism, but one per vertex or face, so this may quickly overload the simulator.

So as to have the derivative or NURB system implemented here too, requires that these systems are software modules able of multiple instances. The mandatory modular implementation of these features makes them available for all the kinds of trajectories.

 

8.12 - NURBs values in the format line

This is about how to deform a NURB object. Not to confuse with NURB-controlled trajectories evoked further.

NURBS are usually coded as a set of coordinates of knot points and control points, called the knot vector, which controls the position of the curve, but also its hems, for smooth joints with other NURBS without gaps or angles.

A difficulty here is that there is no universally recognized standardized NURBs system today, and it will be difficult to set one, as there are many kind of NURBS: 2D curves, 3D surfaces, different order, different curve equations, etc. And if several come into implementation, it is not sure at all which will be preferred by 3D designers. The best described standard seems to be the X3D's « NurbsSurface», where a variety of 2D NURB curves or 3D NURB surfaces are described as sets of integers (order, number of points) along with the knot vector. As the number of vectors is determined by the number of control points, it is mandatory to send these integers first, or better to tell them into the name field, before the values: we hardly see how to change the order of a NURB on the flight, or its number of points. If this is ever needed, it is better to send another NURB instead.

So the X3D NURBs page also describes NURBS interpolators, which could serve as templates for our format line. As an example, we have the NurbsOrientationInterpolator, which moves a 2D NURB curve, the NurbsPositionInterpolator and the NurbsSurfaceInterpolator, which move a 3D NURB surface. Both contain series of floating point numbers, and 2 or 3 dimensions vectors, with some more integers which control the number of elements in the series. It is to be noted here that we don't deal with X3D interpolators (animations) but with Kailye trajectories. However interpolators or animations used by simulators will have to be cast into trajectories, so that it is required to have similar enough parsers and formats.

The number of NURBs variants and the lack of actual standards make that we need to use the hierarchical naming, such as:

,~NURBSurface.X3D.NurbsSurfaceInterpolator.3.5.6,f,f,f...

The ~NURBSurface name tells that the data is about a NURB surface. X3D refers to a standard of this language. NurbsSurfaceInterpolator tells which parsing system is used (in which order the various values come, which will have to be set by the first implementers). In the example name, 3 gives the order of the NURB, while 5 and 6 tell the number of knots in the u v system.

In a more general way, we shall have, for a 2D NURB curve:

,~NURBCurve.method.Algorithm.parsing.order.u.v,f,f,f,f...

where method sets if control points are in the curve or not, Algorithm refers to the equation allowing to compute the curve from the knot vectors (there may be several, with different results, so this has to be specified) and parsing refers to a specification on the order in which the various numbers and vectors will appear.

 

Again there are several possibilities for the simulator to get the parsing order of values:

-obtain it from reading the 3D description file

-have it indicated into the standard used (which is told by the parsing name above)

-use structures, which names will be obtained again from reading the 3D description file. But now the receiver does no longer need to read this file.

It is not clear which of these three possibilities is better without an actual experience return from an implementation. However the third is preferred here, followed by the first. Probably two or three of them will be implemented.

 

 

We may think that, if a writer of simulator software implements a given NURB system, all the others will have to also implement it. This is not necessary true, as, for instance, a character Hosting Company may provide ITS users with a NURB body shape into a unique or proprietary system. But this shape will not need to be computed by all the simulators, which will only monitor it, using just its geometry hierarchy of empty bounding boxes. Only the standard WEM viewer need to add a parser to render this peculiar NURB system.

 

This requirement, as what the WEM browser will have to also implement all the NURB systems actually used, will bring some control on a possibly wild branching of different and incompatible implementations for the same use. Rather there will need to be a mandatory dialogue between the Kailye-WEM standardisation committee, and the groups who create new implementations. But only a very limited portion of the WEM browser is concerned: the NURB rendering module, and it will just have to add parsers and some lines of codes for the equations.

 

8.13 - On NURBS and body shapes

NURBS will become very important, at least in one case: the character shapes. We can hope that Second Life rang the end of the era of character meshes, in painfully highlighting all their defects (polygonal breasts, non-texturable crotch...). NURBS can easily solve these defects, with probably less data than a mesh, especially at close range: NURB defects don't grow with zooming in, and they can remain unnoticeable whatever the scale.

When the user sets his character shape, he adjust some of the knots and control points. But when he moves his arm, the knots at the elbow must accomplish circular movements, and the knots at the hand will accomplish a double rotation (epicycloids). To sort this requires a skeleton-model of the body joints, where each knot and control point remains immobile relative to the relevant body segment. This is known as the h-anim model in X3D. Moving the body will be animating separately each body segment, and thus the corresponding knots. Once this sorted out, we have a NURB surface which can be easily computed from the skeleton model angles. Making it of a low order and into only one piece will much accelerate the calculations. But basically the description of any actual position of the human body will fit into a set of some hundred numbers, which is less than with a mesh.

 

So a simulator will be still able to monitor (in the Kailye meaning) a character it is unable to render, by simply computing the skeleton-model (or any similarly defined model for animals, robots, etc.). The monitoring simulator can easily compute a set of cylindrical bounding boxes and collisions from the skeleton-model it receives from the host simulator, through a geometry hierarchy file, while the host simulator can easily actuate the knot vector itself, after the angles of the skeleton-model it receives from the monitoring simulator. At last the viewer just needs to compute the NURB itself from the knot vector it receives from the host simulator.

This makes that complex and advanced characters will be able to visit all the worlds, even simple or outdated worlds in simple simulators unable to render them. Any better interoperability feature to ask for?

So, especially in the full WEM architecture, animating (monitoring) a body shape will be just dealing with a set of bounding boxes with a hierarchy of angles and positions. Only the standard WEM viewer needs to deal with the NURB itself. So this takes the following form into a Kailye trajectory format line:

,~bodySkeleton.brand.Google.human.female,-.c,-.c,-.c,-.c...

In this example, we suppose that Google has created a Character Hosting Company, with its own model of female human body. In this case it is a Brand model. The following fields describe the angles of all the body segments. The hierarchical naming used here allows to freely define new models within the Kailye language, without compromising the integrity of the standard.

We note that very few data is sent: one char per joint. Using signed chars makes far enough accuracy, unless perhaps the largest segments which may require a -.hc format (decimal mindset is not advisable into body design). The zero value defines the default position, when the body is relaxed, also used to adjust the shape.

One may expect quaternions for the body joints. We can avoid sending them (a good deal in terms of data size) as the x,y,z part of them are constant for each joint, and described into the skeleton model 3D description file. If a joint has several degrees of freedom, we can split it into several joints with each one degree and the same coordinate origin. So for each joint, we have:

-A static description, using a full quaternion and cordinate origin, both adjusted by the user when he sets his body shape,

-An angle of rotation around the previous axis (described by the previous quaternion). Only this angle needs to be sent in the trajectory.

-A second (third) angle, if the joint has two (three) degrees of freedom.

 

The trajectory above will apply to the skeleton model, which is an object formed of a hierarchical geometric model of empty bounding boxes, one per body segment. Once this structure is established, the designer just needs to add into each segments some classical shapes (cylinders, ovoids, NURB parts, etc.) or knots a global NURB, each with a 0,0,0 position relative to the relevant segment of the skeleton model. This is a bit of work to achieve, but this still allows amateur or professional builders to create any body shape, by hand, or with special softwares, and place them on line with defining a hierarchical name and the function of each field. The only limit is that the movements of these shapes must somewhat match the movements of the human body, so that an actual user can understand it and move it.

 

To set knots of a global NURB on different body segments requires the use of a nested structure into the series of knots (which is already a structure). Each of the group of knots in enclosed in a parenthesis having the name of the corresponding body segment. The key word setOriginTo means that the values which follow are in the coordinate system of the indicated body segment. Here is a simple example:

,~knots(,
~setOriginTo$shoulder$(,-c,-c,-c...,~),
~setOriginTo$arm$(,-c,-c,-c...,~),
~setOriginTo$forearm$(,-c,-c,-c...,~),
~setOriginTo$hand$(,-c,-c,-c...,~),
~),
(line breaks are not in the code)

This example could be a first implementation of a simplified exoskeletton arm for industrial purposes in augmented reality. It is to be noted that the «shoulder» segment has a zero length, it is just used to set a second degree of freedom for the shoulder joint. But it is still a body hierarchy level, as it provides «arm» with a rotation, and thus a different coordinate system, with the same origin.

 

8.14 - On exoskeletons and haptic monitoring

Exoskeletons will use the previous skeleton model to send a series of angles to the monitoring simulator. However, if the animated character is not human, the Character Hosting Company will need a translation table, for, as an example, translate human walk into a animal walk, with the user using his limbs as naturally as if he was walking in the human way. However exoskeletons will need that the monitoring simulator uses as a feedback, not inflection points for the trajectory, but forces to the exoskeleton, according to the haptic feedback which is the principle of exoskeletons. This is called haptic monitoring. The difference, however, is only into the feedback method: inflexion keys for simple monitoring, and haptic feedback when using an exoskeleton. In this case it is the user who can now feel the obstacles directly, and actuate his trajectory accordingly, without any calculus from its host simulator.

 

However the format for receiving movements from the haptic viewer can be similar:

,~bodySkeletonHaptic.public.fourLegs.dragon,-.c,-.c,-.c,...

Here instead of a brand name, we have a public model of a standardized body skeleton description, available to all, that all parsers will have to mandatorily recognize.

 

Very probably the force return will need two values per joint, an elastic component, and a maximum angle beyond which the movement is no longer possible. The format for sending these may be:

,~bodySkeletonHapticReturn.public.fourLegs.dragon,-.ch,-.c,-.ch,...

with two times more values. Probably the elastic value must be more accurate, as human sensitivity has a wide dynamic range (from feeling a grass blade to hauling heavy charges). Hence the ch format.

Paddings may be used to tell basic efforts on the body, such as the reaction of the ground under the feet, or to set a pseudo-weightlessness on all the body, when flying.

It is to be noted that exoskeletons will be fantastic machines, which will increase our immersion and experience by a factor 100, from the era of sitting in front of a keyboard and screen. From here the interest of developing them quickly, and the effort to allow for them as soon as this version zero. First practical uses however will probably be much simpler devices, such as simple cylindrical bodies or robotic arms. What is said above is however still fully valid.

 

8.15 - On freedom of creation

A last difficulty with body shapes is that most creators are amateurs without large means. But these amateurs are those who bring by far the most significant part of the quality and interest of the Metaverse. However we cannot ask amateurs to interact on a peer to peer basis with large institutions such as a standardization committee, without seriously impeding their creativity. So we must provide them with a method to add a skeleton-model description file of their own, without having to ask authorisation or wait for approval. This file is given a $name$ which is defined in another Resource Block. This name is then used into the hierarchical name of the body shape, after the key word custom. Here is an example well known in Second Life:

?Ktrajectory=~bodySkeletonHaptic.custom.
SkeletonModelDescriptionFile.scope$name$,c,c,...

with the Resource Block, where the $name$ is defined:

http://www.daryth.com/draconica/Limbo_Dragon_Species/Astral_Dragon_Skeleton.x3D?KID=scope$name$
(line breaks are not part of the code)

In this case, the file is on the author's internet server (ideally the same server as for the simulator, so as a failure of a separate internet server does not affect a correctly running world). In the example it points at a X3D file, which just contains a geometrical hierarchy of empty grouping nodes with their relative positions and angles: the skeleton-model. The fields which follow contain angles into the order they appear into the file. Each body segment must have to be into a «grouping node» (X3D terminology), even if it is alone here. The names of grouping nodes can be used to set a structure for the data fields.

 

It is noted that a custom body hierarchy description file is exposed to pirate simulators, so it is much less protected than the NURB or textures of the body shape. However this does not mean that it is free to use by anybody. Everybody wanting to use it will have to ask for permission, and the author may place it on a Copyright Server, or use WEM functions to restrict its access to only a white list of users. So unauthorised use is by default illegal, not to speak of duplication on another site. Only the public description files can be freely used without permission.

 

Some body parts such as simplified fingers, tails, mermaid tails, long necks, snakes, tentacles, etc. will not rotate around a joint, but have a flexion deformation. This is simple to manage if they are in the last position in the hierarchy: it is enough to transmit the flexion angle to the relevant body part, which must be able to deform accordingly. But if lower hierarchy members are attached, they will move, not only in angle, but also in position. Happily there is a clear mathematical relation between the angle and the position shift, so that we still need to send only one value. But if we use a X3D skeleton-model description file, we need to set both a rotation node and a translation node for the sub-hierarchy part. The set of both could be called a flexion joint (by opposition to rotation joints) and, knowing the relation, only one angle value needs to be sent (the other required value, the length of the flexion part, is constant and known into the geometry hierarchy description file.) Another method is to replace a flexible body part with a series of individual rotation joints equally spaced along the member. If each has a NURB knot, the illusion can be very good.

 

Now that we know this with custom models, we can consider that public models and brand models will work in the same way, save that their skeleton-model description file will be implicitly known by the WEM browser or simulator, or loaded by default in an appropriate folder.

 

It is too soon to define everything in this version zero, without any experience or actual implementation. However some good steps are taken here:

-sorting the basic concepts of skeleton model clothed with shapes or NURB knots, that simulators will always be able to control segment per segment, even if they don't know to calculate the NURB.

-use the hierarchical naming to allow creativity without compromising standardization,

-defining ten base field names:

,~bodySkeletonPosition.public...

,~bodySkeletonHaptic.public...

,~bodySkeletonHapticReturn.public...

,~bodySkeletonPosition.brand...

,~bodySkeletonHaptic.brand...

,~bodySkeletonHapticReturn.brand...

,~bodySkeletonPosition.custom...

,~bodySkeletonHaptic.custom...

,~bodySkeletonHapticReturn.custom...

,SkeletonModelDescriptionFile....

-introducing the skeleton-model description file as a method to allow content creators of any size to define skeleton models of their own.

 

8.16 - Text values in the format line

,~text,"",... this format field allows for a free text.

The double quotes may look useless when we pass only letters or numbers, for machine commands, etc. But if so, we could end up with a situation where a non-Kailye system, or an user, will send separator characters of the Kailye language into a string, and produces a Kailye error. For this reason there is no text format for pure ASCII texts, only free texts. The usual Kailye characters are used only to tell the field functions, such as ~position, ~rotation, etc.

 

The text data fields however cannot have a fixed length, from here the use of separators into the lines of the table into this case, as this was explained in the part on formats.

 

The idea of a text trajectory may seem odd, but they may find a lot of uses. For instance we can send texts accompanying a movement: a guided tour will need coordinated movements and text comments. They can also be used for text readers, delivering lecture at some pace.

If we have only one line in the table, the time field may be omitted, or left empty, or with a past value: this means that the text must be delivered as soon as received. This can be used to send warnings and rules to the user, commands or internal states of machines, etc. Sequences can be sent with a several lines text trajectory.

In a table with several lines, if a free text field in the format line has a content, such as: ,"Title",... (without ~) this will tell that a text data field is expected here, but also that the text in the format line will become the title of the column. This is not a padding, even if they are usually present here. When one or more titles appear, all free text columns are assumed to have one, even if empty.

 

A peculiar use of titles will be for sending the same text into several languages: in this case the fields titles in the format line become something like ,"eng","fra",... and are the normalized values ISO639-3 (or ISO639-2, or ISO639-1 by order of preference, and including artificial or ancient languages. We use "" as there is no warranties that these standards will always use Kailye-compatible characters). Using this ISO standard allows the system to know that the columns have the same content, but in several languages, so it can display the appropriate one, depending on the user's preferences.

The language title can be combined with an actual title:

,"eng"."English Title","fra"."Titre Français",...

In a data field with a language title such as ,"eng",... we can add translate, which will be interpreted as a request for translation. The full syntax is: ,translate"eng",... For coherence with the other syntax rules, the translate fields does not have a ~, as with the request: a value is requested here, but is not yet present, so that no data is sent.

Which column is to be translated? If there is only one column with a language title and containing data, it is of course this one. But if there are several, it is the first we encounter when going to the left. Any other convention would have do, provided that it gives a non-ambiguous result. But we had to select one, so we took one in relation with our reading habits.

But if the field contains ,translate.user,... it will translate into the language of the user. Such a feature will be very interesting for amateur builders who need to create simple menus such as "sit here" and the like. This allows them to be automatically understood into all the variety of languages spoken on Earth. This is not mandatory, thought: not using this feature will impose the language that the builder used, such as for instance Sindarin into an elvish simulation.

If we are in a themed simulation, we can display both the user's language and the theme language: ,"fra",translate.theme,... This will make the original french version to be translated into the theme language of the simulation, whatever it is. However the user may not understand this theme language (Who actually understands Sindarin?), or the simulation may quite simply not have one. So it is cautious to also ask a translation in the user's language, as an help into this language may be needed.

It is to be noted that today automatic translators are not yet able to eliminate all the ambiguities of current conversation. However they are good enough to indicate some basic menus and warnings, as soon as we are sure that they don't turn an affirmation into a negation.

;

 

The free text fields may also contain numbers, in the PHP text syntax. But they are still free texts. To pass true computer formats, use the number formats defined above, into another field. It is up to the receiving device to concatenate them.

 

This text trajectory syntax is primarily intended to send short texts, so some experimental implementations of the Kailye0.xxx versions may limit them to a convenient 256 bytes (UTF-8 included, which may make less than 80 actual characters). So a caution would be not to use longer strings in these versions. But version 1 and further will have to clearly repel such narrow limits at least to 1024 (Length of a group charter or place rule) and anyway to a standard value. It is however possible to send arbitrary long texts, as soon as we split them in separate fields or lines into the table. Caution however that sending a whole book in one time will clog the real time Kailye connexion, which is definitively not intended to pass bulk data. No human reader can read at 10Megabytes per second anyway.

 

 

Typical uses of ,~text,"",... would be chat systems, notices, warnings when entering in places, multi-lingual document readers, or multi-lingual menus for animations running in world. However it is much better to pass large documents as html internet resources.

More technical applications may be sending lists of commands for machines, which can be internal states (booleans, code letters) text commands (start, next, etc.) or numbers (in PHP format). For instance a media player will need commands, titles, track numbers, on-off controls, volume, etc. which can be passed as a set of texts and number fields, or as an unique text containing all the commands.

We can also add a char field value, to pass one letters commands, or even (very) short free texts in a fixed length code format and no separators: ,~character,c,... or ,~character,cccc,.... However only free texts can get a title. Also, most other formats do not make sense here, so it is unadvised to use them, even if they are technically available.

 

8.17 - Boolean values in the format line

,~Boolean,b,b,... gives a table of boolean values. In the mnemonic version of the Kailye language, they appear as Y or N, True or False, 1 or 0, etc. Both must be understood.

Booleans or texts can be used to pass internal states of scripts, especially for things like state machines.

 

We could also have trajectories for binary values, for sending software. However this was never used into 3D modelling, and it could be used to send viruses. So there is no provision for this in the Kailye language. Further versions may think at it, provided that there is some control against evil uses.

,~Boolean,b,b,... or any other data type, must not be used for things like access authorizations, which may engage our moral or legal responsibility. The WEM command KmetaConn is provided for this purpose, and its operation is traceable and monitored by a third party.

 

8.18 - Use of derivatives (speed, acceleration)
for position or rotation, in the format line

In many technical uses, telling a speed, see an acceleration, is more relevant than telling a position. But, rather than adding a new data type, we can pass them as derivatives of a position.

Derivatives will also have important uses in artistic content, such as guided tours. As trajectories are linearly interpolated between key points, displacements may appear angular or with brutal changes in orientation, speed, acceleration, etc. And the human orientation system is very sensitive to these kind of defects, which create uncomfortable feelings. Defining an object's behaviour with a speed, see an acceleration trajectory, makes that the resulting position will be an integral, and thus a smooth and curved path. So this elegantly solves the problem of angular trajectories, without adding a lot of intermediate keys.

For this reason, the Kailye trajectories are provided with a mean to tell if the keys are position, speed, acceleration, or still higher derivatives:

?Ktrajectory=~time,1234560987c,~derivative(,1,~position,f,f,f,~),...

In this example we have a speed trajectory (derivative 1). The parenthesis are used here as a structure to tell to which following values the derivative applies. (Usually we may have a position and orientation together, of the same order, but other values may follow, such as texts, where derivatives don't make sense). The order of the derivative is in the first field into the parenthesis. In this example, it is told as a padding: 1, without a number format, so that no data is sent for this field, and all the position keys in this example are the same order of derivative.

 

But there is an accuracy problem: if we use acceleration (forces applied) to animate an aircraft, we easily obtain some kind of realistic flight animation, but it is now very difficult to make the animation end right on the middle of the runway, at ground level. This is because very small differences in forces accumulate all along the trajectory, leading to large differences in the end position. Various sources of inaccuracy also accumulate all along the trajectory, such as rounding issues, leading to different results on different simulators, a deadly sin into the Metaverse.

This problem requires that, at times, some lesser derivative check-keys are inserted into the trajectory, in order to eliminate unwanted drifts of position and lock the trajectory on the expected position values. For instance acceleration of an aircraft are corrected so that to land right in the middle of the runway, with a check-key as last position. If check-keys are present, the simulator will add a small constant correction at each time frame, all along the trajectory between two check-keys, in such a way to obtain the best match when the object will arrive at the check-key position.

This may not be an exact match however, due to rounding problems with small values of acceleration or corrections added to a large position value. So, if the correction at a given frame is not fully achieved, due to rounding issues, a correction debt is retained for the next frame. If everything is done properly, the residual correction must stand close to the rounding range of the values. And when arriving at a check key, the position will be forced to the exact value indicated in this check key, and whatever remaining correction debt is discarded.

These cautions may sound complicated and nit-picking, but if we don't use them, a small unnoticeable drift may remain, and one hour later we find our aircraft grazing with the cows in the meadow besides the airstrip. Worse, each user with a different implementation will see it at a different place!

Speed keys and position check-keys may still be not enough to smooth trajectories. The most usual combination will be acceleration keys and position check-keys. We can also have many other combinations, such as acceleration keys and speed check-keys, or even use acceleration change (4th derivative), like on railway tracks, as the human feeling is still sensitive to abrupt changes of the 4th derivative.

 

Example of a format for variable derivatives (with check-keys):

?Ktrajectory=~time,1234560987c,~derivative(,h,~position,f,f,f,~),...

It is the same syntax, save that we now we have a h number format into the derivative field, this meaning that this time a data will be sent into this field, telling the order of the derivative for each line.

This system will impose the same derivative value for all the fields in the structure (position, rotation, etc.). If we don't need this, we can have several ~derivative structures. When a check-key is used, we shall often need to send several values for this index: speed, acceleration, position... This is done with several lines in the data table, each with the same time index but each with a different derivative value. Of course the lesser derivatives are the check-keys.

The modular parser of the Kailye also allows to add paddings and signed -h format to the derivative order, so that we can have any derivative or integral value. However this does not seem very useful, and it is probably better to keep to the way of the example. The h format allows to go to the 15th derivative, which is far beyond any predictable use. Integrals may find some rare uses into geometry calculus. Anyway this is just a theoretical possibility, as implementing a given derivative order requires a lot of special code, so that most simulators will implement only a very limited set of derivative values. The basic standard will request only derivatives from 1 to 4, maybe 5, and no integral values.

 

It is to be noted that when the last key of a derivative trajectory is elapsed, the object will not remain completely immobile, it will continue with the last speed or acceleration indicated, thus obeying Newtonian laws. But a rezzed object is assumed immobile (null derivatives), until time comes that movement values are attributed to it. Eventually if the first derivative key falls when or before the object is rezzed, then it will be rezzed with a speed or acceleration. This is useful for a projectile.

 

Also, a realistic acceleration behaviour of an object usually results of a set of forces and couples, including all the forces and couples applied on it, minus its inertia force and inertia moment. All these will result into an acceleration vector and couple of the object. A realistic flight simulator will compute the resultant acceleration and couple, so that it will need to send vector trajectories for each of these forces and couples.

Also, a thing such as a flight simulator usually works with short time frames, in a single computer. The Kailye will allow to share the tasks between several simulators, if needed. The use of trajectories allow us to do so without being hampered by transmission times between simulators.

 

At last, when check keys are sent to a simulator, this forces it to work as a servomechanism, which may lead to some interesting and creative behaviours, such as creating itself a realistic trajectory from scratch, without the need for the designer to bother about its accuracy or to write many detailed keys. But this may also lead to some specific servomechanism problems that the non specialist will find hard to understand. The case we are speaking about here is for small corrections: In the case of the aircraft, we code a looping with accelerations only, and just add a last speed and position key to ensure getting out of the figure into the right place and speed. If so, the whole looping will be scaled appropriately, and no trouble should result of this.

More creative use of the servomechanism may be to force the full calculation of a trajectory, without telling intermediate values. For instance a servomechanism, such as a radar antenna direction control, will receive only 3 keys: start_position+zero_acceleration, middle_position+zero_acceleration, and end_position+zero_speed+zero_acceleration. In such a case, a smooth trajectory will appear, provided there are enough frames between the beginning and the end.

However to have a technically realistic servomotor mechanism will need to know the time constants of each of its parts, and animate them separately. In more, we need to account with the world-wide transmission delays, which will need to make it much slower than a local servomotor, in order to stabilize it. Thus a realistic servomechanism will need to be local, this meaning it needs to be handled or hosted by the local simulator. However commands can be received from another simulator afar, and the actuated output also sent afar.

And, oh, simulators unable to use check-keys would be just lame. There were already very good flight simulators running on Windows 95, able to realistically integrate speed and acceleration, and in more with a very high frame rate.

 

8.19 - NURB-controlled trajectories in the format line

A smooth trajectory without a lot of intermediate keys can also be obtained with a NURB curve, describing the path of an object, along which it will experience a movement. Some uses will prefer this to the derivative system above, for a more predictable behaviour: Each point of a NURB path depends only on the two closest knots, and not of points far away. The drawback is that we cannot act on the trajectory in real time, as with the aircraft controlled in acceleration only. So both systems have to be implemented, and each designer will choose the most appropriate for his use.

The typical example is a railway carriage monitored by several different simulators in a large railway system. Not only it must follow a rigid line, but also joints between these lines in the different simulators must be smooth, with no angles. So we need to use a 2D NURB curve to describe these segments of line, with enough control points and high enough order to allow for the smooth joints.

It is to be noted that the same NURB curve will also describe the track itself. From here the interest to have the NURB equation known, normalized and available for all the simulators and viewers. These NURB algorithms must be certified to give the same results, except for minimal rounding errors. Otherwise we shall see the carriage run besides the track...Even a 10cm mismatch would, even if not noticed, give a bad feeling of disorder.

 

However a fixed NURB is not the kind of object we pass into a trajectory. The proposed syntax is rather to pass this NURB as a different object in the same Kailye message. The use of a $name$ allows to relate the trajectory along the NURB curve to this NURB itself. For instance it is described in a Resource Block, to which is assigned a name:

http://...trackNURBcurve.x3D?KID=scope$track$

we can now define a position/speed/acceleration for the main object, here the carriage, along this NURB curve, into another Resource Block of the same Kailye message:

http://...carriage.x3D

?Ktrajectory=~time,...,~position.linear.scope$track$,f,...

The indication linear tells that the position will be a trajectory along the curve defined by the $name$. In this case, only one position value is needed, not a vector. We may use derivatives if needed. But no rotations, as the three rotation axis of the carriage (turns, slopes, and tilting into curves) will already be described by the NURB path.

The three elements, ~position, linear and scope$name$ are mandatorily associated.

 

And what if, instead of a railway, we have a cars simulation??

http://...roadNURBsurface.x3D?KID=scope$road$

and:

http://...car.x3D

?Ktrajectory=~position.surface.scope$road$,f,f;...

where the key word surface tells that we now have a NURB surface, eventually curved, where the cars are allowed to move on, and a 2D position (or speed, acceleration) 2D vector into this surface...

 

This syntax does not necessarily require that the trajectory or surface is a NURB, anyway. It can be a line (such as VRML's indexedLineSet) or a surface (any 3D shape is a surface), so long as we can define a position coordinate on it. Closed surface must have coordinates looping to the lowest values when we reach the maximum. Usually we have the u,v coordinates on a surface. Only topologically complex surfaces may arise problems. So linear or surface must refer at positions in metres. The ideal definition is the displacement along a line or plane tangeant to the curve or surface. This allows to define movements in any derivable topology. However we may also use nautical miles, defined in a tangeant circle or sphere.

All this is very powerful, and will allow to code easily for a huge variety of complex animations: guided machine parts, games, cars, guided tours, etc.

 

But there is still more.

 

If we animate the NURB curve, we can do things like machines with variable geometries, stunning merry go rounds, etc.

If we animate the NURB surface, we can do things such as a surfer running all along a moving wave... and really free to control his trajectory onto the wave, not a rigidly predefined surf animation like in Second Life!

(Just that a realistic surf animation will need that the host simulator of the surfer calculates the forces applied on him, from the wave geometry sent by the monitor simulator (which runs the waves). In return it sends the actual trajectory of the surfer to the monitor simulator, which can then add effects like foam, etc. A difficulty here is the geometry of the wave crashing, which brings the occlusion of a tube under the wave. This suggests the need for changing the topology of the NURB surface, or its number of knots. But we can avoid this, if we use only one NURB, of which different instances advance each after the other, like a conveyor belt, with their joints forming the angular crest of each wave. In this way the occlusion problem can be managed without changing the NURB topology.)

Waiting to see this implemented... This may look very complicated to do, but if all the previous Kailye functions are implemented as modules, it automatically brings all this interactivity between many basic functions. And the coding of a simulator becomes simple. Soon a rendez-vous with your exoskeleton into Hawaian waves: all the effort, thrill and pleasure, without any risk.

 

8.20 - Database requests in the format line

DatabaseURL

?Ktrajectory=~database.request.MySQL,
~queryString,"queryString",
~KID,scope$requestName$,~input,paddingFormat,...

sends a request to a database. The database type can be specified, MySQL in the example. "queryString" is the character string, specific to the database type, which allows to execute the request. The input data is provided as indicated. This request is given a name with the KID key word, in order to be able to retrieve the results. However this KID is into the format line, not to be confused with a name for the database URL.

Output data is returned as follow:

DatabaseURL

?Ktrajectory=~database.output.MySQL.scope"requestName",
~output,paddingFormat...

It is to be noted that we do not have ?Ktrajectory=~database.input.MySQL, as an input necessary needs a request.

Due to the variety of database systems, and the many kinds of operations which can be performed on them, it is difficult to foresee any standard. MySQL is preferred, however, due to its open source character, and already some implementations in OSGrid. But it is better to push all the specific features of a given system into its query string. And of course the system must interface the database and the Kailye so that data fields of the database input/output are made to match the order, types and names of the Kailye fields.

For instance, a query on German users in this database:

Name Age Country

Richard 50 France

Heinrich 25 Germany

Jean 55 Belgium

Klaus 68 Germany

has its output formatted as follow in Kailye:

?Ktrajectory=~database.output.MySQL,
~output,"";"Heinrich";"Klaus"

An output on country names, with a field name (structure) is formatted as follow:

?Ktrajectory=~database.output.MySQL,
~country(~output,"",);France;Germany;Belgium;

 

Often files are used to enter or exit data of databases.

DatabaseURL

?Ktrajectory=~database.query.MySQL,
~queryString,$queryString$,
~inputFile,message$file$;

with the associated file in its own Resource Block:

fileURL?KID=message$file$

Or, for an output:

databaseURL

?Ktrajectory=~database.output.MySQL,
~outputFile,message$file$,~outputFileParam,ao,~);

with the associated file Resource Block:

fileURL?KID=message$file$

In this case, if the file does not exist, it has to be created with the name and URL indicated. If it already exists, then it has to be overwritten (parameter o) or the data has to be appended (parameter a).

 

8.21 - Number of lines of the format line

At last the lack of separators requires that the reader of a Kailye message knows the number of lines in a trajectory table. This is done quite simply with a last:

...,~lines.2250;

closing the format line.

 

In any case, the format line number is zero. if a format line ends with a semicolon without a ~lines, then the parser must assume that no other lines are expected.

 

Next part: Other Kailye functions related to trajectories