![]() |
VR-Forces 5.0.3 Developer's Guide
|
DtTerrainInterface provides a set of intersection methods you can use to query the terrain database, using 3D chords to define the segment and direction of interest for intersections.
You can ask:
Additionally, for a given intersection query you can specify what kinds of information you want to receive:
For example, to query the terrain interface for the intersection with the terrain surface, returning the location of the intersection only, do the following:
You can use the intersectionTime parameter returned in the intersect() method to determine where along the chord the intersection with the terrain occurred. Values for intersection time t, given a chord(p0, p1) indicate the following:
In the figure, a call to intersect() with chord (P0, P1) intersects the terrain at point Q. The method will return TRUE, because point Q lies along the chord, and the intersection time at Q will be a value between 0 and 1. The intersection time at point R (which lies on an extension of the chord) has an intersection time > 1.
To get more information about the intersection point, you can call a variant of intersect() that returns a DtVrfChordIntersectionRecord, instead of just the DtPoint. The DtVrfChordIntersectionRecord can return information such as the location of the intersection, surface type, normal vector of the terrain at that point, and the polygon intersected. For example, to make an intersection test (similar to the previous example), requesting the intersection point and normal, do the following:
Some terrain types, such as streaming terrain and MetaFlight, utilize paging to limit the amount of terrain loaded by the application at one time. Typically the terrain is broken up into pages along a spatial grid and the pages are loaded on demand when an intersection method requires the data. If the interface was to do nothing special with paged terrains, when an intersection landed in an area where the data was not yet loaded, the system would have to wait for the data to be loaded. In some cases this may take a fairly long time and lead to undesirable results for the simulation. The DtTerrainInterface can cope with the paged terrains in two ways to help minimize the occurrence of missed pages and long intersection times.
The first method is if the user can inform the terrain interface of its desire to use an area that is not loaded ahead of time. This is done through the preloadTerrainAreas() method. Calling this method informs the interface of the areas of the terrain that will be required and the interface will start loading those areas in the background. However, there is no guarantee that those areas will be loaded immediately and be available for intersection calls. In this case the user can perform the intersection calls asynchronously.
To make a terrain method asynchronous the caller must provide a Boolean in the intersection method called DataAvailable. When this Boolean is present and the interface is forced to make a call that would cause it to load a page, the method will return immediately and DataAvailable will be set to false. This indicates that the call has neither succeeded nor failed, just that it will take some time to load the page. The caller then can perform other calls and return to this call at a later time when the data may have had a chance to load. When DataAvailable is not present the call will always block, waiting for the call to end no matter how long it takes.
The following code shows a thread that waits for the data to arrive without consuming the cpu during its wait.
The code gives the terrain interface 10 tries and sleeps between each try, allowing other threads to continue. Also note that while the call to terrainHeightAboveSeaLevel() is only different by the inclusion of the DataAvailable boolean, there needs to be a lot more surrounding code to deal with the case when the data is not available.
The terrain interface also has a method called setAssertOnBlockingTerrainCalls(). By setting this value to True, the interface will assert every time a terrain call is made that is called in a non-asynchronous manner. This is useful for testing to find the calls that are made to the terrain that are blocking. Additionally each call can be set to override the blocking assert when the blocking aspect of the call is the required functionality.