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

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

#1966 fixed rotation and zooming for 3d packings

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