00001 using System;
00002 using System.Collections.Generic;
00003 using System.Linq;
00004 using System.Text;
00005 using System.IO;
00006 using Microsoft.Xna.Framework;
00007 using Microsoft.Xna.Framework.Audio;
00008 using Microsoft.Xna.Framework.Content;
00009 using Microsoft.Xna.Framework.GamerServices;
00010 using Microsoft.Xna.Framework.Graphics;
00011 using Microsoft.Xna.Framework.Input;
00012 using Microsoft.Xna.Framework.Media;
00013 using Microsoft.Xna.Framework.Net;
00014 using Microsoft.Xna.Framework.Storage;
00015 using visLU2.Effects;
00016 using Microsoft.Xna.Framework.Graphics.PackedVector;
00017
00018 namespace visLU2
00019 {
00023 class Data : DrawableGameComponent
00024 {
00025
00026 private RenderTarget2D frontTarget;
00027 private RenderTarget2D backTarget;
00028 private RenderTarget2D screenShotTarget;
00029 private ResolveTexture2D backBuffer_resolved;
00030 private Vector3 stepSize;
00031 private Vector4 scaleFactor;
00032 private int iterations;
00033 private float scaleSteps = 1.0f;
00034
00035 public float slice = 0.5f;
00036
00037
00038 private List<TransferControlPoint> colorControlPoints;
00039 private List<TransferControlPoint> alphaControlPoints;
00040 private Texture2D transferTexture;
00041 private Texture2D transferTextureAlpha;
00042
00043 private List<float> densityValues;
00044 private float[] densityArray;
00045 private float[] distinctDensityValuesArray;
00046 private int[] countDensityValuesArray;
00047
00048 private Vector3[] gradients;
00049
00050 private Matrix worldMatrix;
00051
00052
00053
00054
00055 UInt32 sizeX, sizeY, sizeZ;
00056
00057 private UInt16[][][] data;
00058
00059 public VolumeShader shader;
00060
00061 private String fileName;
00062
00063 private Texture3D volumeData;
00064 private Texture2D frontFaces;
00065
00066 private Model cube;
00067
00068
00069 int texturesSaved = 0;
00070 GraphicsDevice device;
00071
00072
00073
00074 private Camera camera;
00075 private int currentView = 0;
00076
00077 #region Properties
00078 public Camera Camera
00079 {
00080 set { camera = value; }
00081 }
00082 public int CurrentCamera
00083 {
00084 set { currentView = value; }
00085 }
00086 #endregion
00087 #region Constructor
00088
00089
00090
00091
00092
00093 public Data(string _fileName, Game game) : base(game)
00094 {
00095 worldMatrix = Matrix.Identity;
00096
00097 string a = "" + Directory.GetParent((string) Directory.GetCurrentDirectory());
00098 string b = "" + Directory.GetParent(a);
00099 string c = "" + Directory.GetParent(b);
00100
00101 this.fileName = c + "\\"+_fileName;
00102
00103 if (string.IsNullOrEmpty(fileName))
00104 {
00105 throw new ArgumentNullException(fileName);
00106 }
00107
00108 if (!File.Exists(fileName))
00109 {
00110 Console.WriteLine(fileName);
00111 throw new ArgumentException("file not found: "+ fileName);
00112 }
00113
00114 }
00115 #endregion
00116
00117 #region Initialize()
00118
00119
00125 public override void Initialize()
00126 {
00127 base.Initialize();
00128 this.LoadContent();
00129 }
00130
00131 #endregion
00132
00133 #region LoadContent
00134
00135
00136
00137
00138
00139 protected override void LoadContent()
00140 {
00141 device = Game.GraphicsDevice;
00142 PresentationParameters param = Game.GraphicsDevice.PresentationParameters;
00143 SurfaceFormat format = param.BackBufferFormat;
00144 int width = device.PresentationParameters.BackBufferWidth;
00145 int height = device.PresentationParameters.BackBufferHeight;
00146
00147 frontTarget = new RenderTarget2D(device, width, height, 1, format,
00148 device.DepthStencilBuffer.MultiSampleType,
00149 device.PresentationParameters.MultiSampleQuality);
00150
00151 backTarget = new RenderTarget2D(device, width, height, 1, format,
00152 device.DepthStencilBuffer.MultiSampleType,
00153 device.PresentationParameters.MultiSampleQuality);
00154
00155 screenShotTarget = new RenderTarget2D(device, width, height, 1, format,
00156 device.DepthStencilBuffer.MultiSampleType,
00157 device.PresentationParameters.MultiSampleQuality);
00158
00159
00160
00161 #region check format
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 format = SurfaceFormat.Vector4;
00178 #endregion
00179
00180 if (Game.GraphicsDevice.GraphicsDeviceCapabilities.TextureCapabilities.RequiresPower2)
00181 {
00182 loadDatafromFileExtend();
00183
00184 }
00185 else
00186 {
00187 loadDatafromFile();
00188 }
00189
00190
00191
00192 float max = (float)Math.Max(sizeX, Math.Max(sizeY, sizeZ));
00193 stepSize = Vector3.One/max;
00194 Console.WriteLine(stepSize);
00195
00196 Matrix rotate;
00197 if(GameProperties.Instance.dataFilename.StartsWith("skewed_head"));
00198 {
00199 rotate = Matrix.CreateRotationZ(90.0f);
00200 }
00201 worldMatrix = Matrix.CreateTranslation(new Vector3(-(sizeX / max) / 2.0f,
00202 -(sizeY / max) / 2.0f,
00203 -(sizeZ / max) / 2.0f));
00204
00205
00206
00207
00208
00209 iterations = (int)(max * (1.0f / scaleSteps));
00210
00211
00212 Vector3 sizeVector = new Vector3(sizeX, sizeY, sizeZ);
00213 Vector3 scale = Vector3.One / ( (Vector3.One * max)/sizeVector );
00214 scaleFactor = new Vector4(scale.X, scale.Y, scale.Z, 1.0f);
00215
00216
00217 cube = Game.Content.Load<Model>("Models/box");
00218
00219 shader = new VolumeShader(Game, device, Game.Content.Load<Effect>("Effects\\volumeShader"));
00220 shader.SetEffectParameter(volumeData, stepSize * scaleSteps, iterations, 0, scaleFactor, slice);
00221
00222
00223 colorControlPoints = GameProperties.Instance.colorControlPoints;
00224 alphaControlPoints = GameProperties.Instance.alphaControlPoints;
00225
00226
00227 setSliceRange((int)sizeX, (int)sizeY, (int)sizeZ);
00228 base.LoadContent();
00229 }
00230
00240 private void loadDatafromFile()
00241 {
00242 #region read data
00243 Stream file = new FileStream(fileName, FileMode.Open);
00244
00245 string a = "" + Directory.GetParent((string)Directory.GetCurrentDirectory());
00246 string b = "" + Directory.GetParent(a);
00247 string c = "" + Directory.GetParent(b);
00248
00249 string fileName2 = c + "\\" + "Data\\skewed_head.dat";
00250 Stream file2 = new FileStream(fileName2, FileMode.Open);
00251
00252
00253 BinaryReader reader = new BinaryReader(file);
00254 BinaryReader reader2 = new BinaryReader(file2);
00255
00256
00257 sizeX = reader.ReadUInt16();
00258 sizeY = reader.ReadUInt16();
00259 sizeZ = reader.ReadUInt16();
00260
00261 var sizeX2 = reader2.ReadUInt16();
00262 var sizeY2 = reader2.ReadUInt16();
00263 var sizeZ2 = reader2.ReadUInt16();
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 UInt32[] buffer = new UInt32[sizeX * sizeY * sizeZ];
00274
00275
00276 List<byte> extend = new List<byte>();
00277
00278 #region debug
00279 long streamSize = reader.BaseStream.Length;
00280 uint bufferSize = (sizeX * sizeY * sizeZ) * 2;
00281 int diff = (int)(streamSize - bufferSize);
00282 List<int> index = new List<int>();
00283 #endregion
00284
00285 int j = 0;
00286 while (reader.BaseStream.Position < reader.BaseStream.Length)
00287 {
00288 if (j >= buffer.Length)
00289 {
00290 extend.Add(reader.ReadByte());
00291 }
00292 else
00293 {
00294 var dat1 = reader.ReadUInt16();
00295 var dat2 = reader2.ReadUInt16();
00296 if (dat1 != dat2)
00297 {
00298 buffer[j] = dat1;
00299 index.Add(j);
00300 }
00301 else
00302 {
00303 buffer[j] = dat1;
00304 }
00305 }
00306 j++;
00307 }
00308 reader.Close();
00309 reader2.Close();
00310
00311
00312 #endregion
00313
00314 #region scale data
00315
00316 densityValues = new List<float>();
00317 float maxValue = 1.0f/buffer.Max();
00318 for (int i = 0; i < buffer.Length; i++)
00319 {
00320 densityValues.Add((float)buffer[i] * maxValue);
00321 }
00322 #endregion
00323
00324 GameProperties.Instance.dataOrigin = new Vector3(0.5f, 0.5f, sizeZ / 2.0f);
00325
00326 #region add gradients to VolumeData
00327 calculateGradients();
00328
00329
00330 Vector4[] densityVectors = new Vector4[buffer.Length];
00331 int k = 0;
00332 for (int i = 0; i < buffer.Length; i++)
00333 {
00334 if (k < index.Count)
00335 {
00336 if (i == index[k])
00337 {
00338 densityVectors[i] = new Vector4(gradients[i].X,
00339 gradients[i].Y,
00340 gradients[i].Z,
00341 densityValues[i]);
00342 k++;
00343 }
00344 else
00345 {
00346 densityVectors[i] = new Vector4(0.0f,
00347 0.0f,
00348 0.0f,
00349 0.0f);
00350 }
00351 }
00352 else
00353 {
00354 densityVectors[i] = new Vector4(0.0f,
00355 0.0f,
00356 0.0f,
00357 0.0f);
00358 }
00359 }
00360 #endregion
00361
00362 densityArray = densityValues.ToArray();
00363
00364
00365 volumeData = new Texture3D(Game.GraphicsDevice, (int)sizeX, (int)sizeY, (int)sizeZ, 0,
00366 TextureUsage.Linear, SurfaceFormat.Vector4);
00367
00368 volumeData.SetData<Vector4>(densityVectors);
00369
00370 #region sort data
00371 densityValues.Sort();
00372 sortDensityValues();
00373
00374
00375
00376
00377
00378 #endregion
00379
00380 #region setColorPoints
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 #endregion
00408 }
00409
00410
00417 private void sortDensityValues()
00418 {
00419
00420 List<float> distinctDensityValues = new List<float>();
00421 List<int> countDensityValues = new List<int>();
00422
00423 #region debug
00424
00425
00426
00427 #endregion
00428
00429 for (int i = 0; i < densityValues.Count(); i++)
00430 {
00431 int value1 = (int)(densityValues[i] * 255);
00432 int count = 1;
00433
00434 while (i < (densityValues.Count() - 1))
00435 {
00436 int value2 = (int)(densityValues[i + 1] * 255);
00437 if ((value1 == value2))
00438 {
00439 count++;
00440 i++;
00441 }
00442 else
00443 {
00444 break;
00445 }
00446
00447 }
00448
00449 #region debug
00450
00451
00452
00453 #endregion
00454
00455 distinctDensityValues.Add(value1);
00456 countDensityValues.Add(count);
00457
00458 }
00459 distinctDensityValuesArray = distinctDensityValues.ToArray();
00460 countDensityValuesArray = countDensityValues.ToArray();
00461
00462 GameProperties.Instance.distinctDensityValues = distinctDensityValuesArray;
00463 GameProperties.Instance.countDensityValues = countDensityValuesArray;
00464
00465 }
00466
00467 #endregion
00468
00469 public void UnloadContent()
00470 {
00471
00472 this.volumeData.Dispose();
00473 if (this.volumeData.IsDisposed)
00474 {
00475 Console.WriteLine("free memory");
00476 }
00477 }
00484 public override void Update(GameTime gameTime)
00485 {
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 Game.GraphicsDevice.RenderState.AlphaBlendEnable = false;
00501 shader.CurrentTechnique = shader.Techniques["RenderPosition"];
00502 shader.SetEffectParameter(worldMatrix*camera.ViewProjection, worldMatrix);
00503 shader.SetEffectParameter(camera.CameraPosition);
00504
00505
00506 Game.GraphicsDevice.SetRenderTarget(0, frontTarget);
00507 Game.GraphicsDevice.Clear(Color.Black);
00508 GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
00509
00510 DrawVolume(gameTime, 0);
00511
00512 Game.GraphicsDevice.SetRenderTarget(0, null);
00513
00514
00515 Game.GraphicsDevice.SetRenderTarget(0, backTarget);
00516 Game.GraphicsDevice.Clear(Color.Black);
00517 GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
00518
00519 DrawVolume(gameTime, 1);
00520
00521 Game.GraphicsDevice.SetRenderTarget(0, null);
00522 Game.GraphicsDevice.Clear(Color.Black);
00523 shader.FrontFacesTexture = frontTarget.GetTexture();
00524 shader.BackFacesTexture = backTarget.GetTexture();
00525
00526 #region debug
00527
00528
00529
00530
00531
00532
00533 #endregion
00534
00535 setControlpoints();
00536
00537 base.Update(gameTime);
00538 }
00544 public override void Draw(GameTime gameTime)
00545 {
00546 if (currentView == 1)
00547 {
00548 slice = GameProperties.Instance.ySliceValue;
00549 shader.CurrentTechnique = shader.Techniques["RenderSlice"];
00550 }
00551 else if (currentView == 2)
00552 {
00553 slice = GameProperties.Instance.xSliceValue;
00554 shader.CurrentTechnique = shader.Techniques["RenderSlice"];
00555 }
00556 else if (currentView == 3)
00557 {
00558 slice = GameProperties.Instance.zSliceValue;
00559 shader.CurrentTechnique = shader.Techniques["RenderSlice"];
00560 }
00561 else
00562 {
00563
00564 if (GameProperties.Instance.maximumIntensityProjection == true)
00565 {
00566 shader.CurrentTechnique = shader.Techniques["MaximumIntensity"];
00567 }
00568 else
00569 {
00570 shader.CurrentTechnique = shader.Techniques["RayCastSimple"];
00571 }
00572 }
00573
00574
00575
00576
00577
00578
00579 Game.GraphicsDevice.RenderState.AlphaBlendEnable = false;
00580
00581
00582
00583
00584 #region depricated : do we need it!?
00585
00586
00587
00588
00589
00590
00591 #endregion
00592
00593 #region save screenshot
00594 if (GameProperties.Instance.saveView)
00595 {
00596 if (string.IsNullOrEmpty(GameProperties.Instance.saveFilename))
00597 {
00598 throw new ArgumentNullException(GameProperties.Instance.saveFilename);
00599 }
00600 Game.GraphicsDevice.SetRenderTarget(0, screenShotTarget);
00601 Game.GraphicsDevice.Clear(Color.Black);
00602 GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
00603
00604 DrawVolume(gameTime, currentView);
00605
00606 Game.GraphicsDevice.SetRenderTarget(0, null);
00607 Texture2D saveTex = screenShotTarget.GetTexture();
00608 saveTex.Save(GameProperties.Instance.saveFilename, ImageFileFormat.Jpg);
00609
00610
00611 GameProperties.Instance.saveView = false;
00612 }
00613 #endregion
00614
00615
00616 GraphicsDevice.RenderState.CullMode = CullMode.None;
00617
00618
00619 DrawVolume(gameTime, currentView);
00620
00621
00622 }
00623
00629 private void DrawVolume(GameTime gameTime, int side)
00630 {
00631 #region draw cube
00632
00633
00634
00635 foreach (ModelMesh mesh in cube.Meshes)
00636 {
00637 foreach (ModelMeshPart mmp in mesh.MeshParts)
00638 {
00639 mmp.Effect = shader;
00640 shader.SetEffectParameter(volumeData, stepSize * scaleSteps, iterations, side, scaleFactor, slice);
00641 shader.SetEffectParameter(camera.CameraPosition);
00642 };
00643
00644
00645 mesh.Draw();
00646
00647 }
00648 #endregion
00649 }
00650
00655 private void DrawCoordinateSystem(GameTime gameTime)
00656 {
00657
00658 #region coordinate system
00659
00660 BasicEffect basicEffect = new BasicEffect(device, null);
00661 device.RenderState.DepthBufferEnable = false;
00662 device.VertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
00663
00664 basicEffect.LightingEnabled = false;
00665 basicEffect.TextureEnabled = false;
00666 basicEffect.VertexColorEnabled = true;
00667 basicEffect.World = Matrix.Identity;
00668 basicEffect.Projection = camera.Projection;
00669 basicEffect.View = camera.View;
00670
00671 basicEffect.Begin();
00672 foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
00673 {
00674 pass.Begin();
00675 VertexPositionColor[] pointList = {
00676
00677 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkBlue),
00678 new VertexPositionColor(new Vector3(0.0f, 0.0f, -3000.0f), Color.DarkBlue),
00679 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Blue),
00680 new VertexPositionColor(new Vector3(0.0f, 0.0f, 3000.0f), Color.Blue),
00681
00682 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkGreen),
00683 new VertexPositionColor(new Vector3(0.0f, -3000.0f, 0.0f), Color.DarkGreen),
00684 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Green),
00685 new VertexPositionColor(new Vector3(0.0f, 3000.0f, 0.0f), Color.Green),
00686
00687 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.DarkRed),
00688 new VertexPositionColor(new Vector3(-3000.0f, 0.0f, 0.0f), Color.DarkRed),
00689 new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.Red),
00690 new VertexPositionColor(new Vector3(3000.0f, 0.0f, 0.0f), Color.Red),
00691
00692 new VertexPositionColor(new Vector3(10.0f + 2.5f, 5.0f, 0.0f), Color.DarkRed),
00693 new VertexPositionColor(new Vector3(10.0f + 1.25f, 1.25f, 0.0f), Color.DarkRed),
00694 new VertexPositionColor(new Vector3(10.0f + 1.25f, 5.0f, 0.0f), Color.DarkRed),
00695 new VertexPositionColor(new Vector3(10.0f + 2.5f, 1.25f, 0.0f), Color.DarkRed),
00696
00697 new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
00698 new VertexPositionColor(new Vector3(1.875f, 10.0f + 1.125f, 0.0f), Color.DarkGreen),
00699 new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
00700 new VertexPositionColor(new Vector3(2.5f, 10.0f + 5.0f, 0.0f), Color.DarkGreen),
00701 new VertexPositionColor(new Vector3(1.875f, 10.0f + 3.125f, 0.0f), Color.DarkGreen),
00702 new VertexPositionColor(new Vector3(1.125f, 10 + 5.0f, 0.0f), Color.DarkGreen),
00703
00704 new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 2.5f), Color.DarkBlue),
00705 new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 1.25f), Color.DarkBlue),
00706 new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 2.5f), Color.DarkBlue),
00707 new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 1.25f), Color.DarkBlue),
00708 new VertexPositionColor(new Vector3(0.0f, 1.25f, 10.0f + 2.5f), Color.DarkBlue),
00709 new VertexPositionColor(new Vector3(0.0f, 5.0f, 10.0f + 1.25f), Color.DarkBlue)
00710
00711 };
00712 short[] lineListIndices = new short[28] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 };
00713 Game.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
00714 PrimitiveType.LineList,
00715 pointList,
00716 0,
00717 28,
00718 lineListIndices,
00719 0,
00720 14
00721 );
00722 pass.End();
00723 }
00724 basicEffect.End();
00725 device.RenderState.DepthBufferEnable = true;
00726 #endregion
00727 }
00728
00729 #region transfer function
00730
00731
00732
00733
00734 private void setControlpoints()
00735 {
00736
00737 if (GameProperties.Instance.colorControlPoints == null || GameProperties.Instance.colorControlPoints.Count() == 0
00738 || GameProperties.Instance.alphaControlPoints == null || GameProperties.Instance.alphaControlPoints.Count() == 0)
00739 {
00740 TransferControlPoint cp1 = new TransferControlPoint(0.0f, 0.0f, 0.0f, 0);
00741 TransferControlPoint cp2 = new TransferControlPoint(1.0f, 0.0f, 0.0f, 80);
00742 TransferControlPoint cp3 = new TransferControlPoint(0.0f, 1.0f, 0.0f, 128);
00743 TransferControlPoint cp4 = new TransferControlPoint(0.0f, 0.0f, 0.0f, 255);
00744
00745 GameProperties.Instance.colorControlPoints.Add(cp1);
00746 GameProperties.Instance.colorControlPoints.Add(cp2);
00747 GameProperties.Instance.colorControlPoints.Add(cp3);
00748 GameProperties.Instance.colorControlPoints.Add(cp4);
00749 GameProperties.Instance.alphaControlPoints.Add(new TransferControlPoint(0.0f, 0));
00750 GameProperties.Instance.alphaControlPoints.Add(new TransferControlPoint(0.5f, 80));
00751 GameProperties.Instance.alphaControlPoints.Add(new TransferControlPoint(0.5f, 128));
00752 GameProperties.Instance.alphaControlPoints.Add(new TransferControlPoint(0.0f, 255));
00753 }
00754
00755
00756 colorControlPoints = GameProperties.Instance.colorControlPoints;
00757 alphaControlPoints = GameProperties.Instance.alphaControlPoints;
00758
00759 #region debug
00760
00761
00762 #endregion
00763
00764 float amount = 0.0f;
00765 Color[] colorArray = new Color[256];
00766 float[] alphaArray = new float[256];
00767
00768 #region interpolate between ControlPoints
00769
00770
00771 colorControlPoints.Sort(delegate(TransferControlPoint p1,
00772 TransferControlPoint p2) { return p1.isoValue.CompareTo(p2.isoValue); });
00773 alphaControlPoints.Sort(delegate(TransferControlPoint p1,
00774 TransferControlPoint p2) { return p1.isoValue.CompareTo(p2.isoValue); });
00775
00776
00777
00778
00779
00780
00781
00782
00783 for (int i = 0; i < colorControlPoints[0].isoValue; i++)
00784 {
00785 colorArray[i] = Color.Black;
00786 alphaArray[i] = 0.0f;
00787 }
00788
00789 for (int j = 0; j < colorControlPoints.Count-1; j++)
00790 {
00791 for (int i = colorControlPoints[j].isoValue; i < colorControlPoints[j+1].isoValue; i++)
00792 {
00793 amount = (((float)i - colorControlPoints[j].isoValue) /
00794 (colorControlPoints[j+1].isoValue - colorControlPoints[j].isoValue));
00795 colorArray[i] = Color.Lerp(new Color(colorControlPoints[j].color * 255),
00796 new Color(colorControlPoints[j+1].color * 255), amount);
00797
00798
00799 alphaArray[i] = alphaControlPoints[j].color.W * (1.0f - amount) +
00800 alphaControlPoints[j + 1].color.W * amount;
00801 }
00802 }
00803
00804
00805 for (int i = colorControlPoints[colorControlPoints.Count-1].isoValue+1; i < 256; i++)
00806 {
00807 colorArray[i] = Color.Black;
00808 alphaArray[i] = 0.0f;
00809 }
00810
00811 GameProperties.Instance.colorArray = colorArray;
00812 GameProperties.Instance.alphaArray = alphaArray;
00813 GameProperties.Instance.updateColorBar = true;
00814
00815 #endregion
00816
00817 #region write to textures
00818
00819 transferTexture = new Texture2D(Game.GraphicsDevice, 256, 1, 1, TextureUsage.Linear, SurfaceFormat.Color);
00820 transferTextureAlpha = new Texture2D(Game.GraphicsDevice, 256, 1, 1, TextureUsage.Linear, SurfaceFormat.Color);
00821
00822
00823 Byte4[] transferValues = new Byte4[256];
00824 Byte4[] alphaValues = new Byte4[256];
00825 for (int i = 0; i < 256; i++)
00826 {
00827
00828 Vector4 color = new Vector4(colorArray[i].R, colorArray[i].G, colorArray[i].B, alphaArray[i]);
00829 color *= 255.0f;
00830
00831 transferValues[i] = new Byte4(color.Z, color.Y, color.X, color.W);
00832 Vector4 alpha = new Vector4(alphaArray[i]*255.0f);
00833
00834 if ((i < 5) || (i > 250))
00835 {
00836 alpha = new Vector4(255.0f, 0.0f, 0.0f, 1.0f);
00837 }
00838 alphaValues[i] = new Byte4(alpha.Z, alpha.Y, alpha.X, alpha.W);
00839 }
00840
00841 transferTexture.SetData(transferValues);
00842 transferTextureAlpha.SetData(alphaValues);
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 #endregion
00855
00856 shader.TransferTexture = this.transferTexture;
00857 shader.TransferTextureAlpha = this.transferTextureAlpha;
00858
00859
00860
00861
00862
00863 }
00864
00865 #endregion
00866
00867 #region Gradients
00868
00876 private float getSampleAt(int x, int y, int z)
00877 {
00878 x = (int)MathHelper.Clamp(x, 0, sizeX - 1);
00879 y = (int)MathHelper.Clamp(y, 0, sizeY - 1);
00880 z = (int)MathHelper.Clamp(z, 0, sizeZ - 1);
00881
00882
00883
00884 int arrayIndex = x + y * (int)sizeX + z * (int)sizeX * (int)sizeY;
00885
00886
00887
00888
00889
00890 return densityValues[arrayIndex];
00891
00892
00893 }
00894
00902 private void calculateGradients()
00903 {
00904
00905
00906
00907
00908
00909
00910 int sampleSize = GameProperties.Instance.gradientSampleSize;
00911
00912 gradients = new Vector3[sizeX * sizeY * sizeZ];
00913
00914 Vector3 normal = Vector3.Zero;
00915
00916 int i = 0;
00917 for (int z = 0; z < sizeZ; z++)
00918 {
00919 for (int y = 0; y < sizeY; y++)
00920 {
00921 for (int x = 0; x < sizeX; x++)
00922 {
00923 Vector3 gradient = new Vector3(
00924 getSampleAt(x + sampleSize, y, z) - getSampleAt(x - sampleSize, y, z),
00925 getSampleAt(x, y + sampleSize, z) - getSampleAt(x, y - sampleSize, z),
00926 getSampleAt(x, y, z + sampleSize) - getSampleAt(x, y, z - sampleSize));
00927
00928
00929
00930 gradients[i] = gradient;
00931 i++;
00932 }
00933 }
00934 }
00935 }
00936
00937 #endregion
00938
00939 #region help functions
00940
00941
00942
00943
00944 private void loadDatafromFileExtend()
00945 {
00946 #region read data
00947 Stream file = new FileStream(fileName, FileMode.Open);
00948
00949 BinaryReader reader = new BinaryReader(file);
00950
00951
00952 sizeX = reader.ReadUInt16();
00953 sizeY = reader.ReadUInt16();
00954 sizeZ = reader.ReadUInt16();
00955 ushort sizeXOld = (ushort)sizeX;
00956 ushort sizeYOld = (ushort)sizeY;
00957 ushort sizeZOld = (ushort)sizeZ;
00958
00959 sizeX = calculatePowerOfTwo((int)sizeX);
00960 sizeY = calculatePowerOfTwo((int)sizeY);
00961 sizeZ = calculatePowerOfTwo((int)sizeZ);
00962
00963
00964
00965 List<float> scalars = new List<float>();
00966
00967 volumeData = new Texture3D(Game.GraphicsDevice, (int)sizeX, (int)sizeY, (int)sizeZ, 0,
00968 TextureUsage.Linear, SurfaceFormat.Vector4);
00969 for (int idxZ = 0; idxZ < sizeZ; idxZ++)
00970 {
00971 for (int idxY = 0; idxY < sizeY; idxY++)
00972 {
00973 for (int idxX = 0; idxX < sizeX; idxX++)
00974 {
00975 if (idxX >= sizeXOld || idxY >= sizeYOld || idxZ >= sizeZOld)
00976 {
00977 scalars.Add(0.0f);
00978
00979 }
00980 else
00981 {
00982 ushort value = reader.ReadUInt16();
00983 scalars.Add((float)value);
00984
00985 }
00986 }
00987 }
00988 }
00989
00990 reader.Close();
00991 #endregion
00992
00993 #region scale data
00994 float maxVal = 1.0f / scalars.Max();
00995 for (int i = 0; i < scalars.Count(); i++)
00996 {
00997 scalars[i] = scalars[i] * maxVal;
00998 }
00999 #endregion
01000
01001 #region add gradients to VolumeData
01002 densityValues = scalars;
01003
01004 calculateGradients();
01005 Vector4[] densityVectors = new Vector4[scalars.Count()];
01006 for (int i = 0; i < scalars.Count(); i++)
01007 {
01008 densityVectors[i] = new Vector4(gradients[i].X,
01009 gradients[i].Y,
01010 gradients[i].Z,
01011 densityValues[i]);
01012 }
01013 volumeData.SetData<Vector4>(densityVectors);
01014 #endregion
01015
01016 #region sort data
01017 densityValues.Sort();
01018 sortDensityValues();
01019 #endregion
01020
01021 }
01022
01029 private ushort calculatePowerOfTwo(int value)
01030 {
01031
01032 if (value > 0)
01033 {
01034 if ((value & (value - 1)) == 0) return (ushort)value;
01035
01036
01037 else
01038 {
01039 value--;
01040 for (int i = 1; i < sizeof(int) * 8; i <<= 1)
01041 {
01042 value = value | value >> 1;
01043 }
01044
01045 ushort returnValue = (ushort)(value + 1);
01046 return returnValue;
01047 }
01048 }
01049 else
01050 {
01051 return 1;
01052 }
01053 }
01054
01055 private void setSliceRange(int xRange, int yRange, int zRange)
01056 {
01057 GameProperties.Instance.xDataRange = xRange;
01058 GameProperties.Instance.yDataRange = yRange;
01059 GameProperties.Instance.zDataRange = zRange;
01060 GameProperties.Instance.updateGuiForm = true;
01061 }
01062 #endregion
01063 }
01064 }