source: branches/HeuristicLab.BinPacking/PackingPlanVisualizations/3D/PackingGame.cs @ 13497

Last change on this file since 13497 was 13497, checked in by gkronber, 5 years ago

#1966: fixed various problems: bugs in cloning, bugs in persistence, method names, various minor improvements of source code for readability.

File size: 10.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing.Printing;
24using System.Windows.Forms;
25using SharpDX;
26using SharpDX.Direct3D11;
27using SharpDX.Toolkit;
28using SharpDX.Toolkit.Graphics;
29using SharpDX.Toolkit.Input;
30
31using ButtonStateDX = SharpDX.Toolkit.Input.ButtonState;
32
33
34namespace PackingPlanVisualizations {
35  public class PackingGame : Game {
36
37
38    #region Global Private Variables
39    private GraphicsDeviceManager graphicsDeviceManager;
40    private PackingPlan3D control;
41    private Matrix worldMatrix;
42    private Matrix viewMatrix;
43    private Matrix projectionMatrix;
44    private float zoom = 50;
45    private int selectedItemIndex = -1;
46
47    private BasicEffect basicEffect;
48    private Color backgroundColor { get; set; }
49
50    private CenteredContainer container;
51    private MouseManager Mouse;
52    #endregion Global Private Variables
53
54    protected override void Dispose(bool disposeManagedResources) {
55      control.disposedByGame = true;
56      base.Dispose(disposeManagedResources);
57      control.disposedByGame = false;
58    }
59
60
61    public PackingGame(PackingPlan3D control)
62      : base() {
63      this.control = control;
64      graphicsDeviceManager = new GraphicsDeviceManager(this);
65      graphicsDeviceManager.PreferMultiSampling = true;
66      graphicsDeviceManager.PreparingDeviceSettings +=
67        (object sender, PreparingDeviceSettingsEventArgs e) => {
68          e.GraphicsDeviceInformation.PresentationParameters.MultiSampleCount = MSAALevel.X4;         
69          return;
70        };
71      var controlColor = Color.White; // System.Drawing.SystemColors.Control;
72      backgroundColor = new Color(controlColor.R, controlColor.G, controlColor.B, controlColor.A);
73
74      Mouse = new MouseManager(this);
75    }
76
77    public void SetSize(int width, int height) {
78
79      graphicsDeviceManager.PreferredBackBufferHeight = height;
80      graphicsDeviceManager.PreferredBackBufferWidth = width;
81    }
82
83
84
85    public void InitializeContainer(BasicCuboidShape containerShape) {
86      container = new CenteredContainer(containerShape);
87    }
88    public void InitializeContainer(float width, float height, float depth) {
89      InitializeContainer(new BasicCuboidShape(new Vector3(width, height, depth), -1));
90    }
91
92    public void AddItemToContainer(float width, float height, float depth, float x, float y, float z, int index, int material) {
93      container.AddPackingItem(new Vector3(width, height, depth), new Vector3(x, y, z), index, material);
94    }
95
96    public void SelectItem(int itemIndex) {
97      selectedItemIndex = itemIndex;
98    }
99    public void UnselectItem() {
100      selectedItemIndex = -1;
101    }
102
103
104    protected override void Initialize() {
105      base.Initialize();
106      InitializeWorld();
107      previousMouseState = Mouse.GetState();
108      Console.WriteLine("Initial bounds:" + Window.ClientBounds);
109      this.Window.IsMouseVisible = true;
110    }
111    private void InitializeWorld() {
112      #region Matrix-Initialization
113      worldMatrix = Matrix.Identity;
114
115      viewMatrix = Matrix.LookAtLH(
116          new Vector3(0, 10, zoom),
117          Vector3.Zero,
118          Vector3.UnitY);
119
120      projectionMatrix = Matrix.PerspectiveFovLH(
121          (float)Math.PI / 6.0f,
122          (float)GraphicsDevice.BackBuffer.Width /
123          (float)GraphicsDevice.BackBuffer.Height,
124          1.0f, 1000.0f);
125      #endregion Matrix-Initialization
126
127      #region Effect and Color
128      //Effect initialization
129      basicEffect = new BasicEffect(GraphicsDevice);
130      basicEffect.World = worldMatrix;
131      basicEffect.View = viewMatrix;
132      basicEffect.Projection = projectionMatrix;
133
134      //Primitive color
135      basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
136      basicEffect.DiffuseColor = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
137      basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
138      basicEffect.SpecularPower = 5.0f;
139      basicEffect.Alpha = 1.0f;
140      basicEffect.VertexColorEnabled = true;
141      #endregion Effect-World and Color
142
143      #region World lighting
144      basicEffect.LightingEnabled = true;
145
146      basicEffect.PreferPerPixelLighting = true;
147
148      if (basicEffect.LightingEnabled) {
149        basicEffect.DirectionalLight0.Enabled = true; // enable each light individually
150        if (basicEffect.DirectionalLight0.Enabled) {
151          // x direction
152          basicEffect.DirectionalLight0.DiffuseColor = new Vector3(1, 1, 1); // range is 0 to 1
153          basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(-1, 0, 0));
154          // points from the light to the origin of the scene
155          basicEffect.DirectionalLight0.SpecularColor = Vector3.One;
156        }
157
158        basicEffect.DirectionalLight1.Enabled = true;
159        if (basicEffect.DirectionalLight1.Enabled) {
160          // y direction
161          basicEffect.DirectionalLight1.DiffuseColor = new Vector3(1, 1, 1);
162          basicEffect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(0, -1, 0));
163          basicEffect.DirectionalLight1.SpecularColor = Vector3.One;
164        }
165
166        basicEffect.DirectionalLight2.Enabled = true;
167        if (basicEffect.DirectionalLight2.Enabled) {
168          // z direction
169          basicEffect.DirectionalLight2.DiffuseColor = new Vector3(1, 1, 1);
170          basicEffect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(0, 0, -1));
171          basicEffect.DirectionalLight2.SpecularColor = Vector3.One;
172        }
173      }
174      #endregion World lighting
175
176      #region Transparency
177
178      BlendStateDescription blendStateDescription = new SharpDX.Direct3D11.BlendStateDescription();
179      blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
180      blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
181      blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
182      blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add;
183      blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.One;
184      blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
185      blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
186      blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
187      SharpDX.Toolkit.Graphics.BlendState blendState = SharpDX.Toolkit.Graphics.BlendState.New(GraphicsDevice, blendStateDescription);
188      GraphicsDevice.SetBlendState(blendState);
189
190      #endregion
191    }
192
193
194    protected override void LoadContent() {
195
196    }
197
198    protected override void Draw(GameTime gameTime) {
199      GraphicsDevice.Clear(backgroundColor);
200
201      worldMatrix =
202        Matrix.RotationY(MathUtil.DegreesToRadians(-currentViewAngle.X * control.Width / 4)) *
203        Matrix.RotationX(MathUtil.DegreesToRadians(currentViewAngle.Y * control.Height / 4));
204      basicEffect.World = worldMatrix;
205
206      viewMatrix = Matrix.LookAtLH(
207          new Vector3(0, zoom, zoom),
208          Vector3.Zero,
209          Vector3.UnitY);
210      basicEffect.View = viewMatrix;
211
212      foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) {
213        pass.Apply();
214
215        if (container != null) {
216          if (container.PackingItems.Count == 0)
217            container.Container.RenderShapeTrianglesAndLines(GraphicsDevice);
218          else {
219            container.Container.RenderShapeLines(GraphicsDevice, new Color(0, 0, 0));
220            var selectedItem = container.PackingItems.Find(x => x.ShapeID == selectedItemIndex);
221            foreach (BasicCuboidShape item in container.PackingItems) {
222              if (selectedItem == null || selectedItemIndex == item.ShapeID) {
223                item.RenderShapeLines(GraphicsDevice);
224                item.RenderShapeTriangles(GraphicsDevice);
225              } else
226                item.RenderShapeLines(GraphicsDevice, new Color(0, 0, 0));
227            }
228          }
229        }
230      }
231
232      base.Draw(gameTime);
233    }
234
235    protected override void Update(GameTime gameTime) {
236      ComputeMouseHandling();
237      base.Update(gameTime);
238    }
239    #region Mouse-Handling Variables
240    private MouseState previousMouseState;
241    private Vector2 mousePositionOnBtnDown;
242    private Vector2 viewAngleOnBtnRelease;
243    private Vector2 currentViewAngle = new Vector2(0, 0);
244    #endregion Mouse-Handling Variables
245    private void ComputeMouseHandling() {
246      MouseState mouseState = Mouse.GetState();
247
248      ComputeLeftMouseBtnHandling(mouseState);
249      ComputeMouseWheelHandling(mouseState);
250
251      previousMouseState = mouseState;
252    }
253    private void ComputeLeftMouseBtnHandling(MouseState mouseState) {
254      //Left btn pressed
255      if (mouseState.LeftButton.Down && (previousMouseState.LeftButton.Pressed || previousMouseState.LeftButton.Down)) {
256        currentViewAngle = new Vector2(
257          viewAngleOnBtnRelease.X + mouseState.X - mousePositionOnBtnDown.X,
258          viewAngleOnBtnRelease.Y + mouseState.Y - mousePositionOnBtnDown.Y);
259      }
260
261      //Left btn freshly pressed ==> ONLICK-EVENT
262      else if (mouseState.LeftButton.Pressed && !(previousMouseState.LeftButton.Pressed || previousMouseState.LeftButton.Down)) {
263        mousePositionOnBtnDown = new Vector2(mouseState.X, mouseState.Y);
264      }
265
266      //Left btn freshly released ==> ONRELEASE-EVENT
267      else if (mouseState.LeftButton.Released && !previousMouseState.LeftButton.Released) {
268        viewAngleOnBtnRelease = currentViewAngle;
269      }
270    }
271    private void ComputeMouseWheelHandling(MouseState mouseState) {
272      int curr = mouseState.WheelDelta;
273      if (curr < 0 && zoom > 1) {
274        zoom++;
275      } else if (curr > 0 && zoom < 300) {
276        zoom--;
277      }
278    }
279
280  }
281}
Note: See TracBrowser for help on using the repository browser.