diff --git a/applications/sceneviewer/Camera.cs b/applications/sceneviewer/Camera.cs index 5be0fb34..d48a0a16 100644 --- a/applications/sceneviewer/Camera.cs +++ b/applications/sceneviewer/Camera.cs @@ -67,6 +67,11 @@ namespace sceneviewer get { return _view * _projection; } } + public BoundingFrustum Frustum + { + get { return new BoundingFrustum(ViewProjectionMatrix); } + } + /// /// Gets the camera position /// diff --git a/applications/sceneviewer/Prims/LinearPrimVisual.cs b/applications/sceneviewer/Prims/LinearPrimVisual.cs index 0228ab14..b19d5f86 100644 --- a/applications/sceneviewer/Prims/LinearPrimVisual.cs +++ b/applications/sceneviewer/Prims/LinearPrimVisual.cs @@ -474,15 +474,27 @@ namespace sceneviewer.Prims // Top Shear transform.Translation = new Vector3(ratio * Prim.PathShearX, ratio * Prim.PathShearY, 0); - // FIXME: Taper - ; + // Taper + float xScale = 1.0f, yScale = 1.0f; + if (Prim.PathTaperX != 0) + { + float adjratio = (Prim.PathTaperX < 0) ? (1.0f - ratio) : (ratio); + xScale -= Math.Abs(Prim.PathTaperX) * adjratio; + } + if (Prim.PathTaperY != 0) + { + float adjratio = (Prim.PathTaperY < 0) ? (1.0f - ratio) : (ratio); + yScale -= Math.Abs(Prim.PathTaperY) * adjratio; + } + transform *= Matrix.CreateScale(xScale, yScale, 1.0f); - // Twist (TODO: Needs testing) + // Twist float twistBegin = (float)Prim.PathTwistBegin * MathHelper.Pi / 180.0f; float twistEnd = (float)Prim.PathTwist * MathHelper.Pi / 180.0f; float twist = (twistEnd - twistBegin) * ratio; transform *= Matrix.CreateRotationZ(-twist); + // Apply the transformation matrix to this point return Vector3.Transform(v, transform); } diff --git a/applications/sceneviewer/sceneviewer.cs b/applications/sceneviewer/sceneviewer.cs index 3b650c1a..020fca87 100644 --- a/applications/sceneviewer/sceneviewer.cs +++ b/applications/sceneviewer/sceneviewer.cs @@ -55,6 +55,7 @@ namespace sceneviewer // 3d world private Camera Camera; + private BoundingFrustum Frustum; private Matrix World; private Matrix ViewMatrix; private Matrix ViewProjectionMatrix; @@ -80,12 +81,12 @@ namespace sceneviewer // Water private VertexPosTexNormalTanBitan[] WaterVertexArray; - //private VertexPositionTexture[] WaterVertexArray; private VertexBuffer WaterVertexBuffer; private IndexBuffer WaterIndexBuffer; private VertexDeclaration WaterVertexDeclaration; private Texture2D WaterNormalMap; private TextureCube WaterReflectionCubemap; + private float WaterHeight; // Timer related private Timer CameraUpdateTimer; @@ -93,6 +94,7 @@ namespace sceneviewer // State tracking bool Wireframe = false; + bool FPSCounter = false; /// @@ -146,13 +148,14 @@ namespace sceneviewer // Wait for basic information to be retrieved from the current sim while ( - Client.Network.CurrentSim == null || Client.Network.CurrentSim.Region == null || Client.Network.CurrentSim.Region.Name == null) { System.Threading.Thread.Sleep(10); } + WaterHeight = Client.Network.CurrentSim.Region.WaterHeight; + // Initialize the engine InitializeTransform(); InitializeScene(); @@ -281,29 +284,34 @@ namespace sceneviewer protected override void Update(GameTime gameTime) { float elapsed = (float)gameTime.ElapsedRealTime.TotalSeconds; - + // Allows the default game to exit on Xbox 360 and Windows if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); - // Update the FPS counter - float fps = 1.0f / elapsed; - deltaFPSTime += elapsed; - if (deltaFPSTime > 0.1f) - { - Window.Title = fps.ToString() + " FPS"; - deltaFPSTime -= 0.1f; - } - // Update the keyboard and mouse state UpdateInput(); // Check for keypresses and keys that are currently held down HandleInput(); + // Update the camera matrices and bounding frustum ViewMatrix = Camera.ViewMatrix; ViewInverseMatrix = Matrix.Invert(ViewMatrix); ViewProjectionMatrix = Camera.ViewProjectionMatrix; + Frustum = Camera.Frustum; + + if (FPSCounter) + { + // Update the FPS counter + float fps = 1.0f / elapsed; + deltaFPSTime += elapsed; + if (deltaFPSTime > 0.5f) + { + Window.Title = fps.ToString() + " FPS"; + deltaFPSTime -= 0.1f; + } + } base.Update(gameTime); } @@ -444,6 +452,11 @@ namespace sceneviewer { Wireframe = !Wireframe; } + + if (KeyPressedThisFrame(Keys.D2)) + { + FPSCounter = !FPSCounter; + } } @@ -460,7 +473,7 @@ namespace sceneviewer //graphics.GraphicsDevice.RenderState.MultiSampleAntiAlias = true; RenderWater(gameTime); - //RenderBasicPrims(); + RenderBasicPrims(); base.Draw(gameTime); } @@ -471,7 +484,7 @@ namespace sceneviewer /// protected void RenderWater(GameTime gameTime) { - Matrix worldOffset = Matrix.CreateTranslation(new Vector3(0, 0, Client.Network.CurrentSim.Region.WaterHeight)); + Matrix worldOffset = Matrix.CreateTranslation(new Vector3(0, 0, WaterHeight)); Graphics.GraphicsDevice.VertexDeclaration = WaterVertexDeclaration; Graphics.GraphicsDevice.Vertices[0].SetSource(WaterVertexBuffer, 0, VertexPosTexNormalTanBitan.SizeInBytes); @@ -537,26 +550,30 @@ namespace sceneviewer Vector3 basePosition = new Vector3(llBasePosition.X, llBasePosition.Y, llBasePosition.Z); Matrix worldOffset = Matrix.CreateTranslation(basePosition); - Matrix rootRotation = Matrix.CreateFromQuaternion(new Quaternion(llBaseRotation.X, + Matrix rootRotation = Matrix.CreateFromQuaternion(new Quaternion(llBaseRotation.X, llBaseRotation.Y, llBaseRotation.Z, llBaseRotation.W)); EffectBasicPrim.Parameters["WorldViewProj"].SetValue(prim.Matrix * rootRotation * worldOffset * ViewProjectionMatrix); EffectBasicPrim.CommitChanges(); - - Graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, - prim.VertexArray, 0, prim.VertexArray.Length / 3); } } else { - // Root prim or not part of a linkset + // FIXME: We only do this test on unlinked objects for now, since child bounding boxes are + // still broken + //ContainmentType contain = Frustum.Contains(prim.BoundBox); + //if (contain == ContainmentType.Disjoint) + //{ + // continue; + //} + // Root prim or not part of a linkset EffectBasicPrim.Parameters["WorldViewProj"].SetValue(prim.Matrix * ViewProjectionMatrix); EffectBasicPrim.CommitChanges(); - - Graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, - prim.VertexArray, 0, prim.VertexArray.Length / 3); } + + Graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, + prim.VertexArray, 0, prim.VertexArray.Length / 3); } pass.End(); diff --git a/libsecondlife-cs/ObjectManager.cs b/libsecondlife-cs/ObjectManager.cs index 1d0599f2..9d661197 100644 --- a/libsecondlife-cs/ObjectManager.cs +++ b/libsecondlife-cs/ObjectManager.cs @@ -270,15 +270,15 @@ namespace libsecondlife prim.ProfileCurve = block.ProfileCurve; prim.PathBegin = PrimObject.PathBeginFloat(block.PathBegin); prim.PathEnd = PrimObject.PathEndFloat(block.PathEnd); - prim.PathScaleX = PrimObject.PathScaleFloat(block.PathScaleX); - prim.PathScaleY = PrimObject.PathScaleFloat(block.PathScaleY); + prim.PathTaperX = PrimObject.PathScaleFloat(block.PathScaleX); + prim.PathTaperY = PrimObject.PathScaleFloat(block.PathScaleY); prim.PathShearX = PrimObject.PathShearFloat(block.PathShearX); prim.PathShearY = PrimObject.PathShearFloat(block.PathShearY); prim.PathTwist = block.PathTwist; //PrimObject.PathTwistFloat(block.PathTwist); prim.PathTwistBegin = block.PathTwistBegin; //PrimObject.PathTwistFloat(block.PathTwistBegin); prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat(block.PathRadiusOffset); - prim.PathTaperX = PrimObject.PathTaperFloat((byte)block.PathTaperX); - prim.PathTaperY = PrimObject.PathTaperFloat((byte)block.PathTaperY); + //prim.PathTaperX = PrimObject.PathTaperFloat((byte)block.PathTaperX); + //prim.PathTaperY = PrimObject.PathTaperFloat((byte)block.PathTaperY); prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.PathRevolutions); prim.PathSkew = PrimObject.PathSkewFloat((byte)block.PathSkew); prim.ProfileBegin = PrimObject.ProfileBeginFloat(block.ProfileBegin); @@ -621,15 +621,16 @@ namespace libsecondlife prim.PathCurve = (uint)block.Data[i++]; prim.PathBegin = PrimObject.PathBeginFloat(block.Data[i++]); prim.PathEnd = PrimObject.PathEndFloat(block.Data[i++]); - prim.PathScaleX = PrimObject.PathScaleFloat(block.Data[i++]); - prim.PathScaleY = PrimObject.PathScaleFloat(block.Data[i++]); + prim.PathTaperX = PrimObject.PathScaleFloat(block.Data[i++]); + prim.PathTaperY = PrimObject.PathScaleFloat(block.Data[i++]); prim.PathShearX = PrimObject.PathShearFloat(block.Data[i++]); prim.PathShearY = PrimObject.PathShearFloat(block.Data[i++]); prim.PathTwist = (int)block.Data[i++]; prim.PathTwistBegin = (int)block.Data[i++]; prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat((sbyte)block.Data[i++]); - prim.PathTaperX = PrimObject.PathTaperFloat(block.Data[i++]); - prim.PathTaperY = PrimObject.PathTaperFloat(block.Data[i++]); + //prim.PathTaperX = PrimObject.PathTaperFloat(block.Data[i++]); + //prim.PathTaperY = PrimObject.PathTaperFloat(block.Data[i++]); + i += 2; prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.Data[i++]); prim.PathSkew = PrimObject.PathSkewFloat(block.Data[i++]); diff --git a/libsecondlife-cs/Prims.cs b/libsecondlife-cs/Prims.cs index 104960da..446d6875 100644 --- a/libsecondlife-cs/Prims.cs +++ b/libsecondlife-cs/Prims.cs @@ -138,7 +138,7 @@ namespace libsecondlife public static byte PathScaleByte(float pathScale) { // Y = 100 + 100X - return (byte)(100 + Convert.ToInt16(100.0F * pathScale)); + return (byte)(100 + Convert.ToInt16(100.0f * pathScale)); } /// @@ -149,7 +149,7 @@ namespace libsecondlife public static float PathScaleFloat(byte pathScale) { // Y = -1 + 0.01X - return (float)pathScale * 0.01F - 1.0F; + return (float)Math.Round((double)pathScale * 0.01d - 1.0d, 4); } /// @@ -160,21 +160,10 @@ namespace libsecondlife public static sbyte PathTwistByte(float pathTwist) { // Y = 256 + ceil (X / 1.8) - ushort temp = Convert.ToUInt16(256 + Math.Ceiling(pathTwist / 1.8F)); + ushort temp = Convert.ToUInt16(256 + Math.Ceiling(pathTwist / 1.8f)); return (sbyte)(temp % 256); } - /*/// - /// - /// - /// - /// - public static float PathTwistFloat(sbyte pathTwist) - { - // Y = 0.5556X - return (float)pathTwist * 0.5556F; - }*/ - /// /// /// @@ -183,7 +172,7 @@ namespace libsecondlife public static byte PathShearByte(float pathShear) { // Y = 256 + 100X - ushort temp = Convert.ToUInt16(100.0F * pathShear); + ushort temp = Convert.ToUInt16(100.0f * pathShear); temp += 256; return (byte)(temp % 256); } @@ -195,15 +184,19 @@ namespace libsecondlife /// public static float PathShearFloat(byte pathShear) { - // Y = (X - 256) / 100 + if (pathShear == 0) return 0.0f; + if (pathShear > 150) { - return ((float)pathShear - 256.0F) / 100.0F; + // Negative value + return ((float)pathShear - 256.0f) / 100.0f; } else { - return (float)pathShear / 100.0F; - } } + // Positive value + return (float)pathShear / 100.0f; + } + } /// /// @@ -213,7 +206,7 @@ namespace libsecondlife public static byte ProfileBeginByte(float profileBegin) { // Y = ceil (200X) - return (byte)Convert.ToInt16(200.0F * profileBegin); + return (byte)Convert.ToInt16(200.0f * profileBegin); } /// @@ -224,7 +217,7 @@ namespace libsecondlife public static float ProfileBeginFloat(byte profileBegin) { // Y = 0.005X - return (float)profileBegin * 0.005F; + return (float)Math.Round((double)profileBegin * 0.005d, 4); } /// @@ -235,7 +228,7 @@ namespace libsecondlife public static byte ProfileEndByte(float profileEnd) { // Y = 200 - ceil (200X) - return (byte)(200 - (200.0F * profileEnd)); + return (byte)(200 - (200.0f * profileEnd)); } /// @@ -246,7 +239,7 @@ namespace libsecondlife public static float ProfileEndFloat(byte profileEnd) { // Y = 1 - 0.005X - return 1.0F - (float)profileEnd * 0.005F; + return (float)Math.Round(1.0d - (double)profileEnd * 0.005d); } /// @@ -257,7 +250,7 @@ namespace libsecondlife public static byte PathBeginByte(float pathBegin) { // Y = 100X - return (byte)Convert.ToInt16(100.0F * pathBegin); + return (byte)Convert.ToInt16(100.0f * pathBegin); } /// @@ -268,7 +261,7 @@ namespace libsecondlife public static float PathBeginFloat(byte pathBegin) { // Y = X / 100 - return (float)pathBegin / 100.0F; + return (float)pathBegin / 100.0f; } /// @@ -279,7 +272,7 @@ namespace libsecondlife public static byte PathEndByte(float pathEnd) { // Y = 100 - 100X - return (byte)(100 - Convert.ToInt16(100.0F * pathEnd)); + return (byte)(100 - Convert.ToInt16(100.0f * pathEnd)); } /// @@ -290,7 +283,7 @@ namespace libsecondlife public static float PathEndFloat(byte pathEnd) { // Y = 1 - X / 100 - return 1.0F - (float)pathEnd / 100; + return (float)Math.Round(1.0d - (double)pathEnd / 100.0d); } /// @@ -312,7 +305,7 @@ namespace libsecondlife public static float PathRadiusOffsetFloat(sbyte pathRadiusOffset) { // Y = X / 100 - return (float)pathRadiusOffset / 100.0F; + return (float)pathRadiusOffset / 100.0f; } /// @@ -323,7 +316,7 @@ namespace libsecondlife public static byte PathRevolutionsByte(float pathRevolutions) { // Y = ceil (66X) - 66 - return (byte)(Convert.ToInt16(Math.Ceiling(66.0F * pathRevolutions)) - 66); + return (byte)(Convert.ToInt16(Math.Ceiling(66.0f * pathRevolutions)) - 66); } /// @@ -334,7 +327,7 @@ namespace libsecondlife public static float PathRevolutionsFloat(byte pathRevolutions) { // Y = 1 + 0.015X - return 1.0F + (float)pathRevolutions * 0.015F; + return (float)Math.Round(1.0d + (double)pathRevolutions * 0.015d); } /// @@ -362,11 +355,11 @@ namespace libsecondlife /// /// /// - public static sbyte PathTaperByte(float pathTaper) - { - // Y = 256 + 100X - return (sbyte)PathShearByte(pathTaper); - } + public static sbyte PathTaperByte(float pathTaper) + { + // Y = 256 + 100X + return (sbyte)PathShearByte(pathTaper); + } /// /// @@ -377,11 +370,11 @@ namespace libsecondlife { if (pathTaper > 100) { - return (float)(256 - pathTaper) * 0.01F; + return (float)Math.Round((double)(256 - pathTaper) * 0.01d); } else { - return (float)pathTaper * 0.01F; + return (float)Math.Round((double)pathTaper * 0.01d); } } diff --git a/libsecondlife-cs/examples/IA_SimpleInventory/IA_SimpleInventory.cs b/libsecondlife-cs/examples/IA_SimpleInventory/IA_SimpleInventory.cs index 1fb83dd8..6b5b0587 100644 --- a/libsecondlife-cs/examples/IA_SimpleInventory/IA_SimpleInventory.cs +++ b/libsecondlife-cs/examples/IA_SimpleInventory/IA_SimpleInventory.cs @@ -76,12 +76,10 @@ namespace IA_SimpleInventory Console.WriteLine("Attempting to connect and login to SecondLife."); // Setup Login to Second Life - Dictionary loginParams = NetworkManager.DefaultLoginValues(FirstName, LastName, - Password, "00:00:00:00:00:00", "last", "Win", "0", "createnotecard", "static.sprocket@gmail.com"); Dictionary loginReply = new Dictionary(); // Login - if (!client.Network.Login(loginParams)) + if (!client.Network.Login(FirstName, LastName, Password, "createnotecard", "static.sprocket@gmail.com")) { // Login failed Console.WriteLine("Error logging in: " + client.Network.LoginError); diff --git a/libsecondlife-cs/examples/IA_TestAsyncImage/IA_TestAsyncImage.cs b/libsecondlife-cs/examples/IA_TestAsyncImage/IA_TestAsyncImage.cs index 993857f7..bd6b1fad 100644 --- a/libsecondlife-cs/examples/IA_TestAsyncImage/IA_TestAsyncImage.cs +++ b/libsecondlife-cs/examples/IA_TestAsyncImage/IA_TestAsyncImage.cs @@ -180,7 +180,13 @@ namespace IA_TestAsyncImage public void RunMe() { - File.WriteAllBytes(filename, JasperWrapper.jasper_decode_j2c_to_tiff(j2cdata)); + byte[] bytes = JasperWrapper.jasper_decode_j2c_to_tiff(j2cdata); + + FileStream file = new FileStream(filename, FileMode.Create); + BinaryWriter writer = new BinaryWriter(file); + writer.Write(bytes); + writer.Close(); + file.Close(); } } }