-
-
Notifications
You must be signed in to change notification settings - Fork 49
Application Design Notes
The application's goal is to simulate and program any number of different machines in a safe, easy environment.
We know from experience monolithic systems are difficult to maintain. Therefore it should be built out of small, modular blocks that can be joined to form larger behaviors. Research suggests that an Entity Component System would be ideal, as it has been used quite successfully in many games and simulation systems to achieve similar results.
A Model-View-Controller pattern will maintain clear separation between the Model (serialized data), the Controllers (the systems which change the model) and the View (representations of the data to the user).
It should be scriptable from within the application. Something like a node-based system like Donatello.
It may be helpful to think of Systems as Services run by the application.
The Model an c.m.r.entity.EntityManager
that contains a tree of c.m.r.entity.Entity
. On it's own it is a static thing. The Model must be serializable so that the state can be saved and reused for testing. The EntityManager fires events when Entities are added, removed, or renamed.
c.m.r.component.Components
are groups of related properties. Common Components are c.m.r.component.PoseComponent
, c.m.r.component.ShapeComponent
, and c.m.r.component.MaterialComponent
. Entities may have many Components. Entities cannot have two of the same Component. Because the state of Entities must be serializable it follows that all Components must be serializable. There should be a serialization unit test for every Component.
Each c.m.r.system.EntitySystem
is a Controller that updates Entities and Components. The c.m.r.systems.motor.MotorSystem
updates the sate of every c.m.r.components.motors.MotorComponent
. The c.m.r.system.RayPickSystem
performs basic ray tracing and can return the nearest Entity/MeshComponent. There are motion planners like DogRobotSystem
, CrabRobotSystem
, and RobotArmSystem
.
EntitySystems can stack components together - When the c.m.r.renderpanel.OpenGLRenderPanel
sees a c.m.r.components.shapes.BoxComponent
with an adjacent c.m.r.components.MaterialComponent
then it will draw the Box according to the material properties.
EntitySystems can stack component effects between Entities - every c.m.r.components.PoseComponent
has a local transform (this pose considered in isolation) and a world transform (the cumulative effect of all parent PoseComponents on this PoseComponent).
The view is the entire UX. Robot Overlord has:
- one View written in with Swing for the GUI (in
c.m.r.swinginterface.*
) and - one View written in with Jogamp OpenGL for the 3D display (in
c.m.r.renderpanel.*
)
There are several parts to the GUI.
- The GUI has a
c.m.r.s.entitytreepanel.EntityTreePanel
that displays the contents of thec.m.r.s.entitytreepanel.EntityManager
in a JTree. - The GUI has a
c.m.r.s.componentmanagerpanel.ComponentManagerPanel
that displays a list of the Components common to all the currently selected Entities.
ComponentManagerPanel then gives each EntitySystem a c.m.r.parameters.swing.ViewPanelFactory
to generate the Swing GUI equivalent of each Component. ViewPanelFactory ensures that the Swing elements
- have a consistent look and feel across all Components; and
- all work with Actions and Edits for the Undo/Redo system.
The c.m.r.renderpanel.OpenGLRenderPanel
is the class responsible for generating the 3D view. It uses OpenGL 3 with vertex and fragment shaders. It will attempt to render anything that has (at a minimum) a PoseComponent, a MaterialComponent, and a RenderComponent.
There is a pattern equivalence:
- the OpenGLRenderPanel uses GL3 to Decorate the GLJPanel with colored triangles;
- the Systems use ViewPanelFactory to Decorate a JPanel with JComponents like JComboBox, JSlider, JTextField, JRadioButton, etc.