/// <summary> /// Occurs when it is time to render 3d objects. Place all 3d /// drawing code in this event. /// </summary> private void mD3d_DxRender3d(Gosub.Direct3d d3d, Microsoft.DirectX.Direct3D.Device dx) { //if (rendered < 5) { // Setup the lights dx.Lights[0].Enabled = true; dx.Lights[0].Type = LightType.Directional; dx.Lights[0].Direction = new Vector3(0, 0, 1); dx.Lights[0].Diffuse = Color.White; dx.Lights[0].Position = new Vector3(0, 0, 0); dx.RenderState.Lighting = true; // Set viewer dx.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -viewing_distance), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(pan, 1.0f, tilt)); // Set projection matrix dx.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, 640f / 480f, 50.0f, 2000.0f); dx.RenderState.NormalizeNormals = true; rendered++; viewOccupancyGrid(d3d, dx, grid_filename, current_grid_level, 0); } }
/// <summary> /// view a grid from the given file /// </summary> /// <param name="d3d"></param> /// <param name="dx"></param> /// <param name="filename">grid filename</param> /// <param name="grid_level">the level of the grid within the grid to be viewed</param> /// <param name="min_evidence">minimum evidence threshold</param> public void viewOccupancyGrid(Gosub.Direct3d d3d, Microsoft.DirectX.Direct3D.Device dx, String filename, int grid_level, int min_evidence) { if (!grid_loaded) { currentGrid = new occupancygrid(64, 100); switch (grid_type) { case "914": { currentGrid.Load(filename); break; } } grid_loaded = true; } if (currentGrid != null) { if (grid_type == "914") { viewGrid(d3d, dx, currentGrid); } } }
/// <summary> /// The device must not be lost when this function is called /// </summary> public AutoTexture Clone(Direct3d d3d, Format format, Usage usage, Pool pool) { // Copy the texture Texture toTexture = new Texture(d3d.Dx, mSurfDesc.Width, mSurfDesc.Height, 1, usage, format, pool); Surface toSurface = toTexture.GetSurfaceLevel(0); Surface fromSurface = mTexture.GetSurfaceLevel(0); SurfaceLoader.FromSurface(toSurface, fromSurface, Filter.Point, 0); toSurface.Dispose(); fromSurface.Dispose(); // Copy this AutoTexture AutoTexture autoTexture = new AutoTexture(d3d, toTexture); autoTexture.Tag = Tag; return autoTexture; }
/// <summary> /// Dispose this object and the mesh it holds /// </summary> public void Dispose() { if (mTexture != null) { mTexture.Dispose(); mTexture = null; } if (mD3d != null) { mD3d.DxLost -= new Direct3d.DxDirect3dDelegate(d3d_DxLost); mD3d.DxRestore -= new Direct3d.DxDirect3dDelegate(d3d_DxRestore); mD3d = null; } mTextureData = null; }
/// <summary> /// Create an AutoTexture /// </summary> public AutoTexture(Direct3d d3d, Texture texture) { mTexture = texture; mD3d = d3d; mSurfDesc = mTexture.GetLevelDescription(0); d3d.DxLost += new Direct3d.DxDirect3dDelegate(d3d_DxLost); d3d.DxRestore += new Direct3d.DxDirect3dDelegate(d3d_DxRestore); }
/// <summary> /// Occurs once after DirectX has been initialized for the first time. /// Setup AutoMesh's, AutoVertexBuffer's, and AutoTexture's here. /// </summary> private void mD3d_DxLoaded(Gosub.Direct3d d3d, Microsoft.DirectX.Direct3D.Device dx) { }
/// <summary> /// Restore the mesh when the DirectX device is restored /// </summary> void d3d_DxRestore(Direct3d d3d, Device dx) { // If the direct3d device wasn't lost in the first place, don't restore it. // This happens the first timeMs around. if (mMesh != null) return; // Restore mesh mMesh = new Mesh(mNumFaces, mNumVertices, mFlags, mVertexFormat, dx); Debug.Assert(mMesh.NumberBytesPerVertex == mNumBytesPerVertex); // Copy pathIndex buffer GraphicsStream stream = mMesh.LockIndexBuffer(LockFlags.Discard); stream.Write(mIndexBufferCopy); mMesh.UnlockIndexBuffer(); // Copy vertex buffer stream = mMesh.LockVertexBuffer(LockFlags.Discard); stream.Write(mVertexBufferCopy); mMesh.UnlockVertexBuffer(); // Copy attribute buffer int[] attributeBuffer = mMesh.LockAttributeBufferArray(LockFlags.Discard); mAttributeBufferCopy.CopyTo(attributeBuffer, 0); mMesh.UnlockAttributeBuffer(attributeBuffer); mIndexBufferCopy = null; mVertexBufferCopy = null; mAttributeBufferCopy = null; }
/// <summary> /// Cone the mesh (and textures that it contains), /// optionally converting the vertex and texture format. /// </summary> public AutoMesh Clone(Direct3d d3d, MeshFlags flags, VertexFormats vertexFormat, Format textureFormat, Usage usage, Pool pool) { // Clone the mesh vertex info Mesh mesh = mMesh.Clone(flags, vertexFormat, d3d.Dx); AutoMesh autoMesh = new AutoMesh(d3d, mesh); // Clone AutoMesh variables autoMesh.Tag = Tag; // Clone textures and materials if (mTextures.Length != 0) { // Clone materials autoMesh.mMaterials = new Material[mMaterials.Length]; for (int i = 0; i < mMaterials.Length; i++) autoMesh.mMaterials[i] = mMaterials[i]; // Clone textures autoMesh.mTextures = new AutoTexture[mTextures.Length]; for (int i = 0; i < mTextures.Length; i++) if (mTextures[i] != null) { // Already cloned this texture? bool alreadyConvertedTexture = false; for (int j = 0; j < i; j++) if (mTextures[i] == mTextures[j]) { alreadyConvertedTexture = true; autoMesh.mTextures[i] = autoMesh.mTextures[j]; break; } // Clone new texture if (!alreadyConvertedTexture) autoMesh.mTextures[i] = mTextures[i].Clone(d3d, textureFormat, usage, pool); } } return autoMesh; }
/// <summary> /// Create an automesh, which owns the given mesh /// </summary> public AutoMesh(Direct3d d3d, Mesh mesh) { mMesh = mesh; mD3d = d3d; d3d.DxLost += new Direct3d.DxDirect3dDelegate(d3d_DxLost); d3d.DxRestore += new Direct3d.DxDirect3dDelegate(d3d_DxRestore); }
/// <summary> /// Create an AutoVertexBuffer (16 bits, ushort) /// </summary> public AutoIndexBuffer(Direct3d d3d, int numIndices, Usage usage, Pool pool) { mIndexBuffer = new IndexBuffer(typeof(ushort), numIndices, d3d.Dx, usage, pool); mD3d = d3d; mNumIndices = numIndices; mUsage = usage; mPool = pool; d3d.DxLost += new Direct3d.DxDirect3dDelegate(d3d_DxLost); d3d.DxRestore += new Direct3d.DxDirect3dDelegate(d3d_DxRestore); }
/// <summary> /// Restore the vertex buffer when the DirectX device is restored /// </summary> void d3d_DxRestore(Direct3d d3d, Device dx) { // If the direct3d device wasn't lost in the first place, don't restore it. // This happens the first timeMs around. if (mVertexBuffer != null) return; mVertexBuffer = new VertexBuffer(mVertexType, mVertexNumVertices, d3d.Dx, mVertexUsage, mVertexFormat, mVertexPool); mVertexBuffer.SetData(mVertexData, 0, LockFlags.None); mVertexData = null; }
/// <summary> /// Create an AutoVertexBuffer /// </summary> public AutoVertexBuffer(Direct3d d3d, Type vertexType, int numVerts, Usage usage, VertexFormats format, Pool pool) { mVertexBuffer = new VertexBuffer(vertexType, numVerts == 0 ? 1 : numVerts, d3d.Dx, usage, format, pool); mD3d = d3d; mVertexType = vertexType; mVertexNumVertices = numVerts; mVertexUsage = usage; mVertexFormat = format; mVertexPool = pool; d3d.DxLost += new Direct3d.DxDirect3dDelegate(d3d_DxLost); d3d.DxRestore += new Direct3d.DxDirect3dDelegate(d3d_DxRestore); }
public void viewGrid(Gosub.Direct3d d3d, Microsoft.DirectX.Direct3D.Device dx, occupancygrid grid) { bool ground_plane_drawn = false; mCellMesh = new AutoMesh(d3d, Mesh.Box(dx, 1, 1, 1)); //show the grid cells for (int z = grid.dimension - 1; z >= 0; z--) { int plane_hits = 0; for (int x = 1; x < grid.dimension - 1; x++) { for (int y = 1; y < grid.dimension - 1; y++) { if (grid.display_cell[x, y, z]) { plane_hits++; occupancyGridCell c = grid.cell[x, y, z]; int r = 0; int g = 0; int b = 255; if (c != null) { r = c.colour[0]; g = c.colour[1]; b = c.colour[2]; } dx.Transform.World = Matrix.Translation(-grid.dimension / 2, -grid.dimension / 2, -grid.dimension / 2) //Center model //* Matrix.Scaling(1, 1, 1) // Make it bigger //* Matrix.RotationYawPitchRoll(0, 0, 0) * Matrix.Translation(grid.dimension - 1 - x, y, z) * Matrix.RotationYawPitchRoll(0, tilt, 0); // Then move it where you want dx.Material = GraphicsUtility.InitMaterial(Color.FromArgb(r, g, b)); mCellMesh.M.DrawSubset(0); } //for (int z = 0; z < grid.dimension; z++) { if (z == grid.dimension / 2) { if ((x == 1) || (x == grid.dimension - 2) || (y == 1) || (y == grid.dimension - 2)) { dx.Transform.World = Matrix.Translation(-grid.dimension / 2, -grid.dimension / 2, -grid.dimension / 2) //Center model * Matrix.Translation(x, y, z) * Matrix.RotationYawPitchRoll(0, tilt, 0); // Then move it where you want dx.Material = GraphicsUtility.InitMaterial(Color.Green); mCellMesh.M.DrawSubset(0); } } } } } if ((plane_hits > 30) && (!ground_plane_drawn)) { ground_plane_drawn = true; for (int x = 1; x < grid.dimension - 1; x++) { for (int y = 1; y < grid.dimension - 1; y++) { if (grid.empty[x, y]) { //occupancyGridCell c = grid.cell[x, y, z]; int r = 0; int g = 0; int b = 255; dx.Transform.World = Matrix.Translation(-grid.dimension / 2, -grid.dimension / 2, -grid.dimension / 2) //Center model //* Matrix.Scaling(1, 1, 1) // Make it bigger //* Matrix.RotationYawPitchRoll(0, 0, 0) * Matrix.Translation(grid.dimension - 1 - x, y, z) * Matrix.RotationYawPitchRoll(0, tilt, 0); // Then move it where you want dx.Material = GraphicsUtility.InitMaterial(Color.FromArgb(r, g, b)); mCellMesh.M.DrawSubset(0); } } } } } }
/// <summary> /// Save the mesh when the DirectX device is lost /// </summary> void d3d_DxLost(Direct3d d3d, Device dx) { if (mTexture == null) return; // Get surface description int width = mSurfDesc.Width; int height = mSurfDesc.Height; // Isn't there a better way to do this? switch (mSurfDesc.Format) { case Format.Dxt1: mPixelSizeBits = 4; break; case Format.A8: mPixelSizeBits = 8; break; case Format.A4L4: case Format.Dxt2: case Format.Dxt3: case Format.Dxt4: case Format.Dxt5: mPixelSizeBits = 8; Debug.Assert(false); break; case Format.A8R3G3B2: case Format.A4R4G4B4: case Format.A1R5G5B5: mPixelSizeBits = 16; break; case Format.G8R8G8B8: case Format.A8R8G8B8: case Format.X8R8G8B8: case Format.A8B8G8R8: case Format.X8B8G8R8: mPixelSizeBits = 32; break; default: // Insert your vertexFormat above mPixelSizeBits = 32; Debug.Assert(false); break; } // Read the mesh data int pitch; mTextureData = (byte[])mTexture.LockRectangle(typeof(byte), 0, LockFlags.ReadOnly, out pitch, mPixelSizeBits*width*height/8); //Debug.Assert(pitch == mPixelSizeBits*width/8); // New versions of DX fixes Pitch for us mTexture.UnlockRectangle(0); mTexture.Dispose(); mTexture = null; }
/// <summary> /// Create an AutoVertexBuffer initialized with the indices in buffer /// </summary> /// <param name="d3d"></param> /// <param name="buffer"></param> /// <param name="usage"></param> /// <param name="pool"></param> public AutoIndexBuffer(Direct3d d3d, ushort []buffer, Usage usage, Pool pool) { mIndexBuffer = new IndexBuffer(typeof(ushort), buffer.Length, d3d.Dx, usage, pool); mD3d = d3d; mNumIndices = buffer.Length; mUsage = usage; mPool = pool; SetIndices(buffer); d3d.DxLost += new Direct3d.DxDirect3dDelegate(d3d_DxLost); d3d.DxRestore += new Direct3d.DxDirect3dDelegate(d3d_DxRestore); }
/// <summary> /// Restore the mesh when the DirectX device is restored /// </summary> void d3d_DxRestore(Direct3d d3d, Device dx) { // If the direct3d device wasn't lost in the first place, don't restore it. // This happens the first timeMs around. if (mTexture != null) return; // Create mesh int width = mSurfDesc.Width; int height = mSurfDesc.Height; mTexture = new Texture(d3d.Dx, width, height, 1, mSurfDesc.Usage, mSurfDesc.Format, mSurfDesc.Pool); // Write the texture data int pitch; GraphicsStream stream = mTexture.LockRectangle(0, LockFlags.Discard | LockFlags.NoDirtyUpdate, out pitch); //Debug.Assert(pitch == mPixelSizeBits*width/8); // New versions of DX fixes Pitch for us //Debug.Assert(pitch*height == mTextureData.Length); stream.Write(mTextureData); mTexture.UnlockRectangle(0); mTextureData = null; }
/// <summary> /// Dispose this object and the pathIndex buffer it holds /// </summary> public void Dispose() { if (mIndexBuffer != null) { mIndexBuffer.Dispose(); mIndexBuffer = null; } if (mD3d != null) { mD3d.DxLost -= new Direct3d.DxDirect3dDelegate(d3d_DxLost); mD3d.DxRestore -= new Direct3d.DxDirect3dDelegate(d3d_DxRestore); mD3d = null; } mIndexBuffer = null; }
/// <summary> /// Dispose this object and the mesh it holds. /// </summary> public void Dispose() { if (mMesh != null) { mMesh.Dispose(); mMesh = null; } if (mD3d != null) { mD3d.DxLost -= new Direct3d.DxDirect3dDelegate(d3d_DxLost); mD3d.DxRestore -= new Direct3d.DxDirect3dDelegate(d3d_DxRestore); mD3d = null; } mIndexBufferCopy = null; mVertexBufferCopy = null; mAttributeBufferCopy = null; mVertexCache = null; mBoundingBoxValid = false; mSphereValid = false; mSphereMinValid = false; for (int i = 0; i < mTextures.Length; i++) if (mTextures[i] != null) mTextures[i].Dispose(); mTextures = sEmptyAutoTextureArray; mMaterials = sEmptyMaterialArray; }
/// <summary> /// Save the vertex buffer when the DirectX device is lost /// </summary> void d3d_DxLost(Direct3d d3d, Device dx) { if (mIndexBuffer == null) return; mIndexData = (byte[])mIndexBuffer.Lock(0, typeof(byte), LockFlags.ReadOnly, mIndexBuffer.Description.Size); mIndexBuffer.Unlock(); mIndexBuffer.Dispose(); mIndexBuffer = null; }
/// <summary> /// Save the mesh when the DirectX device is lost /// </summary> void d3d_DxLost(Direct3d d3d, Device dx) { if (mMesh == null) return; // Save all data needed to restore the mesh mNumFaces = mMesh.NumberFaces; mNumVertices = mMesh.NumberVertices; mNumBytesPerVertex = mMesh.NumberBytesPerVertex; mFlags = mMesh.Options.Value; mVertexFormat = mMesh.VertexFormat; // Copy pathIndex buffer mIndexBufferCopy = (byte[])mMesh.LockIndexBuffer(typeof(byte), LockFlags.ReadOnly, mMesh.IndexBuffer.Description.Size); mMesh.UnlockIndexBuffer(); // Copy vertex buffer mVertexBufferCopy = (byte[])mMesh.LockVertexBuffer(typeof(byte), LockFlags.ReadOnly, mMesh.NumberBytesPerVertex * mMesh.NumberVertices); mMesh.UnlockVertexBuffer(); // Copy attribute buffer mAttributeBufferCopy = mMesh.LockAttributeBufferArray(LockFlags.ReadOnly); mMesh.UnlockAttributeBuffer(mAttributeBufferCopy); mMesh.Dispose(); mMesh = null; mVertexCache = null; }
/// <summary> /// Restore the vertex buffer when the DirectX device is restored /// </summary> void d3d_DxRestore(Direct3d d3d, Device dx) { // If the direct3d device wasn't lost in the first place, don't restore it. // This happens the first timeMs around. if (mIndexBuffer != null) return; mIndexBuffer = new IndexBuffer(typeof(ushort), mNumIndices, d3d.Dx, mUsage, mPool); byte []data = (byte[])mIndexBuffer.Lock(0, typeof(byte), LockFlags.Discard, mIndexBuffer.Description.Size); mIndexData.CopyTo(data, 0); mIndexBuffer.Unlock(); mIndexData = null; }
/// <summary> /// Read a mesh from an X file, and load the textures which are /// assumed to be in the same directory. /// </summary> public static AutoMesh LoadFromXFile(string path, MeshFlags flags, Direct3d d3d) { ExtendedMaterial[] extendedMaterials; String []fileNames; AutoMesh mesh = new AutoMesh(d3d, Mesh.FromFile(path, MeshFlags.SystemMemory, d3d.Dx, out extendedMaterials)); mesh.mTextures = new AutoTexture[extendedMaterials.Length]; mesh.mMaterials = new Material[extendedMaterials.Length]; fileNames = new string[extendedMaterials.Length]; // Load all the textures for this mesh for (int i = 0; i < extendedMaterials.Length; i++) { if (extendedMaterials[i].TextureFilename != null) { string textureFileName = System.IO.Path.Combine( System.IO.Path.GetDirectoryName(path), extendedMaterials[i].TextureFilename); fileNames[i] = textureFileName; // Scan to see if we already have this texture bool alreadyHaveTexture = false; for (int j = 0; j < i; j++) if (textureFileName == fileNames[j]) { mesh.mTextures[i] = mesh.mTextures[j]; alreadyHaveTexture = true; break; } // Load texture (if we don't already have it) if (!alreadyHaveTexture) mesh.mTextures[i] = new AutoTexture(d3d, TextureLoader.FromFile(d3d.Dx, textureFileName)); } mesh.mMaterials[i] = extendedMaterials[i].Material3D; mesh.mMaterials[i].Ambient = mesh.mMaterials[i].Diffuse; } return mesh; }
/// <summary> /// Called each frame to render the mesh /// </summary> private void d3dModel_DxRender3d(Direct3d d3d, Device dx) { if (mMesh == null) return; // Setup the lights dx.Lights[0].Enabled = true; dx.Lights[0].Type = LightType.Directional; dx.Lights[0].Direction = new Vector3(0, 0, 1); dx.Lights[0].Diffuse = Color.White; dx.Lights[0].Position = new Vector3(0, 0, 0); dx.RenderState.NormalizeNormals = true; // Lighting only when there are normals dx.RenderState.Lighting = (int)(mMesh.M.VertexFormat & VertexFormats.Normal) != 0; // Setup camera dx.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, 640f / 480f, 50.0f, 2000.0f); dx.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -220), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); // Use mip map dx.SamplerState[0].MipFilter = TextureFilter.Linear; dx.SamplerState[0].MinFilter = TextureFilter.Linear; dx.SamplerState[0].MagFilter = TextureFilter.Linear; // Adjust mesh to fit view port Vector3 center; float radius = mMesh.BoundingSphereMin(out center); dx.Transform.World = Matrix.Translation(-1*center) * Matrix.Scaling(1/radius, 1/radius, 1/radius) * Matrix.Scaling(90, 90, 90) * Matrix.RotationQuaternion(mOrientation); // Draw mesh using mesh specified materials mMesh.Draw(true); // For an interesting effect, comment above line and uncomment following lines //dx.Material = GraphicsUtility.InitMaterial(Color.Red); //mMesh.Draw(true); }