Polyline download and visualization over terrain models


Published on

The project implements a number of optimizations to allow
better performance in the visualization of the height model. A client-server architecture allows different themes to be stored within a server, and downloaded using the terrain viewer. Realized using JOGL library.

Published in: Education, Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Polyline download and visualization over terrain models

  1. 1. JOGL Final Project Computer Graphics Principles University of Trento Project: Polyline download and visualization over terrain models Show fu llscreen snapshot Student: Bruno Nardelli Lecturer: Raffaele de Amicis Assistants: Giuseppe Conti and Olga Symonova Page index Abstract 1 Presentation 1.1 Package description 1.2 How to run the program 2 User’s manual 3 Application architecture 3.1 General architecture 3.2 Terrain viewer architecture 3.3 Server architecture
  2. 2. 4 Most interesting features 4.1 Display optimizations 4.2 Polyline visualization over terrain models 5 Implementation notes 5.1 Design patterns 5.2 Geomipmapping and frustum culling 5.3 Polyline fragmentation algorithm 5.4 Polyline points raising algorithm 6 Conclusions and future work Abstract This html page presents the second final project realized by the student Bruno Nardelli as part of the final exam for the course of Computer Graphics Principles at Trento University. By ‘second project’ we refer to the project developed using JOGL, as opposed to the ‘first project’, realized using GL libraries within a C++ program. The main goal of this project is to apply JOGL functionalities -as well as other computer graphics notions acquired during the lessons- writing a terrain viewer. As we will show later in this document, the project implements a number of optimizations to allow better performance on the visualization of the height model. In addition to this, we created a client-server architecture that allows different themes to be stored within a server, and downloaded using the terrain viewer. One can think of a theme as a vector map in GIS terminology. Within this project, themes are implemented as sets of polylines. The most interesting aspect of this architecture is that polyline points are stored as 2D coordinates within the server. Therefore, extra efforts are needed in the client to fragment the lines and correct the height of the points so as each polyline follows the terrain. In the following sections, we present the main features of the program in much more detail, and discuss the way they have been implemented. back to top 1 Presentation
  3. 3. 1.1 Package description First of all, the project consists of two Java programs. One of them is the terrain viewer, that can act as a client, and the other is the theme server. The folder of the project, with the source code, documentation and other files needed to use the program, is available in a zip file. Click here to download it. This zip file includes:  A readme file with a description of the most relevant aspects of the project, and important information on how to launch the programs. A copy of this readme file is also available here.  The ‘Client’ folder with the source code, precompiled classes, images and running scripts of the terrain viewer (client). Also the correspondent JBuilder project (First.jpx) has been attached, just in case it may be useful.  The ‘Server’ folder with the source code, precomp iled classes, images and running scripts of the server application. Also the correspondent JBuilder project (First.jpx) has been attached, just in case it may be useful. Disclaimer: The content of this zip file is distributed ‘as is’, without warranties or support of any kind. It just constitutes a final project implementation for the course of Computer Graphics Principles. Please note that, in addition to the files in the zip file, you will need the following to run the programs.  Jogl libraries. In particular you will need ‘jogl.dll’, ‘jogl_awt.dll’ and ‘jogl_cg.dll’.  ‘jogl.jar’ file.  A text ascii file with the dtm you want to visualize, and a GIF image to be used as a texture. The next section explains where to copy these files if you want to launch the programs using the provided running scripts. 1.2 How to run the program Unzipping the zip file into a directory of your choice will extract two folders, one with the files that correspond to the client application and another one with the files that correspond to the server application. Here we will only show how to launch the client program, i.e. the terrain viewer. Launching the server implies entirely analogous procedures so we will not explain them. Inside the client’s folder you will find a set of folders and files. Before running the program, put the jogl libraries (*.dll files – see previous section) into the ‘libs’ folder, and the ‘jogl.jar’ file into the ‘jars’ folder.
  4. 4. Now the application is ready to be launched. Just double-click on the ‘Run.bat’ icon and the running script will execute the program for you. If this does not work (for example, if you are using a Unix system instead of Windows), try the following command. > java -classpath "…Clientclasses, …Clientjarsjogl.jar" -Djava.library.path=…Clientlibs - Xms512m -Xmx1024m first.MainClass The expected result is the following ‘Application launcher’ window to show up. Otherwise an error message should be displayed in the command prompt. Figure 1.1: Application launcher window If you want to recompile the program, you can open the attached JBuilder project with JBuilder and click on the ‘make’ button. Otherwise, follow the compiling procedures that correspond to your favourite environment. Please note that the ‘classes’ folder contains not only the compiled classes but also other files needed to launch the application, as for example some image files. You must be careful not to remove them when deleting classes or performing cleaning procedures, since they will not be regenerated by any ‘make’ procedure. back to top
  5. 5. 2 User’s manual Because of its size, the application user’s manual has been written on a separate http page. You can access this page by clicking here. back to top 3 Application architecture 3.1 General architecture As introduced before in this document, the application architecture follows the client-server paradigm. This is shown in Figure 3.1, which presents the application architecture at a high level of abstraction. Figure 3.1: Application architecture at a high level of abstraction In this figure you can also note that both client and server present a three-tier architecture internally. At the lowest level we find all the functionalities that regard data management, included synchronized structures that allow the correct execution of concurrent read and write operations. At the logic level we find different functionalities; some of them are related to the control of the connections and sessions between the client and the server. Some others are related to the management of the models that are drawn on the GL canvas, their position and display optimizations. The presentation layer is not highly decoupled from the other layers of the architecture. This is because many data structures used within lower layers have specific methods to display themselves onto the GL canvas. Then a few of the presentation functionalities can be considered to be spread within the lower layers.
  6. 6. However, the functionalities related to the management of windows and input graphical controls, and the definition of the interface through which the user can interact with the program still remain in the presentation layer. 3.2 Terrain viewer architecture The terrain viewer architecture at a lower level of abstraction is shown in Figure 3.2. Figure 3.2: Te rrain vie wer architecture Most of the logic of the program is defined within the Control module. This module uses different structures as the height model and geomipmap module to manage and display the correspondent models onto the GL canvas. In addition to this, the control module uses many other utility modules as the DTM module, textures and geometries, and controls the display optimizations. Finally, it also allows the creation of a connection thread when needed (for example, when downloading themes from the theme server). The vertical bar at one side of the connection thread module (in Figure 3.2) indicates that it is a ‘boundary module’. It uses a socket connection to communicate with the theme server and gather the results of the query. The synchronization of the data manager within the data layer is very important. For example, a connection thread may start writing a new theme while the control module is reading the data buffer.
  7. 7. 3.3 Server architecture The server architecture is under many aspects very similar to the terrain viewer architecture, as it can be seen in Figure 3.3. However in this case the logic of the program is distributed in a different way. The control module does not handle any kind of display optimization apart from the retained mode, which is always active. There exist other two modules entirely dedicated to the service of the clients; the daemon and the handler. Figure 3.3: Server architecture If active, the daemon is continuously listening to a server socket for incoming connections. When a client connects to the server, the daemon creates a handler thread that will serve the client and handle all aspects related to its session. Handlers also register within the control module when a session starts. In this way it is possible to know the number of active sessions at a given time and to interrupt the handlers when needed (for example, think of a hard shutdown). The synchronization of the data layer is even more important in the server than in the terrain viewer. In fact, many handler threads may be accessing the data manager at the same time. Moreover, they may access it while the server administrator is modifying the data in the data manager. back to top 4 Most interesting features
  8. 8. 4.1 Display optimizations Without any doubt, some of the most interesting features of the application are the optimizations that it implements. Using these optimizations can increase the animation speed dramatically, and reduce the load of the system on which the application is running. As you start the terrain viewer program, the first window to show up is the application launcher. On this window, click on the ‘Display settings’ tab, and you will be able to pre-configure the optimizations. If you want to test these optimizations, deselect all of them before the application starts, as shown in Figure 4.1. Figure 4.1: Disabling display optimizations Also, to force the system to work to its limit during the testing, set the display to run as fast as possible as shown in the figure. Otherwise you can also set a very big frame rate. Now, click on the ‘Ok’ button to start the application with no optimizations enabled.
  9. 9. Figure 4.2: Pe rformance testing with no dis play optimizations enabled In our machine, the obtained results were a low frame rate that did not exceed 15 fps, and the general system response to slow down, showing that it was heavily loaded. Moreover, the graphic card fan was continuously working. Turning on the face culling did not make the situation better, since we have obtained the same results as before. We have also tried reversing the model so no polygons were rendered (they were all culled by the face-culling procedure), but it did not make any change. Then we decided to turn on the retained mode, and the animation speed increased enormously (up to 100 fps, the limit of the machine where this tests were performed). Even the graphic card fan stopped working. In fact, the retained mode is the optimization that gave better r esults during our tests. However, within the project context it is the less interesting optimization since it was developed by direct usage of already implemented functionalities in the used graphic libraries. Much more interesting to us is the geomipmapping optimization. It consists of the tessellation of the terrain into many different cells. In principle these cells can have any shape, but for simplicity we have chosen to use a square-cell tessellation. Each of these cells can be displayed separately using a different LOD (Level Of Detail). A lower level of detail uses less polygons to approximate a model, and applies lower definition textures to it. A particular instance of a cell at a given LOD is called ‘patch’.
  10. 10. The advantage of this approach is that, when an object is far away from the camera point of view, a much low level of detail may be sufficient to obtain acceptable results when rendering it. Then, within the structure that we have defined, we can choose the most appropriate level of detail to be used for each cell, and obtain animation speed increments when some of then are far away from the camera point of view. In Figure 4.3 you can see a geomipmapped model displayed in wireframe mode. We added blue lines approximating the boundaries between different LODs. Figure 4.3: Wireframe visualization of a geomipmapped model The increments on the animation speed given by the use of a geomipmapped model may vary a lot, depending on the position of the model. For far distances, the results we obtained were similar to those of the retained mode. However, the animation speed decreased significantly as the model approached positions nearer to the camera point of view. The lowest animation speed observed with the geomipmapping optimization enabled was about 20 fps. This happened when the model was so close to the camera that most of the cells where displayed using the best LOD. The major disadvantage of the naïve geomipmapping techniques is that they may introduce cracks in the model surface. Cracks are boundary edges of some patches that do not coincide with the correspondent edges in the adjacent patches. They can be better understood by looking at the following figure.
  11. 11. Figure 4.4: Cracks in a geomipmapped model Cracks lay in the conjunction points between patches with different LODs. To solve this problem, we designed a different geomipmapping algorithm that impleme nts anticracking techniques to patch up the cracks in the geomipmapped model. The results were really satisfying; the cracks on the geomipmapped model were patched by the implemented algorithm and it didn’t seem to represent a significant overhead when displaying the model. To test the algorithm, we suggest you to increase the height factor (generally this enlarges the cracks in the geomipmapped model) and to change the model’s position until some cracks become notable. Then turn on and off anticracking to check if these cracks are actually covered. The last implemented optimization is the frustum culling. It requires a tessellation of the height model to work, and we reused the geomipmapped model for this. This is the reason why, in our application, the frustum culling only works when the geomipmapping optimization is active. To speed up the culling process, the algorithm uses a quadtree as a support structure. The quadtree is a special type of tree that finds many applications, especially when dealing with geographical data or geometries over a plane. Within a quadtree, elements are ordered according to their x, y location in the space. More precisely, each node in the quadtree corresponds to a rectangular zone of the terrain. This rectangular zone can be further divided into 4 zones (NW, NE, SW, and SE) to which the children of the node correspond. Using this structure, the frustum culling algorithm can be enhanced very much, since, generally, when culling great areas of the terrain it does not need to descend deep in the quadtree to find their correspondent nodes. Suppose, as an example, that the algorithm determines that the entire model is inside the frustum. Then it sets the root of the quadtree to be displayed completely and it does not repeat the same check for each of the subzones. The algorithm descends to the lower level of the tree only when the zone that has been checked is partially inside the frustum (and the correspondent node in the quadtree is not a leaf).
  12. 12. Testing the frustum culling algorithm we have implemented gave very good results. In fact, in those situations in which the geomipmapping becomes less performing, i.e. when the model approaches some position very near to the camera, greater zones of the terrain tend to be outside of the frust um. The minimum frame rate obtained by enabling the frustum culling optimization (with the retained mode disabled) was about 50 fps. Finally, to test the correctness of the frustum culling algorithm, you can use the quadtree viewer integrated within the application. The quadtree viewer is shown by clicking on the ‘Show QuadTree’ button in the ‘Optimizations’ panel. Doing so, the following window will show up. Figure 4.5: Quadtree viewer The quadtree viewer shows the state of the quadtree nodes by representing them as rectangles. Note that it only shows the nodes that where visited during the frustum culling process. If the culling algorithm did not descend deep in the quadtree, just a few rectangles will be shown. A green square represents a node whose correspondent zone is displayed, while a red square represents a node whose correspondent zone has been culled. For example, the snapshot of the quadtree state in Figure 4.5 has been taken when the model was entirely inside the frustum. For performance reasons, automatic refresh of the quadtree viewer is not enabled by default. However, it can be convenient for you to turn it on when testing the correctness of the frustum culling algorithm. Another recommendation that may be useful at this scope is to evidence the model bounding box (to see which parts of the model are actually inside the frustum and which of them are not).
  13. 13. Figure 4.6: Frustum culling evaluation Please note that the automatic refresh of the quadtree viewer has a bad impact over the animation speed, so we strongly recommend to turn it off when testing the anima tion speed increments of each optimization. 4.2 Polyline visualization over terrain models Another amazing feature of the application is it capability of modifying the downloaded polylines so as they follow the terrain. In particular, what the server provides are 2D themes (only x-y coordinates are specified for the theme points). This means that these polylines cannot be displayed properly over the 3D terrain model. Note: Sometimes height models are called 2,5D or 2D+, because they are not considered comp lete 3D structures, however, for simplicity, let us say here that we are displaying a 3D model. Clearly, the naïve solution of modifying the height of the points in the polyline directly does not work. Consider, for example, the following case.
  14. 14. Figure 4.7: A polyline over a height model The polyline has only two points, and if we modify their height so as they touch the ground, the mayor part of the polyline will still not touch the ground. There exist even worse cases in which part of the polyline will become covered by a bump of the terrain model. Then the solution is to apply a fragmentation algorithm to divide the original lines into proper segments whose height values can be modified so every point of the resulting polyline will touch the ground. Now the question is: Where to divide the polyline? The answer is that the division of the polyline must be driven by the triangle mesh of the height model. Considering an orthogonal projection, a height model mesh has the following aspect if seen from above. Figure 4.8: A triangle mesh Now, consider the following line over the mesh. We want to fragment it so as to make it follow the terrain.
  15. 15. Figure 4.9: A line over the mesh The problem is surely solved if we divide the line at each correspondence with a mesh edge (note that this correspondence is not an intersection, since the height of the polyline points is not yet defined). The following Figure illustrates this. Figure 4.10: Mesh-driven line fragme ntation Someone may say that this is an overkill, since in some cases the surface slope may not vary from one triangle of the mesh to an adjacent one. However, we claim that in most height models the slope variation is high, and an algorithm that divides a line at every correspondence with a mesh edge is much simpler and easier to understand than one that divides lines only when necessary. The final step of the algorithm has to set the height of each point to matc h that of the model’s surface. In the next section we explain deeper in detail how this was implemented. Figure 4.11 shows an example of the results obtained with the implemented algorithm.
  16. 16. Figure 4.11: Modified polylines follow the terrain Remark: Remember that results like the one shown by the figure can only be obtained turning off geomipmapping optimizations. Now we will present some guidelines that may help you testing the polyline modification algorithm in Computer GraGIS. Usually, the first thing that one would like to check is if the fragmentation algorithm is working properly. To do this, it may be better to turn on the wireframe mode and to evidence theme points. For more information about how to turn on these features, please read the user’s manual. Now, if the bumps or variations of the surface disturb your analysis, it can be useful to reduce the height factor to the minimum (0,1), and to put the model in vertical position (this can be done by clicking on the ‘Reset angles’ button on the ‘Position’ panel – see the user’s manual). You should see something like this:
  17. 17. Figure 4.12: Fragmentation algorithm evaluation In this way it is easy to see if at every correspondence between the polylines and the mesh edges the algorithm has added one point (i.e. fragmented the polyline). Now, to check if the height of each point has been determined correctly, put the model in an oblique position to obtain a better perspective. Then, set the height factor to the maximum. This will not only exaggerate the bumps on the model, but it will also enlarge any difference between the surface height and the height of the points in the polylines. Figure 4.13: Point height evaluation By performing this tests, we have always found that the height of the points in the resulting polyline coincides with that of the surface of the model at the same (x, y) location.
  18. 18. However, we remark here that the algorithm we have implemented aims at raising the points to exactly the same height that the one of the model’s surface at the same (x, y) location, not to a greater height. Then, even an insignificant numerical computation error, due to the fact that we are working with a limited precision representation of numbers –or a little imprecision on the depth test-, could cause part of the line to be covered by the ground. Although this happens very rarely, you can overcome the problem by setting a height greater than zero for the lines on the theme selection table (even a very little height will work). Augmenting the line width can also help in evidencing the lines. The following figure shows a snapshot of the theme selection table. Figure 4.14: The me selection table back to top 5 Implementation notes 5.1 Design patterns When implementing the application, we have applied different design patterns. The use of design patterns has been always considered a good design practice, since it allows reusing solutions that have been experienced by others and proved to perform well in the contexts of application. One very diffused design pattern is the one we implemented with the daemon and server t hreads to handle the clients connections. Another example is the design pattern ‘Singleton’ that turned out to be particularly useful for the instantiation of the data manager, in both client and server, since within each program a unique instance of the data manager is required. 5.2 Geomipmapping and frustum culling The geomipmapping algorithm we implemented for the project divides the height model into square cells. Points in these cells are organized in rows and columns, uniformly distributed in the pla ne (if we consider only their x and y coordinates). The mesh is then obtained by considering some edges that these points determine, in the same way it is done for the original height model.
  19. 19. Patches with best LOD are obtained from the original model just by tessellating it. Other patches are obtained from patches with better LOD by removing some of their columns and rows. More precisely, a patch of LOD n has twice as columns (or, equivalently, rows) than a patch of LOD n + 1 (the higher the LOD number, the worse the level of detail). The height model can only be properly tessellated if the number of columns in it is a multiple of the number of columns of a patch with best LOD (this holds also for the rows). Then it follows that in some cases it is necessary to add (or alternatively, remove) columns or rows to the height model before creating the geomipmapped model. This is exactly what we have done. Textures at different LODs are computed in a very similar way. However, in this case the algorithm does not simply remove values from one texture to obtain one texture at a worse LOD, but recomputes the RGB values of each pixel determining the average of the four pixels it is replacing (also for a texture the width and height are the half of those of a texture of better LOD). This is more complex, but gives much better results than simply dropping the values of the original textures. As introduced before, for the frustum culling, nodes in the quadtree correspond to portions of the geomipmapped terrain model. More precisely, each node of the quadtree stores a bounding box. Then the zone that corresponds to a node is the set of cells inside the node’s bounding box. Because of this, a perfect quadTree could only be obtained if the number of ‘column cells’ and the number of ‘row cells’ in the tessellation of the height model are both powers of two. However, we considered that it wasn’t a good idea to modify the geomipmapped model adding cells to obtain a better quadtree. In fact, some worst cases show that the resulting structure could be almost four times bigger than the original one. Consider, for example, a geomipmapped model of 33x33 cells. The minimum power of two greater than 33 is 64. Then if we added the necessary cells to obtain a better quadtree we would obtain a geomipmapped model of 64x64 cells. It is also true that we can remove cells instead of adding them. We didn’t want to do that because it would potentially drop parts of the terrain that the user of the program considers important. Our approach was to separate the zones at the best possible points. This means that if the model has 33 ‘column cells’ and 33 ‘row cells’, the zone that corresponds to the first child of the quadtree node root should be 16x16 cells, the second child’s zone 16x17, the third child’s zone 17x16 and the fourth child’s zone 17x17. There is no real disadvantage in performing the separation into zones this way, apart from the fact that the algorithm that constructs the quadtree can become a little more complex. 5.3 Polyline fragmentation algorithm In section 4.2 we have presented the algorithm that modifies the polylines so as to make them follow the terrain. We have also explained the reasons why the algorithm fragments each polyline before modifying the height of the points.
  20. 20. Now we want to show how the fragmentation algorithm was implemented. Since the algorithm is long, we are not going to include its source code here (however, it is part of the distributed package, see section 1.1), but we will show how it works graphically. The algorithm was entirely written by the student Bruno Nardelli, as part of the final project for the course of Computer Graphics Principles at the University of Trento. To simplify the algorithm, we have written it to perform three different fragmentation steps. At the first step, lines are fragmented at the correspondences with horizontal edges of the terrain mesh, as shown by Figure 5.1. Figure 5.1: Fragmentation driven by the horizontal edges of the mesh Knowing that the mesh edges under consideration are horizontal, the division point coordinates can be determined easily, using an algorithm that finds a point in a line given its y coordinate. After fragmenting the polyline according to the horizontal edges of the triangle mesh, the algorithm continues with a fragmentation driven by the vertical edges of the mesh. This can be seen in Figure 5.2. Figure 5.2: Fragmentation driven by the vertical edges of the mesh Also in this case the division point coordinates can be easily determined using an algorithm that finds a point in a line given its x coordinate. Finally, the algorithm applies a fragmentation driven by the oblique edges of the mesh. To do this, it simply projects the points of the polyline onto the y axis and performs a vertical-edge-driven fragmentation (see Figure 5.3). Then it reprojects the new points back to the line.
  21. 21. Figure 5.3: Fragmentation driven by the oblique edges of the mesh Note that projecting the points onto the y axis as shown in Figure 5.3 is extremely easy, since the oblique edges in the mesh form a 135° angle with respect to the x axis. This means that the y’ coordinate of a projected point is equal to x + y, where x and y are the original coordinates of the point. That’s it. Now the points in the polyline are ready to be raised so as they touch the model’s surface. 5.4 Polyline points raising algorithm To explain how the points raising algorithm works, we will consider the simple case of only one point to be raised. Again, we will consider an orthogonal projection and look at the model from above, as shown in Figure 5.4. Figure 5.4: The point to be raised Different situations can happen. One of them is the one presented in Figure 5.4. In other cases, the point coordinates correspond to the x- y coordinates of some point of the mesh edges. Here we are
  22. 22. going to explain how the algorithm behaves in a situation like the shown in the Figure 5.4. The other cases are much simpler. The first thing that the algorithm does is to choose the three points in the mesh that it will use to determine the height of the polyline point. Observe that these points describe a triangle. Figure 5.5: Mesh triangle considered by the algorithm Then it computes the intersection points between the triangle edges and the vertical plane that the polyline point characterizes (see Figure 5.6). Note that the new points describe a line. Let’s call it auxiliary line. Figure 5.6: Two other auxiliary points determined by the algorithm Finally, the algorithm determines the raised point as the intersection between the auxiliary line and the horizontal plane characterized by the polyline point. Figure 5.7: Final step
  23. 23. back to top 6 Conclusions and future work During the lessons, we have learnt different concepts, useful for writing 3D applications. Particularly important were the lessons about the display optimizations. These optimizations provided a great enhancement in the animation speed of our program, that only displays one terrain model. Just think of the importance of them when writing, for example, a complex 3D videogame, with the scenery, lots of ‘enemies’ and animations, requiring a huge number of polygons to be rendered and a good response to the user’s commands. Many of the guidelines and examples in class helped motivating the participation and creativity of the student, which succeeded writing his own fragmentation and point raising algorithm as part of the final project. As a future work proposal, it could be interesting to modify the fragmentation algorithm to add new points only where absolutely necessary (read the discussions about it in section 4.2). In average cases, this may represent an insignificant enhancement. However, in some cases were the terrain presents just a few slope variations, the number of points in the polylines can be reduced considerably. Another interesting feature that we would like to implement as a project extension is the concept of generic maps. This should provide means of treating two types of maps, regardless their location or format:  Raster maps (this category also includes elevation maps, like the one in an ascii dtm file).  Vector maps. Finally, adding proper support for dealing with different reference systems could allow the application to work with different data sources at the same time (for example, displaying a raster map loaded from a file and retrieving vector maps from a PostGIS database). back to top