UnityMol  0.9.6-875
UnityMol viewer / In developement
Developer Guide - A Primer

post-v0.9.5

umollogo

Things you might need to know to understand how UnityMol works

General conventions

Tags that should be used are:

  • !WiP : work in progress, the documenting/coding work is not in a stable build state.
  • !Dep : Deprecated and not used at the moment, probably to be deleted in the next build.

UnityMol Scenes

(This section is from 2009, UnityMol/SVN revision r251)

Scene organization

  • Molecule.unity: Full UnityMol application. Only works as standalone or in the editor.
  • MainMenu.unity: Main Menu with buttons to load pre-defined scenes in a webplayer context.
  • 1KX2.unity: pre-defined scene loading 1KX2.pdb from Scenes/1KX2/
  • Fieldines.unity: pre-defined scene loading fieldline.pdb/.json/.obj from Scenes/fieldlines/
  • Network.unity: pre-defined scene loading a CytoScape network
  • FromPDB.unity: pre-defined scene fetching a PDB file corresponding to the PDB id entered in the Main Menu (no validation for the moment)

If a scene is not loaded correctly, no error message is displayed for the moment. Try to go back to the Main Menu (Open->Main menu) and load another scene.

Scene creation

Let's create a scene called Toto:

  • Copy Molecule.unity into Toto.unity
  • Create a C# script named ScenePreload_Toto.cs in Assets/Scripts/. The class must inherit from MonoBehaviour.
    • You need a method with the following signature:
      1 IEnumerator InitScene(RequestPDB requestPDB)
      2 {
      3 
      4 }
    • Inspire yourself from ScenePreload_Fieldlines or ScenePreload_1KX2 to initialize the scene with the content you want.
  • Be sure to be in the scene Toto in Unity and select the LoadBox object in the hierarchy. Then just add ScenePreload_Toto.cs as a component of LoadBox.

The method InitScene will be called after Molecule3D and the GUI are initialized. Normally you can initialize everything and change any flag from here. UIData.server_url will be www.shaman.ibpc.fr/umolweb in the Editor and "." otherwise.

PDB loading

Todo:
Complete the section on PDB file loading.

Representation

Files in the folder "Scripts/Molecule/View/DisplayAtom or DisplayBond" define how to create the objects to represent each atom and each bond. Then there are Managers in the "Scripts/Molecule/View/" folder that are used to modify the representation, for example the radius, the color ... and that derive from the GenericManager.

Xavier added a new representation called optihb and optihs for optimized hyperball or hyperstick : when the user loads a file or change the representation to optimized hyperball, the script AtomMeshStyle is called for the atoms and the script BondMeshStyle is called for the bonds. These scripts read the atoms array from the MoleculeModel filled when we parsed the PDB and create a mesh or several meshes + one or several texture to store the parameters of each atom/bond. The texture is used to pass parameters to the shader as there is no other way to access to them in the shader. These information are encoded from a float to a color (which is a 8 bits x 4) to not loose precision but for performance reasons (not tested though) we encode these floats using a fast routine that can store float ranging from -500 to 500 and that are decoded in the shader. If we have some precision issue we can use the IEEE version of encoding float that is also implemented in the script "Scripts/Utility/EncodeFloatToColor.cs".

At a higher level, when we want to change the representation there is a script called DisplayMolecule containing a function called ChangeRepresentation that manages all the representation changes. It uses the managers to disable or enable the renderers and to create the representation if not already shown.

About the HyperBalls shaders (legacy)

(This subsection is from 2009, UnityMol/SVN revision r251)

The shaders are working great for OpenGL versions of Unity (MacOS, Windows with the -force-opengl flag). If you want to modify these shaders and have them work in Direct3D you have to follow this procedure:

  • Make your changes in the OpenGL version of the shaders: BallImproved.shader and StickImproved.shader.
  • Let Unity compile them. It will throw some errors. Select the shader in the project tree and click on Open compiled shader in the inspector.
  • Copy the content of this file and paste it into Ball_HyperBalls_D3D.shader or Stick_HyperBalls_D3D.shader, respectively.
  • Then replace the occurences of oDepth.z by oDepth. There is only one in the original shader.
  • Change the name of the shader at the top of the file to FvNano/Ball HyperBalls D3D or FvNano/Stick HyperBalls D3D.

Unity3D/UnityMol is able to detect the platform it runs on and choose the appropriate shaders.

Color panel text database

(From Erwan on 22/10/13 at UnityMol SVN revision r350.)

ColorPanel.txt contains all the premade settings that can be used in UnityMol through the Panels menu. You should find the file at : Assets/Resources/ColorPanel.txt. Here's how the parser reads informations in this file, which is important to know if you want to add/edit panels.

The name of the panel must start with a "$" so the parser knows it's a name.

1 $NAME

You can then use the name (without the "$") in the program to call a panel with SetColorPanel(name) or SetTexturePanel(name). The contents of the panel are written like this :

1 ATOM; RESIDUE; CHAIN; R; G; B; A; TEXTURE_PATH

Please respect the indentation in the file for a better readability. Remember to fill every field :

  • with "All" for atom/residue/chain if you don't want to be specific about them,
  • with white (1.0, 1.0, 1.0, 1.0) for the color if you want a pure texture panel,
  • with "lit_spheres/divers/daphz05" as texture if you want a plain aspect (it's the default texture for hyperballs).

Remember to end the file with a last "$"

1 $

This is important for the parser, that really cares about this file ending!

Thanks for reading, you can now ColorPanel everything !

The UI

The old UI

Each script is stored in the folder "Scripts/UI". During the factoring step, we separated each UI part to a specific script like SecondaryStructureOldGUI.cs and each button is supposed to call one or few functions from the correspond manager ie "Scripts/SecondaryStrutures/SecondaryStructureManager.cs".

The new UI

Todo:
Complete the section on new UI implementation.

Ambient Occlusion

The version Xavier implemented is using rays to detect if each atom is occluded by other atoms. The current implementation is using the Unity way to send a ray using the physical engine function "Physics.Raycast" that works if there are colliders on the atoms. It stores the result of nearly 8x8=64 rays by atom in a 8x8 texture encoded in 8 bits format Alpha8.

The position of the ray is determined by the otahedron mapping of the texture over the sphere so that each patch of the texture is colored in black if the corresponding ray hit another atom.

The texture is then blured using a custom algorithm : when bluring a pixel located at the edges of the texture, because of the mapping, we have to make sure that the neighboor pixels when the texture is mapped are contributing to the blured pixel so that there is no brutal difference between close pixels.

The ambient occlusion takes time mainly because of the blur step made on the CPU for now.

Skyboxes

(notes from legacy UnityMol version in Assets/Standard Assets/Skyboxes)

The Skyboxes are imported at 512x512 to speed up the import process, but the original files are 1024x1024 and can be re-imported at that size for higher quality.

Each Skybox Texture also contains an Alpha Channel which can be used to modulate certain Image Effects (Pro Only). If you are not going to use the Alpha Channels it is best to re-import the Skybox Textures without them to preserve texture memory.

OpenCL

There is a way to launch OpenCL kernels, edit textures directly on the GPU without transfering it back to the CPU, directly in Unity. The library (https://github.com/leith-bartrich/openclnet_unity) is a set of bindings for OpenCL, modified for Unity. This could be used to accelerate some algorithms we use in UnityMol, like the marching cubes or the blur in the Ambient Occlusion (#ambientocclusion) for example.

Scripting Define Symbols

Unity provides a macro system for platform specific and conditional compilation while performing a build. These macros are called Platform Defines and Platform Custom Defines. http://docs.unity3d.com/Manual/PlatformDependentCompilation.html

If you want to use such a define while running the project in the editor (rather than only for a specific build), you may need to use the Global custom defines mechanism, which would mean to create a Assets/smcs.rsp file, for instance with the contents -define:ENABLE_UMOL_DB. After doing so, the scripts using these defines need to be recompiled manually.

Current Define Symbols

UnityMol has the following defines:

  • ENABLE_UMOL_DB: Enable (experimental) functions to connect to the UnityMol database for things such as lit sphere texture retrieval. When changing this setting in Assets/smcs.rsp, recompile the Assets/Scripts/UI/GUIDisplay.cs script afterwards.

Legacy

The following defines were previously used:

  • DISABLE_HIRERNACONTEST_UPLOAD: Disallow file upload to the HiRE-RNA Contest Web App.
  • DISABLE_VRPN: Disable the VRPN menu (does not appear).
  • HIRERNA_P7_Courses: Setting it at build disables the SMD and HiRE-RNA Contest GUIs.

Collection of ideas, code snippets, suggestions..

Shader debugging?

Multi-button input from device (e.g. joypad) {#multibutton)

(from CG Deer - thanks!)

For multi button inputs I have used the following C# in the past:

1 if(Input.GetButton("Fire2")&& (grabObject!=null)){
2  ...
3  ...
4  }

Where grabObject is defined earlier by a raycast collider hit that moves an object in hierarchy when the user presses the "Fire1" button (and thereby making the "Fire1" + "Fire2" do some function). In this case I was rotating elements in a model.

For the record, while wearing a HMD, reference sheets are restricted to those who know brail, so making the multi button input somewhat intutitive is important. For example if "Fire2" rotates the entire model, and "Fire1" grabs a part of that model, then "Fire1" + "Fire2" makes sense that it would rotate only a part of the model. However, if "Fire1" grabs a part of the model, and "Fire2" resets that piece of the model back to its original position it will not make sense to make a binding of "Fire1"+"Fire2" make a piece rotate.

A way of getting around this is to have a context menu describing what combinations of buttons will do that shows up when the button is held. However, that assumes that the base button does nothing by itself when held as the reference canvas would interfere with any OnButtonDown statements that requires holding the button. However, once the barebones skeleton of the if a and b are held is done, any button can be converted to multibutton input.

General remarks related to coding and development

Project versioning with git

It is preferrable to store the project and all its assets as serialized text documents. This feature can be activated through the Unity3D menu Edit > Project Settings > Editor by setting the field concerning Asset Serialization to Force Text.