My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ProposedArchitectureChanges  
Proposed Architecture Changes for making droidViz more general purpose and usable.
Phase-Design, Phase-Implementation
Updated Jul 4, 2010 by griffyb...@gmail.com

Introduction

The following is a proposed set of architecture changes. These are class definitions which should be sufficient enough for programmers to perform any task droidViz was designed for from either the Java or native layers.

Current State

The new spec is about 80% there. Coding can begin on the lower classes. Areas such as input and the JNI wrapper need further specification.

Architecture

RenderLayer

RenderLayer encapsulates the required interface that each RenderLayer Object must/may overload in order to function. Renderlayers are added to the RenderStack object internally in droidViz

Public Methods/Interface

  • void SetShader( char* VShader, char* FShader ) // Called externally, maybe
  • void Render( FluidSimData &fsd, Input &in ) // Called every frame, passed in fluid variables as well as input.
  • void OnHalt() // Called when the simulation/rendering halts
  • void OnResize( int width, int height ) // Called when the simulation resize (tilting)

When the RenderLayer is created/pushed into the stack its constructor is called. When the RenderLayer is removed from the stack, its destructor is called.

RenderStack

The RenderStack is global. We'll still encapsulate it in a separate class, but we don't want to encourage creation of more than one RenderStack. The Renderstack will be internal to droidViz. The render stack will render a stack of layers from the top to the bottom. Because, in some cases, the visualization may depend on layering, we will treat the RenderStack as some sort of "Vector" of render layers. We don't have access to std::vector from the android library, so we'll have to implement something of our own. This will be nontrivial to implement, so we'll just code with this future expansion in mind and implement the functions we don't need right away later.

public:

  • RenderStack() // Allocates required memory and sets required defaults
  • ~RenderStack()
  • int PushBackRenderLayer( RenderLayer* ) // returns an index - a handle, if you will
  • int PushFrontRenderLayer( RenderLayer* ) // returns index
  • int InsertRenderLayer( RenderLayer*, int pos ) // returns an index
  • bool RemoveRenderLayer( int index ) // returns true if succeeded, false if not
  • int NumRenderLayers() // Returns the number of render layers currently instantiated

  • void Render( const FluidSimData* fsd, Input* in ); // Calls the render function of all renderlayers and feeds the input and fluid sim data to it
  • void Halt(); // Calls the halt function of all renderLayers.
  • void Resize( int width, int height ); // Calls the onResize function for all renderLayers

private:

  • RenderLayer* mLayers;
  • int mNumLayers

FluidSimData

FluidSimData is a class which allocates memory for the fluid matrices, and contains accessor functions which provide read only access to the data. This is a friend class of FluidSim, so only FluidSim has non-const access to the data contained within.

public:

  • friend class FluidSim;
  • FluidSimData( int Size ); // Allocates proper memory for the fluid simulation
  • ~FluidSimData(); // Deallocates memory

Consider inlining some of this for performance

  • const float VelocityX( I, J ); // returns the velocity at index I J
  • const float VelocityY( I, J ); // returns the Y velocity at index I J
  • const float Density( I, J ); // returns the density at index I J
  • int Size() { return mSize; }
  • void ScreenToIndex( ScreenWidth, ScreenHeight, X, Y, &I, &J ) // Converts screenspace to fluidspace

private:

  • float* mU // X coordinate of velocity
  • float* mV // y coordinate of velocity
  • float* mD // density value
  • int mSize;

FluidSim

FluidSim carrys out the fluid calculations and performs updating of the FluidSimData object. droidViz passes the FluidSimData object on to the RenderStack each frame after its performed an update to the simulation. Solver.c will be converted to a bunch of static functions within this class

public: // Constructor and Deconstructor

  • FluidSim( int Size ) // Constructor allocates the proper sized FluidSimData object
  • ~FluidSim() // Deallocates memory associated with the simulation

// Updating and returning data

  • FluidSimData* Update( int dt ) // dt is the time in milliseconds since the last update. Update then returns the most current FluidSimData. Renders in most current source/velocity commands.
  • FluidSimData* Data() { return mData; } // Returns a pointer to the current FluidSimData object

// Fluid Parameters

  • int Size() { return mSize; }
  • float Diff() { return mDiff; }
  • float Visc() { return mVisc; }
  • void SetDiff( float diff ) { mDiff = diff; }
  • void SetVisc( float visc ) { mVisc = visc; }

// Input Functions - Note, use the conversion method in the FluidSimData class to convert XY to IJ

  • void CreateSource( I, J, Source ) // Source is an integer, 0 - 100
  • void CreateVelocity( I, J, dX, dY ) // dX, dY indicates a vector (magnitude and direction)

private:

  • FluidSimData* mData;
  • float mDiff;
  • float mVisc;

Input

Input is a special class which holds information about a new input event. It holds the type of input, the number of inputs (in the instance of multitouch) and information about the individual inputs in array form - X, Y. The input structure is designed to be expandable in the future (Pressure?)

Implementation is trivial.

DroidViz

DroidViz is the wrapper object which instantiates one RenderStack and one FluidSim, and exposes the functions of both to each other and the JNI interface. DroidViz will aggregate input until the next fluid update and render cycle.

public:

  • DroidViz( int Size ) // Constructs a new fluid simulation of a certian size
  • ~DroidViz() // Deallocates everything necessary

  • {Exposed FluidSim Public Functions}
  • {Exposed RenderStack Public Functions}
  • void SetInput( int* X, int* Y, int numInputs ) // X and Y are arrays of position data of size numInputs long. SetInput just overwrites mInput. mOldInput is only set once a render cycle has occurred
  • void Update( dt ) // Updates the fluid simulation, feeds the results to the RenderStack and performs a render. Sets the current input to the old input. It is up to the JNI wrapper to only call this function 30 times per second to accurately limit frames and CPU usage.

private:

  • FluidSim* mFluidSim;
  • RenderStack* mRenderStack;
  • Input mInput;
  • Input mOldInput; // Input from the last render cycle

JNI Wrapper

The jni wrapper is a set of functions which exposes the main object and associated functions it performs. The following is a list of exposed JNI functions and what they do

  • Initialize( Size ) // Creates the DroidViz object of a certian size
  • SetFPS( int FPS ) // Sets the timers to only call the droidViz.update( dt ) function FPS times per second.
  • Start() // Starts the Visualization
  • Pause() // Pauses the Visualization, calls RenderStack.Halt()
  • Resize( Width, Height ) // Resizes the window, calls the renderstack OnResize
  • SendInput( int[] X, int[] Y ) // exposes input at JNI level.
  • Cleanup() // Destroys the droidViz object, and with it - everything else
  • {Exposed public DroidViz functions}

Java Level Usage:

The following is a proposed Java scenario which demonstrates how the developer should use the library.

// Create a surface view and the droidViz renderer
DroidVizSurfaceView sv;
DroidViz dv; // (DroidVizRenderer will now be renamed to DroidViz because it contains the majority of the methods.

// Get a list of all available render layers we can instantiate
string[] Types;
dv.GetTypes( Types );

// Add a render layer to the stack
int idx = dv.PushBackRenderLayer( "Density" );
or
int idx = dv.PushFrontRenderLayer( "Density" );
or
assert( pos < dv.NumRenderLayers() )
int idx = dv.InsertRenderLayer( "Velocity", pos );

// Or remove a render layer from the stack
if( dv.RemoveRenderLayer( idx ) )
	Log.v( "droidViz", "Successfully removed the RenderLayer" )
else
	Log.v( "droidViz", "Could not remove the RenderLayer" )


// Set the renderer for this SurfaceView
sv.SetRenderer( dv );

// Set the surface view to show droidViz
SetContentView( sv );

Sign in to add a comment
Powered by Google Project Hosting