#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using SharpDX; using SharpDX.Toolkit; using SharpDX.Toolkit.Graphics; using SharpDX.Toolkit.Input; using ButtonStateDX = SharpDX.Toolkit.Input.ButtonState; using SharpDX.Direct3D11; namespace PackingPlanVisualizations { public class PackingGame : Game { #region Global Private Variables private GraphicsDeviceManager graphicsDeviceManager; private PackingPlan3D control; private Matrix worldMatrix; private Matrix viewMatrix; private Matrix projectionMatrix; private float zoom = 50; private int selectedItemIndex = -1; private BasicEffect basicEffect; private Color backgroundColor { get; set; } private CenteredContainer container; private MouseManager Mouse; #endregion Global Private Variables protected override void Dispose(bool disposeManagedResources) { control.disposedByGame = true; base.Dispose(disposeManagedResources); control.disposedByGame = false; } public PackingGame(PackingPlan3D control) : base() { this.control = control; graphicsDeviceManager = new GraphicsDeviceManager(this); graphicsDeviceManager.PreferMultiSampling = true; graphicsDeviceManager.PreparingDeviceSettings += (object sender, PreparingDeviceSettingsEventArgs e) => { e.GraphicsDeviceInformation.PresentationParameters.MultiSampleCount = MSAALevel.X4; return; }; var controlColor = Color.White;//System.Drawing.SystemColors.Control; backgroundColor = new Color (controlColor.R,controlColor.G, controlColor.B, controlColor.A); Mouse = new MouseManager(this); } public void SetSize(int width, int height) { graphicsDeviceManager.PreferredBackBufferHeight = height; graphicsDeviceManager.PreferredBackBufferWidth = width; } public void InitializeContainer(BasicCuboidShape containerShape) { container = new CenteredContainer(containerShape); } public void InitializeContainer(float width, float height, float depth) { InitializeContainer(new BasicCuboidShape(new Vector3(width, height, depth), -1)); } public void AddItemToContainer(float width, float height, float depth, float x, float y, float z, int index, int material) { container.AddPackingItem(new Vector3(width, height, depth), new Vector3(x, y, z), index, material); } public void SelectItem(int itemIndex) { selectedItemIndex = itemIndex; } public void UnselectItem() { selectedItemIndex = -1; } protected override void Initialize() { base.Initialize(); initializeWorld(); previousMouseState = Mouse.GetState(); Console.WriteLine("Initial bounds:" + Window.ClientBounds); this.Window.IsMouseVisible = true; //this.Window.ClientSizeChanged += (a, b) => { // Console.WriteLine("Resized.."); // this.Tick(); //}; } private void initializeWorld() { #region Matrix-Initialization worldMatrix = Matrix.Identity; viewMatrix = Matrix.LookAtLH( new Vector3(0, 10, zoom), Vector3.Zero, Vector3.UnitY); projectionMatrix = Matrix.PerspectiveFovLH( (float)Math.PI / 6.0f, (float)GraphicsDevice.BackBuffer.Width / (float)GraphicsDevice.BackBuffer.Height, 1.0f, 1000.0f); #endregion Matrix-Initialization #region Effect and Color //Effect initialization basicEffect = new BasicEffect(GraphicsDevice); basicEffect.World = worldMatrix; basicEffect.View = viewMatrix; basicEffect.Projection = projectionMatrix; //Primitive color basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f); basicEffect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f); basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f); basicEffect.SpecularPower = 5.0f; basicEffect.Alpha = 1.0f; basicEffect.VertexColorEnabled = true; #endregion Effect-World and Color #region World lighting basicEffect.LightingEnabled = true; basicEffect.PreferPerPixelLighting = true; if (basicEffect.LightingEnabled) { basicEffect.DirectionalLight0.Enabled = true; // enable each light individually if (basicEffect.DirectionalLight0.Enabled) { // x direction basicEffect.DirectionalLight0.DiffuseColor = new Vector3(1, 1, 1); // range is 0 to 1 basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(-1, 0, 0)); // points from the light to the origin of the scene basicEffect.DirectionalLight0.SpecularColor = Vector3.One; } basicEffect.DirectionalLight1.Enabled = true; if (basicEffect.DirectionalLight1.Enabled) { // y direction basicEffect.DirectionalLight1.DiffuseColor = new Vector3(1, 1, 1); basicEffect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(0, -1, 0)); basicEffect.DirectionalLight1.SpecularColor = Vector3.One; } basicEffect.DirectionalLight2.Enabled = true; if (basicEffect.DirectionalLight2.Enabled) { // z direction basicEffect.DirectionalLight2.DiffuseColor = new Vector3(1, 1, 1); basicEffect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(0, 0, -1)); basicEffect.DirectionalLight2.SpecularColor = Vector3.One; } } #endregion World lighting #region Transparency //basicEffect.GraphicsDevice.RenderState.AlphaBlendEnable = true; //basicEffect.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha; //basicEffect.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha; BlendStateDescription blendStateDescription = new SharpDX.Direct3D11.BlendStateDescription(); blendStateDescription.RenderTarget[0].IsBlendEnabled = true; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.One; blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; SharpDX.Toolkit.Graphics.BlendState blendState = SharpDX.Toolkit.Graphics.BlendState.New(GraphicsDevice, blendStateDescription); GraphicsDevice.SetBlendState(blendState); #endregion } protected override void LoadContent() { } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(backgroundColor); worldMatrix = Matrix.RotationY(MathUtil.DegreesToRadians(-currentViewAngle.X / 4)) * Matrix.RotationX(MathUtil.DegreesToRadians(currentViewAngle.Y / 4)); basicEffect.World = worldMatrix; viewMatrix = Matrix.LookAtLH( new Vector3(0, zoom, zoom), Vector3.Zero, Vector3.UnitY); basicEffect.View = viewMatrix; foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { pass.Apply(); if (container != null) { if (container.PackingItems.Count == 0) container.Container.RenderShapeTrianglesAndLines(GraphicsDevice); else { container.Container.RenderShapeLines(GraphicsDevice, new Color(0, 0, 0)); var selectedItem = container.PackingItems.Find(x => x.ShapeID == selectedItemIndex); foreach (BasicCuboidShape item in container.PackingItems) { if (selectedItem == null || selectedItemIndex == item.ShapeID) { item.RenderShapeLines(GraphicsDevice); item.RenderShapeTriangles(GraphicsDevice); } else item.RenderShapeLines(GraphicsDevice, new Color(0,0,0)); } } } } base.Draw(gameTime); } protected override void Update(GameTime gameTime) { computeMouseHandling(); base.Update(gameTime); } #region Mouse-Handling Variables private MouseState previousMouseState; private Vector2 mousePositionOnBtnDown; private Vector2 viewAngleOnBtnRelease; private Vector2 currentViewAngle = new Vector2(0, 0); #endregion Mouse-Handling Variables private void computeMouseHandling() { MouseState mouseState = Mouse.GetState(); computeLeftMouseBtnHandling(mouseState); computeMouseWheelHandling(mouseState); previousMouseState = mouseState; } private void computeLeftMouseBtnHandling(MouseState mouseState) { //Left btn released if (mouseState.Left.Equals(ButtonStateDX.Released) && mouseState.Left.Equals(previousMouseState.Left)) { //Console.WriteLine("Released"); } //Left btn pressed else if (mouseState.Left.Equals(ButtonStateDX.Pressed) && mouseState.Left.Equals(previousMouseState.Left)) { currentViewAngle = new Vector2( viewAngleOnBtnRelease.X + mouseState.X - mousePositionOnBtnDown.X, viewAngleOnBtnRelease.Y + mouseState.Y - mousePositionOnBtnDown.Y); //angle += 0.5f; //Console.WriteLine("Pressed"); //Console.WriteLine(currentViewAngle.ToString()); } //Left btn freshly pressed ==> ONLICK-EVENT else if (mouseState.Left.Equals(ButtonStateDX.Pressed) && !previousMouseState.Left.Equals(ButtonStateDX.Pressed)) { Console.WriteLine("OnClick"); PackingPlan3D native = (PackingPlan3D)Window.NativeWindow; Console.WriteLine("Window: " + Window.ClientBounds.ToString()); Console.WriteLine("native: " + native.ClientSize.ToString()); Console.WriteLine("native.parent: " + native.Parent.ClientSize.ToString()); Console.WriteLine(native.ParentForm.ToString()); Console.WriteLine(Window.Name); Console.WriteLine(this.IsActive); mousePositionOnBtnDown = new Vector2(mouseState.X, mouseState.Y); } //Left btn freshly released ==> ONRELEASE-EVENT else if (mouseState.Left.Equals(ButtonStateDX.Released) && !previousMouseState.Left.Equals(ButtonStateDX.Released)) { Console.WriteLine("OnRelease"); viewAngleOnBtnRelease = currentViewAngle; } } private void computeMouseWheelHandling(MouseState mouseState) { int prev = previousMouseState.WheelDelta; int curr = mouseState.WheelDelta; if (curr < prev && zoom > 1) { zoom++; Console.WriteLine(zoom); } else if (curr > prev && zoom < 300) { zoom--; Console.WriteLine(zoom); } } } }