View of /trunk/DefaultRenderer/DefaultRenderer.cs
Parent Directory
|
Revision Log
Revision 54 -
(download)
(annotate)
Thu Oct 16 02:59:36 2008 UTC (4 years, 7 months ago) by albert
File size: 28688 byte(s)
Thu Oct 16 02:59:36 2008 UTC (4 years, 7 months ago) by albert
File size: 28688 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;
using System.IO;
using System.Windows.Media.Imaging;
using OpenMetaverse.Imaging;
using Material = System.Windows.Media.Media3D.Material;
namespace Xenki.DefaultRenderer
{
class DefaultRenderer : IRenderer
{
private readonly Viewport3D m_viewport;
private readonly PerspectiveCamera m_camera;
private CameraControl m_cameracontrol;
private IRendering m_mesher;
private DefaultTexture m_textureManager;
private DefaultDataControl m_primitiveData;
//public ITextureManage TextureManager
//{
// set { m_textureManager = value; }
//}
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 DiffuseMaterial m_terrainMaterial;
private string textureImageFolderPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "texture");
private GridClient m_gridclient;
private GridClient gridClient;
public GridClient Gridclient
{
get { return gridClient; }
set
{
gridClient = value;
m_textureManager = DefaultTexture.SingleTextureManager();
m_textureManager.GridClient = Gridclient;
m_textureManager.OnDownloadFinished = OnTextureDownloaded;
m_textureManager.StartDownload();
}
}
public DefaultRenderer(Viewport3D m_viewport)
{
// Viewport
this.m_viewport = m_viewport;
// m_viewport.ClipToBounds = false;
m_viewport.IsHitTestVisible = true;
//setup data store control
m_primitiveData = DefaultDataControl.SingleSceneDataManager();
// 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 Camera Control
m_cameracontrol = new CameraControl(m_camera,m_primitiveData);
m_cameracontrol.EventSource = m_viewport;
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] = 10.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; }
}
void OnTextureDownloaded(UUID downLoadedTextureID, bool success)
{
if (success)
{
UpdatePrimTexture(downLoadedTextureID);
}
}
public void AddPrimitive(uint id, Primitive data)
{
if(Broken)
return;
m_viewport.Dispatcher.Invoke(
DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker
(delegate
{
// lock (m_primitiveData.PrimModelsInScene)
{
try
{
bool WaitParentIn = true;
if (data.ParentID == 0)
{
//m_primitiveData.AddModelsParentPositions(id, data.Position);
// test = true;
WaitParentIn = false;
}
else
{
if (m_primitiveData.PrimModelsInScene.ContainsKey(data.ParentID))
WaitParentIn = false;
/*
Vector3 vec = m_primitiveData.GetModelsParentPosition(data.ParentID);
if (vec != new Vector3())
{
if (test)
{
OpenMetaverse.Quaternion qqq = m_primitiveData.GetParentRotation(data.ParentID);
data.Position *= qqq;
}
test = false;
data.Position += vec;
//data.Position *= m_primitiveData.PrimModelsInScene[data.ParentID].Rotation ;
m_primitiveData.AddModelsParentPositions(id, data.Position);
WaitParentIn = false;
}
*/
}
if (WaitParentIn == false)
{
if (m_primitiveData.SceneContainVisual(data.LocalID))
{
m_viewport.Children.Remove(m_primitiveData.GetVisualInScene(data.LocalID));
m_primitiveData.RemoveVisualInScene(data.LocalID);
}
ModelVisual3D model = CreateModel(data);
m_primitiveData.AddNewPrimitive(data.LocalID, model, data.ParentID);
m_primitiveData.AddNewPrimitivePrimData(data);
m_primitiveData.RemoveWaitingParentPrimitive(data.LocalID);
m_viewport.Children.Add(model);
List<Primitive> waiting = m_primitiveData.GetModelsWaitingParent(data.LocalID);
foreach (Primitive child in waiting)
{
//Vector3 vec = m_primitiveData.GetModelsParentPosition(data.ParentID);
//if (vec != new Vector3())
//{
// OpenMetaverse.Quaternion qqq = m_primitiveData.GetParentRotation(child.ParentID);
// child.Position *= qqq;
// child.Position += data.Position;
// //data.Position *= m_primitiveData.PrimModelsInScene[data.ParentID].Rotation ;
// m_primitiveData.AddModelsParentPositions(child.LocalID, child.Position);
//}
//ModelVisual3D childmodel = CreateModel(child);
//m_viewport.Children.Add(childmodel);
//m_primitiveData.AddNewPrimitive(child.LocalID, childmodel, child.ParentID);
//m_primitiveData.AddNewPrimitivePrimData(child);
//m_primitiveData.RemoveWaitingParentPrimitive(child.LocalID);
AddPrimitive(child.LocalID, child);
}
waiting.Clear();
waiting = null;
model = null;
}
else
m_primitiveData.AddWaitingParentPrimitive(id, data);
}
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)
{
SimpleMesh basic = m_mesher.GenerateSimpleMesh(data, DetailLevel.Medium);
MeshGeometry3D mesh = new MeshGeometry3D();
GeometryModel3D triangleModel = new GeometryModel3D();
lock(m_primitiveData.PrimModelsInScene)
if (m_primitiveData.PrimModelsInScene.ContainsKey(data.ParentID))
{
//OpenMetaverse.Quaternion rotate = m_primitiveData.GetParentPosition(data.ParentID);
//if (m_primitiveData.PrimModelsInScene.ContainsKey(m_primitiveData.PrimModelsInScene[data.ParentID].ParentID))
// data.Position *= m_primitiveData.PrimModelsInScene[m_primitiveData.PrimModelsInScene[data.ParentID].ParentID].Rotation;
//else
//data.Position *= m_primitiveData.PrimModelsInScene[data.ParentID].Rotation;
data.Position += m_primitiveData.PrimModelsInScene[data.ParentID].Position;
}
// 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.
//Vector3D normal = new Vector3D(v.Normal.X, v.Normal.Y, v.Normal.Z);
//mesh.Normals.Add(normal);
double x = (v.Position.Length() == float.Parse("0")) ? 0 : (v.Position.X / v.Position.Length());
double y = (v.Position.Length() == float.Parse("0")) ? 0 : (v.Position.Y / v.Position.Length());
mesh.TextureCoordinates.Add(new Point(x, y));
}
foreach (ushort ind in basic.Indices)
{
mesh.TriangleIndices.Add(ind);
}
triangleModel = PatchTexture(data, mesh, triangleModel);
ModelVisual3D model = new ModelVisual3D();
model.Content = triangleModel;
return model;
}
private GeometryModel3D PatchTexture(Primitive data, MeshGeometry3D mesh, GeometryModel3D triangleModel)
{
Color col = Colors.YellowGreen;
if (data.Textures != null &&
data.Textures.DefaultTexture != null &&
data.Textures.DefaultTexture.TextureID != null)
{
Material m = m_primitiveData.GetMaterialFromCache(data.Textures.DefaultTexture.TextureID);
if (m != null)
{
triangleModel = new GeometryModel3D(mesh, m);
//
m_primitiveData.RemoveUnAttachedTexture(data.LocalID);
}
else
{
//ImageDownload image = m_textureManager.RetireveTextureData(data.Textures.DefaultTexture.TextureID);
// if (OpenJPEG.DecodeToImage(image.AssetData, out managedimg, out img))
//{
// System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(img);
// ImageSourceConverter converter = new ImageSourceConverter();
// ImageSource imagesource = (BitmapImage) converter.ConvertFrom(bitmap);
// ImageBrush brush = new ImageBrush(imagesource);
// m = new DiffuseMaterial(brush);
// triangleModel = new GeometryModel3D(
// mesh, m);
// //
// m_primitiveData.RemoveUnAttachedTexture(data.LocalID);
// if (m != null)
// m_primitiveData.AddNewMaterial2Cache(data.Textures.DefaultTexture.TextureID, m);
//}
string bitmapPath = System.IO.Path.Combine(textureImageFolderPath, data.Textures.DefaultTexture.TextureID.ToString() + ".jpg");
if (File.Exists(bitmapPath))
{
ImageSource imagesource = new BitmapImage(new Uri(bitmapPath));
ImageBrush brush = new ImageBrush(imagesource);
m = new DiffuseMaterial(brush);
triangleModel = new GeometryModel3D(mesh, m);
//
m_primitiveData.RemoveUnAttachedTexture(data.LocalID);
if (m != null)
m_primitiveData.AddNewMaterial2Cache(data.Textures.DefaultTexture.TextureID, m);
imagesource = null;
brush = null;
m = null;
}
else
{
col = Color.FromScRgb(data.Textures.DefaultTexture.RGBA.A,
data.Textures.DefaultTexture.RGBA.R,
data.Textures.DefaultTexture.RGBA.G,
data.Textures.DefaultTexture.RGBA.B);
triangleModel = new GeometryModel3D(
mesh, new DiffuseMaterial(new SolidColorBrush(col)));
m_primitiveData.AddUnAttachedTexture(data.LocalID, data.Textures.DefaultTexture.TextureID);
}
}
}
else
{
col = Color.FromScRgb(data.Textures.DefaultTexture.RGBA.A,
data.Textures.DefaultTexture.RGBA.R,
data.Textures.DefaultTexture.RGBA.G,
data.Textures.DefaultTexture.RGBA.B);
triangleModel = new GeometryModel3D(
mesh, new DiffuseMaterial(new SolidColorBrush(col)));
//ADD the visual to the needUpdateTexute list.when the texture downloaded update it.
m_primitiveData.AddUnAttachedTexture(data.LocalID, data.Textures.DefaultTexture.TextureID);
}
return triangleModel;
}
//private void SaveTexture2Image(ImageDownload image)
//{
// ManagedImage managedimg;
// Image img;
// //byte[] bytes = GetTextureDataByTextureID(downLoadedTextureID);
// if (OpenJPEG.DecodeToImage(image.AssetData, out managedimg, out img))
// {
// Bitmap bitmap = new Bitmap(img);
// ImageSource source = new BitmapMetadataBlob(
// bitmap.Save(Path.Combine(bmpFilePath, image.ID.ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
// bitmap.Dispose();
// bitmap = null;
// }
// img.Dispose();
// img = null;
// managedimg = null;
//}
ModelVisual3D CreateModelFromFaced(Primitive data)
{
FacetedMesh faceMesh = m_mesher.GenerateFacetedMesh(data, DetailLevel.Medium);
lock (m_primitiveData.PrimModelsInScene)
if (m_primitiveData.PrimModelsInScene.ContainsKey(data.ParentID))
{
//OpenMetaverse.Quaternion rotate = m_primitiveData.GetParentPosition(data.ParentID);
//if (m_primitiveData.PrimModelsInScene.ContainsKey(m_primitiveData.PrimModelsInScene[data.ParentID].ParentID))
// data.Position *= m_primitiveData.PrimModelsInScene[m_primitiveData.PrimModelsInScene[data.ParentID].ParentID].Rotation;
//else
//data.Position *= rotate;// m_primitiveData.PrimModelsInScene[data.ParentID].Rotation;
data.Position += m_primitiveData.PrimModelsInScene[data.ParentID].Position;
}
// 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));
ModelVisual3D model = new ModelVisual3D();
GeometryModel3D triangleModel = new GeometryModel3D();
MeshGeometry3D mesh;
ImageSource imagesource;
ImageBrush brush;
ModelVisual3D visual;
// Draw the prim faces
for (int j = 0; j < faceMesh.Faces.Count; j++)
{
mesh = new MeshGeometry3D();
Face face = faceMesh.Faces[j];
foreach (Vertex v in face.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));
double x = (v.Position.Length() == float.Parse("0")) ? 0 : (v.Position.X / v.Position.Length());
double y = (v.Position.Length() == float.Parse("0")) ? 0 : (v.Position.Y / v.Position.Length());
//mesh.TextureCoordinates.Add(new Point( x,y));
}
//mesh.TextureCoordinates.Add(new Point(0, 0));
//mesh.TextureCoordinates.Add(new Point(1, 0));
//mesh.TextureCoordinates.Add(new Point(0, 1));
//mesh.TextureCoordinates.Add(new Point(1, 1));
foreach (ushort ind in face.Indices)
{
mesh.TriangleIndices.Add(ind);
}
Color col = Colors.YellowGreen;
if (face.TextureFace.TextureID != null)
{
visual = new ModelVisual3D();
Material m = m_primitiveData.GetMaterialFromCache(data.Textures.DefaultTexture.TextureID);
if (m != null)
{
triangleModel = new GeometryModel3D(mesh, m);
//
m_primitiveData.RemoveUnAttachedTexture(data.LocalID);
}
else
{
string bitmapPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "texture\\" + face.TextureFace.TextureID.ToString() + ".jpg");
if (File.Exists(bitmapPath) == false)
{
//ADD the visual to the needUpdateTexute list.when the texture downloaded update it.
m_primitiveData.AddUnAttachedTexture(data.LocalID, face.TextureFace.TextureID);
col = Color.FromScRgb(face.TextureFace.RGBA.A,
face.TextureFace.RGBA.R,
face.TextureFace.RGBA.G,
face.TextureFace.RGBA.B);
triangleModel = new GeometryModel3D(
mesh, new DiffuseMaterial(new SolidColorBrush(col)));
visual.Content = triangleModel;
model.Children.Add(visual);
continue;
}
imagesource = new BitmapImage(new Uri(bitmapPath));
brush = new ImageBrush(imagesource);
m = new DiffuseMaterial(brush);
triangleModel = new GeometryModel3D(
mesh, m);
//
m_primitiveData.RemoveUnAttachedTexture(data.LocalID);
if (m != null)
m_primitiveData.AddNewMaterial2Cache(data.Textures.DefaultTexture.TextureID, m);
}
visual.Content = triangleModel;
model.Children.Add(visual);
}
}
return model;
}
//Dictionary<UUID, Material> m_materials = new Dictionary<UUID,Material>();
public void UpdatePrimTexture(UUID textureID)
{
List<Primitive> NeedUpdateVisuals = m_primitiveData.GetVisualByTextureID(textureID);
foreach (Primitive visual in NeedUpdateVisuals)
{
//m_primitiveData.RemoveUnAttachedTexture(visual.LocalID);
RemovePrimitive(visual.LocalID);
AddPrimitive(visual.LocalID, visual);
}
NeedUpdateVisuals.Clear();
NeedUpdateVisuals = null;
}
public void RemovePrimitive(uint id)
{
m_viewport.Dispatcher.Invoke(
DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker
(delegate
{
{
// Remove from scene and models list
m_viewport.Children.Remove(m_primitiveData.GetVisualInScene(id));
m_primitiveData.RemoveVisualInScene(id);
m_primitiveData.RemovePrimtivePrimData(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 |

