Add files via upload
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
<Application x:Class="Wpf_3D.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:Wpf_3D"
|
||||||
|
StartupUri="MainWindow.xaml">
|
||||||
|
<Application.Resources>
|
||||||
|
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace Wpf_3D {
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
[assembly: ThemeInfo(
|
||||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// or application resource dictionaries)
|
||||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// app, or any theme specific resource dictionaries)
|
||||||
|
)]
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using Global;
|
||||||
|
using System;
|
||||||
|
using System.Windows.Media.Media3D;
|
||||||
|
|
||||||
|
namespace Wpf_3D {
|
||||||
|
/// <summary>
|
||||||
|
/// This class was made with the help of this article
|
||||||
|
/// https://www.csharphelper.com/howtos/howto_3D_sphere.html
|
||||||
|
/// Alot of code is reused from this.
|
||||||
|
/// </summary>
|
||||||
|
public class Ball3DGenerator {
|
||||||
|
private MeshGeometry3D mesh;
|
||||||
|
|
||||||
|
public Model3D GenerateBall(Ball ball) {
|
||||||
|
Model3DGroup modelGroup = new Model3DGroup();
|
||||||
|
DiffuseMaterial ballMaterial = new DiffuseMaterial(ToBrush(ball.color));
|
||||||
|
mesh = new MeshGeometry3D();
|
||||||
|
double x = ball.x + 0.1;
|
||||||
|
double y = ball.y + 0.1;
|
||||||
|
double z = 0.5;
|
||||||
|
|
||||||
|
AddSphere(new Point3D(x + ball.size, y + ball.size, z), ball.size, 32, 32);
|
||||||
|
GeometryModel3D ballModel = new GeometryModel3D(mesh, ballMaterial);
|
||||||
|
modelGroup.Children.Add(ballModel);
|
||||||
|
return modelGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This conversion methode is taken from stackoverflow
|
||||||
|
/// </summary>
|
||||||
|
/// <href = https://stackoverflow.com/a/33523743></href>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private System.Windows.Media.Brush ToBrush(System.Drawing.Color color) {
|
||||||
|
return new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTriangle(Point3D p1, Point3D p2, Point3D p3) {
|
||||||
|
int index1 = mesh.Positions.Count;
|
||||||
|
int index2 = index1 + 1;
|
||||||
|
int index3 = index1 + 2;
|
||||||
|
mesh.Positions.Add(p1);
|
||||||
|
mesh.Positions.Add(p2);
|
||||||
|
mesh.Positions.Add(p3);
|
||||||
|
mesh.TriangleIndices.Add(index1);
|
||||||
|
mesh.TriangleIndices.Add(index2);
|
||||||
|
mesh.TriangleIndices.Add(index3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Taken from https://www.csharphelper.com/howtos/howto_3D_sphere.html
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center"></param>
|
||||||
|
/// <param name="radius"></param>
|
||||||
|
/// <param name="num_phi"></param>
|
||||||
|
/// <param name="num_theta"></param>
|
||||||
|
private void AddSphere(Point3D center,
|
||||||
|
double radius, int num_phi, int num_theta) {
|
||||||
|
double phi0, theta0;
|
||||||
|
double dphi = Math.PI / num_phi;
|
||||||
|
double dtheta = 2 * Math.PI / num_theta;
|
||||||
|
|
||||||
|
phi0 = 0;
|
||||||
|
double y0 = radius * Math.Cos(phi0);
|
||||||
|
double r0 = radius * Math.Sin(phi0);
|
||||||
|
for (int i = 0; i < num_phi; i++) {
|
||||||
|
double phi1 = phi0 + dphi;
|
||||||
|
double y1 = radius * Math.Cos(phi1);
|
||||||
|
double r1 = radius * Math.Sin(phi1);
|
||||||
|
|
||||||
|
// Point ptAB has phi value A and theta value B.
|
||||||
|
// For example, pt01 has phi = phi0 and theta = theta1.
|
||||||
|
// Find the points with theta = theta0.
|
||||||
|
theta0 = 0;
|
||||||
|
Point3D pt00 = new Point3D(
|
||||||
|
center.X + r0 * Math.Cos(theta0),
|
||||||
|
center.Y + y0,
|
||||||
|
center.Z + r0 * Math.Sin(theta0));
|
||||||
|
Point3D pt10 = new Point3D(
|
||||||
|
center.X + r1 * Math.Cos(theta0),
|
||||||
|
center.Y + y1,
|
||||||
|
center.Z + r1 * Math.Sin(theta0));
|
||||||
|
for (int j = 0; j < num_theta; j++) {
|
||||||
|
// Find the points with theta = theta1.
|
||||||
|
double theta1 = theta0 + dtheta;
|
||||||
|
Point3D pt01 = new Point3D(
|
||||||
|
center.X + r0 * Math.Cos(theta1),
|
||||||
|
center.Y + y0,
|
||||||
|
center.Z + r0 * Math.Sin(theta1));
|
||||||
|
Point3D pt11 = new Point3D(
|
||||||
|
center.X + r1 * Math.Cos(theta1),
|
||||||
|
center.Y + y1,
|
||||||
|
center.Z + r1 * Math.Sin(theta1));
|
||||||
|
|
||||||
|
// Create the triangles.
|
||||||
|
AddTriangle(pt00, pt11, pt10);
|
||||||
|
AddTriangle(pt00, pt01, pt11);
|
||||||
|
|
||||||
|
// Move to the next value of theta.
|
||||||
|
theta0 = theta1;
|
||||||
|
pt00 = pt01;
|
||||||
|
pt10 = pt11;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next value of phi.
|
||||||
|
phi0 = phi1;
|
||||||
|
y0 = y1;
|
||||||
|
r0 = r1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<Window x:Class="Wpf_3D.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:Wpf_3D"
|
||||||
|
Title="Window1" Height="398" Width="608" KeyDown="Window_KeyDown">
|
||||||
|
<Window.Resources>
|
||||||
|
<local:Maze3DGenerator x:Key="maze3DGenerator" />
|
||||||
|
<Model3DGroup x:Key="Model3D">
|
||||||
|
<AmbientLight Color="Gray" />
|
||||||
|
<DirectionalLight Color="Gray" Direction="1,-2,-3" />
|
||||||
|
</Model3DGroup>
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid>
|
||||||
|
<Viewport3D Margin="4,4,4,0" Name="viewport3D1" Focusable="True">
|
||||||
|
<ModelVisual3D>
|
||||||
|
<ModelVisual3D.Content>
|
||||||
|
<Model3DGroup>
|
||||||
|
<StaticResource ResourceKey="Model3D" />
|
||||||
|
</Model3DGroup>
|
||||||
|
</ModelVisual3D.Content>
|
||||||
|
</ModelVisual3D>
|
||||||
|
<ModelVisual3D>
|
||||||
|
<ModelVisual3D.Content>
|
||||||
|
<DirectionalLight x:Name="dirLightMain" Direction="-1,0,2" Color="Gray"></DirectionalLight>
|
||||||
|
</ModelVisual3D.Content>
|
||||||
|
</ModelVisual3D>
|
||||||
|
<Viewport3D.Camera>
|
||||||
|
<PerspectiveCamera
|
||||||
|
Position="0,0,15"
|
||||||
|
LookDirection="0,0,-1"
|
||||||
|
UpDirection="0,1,0"
|
||||||
|
FieldOfView="90">
|
||||||
|
</PerspectiveCamera>
|
||||||
|
</Viewport3D.Camera>
|
||||||
|
</Viewport3D>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
using Global;
|
||||||
|
using Logic;
|
||||||
|
using Logica;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media.Media3D;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Wpf_3D {
|
||||||
|
public partial class MainWindow : Window {
|
||||||
|
private int vertR = 0; //vertical angle
|
||||||
|
private int horzR = 0; //horizontal angle
|
||||||
|
private ModelVisual3D visual3D;
|
||||||
|
private Maze filled_maze;
|
||||||
|
private Ball3DGenerator ball3DGenerator = new Ball3DGenerator();
|
||||||
|
private Model3DGroup modelGroup = new Model3DGroup();
|
||||||
|
Maze3DGenerator mazeGen = new Maze3DGenerator();
|
||||||
|
private bool isGameOver = false;
|
||||||
|
private bool popupBeingShown = false;
|
||||||
|
private CancellationTokenSource gameLoopCancellationTokenSource;
|
||||||
|
private PhysicsEngine physicsEngine;
|
||||||
|
|
||||||
|
|
||||||
|
public MainWindow() {
|
||||||
|
InitializeComponent();
|
||||||
|
StartGamePopup();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// initialise the maze generation & 3D models
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeMaze() {
|
||||||
|
Maze maze = new Maze(15, 15); //Change these parameters to change the size of the maze.
|
||||||
|
maze.GenerateGrid(System.Drawing.Color.Red);
|
||||||
|
DepthFirstAlgoritm algo = new DepthFirstAlgoritm(maze);
|
||||||
|
algo.Generate();
|
||||||
|
filled_maze = algo.maze;
|
||||||
|
mazeGen = new Maze3DGenerator();
|
||||||
|
AddGuiElements(mazeGen.GenerateMaze(algo.maze), ball3DGenerator.GenerateBall(maze.ball));
|
||||||
|
physicsEngine = new PhysicsEngine(maze.ball, maze);
|
||||||
|
isGameOver = false;
|
||||||
|
Task.Run(async () => await GameLoopAsync());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// calculate physics on the ball & redraw it every 50ms
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task GameLoopAsync() {
|
||||||
|
gameLoopCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
while (!isGameOver) {
|
||||||
|
await Task.Delay(50);
|
||||||
|
Dispatcher.Invoke(() => {
|
||||||
|
CalculateBallMovement();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Popup for the start of the game
|
||||||
|
/// Starts the game;
|
||||||
|
/// </summary>
|
||||||
|
private void StartGamePopup() {
|
||||||
|
MessageBoxResult result = MessageBox.Show("Druk op OK om het spel te starten, \r\nKantel het bord met de pijltjes (↑ ↓ → ←)\r\nEn zoom de camera in & uit met de 'I' en 'O' toetsen.\r\nDuw op 'R' om het doolhof te resetten", "welkom", MessageBoxButton.OK);
|
||||||
|
if (result == MessageBoxResult.OK) {
|
||||||
|
InitializeMaze();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Popup for the end of the game.
|
||||||
|
/// Can restart or end the game
|
||||||
|
/// </summary>
|
||||||
|
private async void ShowEndPopup() {
|
||||||
|
if (physicsEngine.isFinished == true && !popupBeingShown) {
|
||||||
|
popupBeingShown = true;
|
||||||
|
MessageBoxResult result = MessageBox.Show("Proficiat!\r\nU hebt het doolhof opgelost. \r\nDuw op OK om opnieuw te beginnen en duw op cancel om te stoppen", "Proficiat!", MessageBoxButton.OKCancel);
|
||||||
|
if (result == MessageBoxResult.OK) {
|
||||||
|
await Task.Delay(100);
|
||||||
|
InitializeMaze();
|
||||||
|
}
|
||||||
|
else if (result == MessageBoxResult.Cancel) {
|
||||||
|
gameLoopCancellationTokenSource.Cancel();
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
popupBeingShown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add all GUI elements to the modelgroup
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="maze"></param>
|
||||||
|
/// <param name="ball"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private Task AddGuiElements(Model3D maze, Model3D ball) {
|
||||||
|
modelGroup.Children.Clear();
|
||||||
|
modelGroup.Children.Add(maze);
|
||||||
|
modelGroup.Children.Add(ball);
|
||||||
|
|
||||||
|
visual3D = new ModelVisual3D {
|
||||||
|
Content = modelGroup
|
||||||
|
};
|
||||||
|
|
||||||
|
viewport3D1.Children[1] = visual3D;
|
||||||
|
CentreScreen();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call the PhysicsEngine and move the ball.
|
||||||
|
/// Check if the ball is in the end cell
|
||||||
|
/// </summary>
|
||||||
|
private void CalculateBallMovement() {
|
||||||
|
if (!isGameOver) {
|
||||||
|
Ball calcBall = physicsEngine.CalculateAngleMovement(vertR, horzR);
|
||||||
|
Dispatcher.Invoke(() => {
|
||||||
|
modelGroup.Children[1] = ball3DGenerator.GenerateBall(calcBall);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (physicsEngine.isFinished) {
|
||||||
|
ShowEndPopup();
|
||||||
|
isGameOver = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Center the screen
|
||||||
|
/// </summary>
|
||||||
|
private void CentreScreen() {
|
||||||
|
vertR = 0;
|
||||||
|
horzR = 0;
|
||||||
|
Transform3DGroup rotationGroup = new Transform3DGroup();
|
||||||
|
double centerX = filled_maze.length / 2;
|
||||||
|
double centerY = filled_maze.height / 2;
|
||||||
|
TranslateTransform3D centerTranslation = new TranslateTransform3D(-centerX, -centerY, 0);
|
||||||
|
rotationGroup.Children.Add(centerTranslation);
|
||||||
|
visual3D.Transform = rotationGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the GUI controls
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void Window_KeyDown(object sender, KeyEventArgs e) {
|
||||||
|
switch (e.Key) {
|
||||||
|
case Key.Left:
|
||||||
|
horzR--;
|
||||||
|
HorizontalMovement();
|
||||||
|
break;
|
||||||
|
case Key.Right:
|
||||||
|
horzR++;
|
||||||
|
HorizontalMovement();
|
||||||
|
break;
|
||||||
|
case Key.Up:
|
||||||
|
vertR--;
|
||||||
|
VerticalMovement();
|
||||||
|
break;
|
||||||
|
case Key.Down:
|
||||||
|
vertR++;
|
||||||
|
VerticalMovement();
|
||||||
|
break;
|
||||||
|
case Key.I:
|
||||||
|
ZoomCamera(-5);
|
||||||
|
break;
|
||||||
|
case Key.O:
|
||||||
|
ZoomCamera(5);
|
||||||
|
break;
|
||||||
|
case Key.R:
|
||||||
|
InitializeMaze();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Angle the board on the horizontal axis
|
||||||
|
/// </summary>
|
||||||
|
private void HorizontalMovement() {
|
||||||
|
if (horzR > 30) {
|
||||||
|
horzR = 30;
|
||||||
|
}
|
||||||
|
if (horzR < -30) {
|
||||||
|
horzR = -30;
|
||||||
|
}
|
||||||
|
|
||||||
|
double centerX = filled_maze.length / 2;
|
||||||
|
double centerY = filled_maze.height / 2;
|
||||||
|
|
||||||
|
TranslateTransform3D centerTranslation = new TranslateTransform3D(-centerX, -centerY, 0);
|
||||||
|
RotateTransform3D horizontalRotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), horzR));
|
||||||
|
RotateTransform3D verticalRotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), vertR));
|
||||||
|
Transform3DGroup rotationGroup = new Transform3DGroup();
|
||||||
|
rotationGroup.Children.Add(centerTranslation);
|
||||||
|
rotationGroup.Children.Add(horizontalRotation);
|
||||||
|
rotationGroup.Children.Add(verticalRotation);
|
||||||
|
visual3D.Transform = rotationGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Angle the board on the vertical axis
|
||||||
|
/// </summary>
|
||||||
|
private void VerticalMovement() {
|
||||||
|
if (vertR > 30) {
|
||||||
|
vertR = 30;
|
||||||
|
}
|
||||||
|
if (vertR < -30) {
|
||||||
|
vertR = -30;
|
||||||
|
}
|
||||||
|
|
||||||
|
double centerX = filled_maze.length / 2;
|
||||||
|
double centerY = filled_maze.height / 2;
|
||||||
|
|
||||||
|
TranslateTransform3D centerTranslation = new TranslateTransform3D(-centerX, -centerY, 0);
|
||||||
|
RotateTransform3D horizontalRotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), horzR));
|
||||||
|
RotateTransform3D verticalRotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), vertR));
|
||||||
|
Transform3DGroup rotationGroup = new Transform3DGroup();
|
||||||
|
rotationGroup.Children.Add(centerTranslation);
|
||||||
|
rotationGroup.Children.Add(horizontalRotation);
|
||||||
|
rotationGroup.Children.Add(verticalRotation);
|
||||||
|
visual3D.Transform = rotationGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Change the perspective of the camera to zoom in & out
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="zoomFactor"></param>
|
||||||
|
private void ZoomCamera(double zoomFactor) {
|
||||||
|
PerspectiveCamera camera = (PerspectiveCamera)viewport3D1.Camera;
|
||||||
|
camera.FieldOfView += zoomFactor;
|
||||||
|
|
||||||
|
if (camera.FieldOfView < 1.0) {
|
||||||
|
camera.FieldOfView = 1.0;
|
||||||
|
}
|
||||||
|
if (camera.FieldOfView > 120.0) {
|
||||||
|
camera.FieldOfView = 120.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
using Logica;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Wpf_3D {
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Media3D;
|
||||||
|
|
||||||
|
public class Maze3DGenerator {
|
||||||
|
List<GeometryModel3D> geom = new List<GeometryModel3D>();
|
||||||
|
private Maze maze;
|
||||||
|
|
||||||
|
|
||||||
|
public Model3D GenerateMaze(Maze maze) {
|
||||||
|
this.maze = maze;
|
||||||
|
geom.Clear();
|
||||||
|
GenCubes();
|
||||||
|
Model3D mazeModel = ConvertToSingleModel(geom);
|
||||||
|
|
||||||
|
return mazeModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenCubes() {
|
||||||
|
for (int x = 0; x < maze.cels.GetLength(0); x++) {
|
||||||
|
for (int y = 0; y < maze.cels.GetLength(1); y++) {
|
||||||
|
if (maze.cels[x, y].isWall) {
|
||||||
|
GenCube(x, y);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GenFloor(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenCube(int x, int y) {
|
||||||
|
int z = 0;
|
||||||
|
var material = new MaterialGroup();
|
||||||
|
material.Children.Add(new DiffuseMaterial(Brushes.Red));
|
||||||
|
material.Children.Add(new SpecularMaterial(Brushes.White, 30));
|
||||||
|
|
||||||
|
var geometry = new MeshGeometry3D {
|
||||||
|
Positions = new Point3DCollection
|
||||||
|
{
|
||||||
|
new Point3D(x, y, 0 + z),
|
||||||
|
new Point3D(x + 1, y, 0 + z),
|
||||||
|
new Point3D(x, y + 1, 0 + z),
|
||||||
|
new Point3D(x + 1, y + 1, 0 + z),
|
||||||
|
new Point3D(x, y, 1 + z),
|
||||||
|
new Point3D(x + 1, y, 1 + z),
|
||||||
|
new Point3D(x, y + 1, 1 + z),
|
||||||
|
new Point3D(x + 1, y + 1, 1 + z)
|
||||||
|
},
|
||||||
|
TriangleIndices = new Int32Collection
|
||||||
|
{
|
||||||
|
// Bottom face
|
||||||
|
0, 1, 2, 1, 3, 2,
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
4, 6, 5, 5, 6, 7,
|
||||||
|
|
||||||
|
// Side faces
|
||||||
|
0, 4, 1, 1, 4, 5,
|
||||||
|
2, 3, 6, 3, 7, 6,
|
||||||
|
0, 2, 4, 2, 6, 4,
|
||||||
|
1, 5, 3, 3, 5, 7
|
||||||
|
},
|
||||||
|
Normals = new Vector3DCollection
|
||||||
|
{
|
||||||
|
new Vector3D(0, 0, -1), // Bottom face
|
||||||
|
new Vector3D(0, 0, 1), // Top face
|
||||||
|
new Vector3D(-1, 0, 0), // Left face
|
||||||
|
new Vector3D(1, 0, 0), // Right face
|
||||||
|
new Vector3D(0, -1, 0), // Front face
|
||||||
|
new Vector3D(0, 1, 0) // Back face
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var model = new GeometryModel3D {
|
||||||
|
Geometry = geometry,
|
||||||
|
Material = material
|
||||||
|
};
|
||||||
|
geometry.Freeze();
|
||||||
|
geom.Add(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a floor tile and add it to the model
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x"></param>
|
||||||
|
/// <param name="y"></param>
|
||||||
|
private void GenFloor(int x, int y) {
|
||||||
|
int z = 0;
|
||||||
|
var floorMaterial = new DiffuseMaterial();
|
||||||
|
if (maze.cels[x, y].color == System.Drawing.Color.Blue) {
|
||||||
|
floorMaterial = new DiffuseMaterial(Brushes.Blue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
floorMaterial = new DiffuseMaterial(Brushes.Green);
|
||||||
|
}
|
||||||
|
var floorGeometry = new MeshGeometry3D {
|
||||||
|
Positions = new Point3DCollection
|
||||||
|
{
|
||||||
|
new Point3D(x, y, 0 + z),
|
||||||
|
new Point3D(x + 1, y, 0 + z),
|
||||||
|
new Point3D(x, y + 1, 0 + z),
|
||||||
|
new Point3D(x + 1, y + 1, 0 + z),
|
||||||
|
},
|
||||||
|
TriangleIndices = new Int32Collection {
|
||||||
|
0, 2, 1,
|
||||||
|
1, 2, 3,
|
||||||
|
1, 3, 2,
|
||||||
|
2, 0, 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var floorModel = new GeometryModel3D {
|
||||||
|
Geometry = floorGeometry,
|
||||||
|
Material = floorMaterial
|
||||||
|
};
|
||||||
|
|
||||||
|
geom.Add(floorModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the List of Geometry 3D models to one single modelgroup
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="geom"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private Model3D ConvertToSingleModel(List<GeometryModel3D> geom) {
|
||||||
|
Model3DGroup modelGroup = new Model3DGroup();
|
||||||
|
foreach (var geometryModel in geom) {
|
||||||
|
modelGroup.Children.Add(geometryModel);
|
||||||
|
}
|
||||||
|
return modelGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net7.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Logica\Global.csproj" />
|
||||||
|
<ProjectReference Include="..\Logic\Logic.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<ApplicationDefinition Update="App.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</ApplicationDefinition>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="MainWindow.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETCoreApp,Version=v7.0",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETCoreApp,Version=v7.0": {
|
||||||
|
"Wpf_3D/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Global": "1.0.0",
|
||||||
|
"Logic": "1.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"Wpf_3D.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Global/1.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"Global.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Logic/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Global": "1.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"Logic.dll": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"Wpf_3D/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"Global/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"Logic/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net7.0",
|
||||||
|
"frameworks": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "7.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.WindowsDesktop.App",
|
||||||
|
"version": "7.0.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user