Active Worlds supports a dynamic terrain system where worlds can feature mountains, valleys, and everything in between. Terrain is specified as a series of elevation points (i.e. height values) aligned to a 10 meter grid (the same cell grid used for property.) The Active Worlds browser uses this elevation grid to extrapolate and render a continuous terrain surface in-world. In addition to elevation information, the terrain database also stores texture type information for determining what textures to use when rendering the terrain surface.
Terrain Data Organization
The amount of bandwidth necessary to transmit terrain data for an entire world can be quite large. Combining elevation and texture values for each point on the cell grid adds up quickly. Thus, similar to the property mechanism, the Active Worlds terrain data and access methods are organized in such a way as to make downloading of, and detecting changes to, the terrain data as efficient as possible.
Terrain data is organized in pages. A terrain page is 128 by 128 cells. Thus, each page of terrain data contains 128 x 128 = 16,384 elevation points. The central terrain page of a world is centered on 0N 0W. This means, for example, that all of the terrain data for a world 128 cells in diameter (i.e. buildable out to 64 N/S/E/W) would fit in the single central page. Terrain pages are similar to sectors in the property mechanism in that they provide a organizing unit for quickly detecting and updating a client's view of a world's terrain in response to any recent changes to the terrain data.
Within each page, terrain is further organized into nodes. A node is square chunk of terrain data that can be as large as a page, or as small as 8 by 8 cells. When a client queries a world server for terrain data, the data for a particular page is sent back as a sequence of nodes, often of various sizes. When the terrain query process is complete for that page, the combination of all the nodes will have provided a complete description of all the terrain on that page.
Nodes provide an efficient way to both encode terrain for transmission over the network, and also to detect when certain parts of the terrain have changed. For example, if a large portion of a world is flat, the flat portions can be sent as "simple" nodes that say, in effect, "this entire area here is flat", instead of explicitly sending the same elevation points over and over again for every cell in that area. This allows the terrain for worlds that have flat portions to be sent much more efficiently than if all elevation points were always sent regardless of their values. In the case where an entire terrain page is completely flat (such as is the case when terrain is first enabled in a world) the entire page can be sent as a single short "flat" node.
When terrain data has been altered between one visit and the next, clients such as the Active Worlds browser can use the terrain protocol to detect which nodes have changed on a page, and to only re-download the nodes containing changes, without having to download the entire page of terrain data over again.
Uploading Terrain Data
The most common use for the new terrain methods in the SDK will probably be for the purpose of uploading terrain data to a world from other sources of elevation data. Terrain data could come from many different possible sources, from USGS DEM (Digital Elevation Model) files, to JPEG images, to randomly generated terrain. The central method for uploading terrain to a world from an SDK application is aw_terrain_set. This method allows the SDK application to upload a single horizontal (i.e. Eest/West) row of terrain data to the world server. The row may cross page boundaries. An SDK application that wants to upload a large area of terrain data would typically build an in-memory grid of elevatiaon data from the source, and then enter a loop that calls aw_terrain_set once per each row in the source data until all of the data has been uploaded to the server.
Downloading Terrain Data
The process of download terrain data from a world is slightly more complicated than uploading, but it is also usually far more efficient. The process is similar to querying property in that the application repeatedly calls aw_terrain_query until it is up to date for the terrain page in question. Each terrain page has a sequence number that indicates how "up to date" the application is for that page. If the application has no previous information about a page, then it specifies zero for the sequence number to indicate to the server that it wants all of the data. After the download is complete, the server provides a new sequence number that the application can provide on subsequent queries to determine if the terrain has changed since last time.
Each call to aw_terrain_query generates a sequence of events in return. In order to download terrain data, the application must install event handlers for one or more of these events. Each terrain update begins with a single AW_EVENT_TERRAIN_BEGIN, followed by one or more AW_EVENT_TERRAIN_DATA events that describe the actual terrain data, and then finishes with a single AW_EVENT_TERRAIN_END event. See aw_terrain_query for sample code illustrating how an application would typically receive and process these events.