Announcement

Collapse
No announcement yet.

stereo viewer plugin

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • stereo viewer plugin

    This is a pre-release of my plugin for 3d viewing; it needs the device described in this site to be used, but even if you don't (yet) have it, you could just tell me if the stereo pair is correctly renderd on your screen (looks like on mine it's quite "strange...).
    You could even resize the main window until the stereo pair is little enough to be "comfortably" viewed by distorting your view...

    Past the code into a text file, and load the text file from PLUGIN menu in World Wind 1.3.2:
    Thanks to mashisharu ( http://www.mashiharu.com/ ) for his help.

    (Please note: using this plugin and my stereoviewer device could cause some desease in some people...)

    Code:
    //----------------------------------------------------------------------------
    // NAME: Stereo
    // VERSION: 1.00
    // DESCRIPTION: Displays a stereo pair.
    // DEVELOPER: Luca Cassioli
    // WEBSITE:
    //----------------------------------------------------------------------------
    //
    // This file is in the Public Domain, and comes with no warranty.
    // This plugin is based on work by Bjorn Reppen aka "Mashi": http://http://www.mashiharu.com
    //
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    using System.ComponentModel;
    using WorldWind.Renderable;
    using WorldWind.Camera;
    using WorldWind;
    using System.Drawing;
    
    namespace Stereo
    {
    	/// <summary>
    	/// The plugin (main class)
    	/// </summary>
    	public class StereoPair : WorldWind.PluginEngine.Plugin
    	{
     /// <summary>
     /// Name displayed in layer manager
     /// </summary>
     public static string LayerName = "Stereo Pair";
    
     /// <summary>
     /// Plugin entry point - All plugins must implement this function
     /// </summary>
     public override void Load()
     {
     	MiniGlobeLayer layer = new MiniGlobeLayer(LayerName, Application.WorldWindow);
     	Application.WorldWindow.CurrentWorld.RenderableObjects.Add(layer);
     }
    
     /// <summary>
     /// Unloads our plugin
     /// </summary>
     public override void Unload()
     {
     	Application.WorldWindow.CurrentWorld.RenderableObjects.Remove(LayerName);
     }
    	}
    
    	/// <summary>
    	/// Displays two copies of main window, each one with a different PointOfView.
    	/// </summary>
    	public class MiniGlobeLayer : RenderableObject
    	{
     public float ZoomFactor = 3;
     public int BorderColor = System.Drawing.Color.FromArgb(128,0,0,0).ToArgb();
     World world;
     CameraBase camera;
    // CameraBase camera2;
     Viewport viewPort1; //Right camera.
     Viewport viewPort2; // Left camera.
     CustomVertex.TransformedColored[] borderVertices = new CustomVertex.TransformedColored[5];
    
     /// <summary>
     /// Constructor
     /// </summary>
     public MiniGlobeLayer(string LayerName, WorldWindow worldWindow) : base(LayerName)
     {
     	this.RenderPriority = RenderPriority.Icons;
     	this.world = worldWindow.CurrentWorld;
     	camera = new CameraBase(Vector3.Empty, world.EquatorialRadius );
    // 	camera2 = new CameraBase(Vector3.Empty, world.EquatorialRadius );
     	worldWindow.DrawArgs.device.DeviceResizing += new CancelEventHandler(OnDeviceResizing);
     	OnDeviceResizing(worldWindow.DrawArgs.device, new CancelEventArgs());
     }
    
     /// <summary>
     /// Resize our mini globes with the main view
     /// </summary>
     public void OnDeviceResizing( object sender, CancelEventArgs e)
     {
     	Device device = (Device)sender;
     	viewPort1 = new Viewport();
     	viewPort2 = new Viewport();
     	float scale = 1/2f; // Each miniglobe is as wide as half the screen width,
          	// and positioned in the lower half of the screen.
     	int origWidth = device.Viewport.Width;
     	int origHeight = device.Viewport.Height;
     	//int origWidth2 = device.Viewport.Width;
     	//int origHeight2 = device.Viewport.Height;
     	viewPort1.X = 0;
     	viewPort1.Y = (int)(origHeight*scale);
     	viewPort1.Width = (int)(origWidth*scale);
     	viewPort1.Height = (int)(origHeight*scale);
     	viewPort2.X = viewPort1.Width;
     	viewPort2.Y = (int)(origHeight*scale);
     	viewPort2.Width = (int)(origWidth*scale);
     	viewPort2.Height =(int)(origHeight*scale);
     }
    
     /// <summary>
     /// Render the active map imagery layers only
     /// </summary>
     void RenderMap(DrawArgs drawArgs, RenderableObject ro)
     {
     	if(!ro.IsOn)
      return;
    
     	if(ro is RenderableObjectList)
     	{
      RenderableObjectList rol = (RenderableObjectList) ro;
      foreach(RenderableObject child in rol.ChildObjects)
      	RenderMap(drawArgs, child);
      return;
     	}
    
     	if (ro is QuadTileSet)
      ro.Render(drawArgs);
     }
    
     #region RenderableObject
    
     /// <summary>
     /// This is where we do our rendering
     /// Called from UI thread = UI code safe in this function
     /// Stereo view is possible when each eye views the same object, but each
     /// one from a slightly different point of view.
     /// This plugin requires using a special mirror-based "stereoviewer", like
     /// the one described at http://jumpjack.altervista.org/stereo/stereo.html
     /// </summary>
     public override void Render(DrawArgs drawArgs)
     {
     	Device device = drawArgs.device;
    
     	// Save default viewport/camera
     	Viewport origVp = device.Viewport;
     	CameraBase defaultCamera = drawArgs.WorldCamera;
    
     	// Copy camera position, but position us ZoomFactor times further out
     	camera.CurrentOrientation = defaultCamera.CurrentOrientation;
     	camera.Distance = defaultCamera.Distance;
     	// Set first point of view:
     	camera.SetPosition(defaultCamera.Latitude.Degrees, defaultCamera.Longitude.Degrees,
      defaultCamera.Heading.Degrees, defaultCamera.Altitude, defaultCamera.Tilt.Degrees, defaultCamera.Bank.Degrees);
     	camera.Update(device);
    
     	// Install the mini globe lower right corner small view port
     	device.Viewport = viewPort2;
     	drawArgs.WorldCamera = camera;
     	// Render the active map layers only
     	RenderMap( drawArgs, world.RenderableObjects );
    
     	camera.Distance = defaultCamera.Distance;
     	// Set second point of view:
     	camera.SetPosition(defaultCamera.Latitude.Degrees, defaultCamera.Longitude.Degrees,
      defaultCamera.Heading.Degrees+5, defaultCamera.Altitude, defaultCamera.Tilt.Degrees, defaultCamera.Bank.Degrees);
     	camera.Update(device);
    
     	// Install the mini globe lower right corner small view port
     	device.Viewport = viewPort1;
     	// Render the active map layers only
     	RenderMap( drawArgs, world.RenderableObjects );
    
     	// Restore default view port and camera
     	drawArgs.WorldCamera = defaultCamera;
     	device.Viewport = origVp;
    
     	RenderRectangle(device);
     }
    
     /// <summary>
     /// Put a rectangle around the mini maps
     /// </summary>
     /// <param name="device"></param>
     void RenderRectangle(Device device)
     {
     	borderVertices[0].X = viewPort1.X;
     	borderVertices[0].Y = viewPort1.Y;
     	borderVertices[0].Color = BorderColor;
    
     	borderVertices[1].X = viewPort1.X + viewPort1.Width;
     	borderVertices[1].Y = viewPort1.Y;
     	borderVertices[1].Color = BorderColor;
    
     	borderVertices[2].X = viewPort1.X + viewPort1.Width;
     	borderVertices[2].Y = viewPort1.Y + viewPort1.Height;
     	borderVertices[2].Color = BorderColor;
    
     	borderVertices[3].X = viewPort1.X;
     	borderVertices[3].Y = viewPort1.Y + viewPort1.Height;
     	borderVertices[3].Color = BorderColor;
    
     	borderVertices[4].X = viewPort1.X;
     	borderVertices[4].Y = viewPort1.Y;
     	borderVertices[4].Color = BorderColor;
    
     	borderVertices[0].X = viewPort2.X;
     	borderVertices[0].Y = viewPort2.Y;
     	borderVertices[0].Color = BorderColor;
    
     	// Draw first rectangle
     	device.VertexFormat = CustomVertex.TransformedColored.Format;
     	device.TextureState[0].ColorOperation = TextureOperation.Disable;
     	device.DrawUserPrimitives(PrimitiveType.LineStrip, borderVertices.Length - 1, borderVertices);
    
     	borderVertices[1].X = viewPort2.X + viewPort2.Width;
     	borderVertices[1].Y = viewPort2.Y;
     	borderVertices[1].Color = BorderColor;
    
     	borderVertices[2].X = viewPort2.X + viewPort2.Width;
     	borderVertices[2].Y = viewPort2.Y + viewPort2.Height;
     	borderVertices[2].Color = BorderColor;
    
     	borderVertices[3].X = viewPort2.X;
     	borderVertices[3].Y = viewPort2.Y + viewPort2.Height;
     	borderVertices[3].Color = BorderColor;
    
     	borderVertices[4].X = viewPort2.X;
     	borderVertices[4].Y = viewPort2.Y;
     	borderVertices[4].Color = BorderColor;
    
      // Draw second rectangle
     	device.VertexFormat = CustomVertex.TransformedColored.Format;
     	device.TextureState[0].ColorOperation = TextureOperation.Disable;
     	device.DrawUserPrimitives(PrimitiveType.LineStrip, borderVertices.Length - 1, borderVertices);
     }
    
     /// <summary>
     /// RenderableObject abstract member (needed)
     /// OBS: Worker thread (don't update UI directly from this thread)
     /// </summary>
     public override void Initialize(DrawArgs drawArgs)
     {
     }
    
     /// <summary>
     /// RenderableObject abstract member (needed)
     /// OBS: Worker thread (don't update UI directly from this thread)
     /// </summary>
     public override void Update(DrawArgs drawArgs)
     {
     }
    
     /// <summary>
     /// RenderableObject abstract member (needed)
     /// OBS: Worker thread (don't update UI directly from this thread)
     /// </summary>
     public override void Dispose()
     {
     }
    
     /// <summary>
     /// Gets called when user left clicks.
     /// RenderableObject abstract member (needed)
     /// Called from UI thread = UI code safe in this function
     /// </summary>
     public override bool PerformSelectionAction(DrawArgs drawArgs)
     {
     	return false;
     }
    
     #endregion
    	}
    }

  • #2
    Stereo viewing is definitly something on my wish/work list for WW. However, i favor more anaglyphs rather than split views.

    One comment i can make is that the two points of view should be from different lat/lon rather than just different headings. A rule of thumb i use to shoot stereo pairs is to move the second view point by a distance of 1/100 the distance to the target scenery. That will require some trigonometry to figure out the corresponding lat/lon.
    My World Wind Java Blog & WW.net Plugins page

    Comment


    • #3
      Originally posted by patmurris@Jul 19 2005, 10:41 AM
      Stereo viewing is definitly something on my wish/work list for WW. However, i favor more anaglyphs rather than split views.

      One comment i can make is that the two points of view should be from different lat/lon rather than just different headings. A rule of thumb i use to shoot stereo pairs is to move the second view point by a distance of 1/100 the distance to the target scenery. That will require some trigonometry to figure out the corresponding lat/lon.
      You got an annoying result by simply shifting to right to "take the second snapshot", as I experienced by taking real pictures of real world: you obtain a 3d view, but objects have no volume, they just appear one behind the other, but they look like if they are "sheets", not solid bodies. This happens because, although your eyes are actually "shifted" one from the other, they don't look both straight on, but left one looks right and right one looks left.
      So, we need a combination of shift and rotation.

      As I said, this is a preliminary version of the plugin.
      But now that Mashi is working on this ( http://forum.worldwind.arc.nasa.gov/index....t=0&#entry21803 ), I think it will be easier for me to complete the plugin (or maybe he could implement mine into his). Unfortunately I don't know how to change the "master" color of NWW images to write my own anaglyph-plugin.

      Comment


      • #4
        Heres a nice page I found, maybe you could make a plugin for this too http://individual.utoronto.ca/iizuka...cellophane.htm it looks very similar to your mirror approach, and as I have a 19" lcd monitor it woud be real nice
        Bull_[UK]

        Comment


        • #5
          Originally posted by jumpjack@Jul 19 2005, 12:05 PM
          You got an annoying result by simply shifting to right to "take the second snapshot", as I experienced by taking real pictures of real world: you obtain a 3d view, but objects have no volume, they just appear one behind the other, but they look like if they are "sheets", not solid bodies. This happens because, although your eyes are actually "shifted" one from the other, they don't look both straight on, but left one looks right and right one looks left.
          So, we need a combination of shift and rotation.

          I used only rotation with a small angle, around the same point. I do it taking 3D pictures with my camera. I think it's a right way.
          A little one :

          http://img345.imageshack.us/img345/4388/3d...tente0696lk.jpg

          I published recently anaglyphs here :

          http://forum.worldwind.arc.nasa.gov/index....wtopic=3740&hl=

          I Made a parallel of Everest if you don't have glasses* :

          http://img330.imageshack.us/img330/6531/3d...tcrossed4rd.png

          Sacha

          * The couple is not confortable with real color L and R, because I didn't kept the original couple. A program (Anabuilder, a good freeware) recovered it for me but in red cyan.

          Comment


          • #6
            Nice, I can't find my glasses, but the everest one looks really cool.
            Note: The above statement is probably an educated guess, derived from much forum reading, IRC chatting, general curiosity, etc. Use at your own risk.
            Before asking, check the FAQ or search, and Ask a good question.

            Having problems? Make sure you have Managed DirectX and .NET Framework.
            Then check the Video Card Compatibility List


            Comment


            • #7
              Originally posted by 5of0@Jul 20 2005, 12:21 AM
              Nice, I can't find my glasses, but the everest one looks really cool.
              Thanks
              I hope I will get fix for the Mashi's wonder. I'm waiting for since I have discovered WW

              Comment


              • #8
                Originally posted by jumpjack@Jul 19 2005, 12:05 PM
                You got an annoying result by simply shifting to right to "take the second snapshot", [...]
                Thanks for the plugin.
                I've only a view issue :
                It works, but the mapped features are minced along the tiles borders. I don't know if it's a problem of RAM or speed, like I have with the Mashi's anaglyph one... No luck with 3D.
                But it appears to be great when it works. gasp, Time to upgrade my computer. I'm going to print 1500 euros on first quality paper, and I come back.

                Comment


                • #9
                  Originally posted by Sacha@Jul 19 2005, 05:07 PM
                  I used only rotation with a small angle, around the same point.
                  When you rotate around the same point looking at it, you actually move to right (or left) and turn your view to left (or right); probably the additional component of the move (you also go straight on) has no consequences on the 3d effect.

                  I Made a parallel of Everest if you don't have glasses* :
                  Unfortunately, it's of no use if images are in different colors; but converting both of them to grayscale should make the job.

                  Do you know these programs?
                  http://stereo.jpn.org/eng/

                  Comment


                  • #10
                    Originally posted by Sacha@Jul 20 2005, 07:05 AM
                    Thanks for the plugin.
                    I've only a view issue :
                    It works, but the mapped features are minced along the tiles borders. I don't know if it's a problem of RAM or speed, like I have with the Mashi's anaglyph one... No luck with 3D.
                    But it appears to be great when it works. gasp, Time to upgrade my computer. I'm going to print 1500 euros on first quality paper, and I come back.
                    I'm not sure about what you mean... maybe about the trasparent background of the two small images? I don't know how to fill it... :unsure: :(

                    Comment


                    • #11
                      I can't install it. =(
                      Should I save the code in .txt, .cs, .xml or what format? I tried .txt, but it didn't work. Notepad doesn't support .cs. I tried xml, too, but it's still not working.
                      Could someone help me?

                      Ps: Sorry my bad english.. =)

                      Comment


                      • #12
                        Originally posted by Harakka@Aug 13 2005, 04:57 PM
                        Should I save the code in .txt, .cs, .xml or what format? I tried .txt, but it didn't work. Notepad doesn't support .cs. I tried xml, too, but it's still not working.
                        In .cs

                        * when you are saving file in notepad choose the 'all files (*.*)' option from the drop-down menu - now you can enter "plugin.cs" as a filename
                        * you can always change the extension with windows explorer


                        (of course you have 1.3.2 and Plugins folder with .cs files, right? )
                        Hot stuff: FAQ, forum search, DirectX, .NET, Video Card Compatibility list

                        Comment


                        • #13
                          Weeeee now it works! I tried it with the cross-eye techique, and this plugin is AMAZING! It looks so realistic.. THANK YOU JUMPJACK!

                          Comment


                          • #14
                            Wow, EXCELLENT! I've wanted this for a while, stereo has always worked better for me than the anaglyph stuff. However, I use the crosseyed method (as opposed to the look-beyond-the page, I think they call it "parallel" method, as in the Magic Eye books).
                            But no worries, I just changed a tiny bit of code. Towards the end, in the Render routine, I changed this:
                            Code:
                             // Install the mini globe lower right corner small view port
                             device.Viewport = viewPort2;
                             drawArgs.WorldCamera = camera;
                             // Render the active map layers only
                             RenderMap( drawArgs, world.RenderableObjects );
                            to this:
                            routine, I changed this:
                            Code:
                             // Install the mini globe lower right corner small view port
                             device.Viewport = viewPort1;
                             drawArgs.WorldCamera = camera;
                             // Render the active map layers only
                             RenderMap( drawArgs, world.RenderableObjects );
                            And vice versa below (viewPort1->ViewPort2). But once that was changed (and placenames turned off), WOW! World wind in true 3D! Thanks for such awesome work. Just a little buggy, still though. When I run it, it seems that it renders the tiles front to back instead of back to front - the sides of the tiles show through. Here's a pic:
                            [attachmentid=1192]
                            Oh, and would you mind if I fooled with adding a settings dialog, to specify crosseyed or parallel, among other things?
                            Attached Files
                            Note: The above statement is probably an educated guess, derived from much forum reading, IRC chatting, general curiosity, etc. Use at your own risk.
                            Before asking, check the FAQ or search, and Ask a good question.

                            Having problems? Make sure you have Managed DirectX and .NET Framework.
                            Then check the Video Card Compatibility List


                            Comment


                            • #15
                              Originally posted by 5of0@Aug 17 2005, 02:11 AM
                              Wow, EXCELLENT!
                              Thanks.

                              I've wanted this for a while, stereo has always worked better for me than the anaglyph stuff. However, I use the crosseyed method (as opposed to the look-beyond-the page, I think they call it "parallel" method, as in the Magic Eye books).
                              But no worries, I just changed a tiny bit of code[...] Just a little buggy,
                              I know... it is a pre-release indeed.

                              When I run it, it seems that it renders the tiles front to back instead of back to front - the sides of the tiles show through. Here's a pic:
                              [...]
                              I thought it was an issue just on my video card. It's very annoying, and I don't know at all how to get rid of it! :angry:

                              Oh, and would you mind if I fooled with adding a settings dialog, to specify crosseyed or parallel, among other things?
                              If you are able to work on it, please feel free to do any change you like: currently I have not so much spare time to complete the plugin.

                              I'd like to solve the issue of the transparent background of the two mini-windows, but I don't know where to start from... I should study NWW & C# a bit more... or just let you continue my (and Mashiharu's) work!

                              The option to choose between cross- and parallel-eyes is a good thing... although I think that both of these methods are... the fastest way to obtain a BIG headache! (That's why I built my stero-viewer device).

                              Comment

                              Working...
                              X