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; } }
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(); }
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; } }
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; }
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; }
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; } }
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; } }