\chapter{Sandstorm Software Specification and Design}\label{ch4}

Chapter 2 presented the background and problems with creating such a particle system as Sandstorm.
Also Chapter 3 presented what Sandstorm is trying to accomplish.
This chapter presents a formal description of the goals, requirements, and use cases of Sandstorm.
The goals will describe four major attributes that the Sandstorm prototype shall have.
The requirements are presented in two categories: functional, and non-functional requirements.
These describe the basics features of the Sandstorm prototype.
The use cases describe the use and basic functionality of the Sandstorm.
Later in the chapter, you'll find a more detailed discussion of the overall system and subsystems of Sandstorm.
The software engineering practices and principles used to develop Sandstorm can be found in ~\cite{arlow2002:uml}, ~\cite{endres03:handbook}, and ~\cite{sommerville04:se}.
Providing the reader with an understanding of the structure and methodology behind Sandstorm is the aim of this chapter.

\section{Sandstorm Goals}\label{sec:Goals}

First off, Sandstorm is meant to be a tool for the visualization of atmospheric phenomenon for scientific study, such as dust clouds and smoke.
Thus, Sandstorm must allow for the input of observed scientific data to fuel the visualization of these phenomenon.
For instance, the use of vector fields to guide the trajectory of the particles in an atmospheric phenomenon visualization is one example of allowing for the input of observed scientific data. 
Therefore, Sandstorm uses vector fields to allow for the input of observed scientific data to fuel the visualization of atmospheric phenomenon.

According to other particle systems ~\cite{kipfer04:uber} and ~\cite{latta}, the higher amount and smaller size of particles add to the realism of a particle system.
Traditional CPU-based particle systems are stuck at around 100,000 particles~\cite{latta}, and are limited by the transfer of particle rendering information across the graphics bus.
Newer GPU-based particle systems ~\cite{kipfer04:uber}, ~\cite{latta}, and ~\cite{ParticleGS}, allow for a much higher amount of particles to be displayed, around 500,000.
Therefore, Sandstorm uses a GPU-based approach to allow for a high amount of smaller sized particles, which adds a higher degree of realism.

Allowing the user to immerse themselves into the scientific phenomenon that they are studying may allow for a better understanding of the phenomenon.
Using a 3D virtual reality environment will allow a user to immerse themselves into a particular application.
Therefore, Sandstorm will utilize a 3D virtual reality environment to allow for the immersion of the user into a scientific phenomenon.

Like previously stated, Sandstorm is meant to be a tool for the visualization of atmospheric phenomenon for scientific study, such as dust clouds and smoke.
Thus, Sandstorm must have the ability to allow the application programmer to customize the particle system.
Such customization could include, whether or not to display the particles as points or textured billboards, the size of particles, and the maximum life time of the particles.
Therefore, Sandstorm allows for a horde of attributes to be changed both programmatically and during run-time, for a complete list see Table~\ref{tab:dynamic} in Chapter 5.

\section{System Requirements}\label{sec:SysReq}

Like all software systems, Sandstorm has minimum system requirements that must be met in order for the system to perform properly.
This section will describe the minimum system requirements of Sandstorm and describe some of the specifications of the system that Sandstorm was tested and developed on.

The first requirement is the most apparent, and that is the virtual reality environment.
Sandstorm was developed for use in an active stereo CAVE system.
The CAVE system that Sandstorm was tested on was at the Desert Research Institute.
This CAVE system was an active stereo, four-wall flex CAVE system designed by FakeSpace~\cite{fakespace:cave}.
The system utilizes a multi-cored machine and a Nvidia quadroplex to power it~\cite{quadroplex}.

Like previously stated throughout this paper, Sandstorm utilizes a GPU-based approach.
However, this GPU-based approach is not your run-of-the-mill approach, it utilizes Shader Model 4, more specifically geometry shaders and transform feedback.
The system that Sandstorm was developed and executed on, uses a Nvidia quadroplex with a G80 chipset in it, thus a system that is going to run Sandstorm will also have to have a G80 chipset.
The video cards that have this chipset are any Nvidia 8000 series cards~\cite{g80}.
Currently Radeon cards don't support transform feedback.
However, current Radeon cards, such as the Radeon HD 3800, support vertex stream out, which is DirectX 10's version of transform feedback~\cite{streamoutput}. 

\section{Software Specifications}\label{sec:Requirements}

Before the use case and class diagrams can be presented, the requirements of Sandstorm must first be outlined (Table~\ref{tab:funcreq}).
These requirements were distilled through domain knowledge and the requirements of the Helicopter and Dust Simulation application described in Chapter 2. 
\begin{table}[h]
\begin{center}
\begin{tabular}{|ll|} \hline
	F01 & Sandstorm shall display a visual representation of phenomena \\
		& such as dust clouds, i.e. particle system. \\
	F02 & Sandstorm shall use vector fields to guide particles. \\
	F03 & Sandstorm shall utilize GPU-offloading. \\
	F04 & Sandstorm shall be written to work in a 3D virtual reality \\
		& environment. \\
	F05 & Sandstorm shall allow users to change the maximum lifetime of \\
		& the particles. \\
	F06 & Sandstorm shall allow users to change the size of the particles. \\
	F07 & Sandstorm shall allow users to change the area in which the \\
		& particles are emitted. \\
	F08 & Sandstorm shall allow users to change the rate at which particles \\
		& are emitted. \\
	F09 & Sandstorm shall allow users to change the maximum number of \\
		& particles that are allowed to be emitted. \\
	F10 & Sandstorm shall allow users to start/stop and pause the \\
		& particle simulation. \\
	F11 & Sandstorm shall allow users to change the attributes both \\
		& programmatically and during run time. \\
	F12 & Sandstorm shall allow for a large number of particles to be \\
		& displayed (above 100,000). \\ \hline
\end{tabular}
\end{center}
\caption{Functional requirements for the Sandstorm prototype application.}
\label{tab:funcreq}
\end{table}

Next the non-functional requirements (Table~\ref{tab:nonfuncreq}) show what technologies are used in Sandstorm and software features.
These non-functional requirements largely control the software engineering of Sandstorm and its subsystems.
\begin{table}[h]
\begin{center}
\begin{tabular}{|rl|} \hline
	N01 & Sandstorm's CPU based portion shall be written in C++. \\
	N02 & Sandstorm's GPU based portion shall be written in GLSL. \\
	N03 & Sandstorm shall be implemented in a modular fashion allowing for the \\
        & replacement of components when more efficient methods are discovered. \\
	N04 & Sandstorm shall maintain independence from windowing/VR toolkit. \\
	N05 & Sandstorm shall use the VRUI library for prototype application. \\ 
	N06 & Sandstorm shall maintain interactive levels of temporal fidelity, \\
		& above 15 FPS. \\
	N07 & Sandstorm shall use geometry shaders for the creation and updating \\
	    & of particles. \\
	N08 & Sandstorm shall use geometry shaders for the rendering of particles.\\
	N09 & Sandstorm shall use transform feedback to transmit the particle \\
		& data to the update/creation shader(s) to the render shader(s). \\ \hline
\end{tabular}
\end{center}
\caption{Non-functional requirements for the Sandstorm prototype application.}
\label{tab:nonfuncreq}
\end{table}

\section{Use Cases}\label{sec:UseCases}

The use cases in Figure~\ref{fig:uc}, depicts the functionality provided to the end user.
These use cases were developed using the functional requirements presented above.
There are two actors that directly influence the Sandstorm particle system.
The user manipulates Sandstorm by changing the dynamic attributes of the systems.
Time is also a major actor on Sandstorm, it controls the update of the simulation, and animates the particles. 

\begin{figure}
    \centerline{\epsfig{file=images/SandStormUseCase.png, width=14cm}}
    \caption{Use cases for the Sandstorm prototype.}
    \label{fig:uc}
\end{figure}

\section{Modeling and Design}\label{sec:ModelDesgin}

This section describes the structure and design of the Sandstorm particle system.
This includes a Main Class Hierarchy diagram, which includes a description of the classes including a description of the Utility Classes that were used.

\subsection{Main Class Hierarchy}\label{sec:Heirarchy}

In Figure~\ref{fig:mainclass} you can find the main class hierarchy of the Sandstorm particle system.
This is not an inheritance hierarchy, rather a flow of control between the classes.
Also there are other classes that were used in the creation of Sandstorm and they will be covered in the following section.

\begin{figure}
	\centerline{\epsfig{file=images/MainClass.png, width=14cm}}
	\caption{The main system structure of the Sandstorm system.}
	\label{fig:mainclass}
\end{figure}

\noindent
\textbf{Multicontextual ParticleSystem}

This class is the main control mechanism for the entire particle systems, from controlling the flow of the simulation to the flow of data.
This class contains a list of ParticleSystem class, each ParticleSystem class is responsible for a context. 
The list containing ParticleSystem is updated with data such as time between frames and changes in dynamic attributes.

In a multicontextual environment the generation of random numbers needs to be done on a single context to ensure that all contexts get the same random numbers.
During initialization, the Multicontextual ParticleSystem is responsible for generating any random numbers that are needed for the per context simulations.
 
\noindent
\textbf{ParticleSystem}

Each context contains a ParticleSystem class, which is responsible for the creation and coordination of the Shader objects.
During creation, this class creates and initializes the shader objects with data that they need, such as pointers to render buffers and particle information buffers.
First this class creates and initializes the ParticleGeoUpdate shader, which is responsible for the particle information buffers.
Once the ParticleGeoUpdate shader object is initialized, the ParticleSystem  initializes the ParticleRender shader object with a pointer to the particle position buffer initialized by the ParticleGeoUpdate.
Finally, when the ParticleRender shader object is initialized the ParticlePost shader object is initialized with the output buffer of the ParticleRender shader object.

During the simulation the ParticleSystem class will call the ParticleGeoUpdate class to update the particle information.
Once the particles have been updated, the ParticleSystem class will first call the ParticleRender shader to render the particles into an off screen buffer.
After the ParticleRender shader object is called, the ParticlePost shader object is called to render the result of the deferred shading.
Also while the simulation is running the ParticleSystem class directs the flow of the data to the correct shader objects, such as change in the size of the particles or the maximum life time of the particles.


\noindent
\textbf{ParticleGeoUpdate}

In every context there is a ParticleGeoUpdate class, which is responsible for updating and creation of the particles.
During initialization the ParticleGeoUpdate class creates and initializes all of the particle information buffers, such as the particle positions and particle velocity buffers.
The ParticleGeoUpdate class will create two sets of these buffers so that the data is double buffered.

During the simulation, the ParticleGeoUpdate updates the particle information, which includes the particle positions, velocities, and time lived.
This is done by storing the particle information into VBOs, and feeding those VBOs into a shader that will update and create the particles.
Once the shader has updated and created the particles, the ParticleGeoUpdate class gets the result, using transform feedback, and swaps the two set of buffers.

\noindent
\textbf{ParticleRender}

The ParticleRender class is responsible for the rendering of the particles into an off screen buffer for use in the ParticlePost class.
During initialization the ParticleRender class receives from the ParticleSystem class, a pointer to the two particle positions buffers.
Also, the ParticleRender class receives from the ParticleSystem class a pointer to the off screen buffer that it is to render to.

During the simulation the ParticleRender class uses the particle position buffer pointer to feed the render shader the particle position information.
But before the ParticleRender tells the render shader to render the particles, it redirects the output of the render shader into the off screen buffer.
Once the render shader has rendered the particles, the ParticleRender class swaps the pointer of the particle position buffer, so that it matches the correct one that the ParticleGeoUpdate will use next round.

\noindent
\textbf{ParticlePost}

Once the ParticleRender class is done rendering the particles into an off screen buffer, the ParticleSystem class calls the ParticlePost class.
The ParticlePost class is responsable for the deferred shading rffect described in Chapter 5.
During initialization the ParticlePost class receives from the ParticleSystem class, a pointer to an off screen buffer, which holds the results of the ParticleRender class.
During the simulation, the ParticlePost class uses the off screen buffer to feed the deferred shading shader.

\noindent
\textbf{Shader}

The Shader class is a small utility class that handles the creation, compilation, and linking of all shader code.
Each of the three shader object classes ParticleGeoUpdate, ParticlRender, and ParticlePost inherit from this class.
During the initialization of this class, the shader source code is located and loaded, if the shader source code cannot be located or loaded an error is returned.
Once the shader source code is loaded, it is then complied and linked.
If any errors occurred in the compiling or linking of the code those errors are printed.
Once the shader source has been compiled and linked successfully, an identification number is stored into the Shader class.
It is up to the class that inherits from the Shader class, to implement the two virtual functions that are present in this class.
The first virtual function that needs to be implemented is the initialize uniforms function, this function finds and stores the location of any input variables to the shader.
The second virtual function that needs to be implemented is the draw function, which is responsible for setting up the proper OpenGL state and activating the shader.
Each of the Shader object classes (ParticleGeoUpdate, ParticleRender, and ParticlePost), all implement these two functions and store the location of the shader input variables.

\subsection{Utility Classes}\label{sec:Util}

The class/objects/functions listed in the previous section were not the only ones used in this project, below is a brief description of some of the other pieces of Sandstorm.
First the GFX Utility Library, created by Roger Hoang, is a small multi-contextual graphics library.
And second, Vector Field File Loader, is a small object orientation system that loads vector data from a file for use in Sandstorm.

\noindent
\textbf{GFX Utility Library}

GFX Utility Library, created by Roger Hoang, is a small multi-contextual graphics library, that handles such things as multi-contextual textures and framebuffers and OpenGL state-saving and restoring code.

The GFX texture and framebuffer classes are multi-contextual texture and framebuffer classes that are used in Sandstorm for ensuring that any texture/framebuffer data is multi-context safe.
This is done by taking the same approach that Sandstorm does to multi-contextualism, and that is to create a copy of the data for each context.
The multi-contextual classes each contain a list that holds pre-context copy.
When a new context is added, an object(texture/framebuffer) is created and initialized with the proper data, then it is added to the context list of the class.

Other functions of the GFX Library that are used in Sandstorm are the popAll and pushAll functions, which are nothing more than wrappers for OpenGL state saving and restoring code. 

\noindent
\textbf{Vector Field File Loader}

The Vector Field File Loader(VFFL), is a simple class that handles the loading of vector field data and translates the data into a form that can be used by Sandstorm.
First off, the VFFL loads the file data into a three dimensional array for simplicity of loading different file formats.
Sandstorm uses 3D-textures to transmit the vector field data to the GPU order to use the vector field data along with any texture the data needs to be in a single dimensional array.
Once the data is loading from the file into the three dimensional array, the VFFL translates that data into a single dimensional array so that it can be used in the vector field texture. 
