예제 #1
0
 void Viewer3DRenderingSurface_MouseDown(object sender, MouseEventArgs e)
 {
     if (e.Button == MouseButtons.Middle)
     {
         Mesh lMesh = mRenderer.Pick(e.X, e.Y);
         if (lMesh != null)
         {
             if (lMesh is OwnedMesh && ((OwnedMesh)lMesh).Owner is Chunk)
             {
                 OwnedMesh om = (OwnedMesh)lMesh;
                 Chunk     c  = (Chunk)om.Owner;
                 MessageBox.Show(string.Format("Clicked on {0} with name {1}", c.GetType().Name, c.Name));
             }
             else if (lMesh is OwnedMesh && ((OwnedMesh)lMesh).Owner is FlatChunk.ObjectEntry)
             {
                 FlatChunk.ObjectEntry oe = (FlatChunk.ObjectEntry)((OwnedMesh)lMesh).Owner;
                 MessageBox.Show(string.Format("Clicked on object type {0} at {1}, rotation {2}", oe.ObjtType, oe.OriginPosition, oe.RotationVector));
             }
             else if (lMesh is OwnedMesh && ((OwnedMesh)lMesh).Owner is FlatChunk.WeaponEntry)
             {
                 FlatChunk.WeaponEntry we = (FlatChunk.WeaponEntry)((OwnedMesh)lMesh).Owner;
                 MessageBox.Show(string.Format("Clicked on weapon type {0} at {1}", we.WeaponType, we.OriginPosition));
             }
             else
             {
                 lMesh.RenderMode = lMesh.RenderMode == RenderMode.Filled ?
                                    RenderMode.Textured : RenderMode.Filled;
                 InvalidateViewer();
             }
         }
     }
     else
     {
         mMainForm.Viewer3DRenderingSurface.Capture = true;
         mLastMouseDown  = e.Location;
         mDraggingButton = e.Button;
         mDraggingView   = true;
     }
 }
예제 #2
0
        void Viewer3DRenderingSurface_MouseDown(object sender, MouseEventArgs e)
        {
            Camera lCamera = mViews[(RenderingSurface)sender].Camera;

            if (Control.ModifierKeys != Keys.Control)
            {
                ((RenderingSurface)sender).Capture = true;
                mLastMouseDown  = e.Location;
                mDraggingButton = e.Button;
                mDraggingView   = true;
            }
            else if (e.Button == MouseButtons.Left)
            {
                OwnedMesh lMesh = mViews[(RenderingSurface)sender].Renderer.Pick(e.X, e.Y) as OwnedMesh;
                if (lMesh != null)
                {
                    ActiveObject = lMesh.Owner;
                }
            }

            ((RenderingSurface)sender).Focus();
        }
예제 #3
0
        protected override void RenderScene()
        {
            if (mCamera.ProjectionMode != eProjectionMode.Orthographic &&
                mViewer.DrawNormalsMode == eDrawNormalsMode.DrawNormals)
            {
                mRenderer.RenderScene(mScene, mCamera, RenderOptions.ShowNormals);
            }
            else
            {
                base.RenderScene();
            }

            if (mActiveEntity == null)
            {
                foreach (Entity lEntity in mScene.Entities)
                {
                    foreach (Mesh lMesh in lEntity.Meshes)
                    {
                        OwnedMesh lOm = lMesh as OwnedMesh;
                        if (lOm != null && lOm.Owner == mViewer.ActiveObject)
                        {
                            mActiveEntity = lEntity;
                            goto breakouter;
                        }
                    }
                }
                breakouter :;
            }

            if (mActiveEntity != null)
            {
                Mesh   lBoundingMesh = new Mesh(PolygonMode.Quads);
                Cuboid lBounds       = mActiveEntity.GetBoundingBox();

                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMax), Color.Red));
                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMin), Color.Red));
                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMin), Color.Red));
                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMax), Color.Red));
                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMax, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMax, lBounds.YMin, lBounds.ZMax), Color.Red));
                lBoundingMesh.AddFace(
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMin), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMin, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMax), Color.Red),
                    new Vertex(new GLTK.Point(lBounds.XMin, lBounds.YMax, lBounds.ZMin), Color.Red));

                lBoundingMesh.RenderMode = RenderMode.Wireframe;

                Entity lBox = new Entity();
                lBox.Transform = mActiveEntity.Transform;
                lBox.Meshes.Add(lBoundingMesh);

                mRenderer.ClearDepthBuffer();
                mRenderer.RenderSingleObject(lBox, RenderOptions.Default);
                mActiveEntity = null;
            }
        }
예제 #4
0
        private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            // notes:
              // invert the textures along the y-axis
              // use level co-ords, so z is down

              /////////////////////////////////////////////////////
              // The surface
              Entity lSurface = new MMEdEntity(this);

              Font lNumberFont = null;
              Brush lNumberFGBrush = null, lNumberBGBrush = null;
              Pen lWaypointPen = null, lKeyWaypointPen = null;
              if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
            lNumberFont = new Font(FontFamily.GenericMonospace, 10);
            lNumberFGBrush = new SolidBrush(Color.Black);
            lNumberBGBrush = new SolidBrush(Color.White);
            lWaypointPen = new Pen(Color.Black, 1f);
            lKeyWaypointPen = new Pen(Color.Red, 2f);
              }

              for (int x = 0; x < Width; x++)
              {
            for (int y = 0; y < Height; y++)
            {
              Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads);
              lSquare.AddFace(
            new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0),
            new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0),
            new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1),
            new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1));

              switch (xiTextureMode)
              {
            case eTextureMode.WireFrame:
              lSquare.RenderMode = RenderMode.Wireframe;
              break;

            // normal textures, optionally with metadata drawn on
            case eTextureMode.NormalTextures:
            case eTextureMode.NormalTexturesWithMetadata:
              TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]);

              if (lTIM != null)
              {
                //some TIMs can't be loaded yet: they're null
                Bitmap lTexture = lTIM.ToBitmap();
                if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata
                    && TexMetaData != null)
                {
                  byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata];

                  if (lVal != 0)
                  {
                    // we create a new bitmap based on the given texture
                    // a) so that we can modify it freely
                    // and b) to change it from indexed to full colour mode, to allow us
                    // to draw on it (otherwise we'll get an exception)
                    lTexture = new Bitmap(lTexture);

                    Graphics g = Graphics.FromImage(lTexture);

                    string lText = lVal.ToString();

                    SizeF size = g.MeasureString(lText, lNumberFont);

                    float xf = lTexture.Width / 2.0f - size.Width / 2.0f;
                    float yf = lTexture.Height / 2.0f - size.Height / 2.0f;

                    g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height);

                    g.DrawString(
                        lText,
                        lNumberFont,
                        lNumberFGBrush,
                        xf,
                        yf);

                    if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint)
                    {
                      Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal)
                          ? lKeyWaypointPen
                          : lWaypointPen;

                      g.DrawRectangle(
                          lPen,
                          0, 0, lTexture.Width - 1, lTexture.Height - 1);

                    }
                  }
                }

                lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
              }
              break;

            //draw the bumpmap textures on:
            case eTextureMode.BumpmapTextures:
              if (TexMetaData != null)
              {
                BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]);

                if (lBIC != null)
                {
                  Bitmap lTexture = lBIC.ToBitmap();
                  lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
                }
              }
              break;

            default: throw new Exception("Unexpected case");

              } //end switch

              lSurface.Meshes.Add(lSquare);
            }
              }

              lSurface.Scale(ScaleX, ScaleY, 1.0);
              if (RotationVector.Norm() != 0)
              {
            //the rotation is z-y-x
            lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis);
            lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis);
            lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis);
              }

              Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition);
              lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z);

              return lSurface;
        }
예제 #5
0
        public Entity GetEntity(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata, object xiMeshOwner)
        {
            MMEdEntity lAcc = new MMEdEntity(xiMeshOwner);
              Mesh lColouredMesh = null;
              Dictionary<int, Mesh> lPageIdToTexturedMeshMap = new Dictionary<int, Mesh>();
              List<Mesh> lTranslucentMeshes = new List<Mesh>();

              //qq move all this into Face class?
              //qq add quad mode meshes (needs separate meshes currently...)
              Vertex[] lVBuff = new Vertex[4];
              foreach (Face f in Faces)
              {
            if (!f.IsUnknownType())
            {
              for (int v = 0; v < f.mVertexIds.Length; v++)
              {
            lVBuff[v] = new Vertex(ThreeDeeViewer.Short3CoordToPoint(Vertices[f.mVertexIds[v]]));

            //normal
            if (v < f.mNormalIds.Length)
              lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[v]]).GetPositionVector().Normalise();
            else lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[0]]).GetPositionVector().Normalise();

            //color:
            if (f.mColors != null && v < f.mColors.Length)
              lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[v]);
            else if (f.mColors != null)
              lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[0]);

            //tex coords
            if (f.mTexCoords != null && v < f.mTexCoords.Length)
            {
              lVBuff[v].TexCoordX = f.mTexCoords[v].X / (double)VRAMViewer.TEX_PAGE_WIDTH;
              lVBuff[v].TexCoordY = f.mTexCoords[v].Y / (double)VRAMViewer.TEX_PAGE_HEIGHT;
            }
              }

              // Create a new mesh if appropriate, or add this face to an existing mesh
              // First check if it's tex or solid?
              Mesh lMesh;
              if (f.mTexCoords != null)
              {
            if (!lPageIdToTexturedMeshMap.ContainsKey(f.mTexPage))
            {
              lMesh = new OwnedMesh(xiMeshOwner);
              lPageIdToTexturedMeshMap[f.mTexPage] = lMesh;

              if (xiTextureMode == eTextureMode.NormalTextures
                || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
                lMesh.RenderMode = RenderMode.Textured;
                lMesh.Texture = AbstractRenderer.ImageToTextureId(
                  VRAMViewer.GetInstance().GetTexturePage(xiRootChunk, f.mTexPage));
              }
              else
              {
                lMesh.RenderMode = RenderMode.Wireframe;
              }
            }
            else
            {
              lMesh = lPageIdToTexturedMeshMap[f.mTexPage];
            }
              }
              else
              {
            if (f.IsTranslucent())
            {
              lMesh = new OwnedMesh(xiMeshOwner);
              if (xiTextureMode == eTextureMode.NormalTextures
                || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
                lMesh.RenderMode = RenderMode.TranslucentFilled;
              }
              else
              {
                lMesh.RenderMode = RenderMode.Wireframe;
              }
              lTranslucentMeshes.Add(lMesh);
            }
            else
            {
              if (lColouredMesh == null)
              {
                lColouredMesh = new OwnedMesh(xiMeshOwner);

                if (xiTextureMode == eTextureMode.NormalTextures
                  || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
                {
                  lColouredMesh.RenderMode = RenderMode.Filled;
                }
                else
                {
                  lColouredMesh.RenderMode = RenderMode.Wireframe;
                }
              }
              lMesh = lColouredMesh;
            }
              }

              if (f.mVertexIds.Length == 3)
              {
            lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
              }
              else //4
              {
            lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
            lMesh.AddFace(lVBuff[0], lVBuff[2], lVBuff[3]);
              }
            }
              }

              foreach (Mesh lTexturedMesh in lPageIdToTexturedMeshMap.Values)
              {
            lAcc.Meshes.Add(lTexturedMesh);
              }
              if (lColouredMesh != null) lAcc.Meshes.Add(lColouredMesh);
              lAcc.Meshes.AddRange(lTranslucentMeshes);

              lAcc.Scale(1, 1, -1);

              return lAcc;
        }
예제 #6
0
        private void InitialiseThreeDeeView()
        {
            if (mSubject == null)
              {
            return;
              }

              int SCALE = 256;
              int GRIDSIZE = 9; // Should be an odd number so the centre is the middle of a tile.
              mRenderer = new ImmediateModeRenderer();
              mRenderer.Attach(mMainForm.CameraRenderingSurface);

              mScene = new Scene();
              mCamera = new Camera(80, 0.1, 1e10);
              mView = new GLTK.View(mScene, mCamera, mRenderer);

              mScene.Clear();
              if (mMainForm.CurrentLevel != null)
              {
            // Create a surface and fill it with a 10 x 10 grid of squares
            MMEdEntity lSurface = new MMEdEntity(mSubject);

            for (int x = 0; x < GRIDSIZE; x++)
            {
              for (int y = 0; y < GRIDSIZE; y++)
              {
            Mesh lSquare = new OwnedMesh(mSubject, PolygonMode.Quads);
            lSquare.AddFace(
              new Vertex(new GLTK.Point(x, y, 0), 0, 0),
              new Vertex(new GLTK.Point(x + 1, y, 0), 1, 0),
              new Vertex(new GLTK.Point(x + 1, y + 1, 0), 1, 1),
              new Vertex(new GLTK.Point(x, y + 1, 0), 0, 1));
            lSquare.RenderMode = RenderMode.Wireframe;
            lSurface.Meshes.Add(lSquare);
              }
            }

            // Add it to the scene at the origin
            lSurface.Scale(SCALE, SCALE, 1.0);
            short lOffset = (short)(-SCALE * GRIDSIZE / 2);
            GLTK.Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(new Short3Coord(lOffset, lOffset, 0));
            lSurface.Position = new GLTK.Point(lNewPos.x, lNewPos.y, -lNewPos.z);
            mScene.AddRange(new MMEdEntity[] { lSurface });

            // Use a random object from the level for now.
            Level lLevel = mMainForm.CurrentLevel;
            TMDChunk lObject = lLevel.GetObjtById(1);
            mScene.AddRange(lObject.GetEntities(
              mMainForm.CurrentLevel,
              MMEd.Viewers.ThreeDee.eTextureMode.NormalTextures,
              eTexMetaDataEntries.Steering));

            string lExceptionWhen = "opening file";
            try
            {
              ThreeDeeViewer.SceneHolder sh;
              string lFilename = string.Format("{0}{1}..{1}camera-editor-scene.xml",
            Path.GetDirectoryName(
              new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath),
            Path.DirectorySeparatorChar);

              using (FileStream fs = File.OpenRead(lFilename))
              {
            lExceptionWhen = "deserialising the scene";
            XmlSerializer xs = new XmlSerializer(typeof(ThreeDeeViewer.SceneHolder));
            sh = (ThreeDeeViewer.SceneHolder)xs.Deserialize(fs);
              }
              lExceptionWhen = "fixing texture ids";
              Dictionary<int, int> lSavedTexIdsToLiveTexIds = new Dictionary<int, int>();
              foreach (ThreeDeeViewer.TextureHolder th in sh.Textures)
              {
            if (th.Bitmap != null)
            {
              lSavedTexIdsToLiveTexIds[th.ID] = AbstractRenderer.ImageToTextureId(th.Bitmap);
            }
            else
            {
              lSavedTexIdsToLiveTexIds[th.ID] = 0;
            }
              }
              foreach (Entity ent in sh.Entities)
              {
            foreach (Mesh m in ent.Meshes)
            {
              if (m.RenderMode == RenderMode.Textured)
              {
                m.Texture = lSavedTexIdsToLiveTexIds[m.Texture];
              }
            }
              }
              mScene.Objects.Clear();
              mScene.AddRange(sh.Entities);
            }
            catch (Exception err)
            {
              System.Diagnostics.Trace.WriteLine(err);
              MessageBox.Show(string.Format("Exception occurred while {0}: {1}", lExceptionWhen, err.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            UpdateCameraThreeDee();
              }
              else
              {
            System.Windows.Forms.MessageBox.Show("3D view is only available when editing a level");
            mMainForm.CameraRenderingSurface.Visible = false;
              }
        }
예제 #7
0
        private void InitialiseThreeDeeView()
        {
            if (mSubject == null)
            {
                return;
            }

            int SCALE    = 256;
            int GRIDSIZE = 9; // Should be an odd number so the centre is the middle of a tile.

            mRenderer = new ImmediateModeRenderer();
            mRenderer.Attach(mMainForm.CameraRenderingSurface);

            mScene  = new Scene();
            mCamera = new Camera(80, 0.1, 1e10);
            mView   = new GLTK.View(mScene, mCamera, mRenderer);

            mScene.Clear();
            if (mMainForm.CurrentLevel != null)
            {
                // Create a surface and fill it with a 10 x 10 grid of squares
                MMEdEntity lSurface = new MMEdEntity(mSubject);

                for (int x = 0; x < GRIDSIZE; x++)
                {
                    for (int y = 0; y < GRIDSIZE; y++)
                    {
                        Mesh lSquare = new OwnedMesh(mSubject, PolygonMode.Quads);
                        lSquare.AddFace(
                            new Vertex(new GLTK.Point(x, y, 0), 0, 0),
                            new Vertex(new GLTK.Point(x + 1, y, 0), 1, 0),
                            new Vertex(new GLTK.Point(x + 1, y + 1, 0), 1, 1),
                            new Vertex(new GLTK.Point(x, y + 1, 0), 0, 1));
                        lSquare.RenderMode = RenderMode.Wireframe;
                        lSurface.Meshes.Add(lSquare);
                    }
                }

                // Add it to the scene at the origin
                lSurface.Scale(SCALE, SCALE, 1.0);
                short      lOffset = (short)(-SCALE * GRIDSIZE / 2);
                GLTK.Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(new Short3Coord(lOffset, lOffset, 0));
                lSurface.Position = new GLTK.Point(lNewPos.x, lNewPos.y, -lNewPos.z);
                mScene.AddRange(new MMEdEntity[] { lSurface });

                // Use a random object from the level for now.
                Level    lLevel  = mMainForm.CurrentLevel;
                TMDChunk lObject = lLevel.GetObjtById(1);
                mScene.AddRange(lObject.GetEntities(
                                    mMainForm.CurrentLevel,
                                    MMEd.Viewers.ThreeDee.eTextureMode.NormalTextures,
                                    eTexMetaDataEntries.Steering));

                string lExceptionWhen = "opening file";
                try
                {
                    ThreeDeeViewer.SceneHolder sh;
                    string lFilename = string.Format("{0}{1}..{1}camera-editor-scene.xml",
                                                     Path.GetDirectoryName(
                                                         new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath),
                                                     Path.DirectorySeparatorChar);

                    using (FileStream fs = File.OpenRead(lFilename))
                    {
                        lExceptionWhen = "deserialising the scene";
                        XmlSerializer xs = new XmlSerializer(typeof(ThreeDeeViewer.SceneHolder));
                        sh = (ThreeDeeViewer.SceneHolder)xs.Deserialize(fs);
                    }
                    lExceptionWhen = "fixing texture ids";
                    Dictionary <int, int> lSavedTexIdsToLiveTexIds = new Dictionary <int, int>();
                    foreach (ThreeDeeViewer.TextureHolder th in sh.Textures)
                    {
                        if (th.Bitmap != null)
                        {
                            lSavedTexIdsToLiveTexIds[th.ID] = AbstractRenderer.ImageToTextureId(th.Bitmap);
                        }
                        else
                        {
                            lSavedTexIdsToLiveTexIds[th.ID] = 0;
                        }
                    }
                    foreach (Entity ent in sh.Entities)
                    {
                        foreach (Mesh m in ent.Meshes)
                        {
                            if (m.RenderMode == RenderMode.Textured)
                            {
                                m.Texture = lSavedTexIdsToLiveTexIds[m.Texture];
                            }
                        }
                    }
                    mScene.Objects.Clear();
                    mScene.AddRange(sh.Entities);
                }
                catch (Exception err)
                {
                    System.Diagnostics.Trace.WriteLine(err);
                    MessageBox.Show(string.Format("Exception occurred while {0}: {1}", lExceptionWhen, err.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                UpdateCameraThreeDee();
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("3D view is only available when editing a level");
                mMainForm.CameraRenderingSurface.Visible = false;
            }
        }