private void RenderShape(GraphicsDevice graphicsDevice, PrimitiveJob job)
    {
      Submesh submesh;
      Matrix matrix;
      ShapeMeshCache.GetMesh(_graphicsService, job.Shape, out submesh, out matrix);
      if (submesh.VertexBuffer == null)
        return;   // This could happen for shapes without a mesh, like an InfiniteShape.

      Effect.World = (Matrix)matrix * Matrix.CreateScale((Vector3)job.Size.Scale) * job.Pose;
      Effect.CurrentTechnique.Passes[0].Apply();

      var originalRasterizerState = graphicsDevice.RasterizerState;
      var triangleMeshShape = job.Shape as TriangleMeshShape;
      if (triangleMeshShape != null && triangleMeshShape.IsTwoSided && originalRasterizerState.CullMode != CullMode.None)
      {
        if (AutoRasterizerState)
        {
          // For two-sided meshes we disable back-face culling.
          graphicsDevice.RasterizerState = DrawWireFrame ? GraphicsHelper.RasterizerStateWireFrame : GraphicsHelper.RasterizerStateCullNone;
          submesh.Draw();
          graphicsDevice.RasterizerState = originalRasterizerState;
        }
        else
        {
          submesh.Draw();
        }
      }
      else
      {
        submesh.Draw();
      }
    }
        public void UpdateSubmesh(IGraphicsService graphicsService, WaterNode node)
        {
            if (node.Volume == null)
            {
                return;
            }

            // We have to update the submesh if it is null or disposed.
            //   Submesh == null                            --> Update
            //   Submesh != null && VertexBuffer.IsDisposed --> Update
            //   Submesh != null && VertexBuffer == null    --> This is the EmptyShape. No updated needed.
            if (Submesh == null || (Submesh.VertexBuffer != null && Submesh.VertexBuffer.IsDisposed))
            {
                ShapeMeshCache.GetMesh(graphicsService, node.Volume, out Submesh, out SubmeshMatrix);
            }
        }
        public void UpdateClipSubmesh(IGraphicsService graphicsService, LightNode node)
        {
            var clip = node.Clip;

            Debug.Assert(clip != null);

            // We have to update the submesh if it is null or disposed.
            //   Submesh == null                            --> Update
            //   Submesh != null && VertexBuffer.IsDisposed --> Update
            //   Submesh != null && VertexBuffer == null    --> This is the EmptyShape. No updated needed.
            if (ClipSubmesh == null || (ClipSubmesh.VertexBuffer != null && ClipSubmesh.VertexBuffer.IsDisposed))
            {
                ShapeMeshCache.GetMesh(graphicsService, clip.Shape, out ClipSubmesh, out ClipMatrix);

                // Add transform of Clip.
                ClipMatrix = clip.Pose * Matrix.CreateScale(clip.Scale) * ClipMatrix;
            }
        }