UnityMol  0.9.6-875
UnityMol viewer / In developement
AmbientOcclusion.cs
Go to the documentation of this file.
1 
60 using UnityEngine;
61 using System.Collections;
62 using System.Collections.Generic;
63 using Molecule.Model;
64 //using UI;
65 
66 public class AmbientOcclusion {
67  private static GameObject pdb2den;
68  private static PDBtoDEN genDensity;
69  private static float[,,] density;
70  private static float[,,] occlusion;
71  private static BallUpdate[] balls;
72  private static Vector3 delta;
73  private static Vector3 origin = MoleculeModel.MinValue;
74  private static Vector3 fudgeFactor;
75 
76  private static Vector3 inverseDelta ;
77  private static int xDim, yDim, zDim;
78  private static List<Color> originalColors;
79 
80  private static float minDensity = float.MaxValue; // Unused ?
81  private static float maxDensity = -float.MaxValue;
82 
83  public static bool isEnabled = false;
84  public static bool reset = false;
85 
86  private const float faceCoef = 1f;
87  private const float diagCoef = 0.707106781186548f; // 1/sqrt(2)
88  private const float cornerCoef = 0.25f;
89  private const float totalWeightFactor = 1f/(6f*faceCoef + 12f*diagCoef + 8f*cornerCoef);
90 
91  private static bool weighted = true;
92  private static float compensationFactor = 1.30f;
93  //private static float compensationTerm = 0.12f;
94  //private static Color compensationColor = new Color(compensationTerm, compensationTerm, compensationTerm);
95 
96 
113  private static float AverageOfSurroundingCubes(int i, int j, int k) {
114  // j-1 // i-1 // i // i+1
115  float lowerNine = density[i-1, j-1, k-1] + density[i, j-1, k-1] + density[i+1, j-1, k-1] + // k-1
116  density[i-1, j-1, k] + density[i, j-1, k] + density[i+1, j-1, k] + // k
117  density[i-1, j-1, k+1] + density[i, j-1, k+1] + density[i+1, j-1, k+1] ; // k+1
118 
119  // j // i-1 // i // i+1
120  float middleEight = density[i-1, j, k-1] + density[i, j, k-1] + density[i+1, j, k-1] + // k-1
121  density[i-1, j, k] + 0f + density[i+1, j, k] + // k
122  density[i-1, j, k+1] + density[i, j, k+1] + density[i+1, j, k+1] ; // k+1
123 
124  // j+1 // i-1 // i // i+1
125  float upperNine = density[i-1, j+1, k-1] + density[i, j+1, k-1] + density[i+1, j+1, k-1] + // k-1
126  density[i-1, j+1, k] + density[i, j+1, k] + density[i+1, j+1, k] + // k
127  density[i-1, j+1, k+1] + density[i, j+1, k+1] + density[i+1, j+1, k+1] ; // k+1
128 
129  float result = lowerNine + middleEight + upperNine;
130  result /= 26;
131  return result;
132  }
133 
134 
135  private static float WeightedAverageOfSurroundingCubes(int i, int j, int k) {
136  // j-1 // i-1 // i // i+1
137  float lowerNine = cornerCoef * density[i-1, j-1, k-1] + diagCoef * density[i, j-1, k-1] + cornerCoef * density[i+1, j-1, k-1] + // k-1
138  diagCoef * density[i-1, j-1, k] + faceCoef * density[i, j-1, k] + diagCoef * density[i+1, j-1, k] + // k
139  cornerCoef * density[i-1, j-1, k+1] + diagCoef * density[i, j-1, k+1] + cornerCoef * density[i+1, j-1, k+1] ; // k+1
140 
141  // j // i-1 // i // i+1
142  float middleEight = diagCoef * density[i-1, j, k-1] + faceCoef * density[i, j, k-1] + diagCoef * density[i+1, j, k-1] + // k-1
143  faceCoef * density[i-1, j, k] + 0f + faceCoef * density[i+1, j, k] + // k
144  diagCoef * density[i-1, j, k+1] + faceCoef * density[i, j, k+1] + diagCoef * density[i+1, j, k+1] ; // k+1
145 
146  // j+1 // i-1 // i // i+1
147  float upperNine = cornerCoef * density[i-1, j+1, k-1] + diagCoef * density[i, j+1, k-1] + cornerCoef * density[i+1, j+1, k-1] + // k-1
148  diagCoef * density[i-1, j+1, k] + faceCoef * density[i, j+1, k] + diagCoef * density[i+1, j+1, k] + // k
149  cornerCoef * density[i-1, j+1, k+1] + diagCoef * density[i, j+1, k+1] + cornerCoef * density[i+1, j+1, k+1] ; // k+1
150 
151  float result = lowerNine + middleEight + upperNine;
152  result *= totalWeightFactor;
153  return result;
154  }
155 
159  private static void BuildColorList() {
160  originalColors = new List<Color>(MoleculeModel.atomsColorList);
161  }
162 
168  private static void FillFacesWithZeros() {
169  for(int i=0; i<xDim; i++) {
170  for(int j=0; j<yDim; j++) {
171  occlusion[i, j, 0 ] = 0f; // front face
172  occlusion[i, j, zDim-1 ] = 0f; // back face
173  }
174  for(int k=0; k<zDim; k++) {
175  occlusion[i, 0, k ] = 0f; // bottom face
176  occlusion[i, yDim-1, k ] = 0f; // top face
177  }
178  }
179 
180  for(int j=0; j<yDim; j++) {
181  for(int k=0; k<zDim; k++) {
182  occlusion[0, j, k ] = 0f; // left face
183  occlusion[xDim-1, j, k ] = 0f; // right face
184  }
185  }
186  }
187 
192  private static void SetOcclusionGridBounds() {
193  minDensity = float.MaxValue;
194  maxDensity = -float.MaxValue;
195  foreach(float f in density) {
196  if(f < minDensity)
197  minDensity = f;
198  if(f > maxDensity)
199  maxDensity = f;
200  }
201 
202  /*
203  float threshold = maxDensity * 0.3f;
204  foreach(float f in occlusion)
205  if(f > threshold)
206  Debug.Log(f.ToString());
207  */
208 
209  Debug.Log("Density bounds, min and max:");
210  Debug.Log(minDensity.ToString());
211  Debug.Log(maxDensity.ToString());
212  }
213 
217  public AmbientOcclusion () {
218  // First we use PDBtoDen to create a density grid.
219  pdb2den = new GameObject();
220  pdb2den.AddComponent<PDBtoDEN>();
221  genDensity = pdb2den.GetComponent<PDBtoDEN>();
222 
223 
224  float delta_scalar;
225  int moleculeSize = MoleculeModel.atomsLocationlist.Count;
226  if(moleculeSize < 2000)
227  delta_scalar = 0.2f;
228  else if (moleculeSize < 5000)
229  delta_scalar = 0.4f;
230  else if (moleculeSize < 10000)
231  delta_scalar = 0.2f;
232  else
233  delta_scalar = 0.16f;
234  //fudgeFactor = PDBtoDEN.fudgeFactor /delta_scalar; ???
235  delta = new Vector3(delta_scalar, delta_scalar, delta_scalar);
236  genDensity.TranPDBtoDEN(delta_scalar, false);
237  density = PDBtoDEN.GridS;
238  fudgeFactor = PDBtoDEN.fudgeFactor;
239 
240  // We need to refresh the molecule's origin when it's not the first molecule for which we generate a volumetric density.
241  origin = MoleculeModel.MinValue;
242 
243  xDim = density.GetLength(0);
244  yDim = density.GetLength(1);
245  zDim = density.GetLength(2);
246 
247  Debug.Log("Density grid size :");
248  Debug.Log(xDim.ToString());
249  Debug.Log(yDim.ToString());
250  Debug.Log(zDim.ToString());
251 
252  occlusion = new float[xDim, yDim, zDim];
253 
254  for(int i=1; i<(xDim-1); i++)
255  for(int j=1; j<(yDim-1); j++)
256  for(int k=1; k<(zDim-1); k++)
257  if(weighted)
258  occlusion[i,j,k] = WeightedAverageOfSurroundingCubes(i,j,k);
259  else
260  occlusion[i,j,k] = AverageOfSurroundingCubes(i,j,k);
261 
264  balls = GameObject.FindObjectsOfType(typeof(BallUpdate)) as BallUpdate[];
265  BuildColorList();
266  reset = false;
267  }
268 
272  public void Occlude() {
273  int x, y, z;
274  Vector3 position = Vector3.zero;
275  Vector3 indices = Vector3.zero;
276  float colorFactor;
277  Debug.Log(maxDensity.ToString());
278  //float threshold = 0.3f * maxDensity;
279 
280  /*
281  foreach(float f in occlusion) {
282  if(f > threshold)
283  Debug.Log(f.ToString());
284  }
285  */
286  Color color;
287  foreach(BallUpdate bu in balls) {
288  position = bu.transform.position;
289  //indices = Vector3.Scale(delta, (position + fudgeFactor - origin));
290  indices = Vector3.Scale(delta, (position - origin)) + fudgeFactor;
291  /*
292  x = (int) indices.x;
293  y = (int) indices.y;
294  z = (int) indices.z;
295  */
296  x = Mathf.RoundToInt(indices.x);
297  y = Mathf.RoundToInt(indices.y);
298  z = Mathf.RoundToInt(indices.z);
299  colorFactor = (maxDensity - occlusion[x,y,z]) / maxDensity;
300 
301  /*
302  if(occlusion[x,y,z] > threshold) {
303  Debug.Log(occlusion[x,y,z].ToString());
304  Debug.Log(colorFactor.ToString());
305  }
306 
307 
308  //if(colorFactor > 0.1f)
309  //Debug.Log(colorFactor + " - " + maxDensity);
310  */
311  //bu.atomcolor = bu.atomcolor * colorFactor;
312  color = MoleculeModel.atomsColorList[(int)bu.number];
313  color = (color * colorFactor * compensationFactor);// + compensationColor;
314  MoleculeModel.atomsColorList[(int)bu.number] = color;
315  /*
316  Color test = bu.atomcolor;
317  test.a = test.a * (1 - colorFactor);
318  bu.atomcolor = test;
319  */
320  }
321  BallUpdate.resetColors = true;
322  isEnabled = true;
323  }
324 
328  public void Revert() {
329  Debug.Log("AmbientOcclusion: reverting to original colors.");
331  BallUpdate.resetColors = true;
332  isEnabled = false;
333  }
334 }
static void SetOcclusionGridBounds()
Sets the occlusion grid bounds.
static float compensationFactor
void Revert()
Reverts the molecule to its original colors, that is before the Depth Cueing effect was applied...
static bool isEnabled
const float cornerCoef
AmbientOcclusion()
Initializes a new instance of the AmbientOcclusion class.
static Vector3 origin
void TranPDBtoDEN(float resolution=DEFAULT_RESOLUTION, bool cap=true)
Definition: PDBtoDEN.cs:141
static float[,,] density
static void BuildColorList()
Builds the list of the original colors, that is before the Depth Cueing effect is applied...
static float maxDensity
static PDBtoDEN genDensity
void Occlude()
Perfoms the actual Ambient Occlusion operations.
const float faceCoef
static bool weighted
static Vector3 fudgeFactor
static BallUpdate[] balls
static float WeightedAverageOfSurroundingCubes(int i, int j, int k)
static GameObject pdb2den
static bool resetColors
Definition: BallUpdate.cs:73
static float[,,] GridS
Definition: PDBtoDEN.cs:77
const float totalWeightFactor
const float diagCoef
long number
Definition: BallUpdate.cs:84
static Vector3 inverseDelta
static Vector3 delta
static List< Color > atomsColorList
The color of each atom.
static Vector3 fudgeFactor
Definition: PDBtoDEN.cs:90
static void FillFacesWithZeros()
This fills the "faces" of the cube with zeros, because they do not have the necessary number of neigh...
static float AverageOfSurroundingCubes(int i, int j, int k)
Computes the sum of the surrounding cubes.
static Vector3 MinValue
The "smallest" corner of the bounding box that encloses the molecule.
static float[,,] occlusion
static List< Color > originalColors
static List< float[]> atomsLocationlist
The coordinates of each atom.
static float minDensity