View of /trunk/IdealistViewer/Application/BaseIdealistViewer.cs
Parent Directory
|
Revision Log
Revision 21 -
(download)
(annotate)
Tue Oct 28 10:14:35 2008 UTC (4 years, 7 months ago) by teravus
File size: 62223 byte(s)
Tue Oct 28 10:14:35 2008 UTC (4 years, 7 months ago) by teravus
File size: 62223 byte(s)
* Found where the general textures are located in the Primitive object * Load textures as the viewer encounters them. (though they appear white when calling for some reason) A second run pulls the files from disk. (maybe irrlicht has a disk cache?)
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using log4net;
using log4net.Appender;
using log4net.Core;
using log4net.Repository;
using IrrlichtNETCP;
using OpenMetaverse;
using Nini.Config;
using PrimMesher;
namespace IdealistViewer
{
public class BaseIdealistViewer : conscmd_callback
{
public IdealistViewerConfigSource m_config = null;
private IrrlichtDevice device = null;
private VideoDriver driver = null;
private SceneManager smgr = null;
private GUIEnvironment guienv = null;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Thread guithread;
private Dictionary<ulong, System.Drawing.Bitmap> terrainBitmap = new Dictionary<ulong, System.Drawing.Bitmap>();
private SLProtocol avatarConnection;
private Dictionary<ulong,TerrainSceneNode> terrains = new Dictionary<ulong,TerrainSceneNode>();
private Dictionary<ulong, Dictionary<int, float[]>> m_landmaps = new Dictionary<ulong, Dictionary<int, float[]>>();
private Dictionary<ulong, TriangleSelector> terrainsels = new Dictionary<ulong,TriangleSelector>();
private static SceneNode SNGlobalwater;
private static MetaTriangleSelector mts;
private static Queue<VObject> objectModQueue = new Queue<VObject>();
private static Queue<VObject> UnAssignedChildObjectModQueue = new Queue<VObject>();
private static Simulator currentSim;
private static Dictionary<ulong, Simulator> Simulators = new Dictionary<ulong, Simulator>();
private static Dictionary<string, VObject> Entities = new Dictionary<string, VObject>();
private static Dictionary<UUID, VObject> Avatars = new Dictionary<UUID, VObject>();
private static bool ctrlHeld = false;
private static bool shiftHeld = false;
private static bool appHeld = false;
private static bool LMheld = false;
private static bool RMheld = false;
private static bool MMheld = false;
private static bool loadTextures = true;
private int OldMouseX = 0;
private int OldMouseY = 0;
private static int WindowWidth = 1024;
private static int WindowHeight = 768;
private static float WindowWidth_DIV2 = WindowWidth * 0.5f;
private static float WindowHeight_DIV2 = WindowHeight * 0.5f;
private static float aspect = (float)WindowWidth / WindowHeight;
private Camera cam;
private static Vector3 m_lastTargetPos = Vector3.Zero;
private static List<KeyCode> m_heldKeys = new List<KeyCode>();
private int tickcount = 0;
private int mscounter = 0;
private int msreset = 100;
private uint framecounter = 0;
private int maxFPS = 30; // cap frame rate at 30 fps to help keep cpu load down
private ulong TESTNEIGHBOR = 1099511628032256;
private uint objectmods = 5; // process object queue 2 times a second
private static Object mesh_synclock = new Object();
public static IrrlichtNETCP.Quaternion Cordinate_XYZ_XZY = new IrrlichtNETCP.Quaternion();
private TextureManager textureMan = null;
// experimental mesh code - only here temporarily - up top so it's visible
public Vector2D convVect2d(UVCoord uv)
{
return new Vector2D(uv.U, uv.V);
}
public Vector3D convVect3d(Coord c)
{// translate coordinates XYZ to XZY
return new Vector3D(c.Y, c.Z, c.X);
}
# region PrimTesting
public Mesh makeSamplePrim()
{
PrimMesh primMesh = new PrimMesh(24, 0.0f, 1.0f, 0.0f, 24);
primMesh.ExtrudeCircular();
//primMesh.CalcNormals(); // surface normals for now
primMesh.Scale(128.0f, 128.0f, 128.0f);
Mesh mesh = new Mesh();
MeshBuffer mb = new MeshBuffer(VertexType.Standard);
for (uint index = 0; index < primMesh.coords.Count; index++)
{
Vertex3D vert = new Vertex3D();
vert.Position = convVect3d(primMesh.coords[(int)index]);
//vert.Normal = convVect3d(primMesh.normals[(int)index]);
vert.Color = new Color(255, 128, 0, 0);
mb.SetVertex(index, vert);
}
uint nr = 0;
int faceIndex = 0;
foreach (Face f in primMesh.faces)
{
Vector3D surfaceNormal = convVect3d(primMesh.SurfaceNormal(faceIndex));
mb.SetIndex(nr++, (ushort)f.v1);
mb.SetIndex(nr++, (ushort)f.v2);
mb.SetIndex(nr++, (ushort)f.v3);
mb.GetVertex((ushort)f.v1).Normal = surfaceNormal;
mb.GetVertex((ushort)f.v2).Normal = surfaceNormal;
mb.GetVertex((ushort)f.v3).Normal = surfaceNormal;
faceIndex++;
}
mesh.AddMeshBuffer(mb);
//mb.Dispose();
return mesh;
}
public Mesh makeSamplePrimNew()
{
PrimMesh primMesh = new PrimMesh(24, 0.0f, 1.0f, 0.0f, 24);
primMesh.viewerMode = true;
primMesh.ExtrudeCircular();
primMesh.Scale(128.0f, 128.0f, 128.0f);
Mesh mesh = new Mesh();
MeshBuffer mb = new MeshBuffer(VertexType.Standard);
Color color = new Color(255, 128, 0, 0);
uint index = 0;
for (uint vfIndex = 0; vfIndex < primMesh.viewerFaces.Count; vfIndex++)
{
ViewerFace vf = primMesh.viewerFaces[(int)vfIndex];
mb.SetVertexT2(index, new Vertex3DT2(convVect3d(vf.v1), convVect3d(vf.n1), color, convVect2d(vf.uv1), convVect2d(vf.uv1)));
mb.SetIndex(vfIndex, (ushort)index++);
mb.SetVertexT2(index++, new Vertex3DT2(convVect3d(vf.v2), convVect3d(vf.n2), color, convVect2d(vf.uv2), convVect2d(vf.uv2)));
mb.SetIndex(vfIndex, (ushort)index++);
mb.SetVertexT2(index++, new Vertex3DT2(convVect3d(vf.v3), convVect3d(vf.n3), color, convVect2d(vf.uv3), convVect2d(vf.uv3)));
mb.SetIndex(vfIndex, (ushort)index++);
}
mesh.AddMeshBuffer(mb);
return mesh;
}
public void generateRandomPrim(int count)
{
Random rnd = new Random(System.Environment.TickCount);
// dahlia's sample prim
for (int j = 0; j < count; j++)
{
Mesh samplePrim = makeSamplePrim();
if (samplePrim != null)
{
SceneNode samplePrimNode = smgr.AddMeshSceneNode(samplePrim, smgr.RootSceneNode, -1);
samplePrimNode.Position = new Vector3D((float)(rnd.NextDouble() * 256), (float)(rnd.NextDouble() * 256), (float)(rnd.NextDouble() * 256));
samplePrimNode.Scale = new Vector3D(0.1f, 0.1f, 0.1f);
samplePrimNode.SetMaterialFlag(MaterialFlag.Lighting, true);
}
m_log.Debug(j);
}
}
#endregion
private static Queue<ulong> m_dirtyTerrain = new Queue<ulong>();
/// <summary>
/// Time at which this server was started
/// </summary>
protected DateTime m_startuptime;
/// <summary>
/// Record the initial startup directory for info purposes
/// </summary>
protected string m_startupDirectory = Environment.CurrentDirectory;
/// <summary>
/// Server version information. Usually VersionInfo + information about svn revision, operating system, etc.
/// </summary>
protected string m_version;
protected ConsoleBase m_console;
public BaseIdealistViewer(IConfigSource iconfig)
{
m_config = new IdealistViewerConfigSource();
m_config.Source = new IniConfigSource();
string iniconfig = Path.Combine(Util.configDir(), "IdealistViewer.ini");
if (File.Exists(iniconfig))
{
m_config.Source.Merge(new IniConfigSource(iniconfig));
}
m_config.Source.Merge(iconfig);
m_startuptime = DateTime.Now;
}
public void startupGUI(object o)
{
device = new IrrlichtDevice(DriverType.OpenGL,
new Dimension2D(WindowWidth, WindowHeight),
32, false, true, false, true);
/*Now we set the caption of the window to some nice text. Note that there is a 'L' in front of the string: the Irrlicht Engine uses
wide character strings when displaying text.
*/
device.WindowCaption = "IdealistViewer 0.000000000001f";
device.FileSystem.WorkingDirectory = m_startupDirectory + "\\" + Util.MakePath("media", "materials", "textures", ""); //We set Irrlicht's current directory to %application directory%/media
//
driver = device.VideoDriver;
smgr = device.SceneManager;
guienv = device.GUIEnvironment;
device.OnEvent += new OnEventDelegate(device_OnEvent);
if (loadTextures)
textureMan = new TextureManager(device, driver, "IdealistCache", avatarConnection);
//guienv.AddStaticText("Hello World! This is the Irrlicht Software engine!",
// new Rect(new Position2D(10, 10), new Dimension2D(200, 22)), true, false, guienv.RootElement, -1, false);
//Image img =
//
cam = new Camera(smgr);
smgr.SetAmbientLight(new Colorf(0, 0.5f, 0.5f, 0.5f));
//AnimatedMesh mesh = smgr.GetMesh("sydney.md2");
//AnimatedMeshSceneNode node = smgr.AddAnimatedMeshSceneNode(mesh);
//if (node != null)
//{
// node.SetMaterialFlag(MaterialFlag.Lighting, false);
// node.SetFrameLoop(0, 310);
// node.SetMaterialTexture(0, driver.GetTexture("sydney.bmp"));
// node.Position = new Vector3D(128, 32, 128);
//}
//we add the skybox which we already used in lots of Irrlicht examples.
driver.SetTextureFlag(TextureCreationFlag.CreateMipMaps, false);
smgr.AddSkyBoxSceneNode(null, new Texture[] {
driver.GetTexture("irrlicht2_up.jpg"),
driver.GetTexture("irrlicht2_dn.jpg"),
driver.GetTexture("irrlicht2_lf.jpg"),
driver.GetTexture("irrlicht2_rt.jpg"),
driver.GetTexture("irrlicht2_ft.jpg"),
driver.GetTexture("irrlicht2_bk.jpg")}, 0);
driver.SetTextureFlag(TextureCreationFlag.CreateMipMaps, true);
SceneNode light = smgr.AddLightSceneNode(smgr.RootSceneNode, new Vector3D(0, 0, 0), new Colorf(1, 1, 1, 1), 90, -1);
Animator anim = smgr.CreateFlyCircleAnimator(new Vector3D(128, 250, 128), 250.0f, 0.0010f);
light.AddAnimator(anim);
anim.Dispose();
SceneNode light2 = smgr.AddLightSceneNode(smgr.RootSceneNode, new Vector3D(0, 255, 0), new Colorf(0, 0.9f, 0.9f, 0.9f), 250, -1);
// dahlia's sample prim
//Mesh samplePrim = makeSamplePrim();
//if (samplePrim != null)
//{
// SceneNode samplePrimNode = smgr.AddMeshSceneNode(samplePrim, smgr.RootSceneNode, -1);
// samplePrimNode.Position = new Vector3D(128,64,128);
// samplePrimNode.SetMaterialFlag(MaterialFlag.Lighting, true);
//}
//generateRandomPrim(4000);
AnimatedMesh mesh = smgr.AddHillPlaneMesh("myHill",
new Dimension2Df(120, 120),
new Dimension2D(40, 40), 0,
new Dimension2Df(0, 0),
new Dimension2Df(10, 10));
SNGlobalwater = smgr.AddWaterSurfaceSceneNode(mesh.GetMesh(0),
0.4f, 300.0f, 12.0f, smgr.RootSceneNode, -1);
SNGlobalwater.SetMaterialTexture(0, driver.GetTexture("water.jpg"));
SNGlobalwater.SetMaterialTexture(1, driver.GetTexture("water2.tga"));
SNGlobalwater.SetMaterialType(MaterialType.TransparentReflection2Layer);
SNGlobalwater.SetMaterialFlag(MaterialFlag.NormalizeNormals, true);
SNGlobalwater.Position = new Vector3D(0, 0, 0);
mts = smgr.CreateMetaTriangleSelector();
int minFrameTime = (int)(1.0f / maxFPS);
bool running = true;
while (running)
{
try
{
running = device.Run();
}
catch (AccessViolationException)
{
m_log.Error("[VIDEO]: Error in device");
}
if (!running)
break;
tickcount = System.Environment.TickCount;
UpdateTerrain();
//cam.Position = new Vector3D(cam.Position.X , cam.Position.Y, cam.Position.Z- 0.5f);
//cam.Target = new Vector3D(0, 0, 0);//cam.Target.X - 0.5f, cam.Target.Y, cam.Target.Z);
driver.BeginScene(true, true, new Color(255, 100, 101, 140));
smgr.DrawAll();
guienv.DrawAll();
driver.Draw3DTriangle(new Triangle3D(
new Vector3D(0, 0, 0),
new Vector3D(10, 0, 0),
new Vector3D(0, 10, 0)),
Color.Red);
//m_log.Debug(driver.FPS);
driver.EndScene();
mscounter += System.Environment.TickCount - tickcount;
msreset = 55;
//
if (mscounter > msreset)
{
processHeldKeys();
mscounter = 0;
framecounter++;
if (framecounter == uint.MaxValue)
framecounter = 0;
}
if ((framecounter % objectmods) == 0)
{
doObjectMods(5);
CheckAndApplyParent(5);
}
//Thread.Sleep(50);
int frameTime = System.Environment.TickCount - tickcount;
if (frameTime < minFrameTime)
Thread.Sleep(minFrameTime - frameTime);
//Thread.Sleep(50);
}
//In the end, delete the Irrlicht device.
Shutdown();
}
#region Object Management
public void enqueueVObject(VObject newObject)
{
if (newObject.mesh != null)
{
lock (Entities)
{
if (!Entities.ContainsKey(VUtil.GetHashId(newObject)))
{
Entities.Add(VUtil.GetHashId(newObject), newObject);
}
else
{
// Full object update
//m_log.Warn("[NEWPRIM] ");
}
}
objectModQueue.Enqueue(newObject);
}
}
private void doObjectMods(int pObjects)
{
for (int i = 0; i < pObjects; i++)
{
if (objectModQueue.Count == 0)
break;
VObject vObj = objectModQueue.Dequeue();
if (vObj.prim != null)
{
ulong simhandle = vObj.prim.RegionHandle;
if (simhandle == 0)
simhandle = TESTNEIGHBOR;
Vector3 WorldoffsetPos = Vector3.Zero;
if (currentSim != null)
{
if (simhandle != currentSim.Handle)
{
Vector3 gposr = Util.OffsetGobal(simhandle, Vector3.Zero);
Vector3 gposc = Util.OffsetGobal(currentSim.Handle, Vector3.Zero);
WorldoffsetPos = gposr - gposc;
}
}
VObject parentObj = null;
SceneNode parentNode = smgr.RootSceneNode;
//VObject vObj = UnAssignedChildObjectModQueue.Dequeue();
//if (Entities.ContainsKey(vObj.prim.RegionHandle.ToString() + vObj.prim.ParentID.ToString()))
//{
if (vObj.prim.ParentID != 0)
{
lock (Entities)
{
if (Entities.ContainsKey(simhandle.ToString() + vObj.prim.ParentID.ToString()))
{
parentObj = Entities[simhandle.ToString() + vObj.prim.ParentID.ToString()];
if (parentObj.node != null)
{
//parentNode = parentObj.node;
//pscalex = parentObj.prim.Scale.X;
//pscaley = parentObj.prim.Scale.Y;
//pscalez = parentObj.prim.Scale.Z;
}
else
{
UnAssignedChildObjectModQueue.Enqueue(vObj);
}
}
}
}
//}
bool creatednode = false;
SceneNode node = null;
if (vObj.node == null)
{
node = smgr.AddMeshSceneNode(vObj.mesh, parentNode, (int)vObj.prim.LocalID);
creatednode = true;
vObj.node = node;
}
else
{
node = vObj.node;
}
node.Scale = new Vector3D(vObj.prim.Scale.X, vObj.prim.Scale.Z , vObj.prim.Scale.Y);
// m_log.WarnFormat("[SCALE]: <{0},{1},{2}> = <{3},{4},{5}>", vObj.prim.Scale.X, vObj.prim.Scale.Z, vObj.prim.Scale.Y, pscalex, pscaley, pscalez);
if (vObj.prim.ParentID == 0)
{
node.Position = new Vector3D(WorldoffsetPos.X + vObj.prim.Position.X, WorldoffsetPos.Z + vObj.prim.Position.Z, WorldoffsetPos.Y + vObj.prim.Position.Y);
}
else
{
node.Position = new Vector3D(WorldoffsetPos.X + parentObj.prim.Position.X + vObj.prim.Position.X, WorldoffsetPos.Z + parentObj.prim.Position.Z + vObj.prim.Position.Z, WorldoffsetPos.Y + parentObj.prim.Position.Y + vObj.prim.Position.Y);
}
//m_log.Warn(vObj.prim.Rotation.ToString());
IrrlichtNETCP.Quaternion iqu = new IrrlichtNETCP.Quaternion(vObj.prim.Rotation.X, vObj.prim.Rotation.Z, vObj.prim.Rotation.Y, vObj.prim.Rotation.W);
iqu.makeInverse();
IrrlichtNETCP.Quaternion finalpos = iqu;
if (vObj.prim.ParentID != 0)
{
//IrrlichtNETCP.Quaternion parentrot = new IrrlichtNETCP.Quaternion(parentObj.node.Rotation.X, parentObj.node.Rotation.Y, parentObj.node.Rotation.Z);
// parentrot.makeInverse();
//parentrot = Cordinate_XYZ_XZY * parentrot;
//finalpos = parentrot * iqu;
}
finalpos = Cordinate_XYZ_XZY * finalpos;
node.Rotation = finalpos.Matrix.RotationDegrees;
if (creatednode)
{
node.SetMaterialTexture(0, driver.GetTexture("red_stained_wood.tga"));
node.SetMaterialFlag(MaterialFlag.NormalizeNormals, true);
node.SetMaterialFlag(MaterialFlag.BackFaceCulling, false);
node.SetMaterialFlag(MaterialFlag.GouraudShading, true);
TriangleSelector trisel = smgr.CreateTriangleSelector(vObj.mesh, node);
node.TriangleSelector = trisel;
lock (mts)
{
mts.AddTriangleSelector(trisel);
}
if (vObj.prim.Textures != null)
{
if (vObj.prim.Textures.DefaultTexture != null)
{
if (vObj.prim.Textures.DefaultTexture.TextureID != UUID.Zero)
{
UUID textureID = vObj.prim.Textures.DefaultTexture.TextureID;
if (textureMan != null)
textureMan.RequestImage(textureID, node);
}
}
if (vObj.prim.Textures.FaceTextures != null)
{
Primitive.TextureEntryFace[] objfaces = vObj.prim.Textures.FaceTextures;
for (int i2 = 0; i2 < objfaces.Length; i2++)
{
if (objfaces[i2] == null)
continue;
UUID textureID = objfaces[i2].TextureID;
if (textureID != UUID.Zero)
{
if (textureMan != null)
textureMan.RequestImage(textureID, node);
}
}
}
}
}
node.UpdateAbsolutePosition();
}
}
}
private void CheckAndApplyParent(int pObjects)
{
if (UnAssignedChildObjectModQueue.Count < pObjects)
pObjects = UnAssignedChildObjectModQueue.Count;
for (int i = 0; i < pObjects; i++)
{
if (objectModQueue.Count == 0)
break;
Vector3 WorldoffsetPos = Vector3.Zero;
VObject vObj = UnAssignedChildObjectModQueue.Dequeue();
ulong simhandle = vObj.prim.RegionHandle;
if (simhandle == 0)
simhandle = TESTNEIGHBOR;
if (Entities.ContainsKey(simhandle.ToString() + vObj.prim.ParentID.ToString()))
{
VObject parentObj = Entities[simhandle.ToString() + vObj.prim.ParentID.ToString()];
if (parentObj.node != null)
{
if (currentSim != null)
{
if (simhandle != currentSim.Handle)
{
Vector3 gposr = Util.OffsetGobal(simhandle, Vector3.Zero);
Vector3 gposc = Util.OffsetGobal(currentSim.Handle, Vector3.Zero);
WorldoffsetPos = gposr - gposc;
}
}
bool creatednode = false;
SceneNode node = null;
if (vObj.node == null)
{
node = smgr.AddMeshSceneNode(vObj.mesh, smgr.RootSceneNode, (int)vObj.prim.LocalID);
creatednode = true;
vObj.node = node;
}
else
{
node = vObj.node;
}
//parentObj.node.AddChild(node);
node.Scale = new Vector3D(vObj.prim.Scale.X, vObj.prim.Scale.Z, vObj.prim.Scale.Y);
//m_log.WarnFormat("[SCALE]: <{0},{1},{2}> = <{3},{4},{5}>", vObj.prim.Scale.X, vObj.prim.Scale.Z, vObj.prim.Scale.Y, parentObj.node.Scale.X, parentObj.node.Scale.Y, parentObj.node.Scale.Z);
node.Position = new Vector3D(WorldoffsetPos.X + parentObj.prim.Position.X + vObj.prim.Position.X, WorldoffsetPos.Z + parentObj.prim.Position.Z + vObj.prim.Position.Z, WorldoffsetPos.Y + parentObj.prim.Position.Y + vObj.prim.Position.Y);
//m_log.Warn(vObj.prim.Rotation.ToString());
IrrlichtNETCP.Quaternion iqu = new IrrlichtNETCP.Quaternion(vObj.prim.Rotation.X, vObj.prim.Rotation.Z, vObj.prim.Rotation.Y, vObj.prim.Rotation.W);
iqu.makeInverse();
//IrrlichtNETCP.Quaternion parentrot = new IrrlichtNETCP.Quaternion(parentObj.node.Rotation.X, parentObj.node.Rotation.Y, parentObj.node.Rotation.Z);
//parentrot.makeInverse();
//parentrot = Cordinate_XYZ_XZY * parentrot;
IrrlichtNETCP.Quaternion finalpos = iqu;
//IrrlichtNETCP.Quaternion finalpos = parentrot * iqu;
finalpos = Cordinate_XYZ_XZY * finalpos;
node.Rotation = finalpos.Matrix.RotationDegrees;
if (creatednode)
{
node.SetMaterialTexture(0, driver.GetTexture("red_stained_wood.tga"));
node.SetMaterialFlag(MaterialFlag.NormalizeNormals, true);
node.SetMaterialFlag(MaterialFlag.BackFaceCulling, false);
node.SetMaterialFlag(MaterialFlag.GouraudShading, true);
TriangleSelector trisel = smgr.CreateTriangleSelector(vObj.mesh, node);
node.TriangleSelector = trisel;
lock (mts)
{
mts.AddTriangleSelector(trisel);
}
if (vObj.prim.Textures != null)
{
if (vObj.prim.Textures.DefaultTexture != null)
{
if (vObj.prim.Textures.DefaultTexture.TextureID != UUID.Zero)
{
UUID textureID = vObj.prim.Textures.DefaultTexture.TextureID;
if (textureMan != null)
textureMan.RequestImage(textureID, node);
}
}
if (vObj.prim.Textures.FaceTextures != null)
{
Primitive.TextureEntryFace[] objfaces = vObj.prim.Textures.FaceTextures;
for (int i2 = 0; i2 < objfaces.Length; i2++)
{
if (objfaces[i2] == null)
continue;
UUID textureID = objfaces[i2].TextureID;
if (textureID != UUID.Zero)
{
if (textureMan != null)
textureMan.RequestImage(textureID, node);
}
}
}
}
}
node.UpdateAbsolutePosition();
}
else
{
m_log.Warn("[CHILDOBJ]: Found Parent Object but it doesn't have a SceneNode, Skipping");
UnAssignedChildObjectModQueue.Enqueue(vObj);
}
}
else
{
UnAssignedChildObjectModQueue.Enqueue(vObj);
}
}
}
#endregion
#region Console
/// <summary>
/// Set the level of log notices being echoed to the console
/// </summary>
/// <param name="setParams"></param>
private void SetConsoleLogLevel(string[] setParams)
{
ILoggerRepository repository = LogManager.GetRepository();
IAppender[] appenders = repository.GetAppenders();
IdealistViewerAppender consoleAppender = null;
foreach (IAppender appender in appenders)
{
if (appender.Name == "Console")
{
consoleAppender = (IdealistViewerAppender)appender;
break;
}
}
if (null == consoleAppender)
{
Notice("No appender named Console found (see the log4net config file for this executable)!");
return;
}
if (setParams.Length > 0)
{
Level consoleLevel = repository.LevelMap[setParams[0]];
if (consoleLevel != null)
consoleAppender.Threshold = consoleLevel;
else
Notice(
String.Format(
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
setParams[0]));
}
// If there is no threshold set then the threshold is effectively everything.
Level thresholdLevel
= (null != consoleAppender.Threshold ? consoleAppender.Threshold : log4net.Core.Level.All);
Notice(String.Format("Console log level is {0}", thresholdLevel));
}
/// <summary>
/// Runs commands issued by the server console from the operator
/// </summary>
/// <param name="command">The first argument of the parameter (the command)</param>
/// <param name="cmdparams">Additional arguments passed to the command</param>
public virtual void RunCmd(string command, string[] cmdparams)
{
switch (command)
{
case "help":
ShowHelp(cmdparams);
Notice("");
break;
case "set":
Set(cmdparams);
break;
case "show":
if (cmdparams.Length > 0)
{
Show(cmdparams);
}
break;
case "quit":
case "shutdown":
Shutdown();
break;
}
}
/// <summary>
/// Set an OpenSim parameter
/// </summary>
/// <param name="setArgs">
/// The arguments given to the set command.
/// </param>
public virtual void Set(string[] setArgs)
{
// Temporary while we only have one command which takes at least two parameters
if (setArgs.Length < 2)
return;
if (setArgs[0] == "log" && setArgs[1] == "level")
{
string[] setParams = new string[setArgs.Length - 2];
Array.Copy(setArgs, 2, setParams, 0, setArgs.Length - 2);
SetConsoleLogLevel(setParams);
}
}
/// <summary>
/// Show help information
/// </summary>
/// <param name="helpArgs"></param>
protected virtual void ShowHelp(string[] helpArgs)
{
if (helpArgs.Length == 0)
{
Notice("");
// TODO: not yet implemented
//Notice("help [command] - display general help or specific command help. Try help help for more info.");
Notice("quit - equivalent to shutdown.");
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
Notice("show info - show server information (e.g. startup path).");
//if (m_stats != null)
// Notice("show stats - show statistical information for this server");
Notice("show threads - list tracked threads");
Notice("show uptime - show server startup time and uptime.");
Notice("show version - show server version.");
Notice("shutdown - shutdown the server.\n");
return;
}
}
/// <summary>
/// Outputs to the console information about the region
/// </summary>
/// <param name="showParams">
/// What information to display (valid arguments are "uptime", "users", ...)
/// </param>
public virtual void Show(string[] showParams)
{
switch (showParams[0])
{
case "info":
Notice("Version: " + m_version);
Notice("Startup directory: " + m_startupDirectory);
break;
case "version":
Notice("Version: " + m_version);
break;
}
}
/// <summary>
/// Console output is only possible if a console has been established.
/// That is something that cannot be determined within this class. So
/// all attempts to use the console MUST be verified.
/// </summary>
private void Notice(string msg)
{
if (m_console != null)
{
m_console.Notice(msg);
}
}
#endregion
#region Startup
/// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary>
public virtual void Startup()
{
m_log.Info("[STARTUP]: Beginning startup processing");
m_version = Util.EnhanceVersionInformation();
m_log.Info("[STARTUP]: Version: " + m_version + "\n");
StartupSpecific();
TimeSpan timeTaken = DateTime.Now - m_startuptime;
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
}
/// <summary>
/// Must be overriden by child classes for their own server specific startup behaviour.
/// </summary>
protected void StartupSpecific()
{
m_console = new ConsoleBase("Region", this);
IConfig cnf = m_config.Source.Configs["Startup"];
string loginURI = "http://127.0.0.1:9000/";
string firstName = string.Empty;
string lastName = string.Empty;
string password = string.Empty;
bool loadtextures = true;
if (cnf != null)
{
loginURI = cnf.GetString("login_uri", "");
firstName = cnf.GetString("first_name", "test");
lastName = cnf.GetString("last_name", "user");
password = cnf.GetString("pass_word", "nopassword");
loadtextures = cnf.GetBoolean("load_textures", true);
}
loadTextures = loadtextures;
MainConsole.Instance = m_console;
avatarConnection = new SLProtocol();
avatarConnection.OnLandPatch += landPatchCallback;
avatarConnection.OnGridConnected += connectedCallback;
avatarConnection.OnNewPrim += newPrimCallback;
avatarConnection.OnSimConnected += SimConnectedCallback;
avatarConnection.OnObjectUpdated += objectUpdatedCallback;
avatarConnection.OnObjectKilled += objectKilledCallback;
guithread = new Thread(new ParameterizedThreadStart(startupGUI));
guithread.Start();
IrrlichtNETCP.Matrix4 m4 = new IrrlichtNETCP.Matrix4();
m4.SetM(0, 0, 1);
m4.SetM(1, 0, 0);
m4.SetM(2, 0, 0);
m4.SetM(3, 0, 0);
m4.SetM(0, 1, 0);
m4.SetM(1, 1, 0);
m4.SetM(2, 1, 1);
m4.SetM(3, 1, 0);
m4.SetM(0, 2, 0);
m4.SetM(1, 2, 1);
m4.SetM(2, 2, 0);
m4.SetM(3, 2, 0);
m4.SetM(0, 3, 0);
m4.SetM(1, 3, 0);
m4.SetM(2, 3, 0);
m4.SetM(3, 3, 1);
Cordinate_XYZ_XZY = new IrrlichtNETCP.Quaternion(m4);
Cordinate_XYZ_XZY.makeInverse();
//Cordinate_XYZ_XZY = (CoordinateConversion.
avatarConnection.BeginLogin(loginURI, firstName + " " + lastName, password);
//base.StartupSpecific();
}
#endregion
#region ShutDown
/// <summary>
/// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
/// </summary>
public virtual void Shutdown()
{
ShutdownSpecific();
m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
Environment.Exit(0);
}
/// <summary>
/// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
/// </summary>
protected void ShutdownSpecific()
{
device.Close();
device.Dispose();
avatarConnection.Logout();
//base.ShutdownSpecific();
}
#endregion
public void UpdateTerrain()
{
lock (m_dirtyTerrain)
{
while (m_dirtyTerrain.Count > 0)
{
ulong regionhandle = m_dirtyTerrain.Dequeue();
//m_log.Warn("[TERRAIN]: RegionHandle:" + regionhandle.ToString());
string filename = "myterrain1" + regionhandle.ToString() + ".bmp";
string path = Util.MakePath("media", "materials", "textures", filename);
System.Drawing.Bitmap terrainbmp = terrainBitmap[regionhandle];
lock (terrainbmp)
{
Util.SaveBitmapToFile(terrainbmp, m_startupDirectory + "\\" + path);
}
device.FileSystem.WorkingDirectory = m_startupDirectory + "\\" + Util.MakePath("media", "materials", "textures", "");
TerrainSceneNode terrain = null;
lock (terrains)
{
if (terrains.ContainsKey(regionhandle))
{
terrain = terrains[regionhandle];
terrains.Remove(regionhandle);
}
}
lock (mesh_synclock)
{
if (terrain != null)
{
smgr.AddToDeletionQueue(terrain);
}
Vector3 relTerrainPos = Vector3.Zero;
if (currentSim != null)
{
if (currentSim.Handle != regionhandle)
{
Vector3 Offsetcsg = Util.OffsetGobal(currentSim.Handle, Vector3.Zero);
Vector3 Offsetnsg = Util.OffsetGobal(regionhandle, Vector3.Zero);
relTerrainPos = Offsetnsg - Offsetcsg;
}
}
terrain = smgr.AddTerrainSceneNode(
filename, smgr.RootSceneNode, -1,
new Vector3D(relTerrainPos.X - 4f, relTerrainPos.Z, relTerrainPos.Y + 16f), new Vector3D(0, 270, 0), new Vector3D(1, 1, 1), new Color(255, 255, 255, 255), 3, TerrainPatchSize.TPS17);
//device.FileSystem.WorkingDirectory = "./media/";
terrain.SetMaterialFlag(MaterialFlag.Lighting, true);
terrain.SetMaterialType(MaterialType.DetailMap);
terrain.SetMaterialFlag(MaterialFlag.NormalizeNormals, true);
terrain.SetMaterialTexture(0, driver.GetTexture("Green_Grass_Detailed.tga"));
//terrain.SetMaterialTexture(1, driver.GetTexture("detailmap3.jpg"));
terrain.ScaleTexture(16, 16);
terrain.Scale = new Vector3D(1.0275f, 1, 1.0275f);
}
lock (terrains)
{
terrains.Add(regionhandle, terrain);
}
TriangleSelector terrainsel;
lock (terrainsels)
{
if (terrainsels.ContainsKey(regionhandle))
{
mts.RemoveTriangleSelector(terrainsels[regionhandle]);
terrainsels.Remove(regionhandle);
}
}
terrainsel = smgr.CreateTerrainTriangleSelector(terrain, 1);
terrain.TriangleSelector = terrainsel;
lock (terrainsels)
{
terrainsels.Add(regionhandle, terrainsel);
}
mts.AddTriangleSelector(terrainsel);
//Vector3D terrainpos = terrain.TerrainCenter;
//terrainpos.Z = terrain.TerrainCenter.Z - 100f;
//terrain.Position = terrainpos;
//m_log.DebugFormat("[TERRAIN]:<{0},{1},{2}>", terrain.TerrainCenter.X, terrain.TerrainCenter.Y, terrain.TerrainCenter.Z);
//terrain.ScaleTexture(1f, 1f);
if (currentSim != null)
{
if (currentSim.Handle == regionhandle)
{
cam.SNCamera.Target = terrain.TerrainCenter;
cam.UpdateCameraPosition();
}
}
}
}
}
#region LibOMV Callbacks
public void newPrimCallback(Simulator sim, Primitive prim, ulong regionHandle,
ushort timeDilation)
{
//System.Console.WriteLine(prim.ToString());
//return;
VObject newObject = null;
//bool foundEntity = false;
lock (Entities)
{
if (Entities.ContainsKey(regionHandle.ToString() + prim.LocalID.ToString()))
{
//foundEntity = true;
newObject = Entities[regionHandle.ToString() + prim.LocalID.ToString()];
}
}
if (newObject != null)
{
if (newObject.node != null)
{
smgr.AddToDeletionQueue(newObject.node);
newObject.node = null;
}
}
lock (mesh_synclock)
{
newObject = VUtil.NewVObject(prim,newObject);
}
if (prim.ParentID != 0)
{
bool foundEntity = false;
lock (Entities)
{
if (!Entities.ContainsKey(regionHandle.ToString() + prim.ParentID.ToString()))
{
UnAssignedChildObjectModQueue.Enqueue(newObject);
}
else
{
foundEntity = true;
}
}
if (foundEntity)
{
enqueueVObject(newObject);
}
}
else
{
enqueueVObject(newObject);
}
}
private void landPatchCallback(Simulator sim, int x, int y, int width, float[] data)
{
ulong simhandle = sim.Handle;
if (simhandle == 0)
simhandle = TESTNEIGHBOR;
if (x < 0 || x > 15 || y < 0 || y > 15)
{
m_log.WarnFormat("Invalid land patch ({0}, {1}) received from server", x, y);
return;
}
if (width != 16)
{
m_log.WarnFormat("Unsupported land patch width ({0}) received from server", width);
return;
}
Dictionary<int, float[]> m_landMap;
lock (m_landmaps)
{
if (m_landmaps.ContainsKey(simhandle))
m_landMap = m_landmaps[simhandle];
else
{
m_log.Warn("[TERRAIN]: Warning landmap update XY for land that isn't found");
return;
}
}
lock (m_landMap)
{
if (!m_landMap.ContainsKey(y * 16 + x))
{
m_landMap.Add(y * 16 + x, data);
}
else
{
m_landMap[y * 16 + x] = data;
}
}
updateTerrainBitmap(x, y, sim);
lock (m_dirtyTerrain)
{
if (!m_dirtyTerrain.Contains(simhandle))
{
m_dirtyTerrain.Enqueue(simhandle);
}
}
}
private void updateTerrainBitmap(int x, int y, Simulator sim)
{
Dictionary<int, float[]> m_landMap;
ulong simhandle = sim.Handle;
if (simhandle == 0)
simhandle = TESTNEIGHBOR;
lock (m_landmaps)
{
if (m_landmaps.ContainsKey(simhandle))
{
m_landMap = m_landmaps[simhandle];
}
else
{
m_log.Warn("[TERRAIN]: Warning got terrain update for unknown simulator");
return;
}
}
if (!m_landMap.ContainsKey(y * 16 + x))
{
m_log.Error("Trying to update terrain on a land patch we don't have.");
return;
}
float[] currentPatch = m_landMap[y * 16 + x];
System.Drawing.Bitmap terrainbitmap;
lock (terrainBitmap)
{
if (terrainBitmap.ContainsKey(simhandle))
{
terrainbitmap = terrainBitmap[simhandle];
}
else
{
m_log.Warn("[TERRAIN]:Unable to locate terrain bitmap to write terrain update to");
return;
}
}
lock (terrainbitmap)
{
for (int cy = 0; cy < 16; cy++)
{
for (int cx = 0; cx < 16; cx++)
{
int bitmapx = cx + x * 16;
int bitmapy = cy + y * 16;
//int col = (int)(Util.Clamp(currentPatch[cy * 16 + cx] / 255, 0.0f, 1.0f) * 255);
float col = 0;
col = currentPatch[cy * 16 + cx];
if (col > 1000f || col < 0)
col = 0f;
col *= 0.00388f;
//m_log.Debug("[COLOR]: " + currentPatch[cy * 16 + cx].ToString());
//terrainbitmap.SetPixel(bitmapy, bitmapx, System.Drawing.Color.FromArgb(col, col, col));
terrainbitmap.SetPixel(bitmapy, bitmapx, Util.FromArgbf(1,col,col,col));
}
}
}
}
protected void connectedCallback()
{
}
protected void SimConnectedCallback(Simulator sim)
{
bool isCurrentSim = false;
ulong simhandle = sim.Handle;
m_log.Warn("Connected to sim with:" + simhandle);
if (simhandle == 0)
simhandle = TESTNEIGHBOR;
if (currentSim == null)
{
currentSim = sim;
isCurrentSim = true;
}
else
{
if (currentSim.Handle == simhandle)
{
isCurrentSim = true;
}
}
lock (Simulators)
{
if (!Simulators.ContainsKey(simhandle))
{
Simulators.Add(simhandle, sim);
if (!terrainBitmap.ContainsKey(simhandle))
{
terrainBitmap.Add(simhandle, new System.Drawing.Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format24bppRgb));
Dictionary<int, float[]> m_landMap = new Dictionary<int, float[]>();
if (!m_landmaps.ContainsKey(simhandle))
{
m_landmaps.Add(simhandle, m_landMap);
}
lock (m_dirtyTerrain)
{
if (!m_dirtyTerrain.Contains(simhandle))
{
m_dirtyTerrain.Enqueue(simhandle);
}
}
}
}
}
if (isCurrentSim)
{
SNGlobalwater.Position = new Vector3D(0, sim.WaterHeight-0.5f, 0);
//SNGlobalwater.Position = new Vector3D(0, sim.WaterHeight - 50.5f, 0);
// TODO REFIX!
}
}
private void objectUpdatedCallback(Simulator simulator, ObjectUpdate update, ulong regionHandle,
ushort timeDilation)
{
VObject obj = null;
if (!update.Avatar)
{
lock (Entities)
{
if (Entities.ContainsKey(regionHandle.ToString() + update.LocalID.ToString()))
{
obj = Entities[regionHandle.ToString() + update.LocalID.ToString()];
obj.prim.Acceleration = update.Acceleration;
obj.prim.AngularVelocity = update.AngularVelocity;
obj.prim.CollisionPlane = update.CollisionPlane;
obj.prim.Position = update.Position;
obj.prim.Rotation = update.Rotation;
obj.prim.PrimData.State = update.State;
obj.prim.Textures = update.Textures;
obj.prim.Velocity = update.Velocity;
Entities[regionHandle.ToString() + update.LocalID.ToString()] = obj;
}
}
if (obj != null)
enqueueVObject(obj);
}
}
private void objectKilledCallback(Simulator psim, uint pLocalID)
{
ulong regionHandle = psim.Handle;
m_log.Debug("[DELETE]: obj " + regionHandle.ToString() + ":" + pLocalID.ToString());
lock (Entities)
{
if (Entities.ContainsKey(regionHandle.ToString() + pLocalID.ToString()))
{
VObject obj = Entities[regionHandle.ToString() + pLocalID.ToString()];
if (obj.node != null)
{
smgr.AddToDeletionQueue(obj.node);
obj.node = null;
}
Entities.Remove(regionHandle.ToString() + pLocalID.ToString());
}
}
}
private void newAvatarCallback(Simulator sim, Avatar avatar, ulong regionHandle,
ushort timeDilation)
{
}
#endregion
#region KeyActions
private void processHeldKeys()
{
lock (m_heldKeys)
{
foreach (KeyCode ky in m_heldKeys)
{
doHeldKeyActions(ky);
}
}
}
private void doHeldKeyActions(KeyCode ky)
{
switch (ky)
{
case KeyCode.Up:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
cam.DoKeyAction(ky);
}
}
break;
case KeyCode.Down:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
cam.DoKeyAction(ky);
}
}
break;
case KeyCode.Left:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
//vOrbit.X -= 2f;
cam.DoKeyAction(ky);
}
}
break;
case KeyCode.Right:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
//vOrbit.X += 2f;
//vOrbit.X -= 2f;
cam.DoKeyAction(ky);
}
}
break;
case KeyCode.Prior:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
//vOrbit.Y -= 2f;
cam.DoKeyAction(ky);
}
}
break;
case KeyCode.Next:
if (!shiftHeld && !ctrlHeld)
{
}
else
{
if (ctrlHeld)
{
cam.DoKeyAction(ky);
}
}
break;
}
}
public void doKeyHeldStore(KeyCode ky, bool held)
{
lock (m_heldKeys)
{
if (held)
{
if (!m_heldKeys.Contains(ky))
{
m_heldKeys.Add(ky);
}
}
else
{
if (m_heldKeys.Contains(ky))
{
m_heldKeys.Remove(ky);
}
}
}
}
#endregion
public bool device_OnEvent(Event p_event)
{
processHeldKeys();
if (p_event.Type != EventType.MouseInputEvent)
{
if (p_event.Type == EventType.KeyInputEvent)
{
switch (p_event.KeyCode)
{
case KeyCode.Control:
ctrlHeld = p_event.KeyPressedDown;
if (ctrlHeld)
{
cam.ResetMouseOffsets();
}
else
{
cam.ApplyMouseOffsets();
}
break;
case KeyCode.Shift:
shiftHeld = p_event.KeyPressedDown;
break;
case KeyCode.Up:
case KeyCode.Down:
case KeyCode.Left:
case KeyCode.Right:
case KeyCode.Prior:
case KeyCode.Next:
doKeyHeldStore(p_event.KeyCode,p_event.KeyPressedDown);
break;
}
}
}
if (p_event.Type == EventType.MouseInputEvent)
{
return MouseEventProcessor(p_event);
}
return true;
}
#region Mouse Handler
public bool MouseEventProcessor(Event p_event)
{
//m_log.DebugFormat("[MOOSE]:<{0},{1}>",p_event.MousePosition.X,p_event.MousePosition.Y);
if (p_event.MouseInputEvent == MouseInputEvent.MouseWheel)
{
//KeyCode.RButton
cam.MouseWheelAction(p_event.MouseWheelDelta);
}
if (p_event.MouseInputEvent == MouseInputEvent.LMouseLeftUp)
{
if (ctrlHeld)
{
//if (loMouseOffsetPHI != 0 || loMouseOffsetTHETA != 0)
//{
cam.ApplyMouseOffsets();
//}
}
LMheld = false;
}
if (p_event.MouseInputEvent == MouseInputEvent.LMousePressedDown)
{
LMheld = true;
if (ctrlHeld)
{
//OldMouseX = 0;
// OldMouseY = 0;
cam.ResetMouseOffsets();
Vector3D[] projection = cam.ProjectRayPoints(p_event.MousePosition, WindowWidth_DIV2,WindowHeight_DIV2, aspect);
Line3D projectedray = new Line3D(projection[0], projection[1]);
Vector3D collisionpoint = new Vector3D(0, 0, 0);
Triangle3D tri = new Triangle3D(0, 0, 0, 0, 0, 0, 0, 0, 0);
if (smgr.CollisionManager.GetCollisionPoint(projectedray, mts, out collisionpoint, out tri))
{
//if (collisionpoint != null)
//{
//m_log.DebugFormat("Found point: <{0},{1},{2}>", collisionpoint.X, collisionpoint.Y, collisionpoint.Z);
//}
cam.SetTarget(collisionpoint);
}
//else
//{
//if (smgr.CollisionManager.GetCollisionPoint(projectedray, terrainsel, out collisionpoint, out tri))
//{
//if (collisionpoint != null)
//{
//m_log.DebugFormat("Found point: <{0},{1},{2}>", collisionpoint.X, collisionpoint.Y, collisionpoint.Z);
//}
// cam.SetTarget(collisionpoint);
//}
//}
}
}
if (p_event.MouseInputEvent == MouseInputEvent.RMouseLeftUp)
{
RMheld = false;
}
if (p_event.MouseInputEvent == MouseInputEvent.RMousePressedDown)
{
RMheld = true;
}
if (p_event.MouseInputEvent == MouseInputEvent.MouseMoved)
{
//float pos1 = (float)((p_event.MousePosition.X / WindowWidth_DIV2 - 1.0f) / aspect);
//float pos2 = (float)(1.0f - p_event.MousePosition.Y / WindowHeight_DIV2);
if (LMheld && ctrlHeld)
{
int deltaX = p_event.MousePosition.X - OldMouseX;
int deltaY = p_event.MousePosition.Y - OldMouseY;
//loMouseOffsetTHETA = loMouseOffsetTHETA + (deltaX * CAMERASPEED);
//loMouseOffsetPHI = loMouseOffsetPHI + (deltaY * CAMERASPEED);
cam.SetDeltaFromMouse(deltaX, deltaY);
// m_log.DebugFormat("pos1:{0}, pos2{1}", deltaX, deltaY);
}
OldMouseX = p_event.MousePosition.X;
OldMouseY = p_event.MousePosition.Y;
}
return true;
}
#endregion
}
}
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

