View of /trunk/DefaultRenderer/DefaultRenderer.cs
Parent Directory
|
Revision Log
Revision 12 -
(download)
(annotate)
Wed Aug 27 02:26:39 2008 UTC (4 years, 8 months ago) by albert
File size: 11874 byte(s)
Wed Aug 27 02:26:39 2008 UTC (4 years, 8 months ago) by albert
File size: 11874 byte(s)
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
using OpenMetaverse;
using OpenMetaverse.Rendering;
using Xenki.Framework;
using Quaternion=System.Windows.Media.Media3D.Quaternion;
namespace Xenki.DefaultRenderer
{
class DefaultRenderer : IRenderer
{
private readonly Viewport3D m_viewport;
private readonly PerspectiveCamera m_camera;
private Trackball m_trackball;
private IRendering m_mesher;
private bool Broken;
private readonly Point3D[,] m_heightmapPoints = new Point3D[256,256];
private double[,] m_heightmap = new double[256,256];
private ModelVisual3D m_terrain;
private readonly Dictionary<uint, Visual3D> m_models = new Dictionary<uint, Visual3D>();
private readonly Dictionary<uint, Vector3> m_parentPositions = new Dictionary<uint, Vector3>();
private readonly Material m_defaultMaterial;
private readonly DiffuseMaterial m_terrainMaterial;
public DefaultRenderer(Viewport3D m_viewport)
{
// Viewport
this.m_viewport = m_viewport;
m_viewport.ClipToBounds = false;
m_viewport.IsHitTestVisible = true;
// Camera Issues
Point3D CameraPos = new Point3D(0,0,50);
Point3D CameraLook = new Point3D(128,128,10);
m_camera = new PerspectiveCamera(new Point3D(0, 0, 0), new Vector3D(0, 0, 0),
new Vector3D(0, 0, 1), 90);
m_camera.Position = CameraPos;
m_camera.LookDirection = new Vector3D(CameraLook.X - m_camera.Position.X, CameraLook.Y - m_camera.Position.Y, CameraLook.Z - m_camera.Position.Z);
m_camera.FarPlaneDistance = 1024;
m_camera.NearPlaneDistance = 0.01;
m_viewport.Camera = m_camera;
// Setup Trackball
m_trackball = new Trackball(m_camera);
m_camera.Transform = m_trackball.Transform;
m_trackball.EventSource = m_viewport;
// Default Material Properties
m_defaultMaterial = new DiffuseMaterial(
new SolidColorBrush(Colors.DarkKhaki));
GradientBrush terGrad = new RadialGradientBrush(Colors.ForestGreen, Colors.SandyBrown);
m_terrainMaterial = new DiffuseMaterial(
terGrad);
// Scene Lighting
ModelVisual3D lights = new ModelVisual3D();
lights.Content = new DirectionalLight(Colors.White, new Vector3D(-20, -30, -10));
ModelVisual3D point = new ModelVisual3D();
PointLight pointLight = new PointLight(Colors.WhiteSmoke, new Point3D(128, 128, 80));
point.Content = pointLight;
ModelVisual3D ambient = new ModelVisual3D();
AmbientLight ambientLight = new AmbientLight(Color.FromArgb(0xFF, 0x40, 0x40, 0x40));
ambient.Content = ambientLight;
m_viewport.Children.Add(lights);
m_viewport.Children.Add(point);
m_viewport.Children.Add(ambient);
// Terrain Base
for(int x=0;x<256;x++)
{
for(int y=0;y<256;y++)
{
m_heightmap[x, y] = 30.0;
}
}
m_terrain = CreateTerrain(m_heightmap);
m_viewport.Children.Add(m_terrain);
// Water Plane
SolidColorBrush brush = new SolidColorBrush(Color.FromArgb(128, 0, 128, 255));
DiffuseMaterial material = new DiffuseMaterial(brush);
//m_viewport.Children.Add(DefaultUtil.CreateCube(new Point3D(0,0,0), new Point3D(256,256,20),
// material));
}
public IRendering Mesher
{
set { m_mesher = value; }
}
public void AddPrimitive(uint id, Primitive data)
{
lock(m_parentPositions)
{
m_parentPositions[id] = data.Position;
}
if(Broken)
return;
m_viewport.Dispatcher.Invoke(
DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker
(delegate
{
lock (m_models)
{
try
{
if (m_models.ContainsKey(id))
{
m_viewport.Children.Remove(m_models[id]);
m_models.Remove(id);
}
lock(m_parentPositions)
{
if(m_parentPositions.ContainsKey(data.ParentID))
{
data.Position += m_parentPositions[data.ParentID];
}
}
// Add it to the scene appropriately.
ModelVisual3D model = CreateModel(data);
m_models.Add(id, model);
m_viewport.Children.Add(model);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
Broken = true;
}
}
}
)
);
}
private ModelVisual3D CreateTerrain(double[,] map)
{
MeshGeometry3D mesh = new MeshGeometry3D();
for (int y = 0; y < 256; y++)
{
for (int x = 0; x < 256; x++)
{
m_heightmapPoints[y, x] = new Point3D(x, y, map[x, y]);
mesh.Positions.Add(m_heightmapPoints[y, x]);
mesh.TextureCoordinates.Add(new Point(x/255.0, y/255.0));
}
}
for(int x=0;x<255;x++)
{
for(int y=0;y<255;y++)
{
int p0 = (x*256) + y;
int p1 = (x*256) + (y + 1);
int p2 = ((x + 1)*256) + y;
int p3 = ((x + 1)*256) + (y + 1);
// Δ 013 |\
mesh.TriangleIndices.Add(p1); //#0
mesh.TriangleIndices.Add(p3); //#1
mesh.TriangleIndices.Add(p2); //#3
// Δ 023
mesh.TriangleIndices.Add(p0); //#0
mesh.TriangleIndices.Add(p1); //#2
mesh.TriangleIndices.Add(p2); //#3
}
}
GeometryModel3D triangleModel = new GeometryModel3D(
mesh, m_terrainMaterial);
ModelVisual3D model = new ModelVisual3D();
model.Content = triangleModel;
return model;
}
private ModelVisual3D CreateModel(Primitive data)
{
MeshGeometry3D mesh = new MeshGeometry3D();
SimpleMesh basic = m_mesher.GenerateSimpleMesh(data, DetailLevel.Medium);
// Translation
TranslateTransform3D tt = new TranslateTransform3D(
new Vector3D(data.Position.X, data.Position.Y, data.Position.Z)
);
Quaternion rot = new Quaternion(data.Rotation.X, data.Rotation.Y, data.Rotation.Z, data.Rotation.W);
RotateTransform3D rt = new RotateTransform3D(
new AxisAngleRotation3D(rot.Axis, rot.Angle)
);
// Scale
ScaleTransform3D st = new ScaleTransform3D(
new Vector3D(data.Scale.X, data.Scale.Y, data.Scale.Z));
foreach (Vertex v in basic.Vertices)
{
Point3D d = new Point3D(
v.Position.X,
v.Position.Y,
v.Position.Z);
// Scale
d = st.Transform(d);
// Rotate
d = rt.Transform(d);
// Move
d = tt.Transform(d);
mesh.Positions.Add(d);
// These normals dont appear to be working for some reason,
// however the auto-generated normals appear adequate for now.
// mesh.Normals.Add(new Vector3D(v.Normal.X, v.Normal.Y, v.Normal.Z));
mesh.TextureCoordinates.Add(new Point(v.TexCoord.X, v.TexCoord.Y));
}
foreach (ushort ind in basic.Indices)
{
mesh.TriangleIndices.Add(ind);
}
GeometryModel3D triangleModel;
Color[] colAry = new Color[5];
colAry[0] = Colors.Violet;
colAry[1] = Colors.BlueViolet;
colAry[2] = Colors.Navy;
colAry[3] = Colors.CornflowerBlue;
colAry[4] = Colors.PowderBlue;
Random x = new Random();
Color col = colAry[x.Next(0, 5)];
triangleModel = new GeometryModel3D(
mesh, new DiffuseMaterial(new SolidColorBrush(col)));
//*/
/*
GradientBrush Grad = new LinearGradientBrush(Colors.Red, Colors.Blue, 90);
Material mat = new DiffuseMaterial(Grad);
triangleModel = new GeometryModel3D(
mesh, mat);
*/
ModelVisual3D model = new ModelVisual3D();
model.Content = triangleModel;
model.Transform = new TranslateTransform3D(0,0,0);
return model;
}
public void RemovePrimitive(uint id)
{
m_viewport.Dispatcher.Invoke(
DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker
(delegate
{
if(m_models.ContainsKey(id))
{
// Remove from scene and models list
m_viewport.Children.Remove(m_models[id]);
m_models.Remove(id);
}
}
)
);
}
public void SetTerrain(int x, int y, double val)
{
m_heightmap[x, y] = val;
}
public void SetTerrain(double[,] map)
{
m_heightmap = map;
m_viewport.Dispatcher.Invoke(
DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker
(delegate
{
m_viewport.Children.Remove(m_terrain);
m_terrain = CreateTerrain(map);
m_viewport.Children.Add(m_terrain);
}
)
);
}
}
}
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

