Files
libremetaverse/applications/sceneviewer/Viewer.cs
bushing 2c9080561c It's Party Time\! (r213:HEAD)
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@279 52acb1d6-8a22-11de-b505-999d5b087335
2006-10-14 05:13:39 +00:00

254 lines
9.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using libsecondlife;
using sceneviewer.Prims;
namespace sceneviewer
{
/// <summary>
/// This is the main type for your game
/// </summary>
partial class Viewer : Microsoft.Xna.Framework.Game
{
private SecondLife Client;
private Dictionary<uint, PrimVisual> Prims;
// The shader effect that we're loading
private Effect effect;
// Variables describing the shapes being drawn
private VertexDeclaration vertexDeclaration;
// Matrices
//private Matrix WorldViewProjection;
//private Matrix World, Projection;
private Camera Camera;
// Variables for keeping track of the state of the mouse
private ButtonState PreviousLeftButton;
private Vector2 PreviousMousePosition;
public Viewer()
{
this.AllowUserResizing = true;
this.IsMouseVisible = true;
Window.ClientSizeChanged += new EventHandler(Window_ClientSizeChanged);
this.Exiting += new EventHandler<GameEventArgs>(Viewer_Exiting);
Camera = new Camera(this.Window, new Vector3(0, 0, 40), new Vector3(256, 256, 0));
PreviousLeftButton = ButtonState.Released;
Prims = new Dictionary<uint, PrimVisual>();
Hashtable loginParams = NetworkManager.DefaultLoginValues("Ron", "Hubbard",
"weneedaloginscreen", "00:00:00:00:00:00", "last", 1, 50, 50, 50, "Win", "0",
"botmanager", "contact@libsecondlife.org");
Client = new SecondLife();
Client.Objects.OnNewPrim += new NewPrimCallback(OnNewPrim);
Client.Objects.OnPrimMoved += new PrimMovedCallback(OnPrimMoved);
Client.Objects.OnObjectKilled += new KillObjectCallback(OnObjectKilled);
if (!Client.Network.Login(loginParams))
{
Exit();
}
InitializeComponent();
InitializeTransform();
InitializeEffect();
InitializeScene();
}
void Viewer_Exiting(object sender, GameEventArgs e)
{
Client.Network.Logout();
}
void Window_ClientSizeChanged(object sender, EventArgs e)
{
Camera.UpdateProjection();
}
void OnNewPrim(Simulator simulator, PrimObject prim, ulong regionHandle, ushort timeDilation)
{
PrimVisual primVisual = PrimVisual.BuildPrimVisual(prim);
if (primVisual.GetType() == typeof(PrimVisualBox))
{
lock (Prims)
{
Prims.Add(prim.LocalID, primVisual);
}
}
}
void OnPrimMoved(Simulator simulator, PrimUpdate primUpdate, ulong regionHandle, ushort timeDilation)
{
if (Prims.ContainsKey(primUpdate.LocalID))
{
Prims[primUpdate.LocalID].Update(primUpdate);
}
else
{
Client.Objects.RequestObject(simulator, primUpdate.LocalID);
}
}
void OnObjectKilled(Simulator simulator, uint localID)
{
lock (Prims)
{
Prims.Remove(localID);
}
}
private void InitializeTransform()
{
// set the World matrix to something
//World = Matrix.CreateTranslation(Vector3.Zero);
//WorldViewProjection = World * Camera.ViewMatrix * Projection;
}
private void InitializeEffect()
{
CompiledEffect compiledEffect = Effect.CompileEffectFromFile(
"ReallySimpleEffect.fx", null, null,
CompilerOptions.Debug |
CompilerOptions.SkipOptimization,
TargetPlatform.Windows);
effect = new Effect(graphics.GraphicsDevice,
compiledEffect.GetShaderCode(), CompilerOptions.None,
null);
}
private void InitializeScene()
{
vertexDeclaration = new VertexDeclaration(
graphics.GraphicsDevice, VertexPositionColor.VertexElements);
}
protected override void Update()
{
// The time since Update was called last
float elapsed = (float)ElapsedTime.TotalSeconds;
MouseState currentState = Mouse.GetState();
Camera.Zoom = currentState.ScrollWheelValue * 0.005f;
if (currentState.LeftButton == ButtonState.Pressed &&
PreviousLeftButton == ButtonState.Pressed)
{
Vector2 curMouse = new Vector2(currentState.X, currentState.Y);
Vector2 deltaMouse = PreviousMousePosition - curMouse;
Camera.Theta += deltaMouse.X * 0.01f;
Camera.Phi -= deltaMouse.Y * 0.005f;
PreviousMousePosition = curMouse;
}
// It's implied that the leftPreviousState is unpressed in this situation.
else if (currentState.LeftButton == ButtonState.Pressed)
{
PreviousMousePosition = new Vector2(currentState.X, currentState.Y);
}
PreviousLeftButton = currentState.LeftButton;
// Let the GameComponents update
UpdateComponents();
}
protected override void Draw()
{
Matrix ViewProjectionMatrix = Camera.ViewProjectionMatrix;
// Make sure we have a valid device
if (!graphics.EnsureDevice())
return;
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
graphics.GraphicsDevice.BeginScene();
// Let the GameComponents draw
DrawComponents();
Matrix World = Matrix.CreateTranslation(Vector3.Zero);
effect.Parameters["WorldViewProj"].SetValue(World * ViewProjectionMatrix);
effect.CurrentTechnique = effect.Techniques["TransformTechnique"];
effect.CommitChanges();
graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
graphics.GraphicsDevice.RenderState.FillMode = FillMode.Solid;
graphics.GraphicsDevice.RenderState.MultiSampleAntiAlias = true;
effect.Begin(EffectStateOptions.Default);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
lock (Prims)
{
foreach (PrimVisual prim in Prims.Values)
{
if (prim.Prim.ParentID != 0)
{
if (!Prims.ContainsKey(prim.Prim.ParentID))
{
// We don't have the base position for this child prim, can't render it
continue;
}
else
{
// Child prim in a linkset
// Add the base position of the parent prim and the offset position of this child
LLVector3 llBasePosition = Prims[prim.Prim.ParentID].Prim.Position;
LLQuaternion llBaseRotation = Prims[prim.Prim.ParentID].Prim.Rotation;
Vector3 basePosition = new Vector3(llBasePosition.X, llBasePosition.Y, llBasePosition.Z);
Matrix worldOffset = Matrix.CreateTranslation(basePosition);
Matrix rootRotation = Matrix.FromQuaternion(new Quaternion(llBaseRotation.X, llBaseRotation.Y,
llBaseRotation.Z, llBaseRotation.W));
effect.Parameters["WorldViewProj"].SetValue(prim.Matrix * rootRotation * worldOffset * ViewProjectionMatrix);
effect.CommitChanges();
graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
prim.VertexArray.Length / 3, prim.VertexArray);
}
}
else
{
// Root prim or not part of a linkset
effect.Parameters["WorldViewProj"].SetValue(prim.Matrix * ViewProjectionMatrix);
effect.CommitChanges();
graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
prim.VertexArray.Length / 3, prim.VertexArray);
}
}
}
pass.End();
}
effect.End();
graphics.GraphicsDevice.EndScene();
graphics.GraphicsDevice.Present();
}
}
}