|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
namespace MdxWpfInteroperability.Example
{
public static class WpfSceneRenderer
{
public static void WpfRenderScene(SceneData scene,
Viewport3D viewport3d)
{
if (scene == null || viewport3d == null)
{
return;
}
viewport3d.Children.Clear();
// Init camera matrices
viewport3d.Camera = new PerspectiveCamera
{
Position = scene.CameraPosition,
UpDirection = new Vector3D(0, 1, 0),
FarPlaneDistance = scene.FarPlaneDistance
};
// Add directional light
Vector3D lightDirection =
new Vector3D(-1, -1, -1);
lightDirection.Normalize();
ModelVisual3D dirlight = new ModelVisual3D
{
Content = new DirectionalLight(
Colors.White, lightDirection)
};
viewport3d.Children.Add(dirlight);
foreach (ConeData cone in scene.Cones)
{
WpfRenderCone(cone, viewport3d);
}
}
private static void WpfRenderCone(ConeData cone,
Viewport3D viewport3d)
{
// Create the cone's material
DiffuseMaterial coneMaterial =
new DiffuseMaterial(
new SolidColorBrush(
cone.MaterialColor));
// Create the cone's geometry
int numOfPoints = (int)cone.BaseRadius;
if (numOfPoints < 10)
{
numOfPoints = 10;
}
double partAngle = Math.PI * 2 / numOfPoints;
// Create the vertices' collections.
MeshGeometry3D coneMesh = new MeshGeometry3D();
coneMesh.Positions = new Point3DCollection();
coneMesh.Normals = new Vector3DCollection();
coneMesh.TriangleIndices = new Int32Collection();
// Set the top vertex.
coneMesh.Positions.Add(new Point3D(
0, cone.Height / 2, 0));
coneMesh.Normals.Add(new Vector3D(0, 1, 0));
// Set the base center vertex.
coneMesh.Positions.Add(new Point3D(
0, cone.Height / -2, 0));
coneMesh.Normals.Add(new Vector3D(0, -1, 0));
double bodyNormalY =
Math.Sin(Math.PI -
Math.Atan(cone.Height /
cone.BaseRadius) * 2) *
Math.Sqrt(cone.Height * cone.Height +
cone.BaseRadius * cone.BaseRadius);
for (int vertexInx = 0; vertexInx <= numOfPoints; vertexInx++)
{
double currAngle = vertexInx * partAngle;
double currX =
cone.BaseRadius * Math.Cos(currAngle);
double currZ =
cone.BaseRadius * Math.Sin(currAngle);
// Set current body vertex.
coneMesh.Positions.Add(new Point3D(
currX, cone.Height / -2, currZ));
Vector3D bodyNormal = new Vector3D(
currX, bodyNormalY, currZ);
bodyNormal.Normalize();
coneMesh.Normals.Add(bodyNormal);
// Set current base vertex.
coneMesh.Positions.Add(new Point3D(
currX, cone.Height / -2, currZ));
coneMesh.Normals.Add(
new Vector3D(0, -1, 0));
// Set current body and base indices.
if (vertexInx > 0)
{
// Set current body index.
coneMesh.TriangleIndices.Add(0); // Top
coneMesh.TriangleIndices.Add(
(vertexInx + 1) * 2);
coneMesh.TriangleIndices.Add(
vertexInx * 2);
// Set current base index.
coneMesh.TriangleIndices.Add(1); // Base center
coneMesh.TriangleIndices.Add(
vertexInx * 2 + 1);
coneMesh.TriangleIndices.Add(
(vertexInx + 1) * 2 + 1);
}
}
GeometryModel3D coneGeometry =
new GeometryModel3D(
coneMesh, coneMaterial);
// Set the world matrix
Transform3DGroup transGroup =
new Transform3DGroup();
transGroup.Children.Add(
new RotateTransform3D(
new AxisAngleRotation3D(
new Vector3D(1, 0, 0),
cone.RotationX)));
transGroup.Children.Add(
new RotateTransform3D(
new AxisAngleRotation3D(
new Vector3D(0, 0, 1),
cone.RotationZ)));
transGroup.Children.Add(
new TranslateTransform3D(
cone.CenterPosition.X,
cone.CenterPosition.Y,
cone.CenterPosition.Z));
// Render the cone
ModelVisual3D coneModel =
new ModelVisual3D
{
Content = coneGeometry,
Transform = transGroup
};
viewport3d.Children.Add(coneModel);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.