object reference
From Wiki
This page is a complete (work in progress) object reference for the JSOM (JSON Sword-of-Moonlight Object Model) schema. Anyone who wants to can participate in the drafting of this specification or whatever you might call it. It is open to whoever likes what they see / would like a little more. You can call it the JSON Scene Object Model if that makes you more comfortable. If the name is not already taken by some more respectable effort that is.
Contents
Overview
More than anything else the "JSOM" schema as a creature of the popular JSON information exchange format. It is a JSON schema after all. JSON is a subset of the popular JavaScript programming language / ECMAScript standard. Minimalism is part and parcel of the JSON specification, which is another way of saying it is really very brief. Now is a good time to read about JSON if you've never heard of it before. Any code in this document is JSON. It's pretty simple stuff, so JSOM by extension is pretty simple. That's good and bad. In case you are wondering why things are so simple, well that is why. OK! Moving on.
The job of a JSOM (JSON) resource is to deliver graphics to an application that is probably programmed in JavaScript and running in a JavaScript engine of some kind, probably in a WWW browser. The application should be to display the graphics themselves, or combine them with other graphics in an interactive fashion if need be. This should be fast to do and not overly complicated. Animation is also very important. In theory every aspect of the JSOM resource should be able to be animated. Animation is not the same as interaction, however direct interaction and scripting is a desirable feature as well.
At the top level of a JSOM resource you will find several named arrays of objects with various characteristic names; externals, templates, images, sounds, arrays, attributes, elements, semantics, materials, graphics, keyframes, keygroups, tracks, are all core to the specification. These are properly referred to as "namespaces" and they represent lists of items. The items themselves can contain sub-lists, so that the general structure of a namespace is more like an outline; Eg. item 0.1.1 refers to the first (zero-based) item at the top of the namespace, and then to the second item of its sub-list, and then to the second item of that item's sub-list. Items can be alternatively addressed by name, hence the term "namespace". Names within a namespace are assumed to be unique IDs, and are not hierarchically arranged, dotted or otherwise. Should a name collision occur, the previous holder of the name is effectively disappeared.
Items and Lists
A JSOM item is a top-level object in the namespace hierarchy. So-named because they are always an object item of a JSON array. Items in an array do not have names, but you can assign a name to an item by giving it a name property. If an item contains a property with the same name of its namespace it will form a sub-list. For examples, an item in the graphics namespace, may contain a 'graphics' property of its own. The graphics property can then contain a list of "sub-graphics" and so on. The only thing to remember is that this kind of "nesting" is strictly limited to the operative namespace. You cannot for instance add a sub-list of "images" to an item in the graphics namespace. Any property that looks like a sub-list from another namespace is more than likely an #index.
Indices, Index singular
Indices are always properties of items, or part of a multi-index array that is itself a property. Each index refers to an item in one of the aforementioned namespaces, if any item at all. The name of the property pre-determines the namespace the index belongs to. If you don't know for sure, then you just have to look it up. Eg. an index property named 'sound' is going to be made up of indices which refer to the 'sounds' namespace. Pretty straightforward. Sometimes however the name of the property does not correspond letter by letter to the name of the namespace. That is what this reference is for.
Now when indices are part an array, you can rest assured in the knowledge that all of the indices refer to items of just one of the multiple namespaces. And just to make things even simpler, you can always bet that a property is either an array (referring to 0 or more items) or not an array (referring to a single item) but never either or. The general rule is that if it would ever under any circumstance make sense to refer to more than one item by with a particular index property then that property is going to be a multi-index array. And before we are done with index arrays. In case you are wondering. An array may be the JSON null value, and it may be empty, and it may contain all null values, in any of these cases it is functionally equivalent to the index array not existing at all, which is the same as a non existent or null value non-array index property.
Index values come in five interchangeable flavors:
- A null value; a null value, as described by the JSON specification. This is equivalent to the property not being defined in the first place.
- A single numeric value; a number indicating a top-level item of the relevant namespace at resource scope. Indexes cannot refer to a scope above the resource in which they are defined. See #External Resources for details.
- An array of number values; each subsequent number indicating an item in a sub-list as explained in the #Items and Lists section. So think comma notation rather than dot notation, but an outline nonetheless.
- A JSON character "string" index. This is a non-numeric name proper index, Ex. "left leg". These global to a namespace, any string literal works.
- An inline item; rather than indexing an item, a new item can alternatively be defined on the spot. Often this is the right idea. The only thing to bear in mind is that inline items can never be indexed into from other indexes. In case you are wondering, yes (in theory anyway) you can make a strictly serial JSOM resource consisting of pure inline notation.
External Resources
The content of a JSOM resource can pull in outside JSOM resources through the power of external references. This is great both for organization and not putting all of your eggs into one basket; so to speak. A typical JSOM resource also includes non-JSOM resources: a reference to a PNG image for example; but these types of resources are dead ends as far as the JSOM schema is concerned, so we will not speak of them again.
The inclusion mechanism is one-way, "downstream", which is to say, a resource can include references to sub-resources, but not vice versa. There is a way around this limitation to some degree, namely through the judicious use of #Templates (keep reading) except for that to say templates refer to or include anything would demonstrate a misconception of how the mechanism is supposed to work.
Unidirectional data flow is not a hard constraint. It is open to discussion. The arguments against it is a resource becomes more brittle if it can reference things upstream. An implementation would have to keep track of what is upstream in every context at the function level should the resource be shared. A special mechanism would need to be devised for upstream indexing. In general its comforting to know that your resources are functionally self contained units top to bottom. Conceptually a resource has direct knowledge of what lies below it. And no clue about what may lay above.
What can be a reference? In practice any item may be a reference. A reference to what? A reference to the namespace of another resource that bears the name of its own namespace. In fact the referenced namespace becomes one of those sub-lists we talked about. Except for one thing! A reference is a second-class item. Even though it has an address, it cannot be addressed; by an index for example. There is really no reason to do so. And either way the reference effectively becomes a placeholder for the first item of the included resource (or no item, if no such item exists) due to "lazy" indexing rules. Maybe you've heard of it. Oh you haven't?
Lazy indexing rules follow: whenever a reference is indexed. If an item in its sub-list is not indexed, then the index will indicate the first item included by the reference, or if that item is itself a reference, the first item included by that reference, and so on. This can be referred to as the "underflow" rule--if you want. If the reference is the last item in its list then the remainder of a numeric index is used to index into the reference's sub-list. You can call this the "overflow" rule--if you will. Whether lazy indexing is technically "lazy" is up to debate. Dotted and named indexes may be unnecessary if you can refactor your resources about lazy indexing. You might even leverage such a scheme to shim in an extra layer of modularity to whatever it is you are doing. Just make sure you understand the rules and everyone involved understands when they are in play.
Template Expansion
A #templates item is a generic bag of properties. In and of itself without meaning. It is not a true item though the same indexing rules apply. Depending on the semantics of an index the properties of the template are usually conferred in some way to some other item either directly or indirectly. Whenever the transfer of properties does take place, it is what we are calling template expansion for our purposes here.
The most basic example of expansion is the universal 'template' property. Every item may have this property: which says that on top of what properties the item has, it will also have the properties of said template(s). Expansion happens at the latest just before the item is to be considered in terms of its properties, first index to last index the template(s) properties are copied into/over those of the item being expanded. Templates may index other templates, same rules apply. Properties are never added together or anything like that. Everything is strictly overwritten. Which in JavaScript normally means that only an object reference or a similarly irreducible literal will be copied. This can be used to your advantage if you need to keep memory overhead to a minimum. Ie. by sharing macro values whenever practical.
JavaScript is usually best at chewing up memory and slow about computing anything on the fly. What seems to work is to compute everything once and keep it in memory if speed is important. So if nothing else effectively managing said memory can be a considerate thing to do on behalf of what users you are able to sucker into whatever it is you are up to.
But that's not the end of templates. Templates are an integral part of the JSOM schema. Template indexes do occur in the wild and you will probably come across one sooner or later. You should just remember that templates do not do anything on their own. Their indexes are inert until expansion happens, and that does not necessarily happen inside the resource in which the template is defined. But what about #expand you ask? Glad that you asked... or ah no. Just kidding. That can be for homework.
Extensibility
Word of warning. You may come across properties that are not mentioned anywhere in this document. They may just be experimental, or they may be user defined properties; which are not-not permitted. A resource might want to (for instance) attach some custom variables to some programmable shaders. Or it may be that some properties are just purely ancillary to some JSOM aware application layer.
Regardless there has been no consideration as of yet concerning collision of custom properties with properties added by a future version of JSOM or whatever, so you can just go wild if you need to.
Universal properties
This section lists properties which are common to all items regardless of namespace. These properties do not take on special meaning under any circumstances.
name
The name property permits an alternative to numeric indexing, with the downside of needing to have names handy or some mechanism for generating them on the fly. Names should be unique unless the behavior you are looking for is to overriding of a named item by the later/possible inclusion of an item with the same name. A name is a character "string".
template
The template property is an array of indexes into the #templates namespace. All properties from the templates indexed will be added, first to last, to the item containing the template property, including any template properties contained within the templates themselves. Note that properties overwrite one another. They are never added together in any way. A template is an array of indices.
ref
The ref property is a name that refers to an undetermined external resource. The item containing a ref property is a reference according to #External Resources however the resource in question is to be determined by the JSOM client application, which will use the value of ref to determine which resource to use. A ref is a character "string".
url
The url property is a numeric index into the #externals namespace. It results in a reference item that is determined entirely by the resource (compare to #ref above) at the time of its creation. A url is a singular index.
<namespace>
Where <namespace> is the same name as the current namespace, Eg. graphics for the graphics names, images for the images namespace. This property is an array of namespace item objects which will form a sub-list beginning at the current item of the current namespace. A <namespace> is an array of namespace item objects.
keygroups
Other than a few exceptions, in theory+ all first class (see #External Resources) items can be animated by #keyframes. Exceptions are templates and keyframes themselves. In order to participate in a keyframe animation an item must be a member of one or more #keygroups. To indicate its membership in a keygroup the keygroup must be included in this index once and only once. The keygroups property is an array of indices into the keygroups namespace.
+Animation applicability and performance is application defined.
Namespace properties
Each heading of this section is representative of a namespace of the same name. Each section below each heading describes the function of the namespace and the non-extended (see #Extensibility) properties that are meaningful to the items of that namespace.
externals
Each item of the externals namespace is a typed URL. Without exception "externals" are indexed by the universal #url property.
<type>
Where <type> is understood to be a JSON key / property name and the value of <type> is a URL. Typically external JSOM resources will use "json", images will use "png". Multiple such properties can coexist where it is understood that each typed URL pair represent the same resource but in different formats. Which format is ultimately used if any is up to the JSOM client application, as is interpretation of the keys and values.
It is not necessary that the type accurately represent the format of the resource indicated by the URL. For instance, a client app may only recognize images by the "png" type regardless of the image format (which may not necessarily be PNG). This is application defined behavior.
priority
The priority property is a number. A complex resource with many external components can indicate in what order it would prefer each component be processed. The minimal value, and highest priority, is 1. The higher the number the lower the priority. It is not required that applications actually sort externals by priority. Typically the external data will get loaded up asynchronously and usually it is desirable to integrate the resource as soon as possible.
Applications should implement a minimum highest priority threshold, where any external component with an at or higher priority than the desired minimum should be fully loaded before the resource is presented to the end user for the first time. It is also desirable to allow for a maximum lowest desired priority threshold, where any external with a priority lower than the maximum is to be discarded (or ignored) entirely.
templates
namespace
The namespace property explicitly states the namespace that the template is intended to be compatible with. Applications may ignore this parameter or perform validation against it if they so choose. If 'null' the template is not limited to any particular namespace, its properties may be expanded into any context whether it makes sense to do so or not.
expand
The expand property is a character string that modifies expansion behavior. It may be null (see #Template Expansion) or "inline". Inline expansion behavior is to immediately expand all index properties to inline objects. Indexes are taken to be local to the resource defining the template.
It is application defined behavior as to what property names are considered indexes. It may aid the application if the template's #namespace property is defined, it may not. An application is not required to implement inline expansion.
<generics...>
Where <generics...> is understood to be any number of property key/value pairs. For example, if the template is intended to be compatible with the #graphics namespace, it may have an #primitives property. When the primitives property is expanded into a graphic that graphic will then contain a copy (usually by reference) of the templates primitives property.
The entire function of templates is to contain any number of such properties. Universal properties cannot take part in template expansion, and neither do template specific properties (see namespace and expand above.)
images
Each item of the images namespace is a graphical image which can include additional 3D texture mapping properties. If an image needs to be texture mapped in more than one way it should be represented by multiple items in the images namespace.
The pixel data of the image can be in the form or a #url or an #rgb (see rgb below) property, where a url is an index into the #externals namespace for a typed image url, and an #rgb property describing a 1x1 pixel image. An application may fall back to the rgb value if the url value cannot be resolved.
rgb
This is a common property describing a red, blue, green, alpha colour. It is a 3 or 4 number array where each number is a colour component (in red, blue, green, alpha order) where red, blue, and green are more than likely in the sRGB gamut, where 0 is pure black and 1 is pure white. Alpha is transparency and defaults to 1 (fully opaque).
See #images for how the rgb property applies to items of the image namespace.
alpha
The image alpha property is a boolean value, either true or false. If true it is an assertion to the client application that the image contains non opaque (transparent or semi-transparent) pixels. If false it is an assertion that the image is fully opaque.
What an application does with this information is implementation defined. Regardless, if present, alpha should reflect the content of the image faithfully.
width
The image width property is a numeric value asserting the width of the image in pixels.
What an application does with this information is implementation defined. Regardless, if present, width should reflect the content of the image faithfully.
height
The height of the image in pixels. Language of #width applies identically.
space
The image space is an index to another image from which the #state property (next section) is taken to be relative to / multiplied with. The default space for an image is the image "above" it in the namespace in terms of nesting, as opposed to listing. If a state is null or not defined then the chain of multiplication ceases.
An image can be put into absolute space by having a space property be an empty inline index.
space : {}
state
A texture transformation matrix. Either a 16 number array constituting a 4x4 transform, or the number 1 indicating an identity matrix, or the number 0 indicating a collapsed (zero-point) matrix.
See also #lights, #controls, and #graphics for comparison of each of the namespaces' state properties.
scale, rotate, translate, skew
These four properties are taken together to compose the #state property. The composition is performed in software. If any of these properties is defined the value of state will be computed and overwritten.
The four properties are each arrays of 2 or more numbers describing the scale, rotation, translation, and skew factors of the computed state matrix.
sounds
Each item of the sounds namespace is a sound effects clip in the form of a #url.
volume
A sounds volume property is a number, where any value 0 or below will be muted as close to silence as possible, and any value at 1 or higher will be played at maximum volume, whatever that may be. Any value between 0 and 1 is mapped between these extremes as desired by the client application. The default is value is 1.
source
The sound source property is a three number array indicating a point in the three dimensional sound 'space' explained below.
velocity
The sound velocity property is a three number array indicating a velocity in the three dimensional sound 'space' explained below.
space
The sound space property is a #graphics index. The sound source (above) is relative to this space. The default space for a sound is that of the sound "above" it in the namespace in terms of nesting, as opposed to listing.
If no space is defined and no sound exists above then the sound is played as recorded.
A sound can be played as recorded by having a space property be an empty inline index.
space : {}
lights
Each item of the lights namespace is a lighting effect.
model
The light model property is a character string indicating a desired lighting model. Models are application defined.
source
The light source property is a four number array or a null or undefined value.
By default something like the "classical" lighting model is recommended. Lights with null sources are global illumination to be summed together as a basis for a global ambient colour baseline. Then the incident values of lights with sources are added to arrive at a per vertex or per pixel light level. The fourth number is a pseudo-homogeneous coordinate differentiating between point (at 1) and directional (at 0) light sources.
shape
The light shape property is a four number array defining the attenuation of the light. The default attenuation is a constant attenuation of 1.0. Meaning the light should be flat and fully saturated across infinite space.
By default something like the "classical" lighting model is recommended. The first number is constant attenuation. The second is linear. The third is quadratic. The fourth value is taken to be an arbitrary cutoff distance.
shade
The light shade is an object containing an #rgb property defining a single colour for the light to emit. This is the bare bones colour scheme for a light. The default is black.
space
The light space is a #graphics index. The light source (above) is relative to this space. The default space for a light is that of the light "above" it in the namespace in terms of nesting, as opposed to listing.
If no space is defined and no light exists above then the light is in global space.
A light can be put into global space by having a space property be an empty inline index.
space : {}