Examining and modifying Active Worlds property (objects) is probably the most complex aspect of the SDK. The reason for this complexity is the need to organize property so that clients and browsers are able to easily remain up to date with the current contents of a world without using a lot of bandwidth.
All property in Active Worlds is stored in a grid of 10 by 10 meter cells. Since the cell grid is a horizontal plane, a cell is actually a "column" of space extending above and below the 10 by 10 meter square. Cell coordinates correspond to the "longitude" and "latitude" coordinates you encounter within Active Worlds. For example, an object located at 32N 13W would be located 32 cells north and 12 cells west of the "ground zero" cell (i.e. the cell located at 0N 0W.)
Each object in a world exists in one and only one cell. Even objects that appear to extend across multiple cells in the 3D scene are still located in only one cell from the system's point of view.
Overlaid on the grid of 10 by 10 meter cells is a larger grid of sectors. A sector is an 8 by 8 grid of cells (i.e. 80 meters by 80 meters.) Finally, sectors are organized into an even larger grid of overlapping zones. A zone is any 3 by 3 grid of sectors. The diagram on the right illustrates the arrangement of cells and sectors within the single zone that surrounds the "ground zero" area of a world.
The lightest gridlines represent the cell grid, thus this diagram shows an area that is 240 meters on a side (the size of one zone). The darker lines show the sector boundaries, and the darker surrounding box shows the boundary of the zone. Finally, the thick lines illustrate the compass axes. Note that north is the positive z direction, south is the negative z direction, west is the positive x direction, and east is the negative x direction. This convention is very important to keep in mind while writing programs that manipulate property. The x and z coordinates labeled in this diagram show the sector coordinates for each of the nine sectors in this zone.
Also, note that the physical area contained by the single zone in this diagram is large. Everything visible to a visitor standing at ground zero with a visibility of 40 meters would fit completely inside the center sector alone. Everything visible to a visitor with a visibility of 120 meters would fit inside this one zone.
Finally, note that zones overlap, unlike sectors or cells. The zone shown above which is centered around sector (0,0) overlaps with 24 other zones (not shown) which are centered around the other sectors in the vicinity. For example, the zone around sector (0,0) and the zone around sector(1,1) overlap because they share in common the sectors at (1,1), (0,1),(1,0), and (0,0)). The zone around sector (0,0) and the zone around sector (2,2) share the single common sector (1,1).
Property is arranged in this manner so that clients can quickly determine which changes, if any, have occurred since the last time they visited the area. Each cell has a sequence number which specifies when the cell was last changed. Each time someone adds, changes, or deletes an object within a cell, the cell's sequence changes to be the highest sequence number in that sector plus one. Sectors in turn have a single sequence number which is simply the sequence number of the most recently changed cell in that sector. The nine sequence numbers for the nine sectors in a zone represent a "snapshot" of the state of the entire zone. By remembering these sector numbers, the client can communicate to the world server exactly what the state of the world was when it last examined the property. During a property query, the world server uses the sequence numbers sent by the client to determine which cells need to be updated so that the client can be brought up to date with the current contents of the entire zone. If the client has queried this zone before, only those cells which have changed since the previous query are sent back.
The API method most central to the process of manipulating property is aw_query. Any application that wishes to examine, search for, or modify property must call this method in order to determine which objects are currently in the vicinity (an exception to this is the new method aw_cell_next introrduced in version 3.1.) aw_query has the following prototype:
int aw_query (int x_sector, int z_sector, int sequence);
x_sector and z_sector are the coordinates of the central sector in the zone being queried; they uniquely specify which zone is currently being queried. sequence is an array of nine sequence numbers, one for each of the nine sectors in the zone. sequence should contain the sector sequence numbers from the last time the application queried for property in this zone, or all zeros if this is the first time the application is querying this zone.
Calling aw_query will trigger a series of events in response. For each non-empty cell in the zone being queried, your application will first receive the AW_EVENT_CELL_BEGIN event, followed by one or more AW_EVENT_CELL_OBJECT events, and finally the AW_EVENT_CELL_END event. A single AW_EVENT_CELL_OBJECT event is received for each object in each cell.
Typically, the entire zone will not be returned in response to a single call to aw_query. The server will only send a portion of the entire zone data and wait for the application to issue additional calls to aw_query before sending the rest. Each time the application calls aw_query, it must send the updated the sequence array from the previous call to aw_query or else the server will simply send back the same data again.
When the server has finished sending the current batch of property data, the boolean attribute AW_QUERY_COMPLETE is set to indicate whether or not the entire zone has been sent. If AW_QUERY_COMPLETE is FALSE, the application should call aw_query again, with the updated sequence array, in order to continue the update process.
A single instance cannot have more than one call to aw_query outstanding at a time. In other words, do not call aw_query again until the previous call to aw_query has completed. However, an application that manages multiple instances can have multiple queries in progress, up to one per instance.
If aw_query is being used in asynchronous mode, the call will return immediately and the callback AW_CALLBACK_QUERY will be called when the query is complete. However if no callback has been installed for AW_CALLBACK_QUERY, then aw_query will block until the current batch of property data has been received.
Sample program 2 contains a simple example of how to use aw_query in order to locate an object in a world.
Live Update Mode
When a call to aw_query has finished and AW_QUERY_COMPLETE is 1( true), the server switches the application into "live update mode." This means that any subsequent changes to the surrounding property will be transmitted immediately to your application via the additional events AW_EVENT_OBJECT_ADD and AW_EVENT_OBJECT_DELETE.
An instance can only be in live update mode for one zone at a time. Once in live update mode, if aw_query is called for a different zone, live update mode is disabled for the previous zone and only enabled for the new zone once the update process is once again complete.
Note that since live update mode is only enabled when a property query is complete, if you are writing an application that needs to respond to modifications to property as they happen, you must first bring your application up to date for that zone by completing the query process as described above.