Example #1
0
    public override void Update(GameTime gameTime)
    {
      // If an item in a spatial partition changes (e.g. if it moves or if the AABB changes) you 
      // have to call
      //_spatialPartition.Invalidate(changedGeometryobject);
      // If many or all items have changed you can call 
      //_spatialPartition.Invalidate();
      // After an item was invalidated, the spatial partition needs to be rebuilt. This happens
      // automatically when needed or when you call
      //_spatialPartition.Update(forceRebuild: false);

      // Get a ray which shoots forward.
      var cameraPose = GraphicsScreen.CameraNode.PoseWorld;
      var ray = new Ray
      {
        Origin = cameraPose.Position,
        Direction = cameraPose.ToWorldDirection(Vector3F.Forward),
        Length = 100,
      };

      // Draw objects.
      var debugRenderer = GraphicsScreen.DebugRenderer;
      debugRenderer.Clear();
      foreach (var geometricObject in _spatialPartition)
        debugRenderer.DrawObject(geometricObject, Color.LightGreen, false, false);

      GeometricObject closestHitGeometricObject = null;
      Triangle closestHitTriangle = new Triangle();
      float closestHitDistance = float.PositiveInfinity;

      // Use the spatial partition to get all objects where the AABB overlaps the ray.
      foreach (var geometricObject in _spatialPartition.GetOverlaps(ray))
      {
        var triangleMeshShape = (TriangleMeshShape)geometricObject.Shape;

        // Transform the ray into the local space of the triangle mesh.
        var localRay = new Ray
        {
          Origin = geometricObject.Pose.ToLocalPosition(ray.Origin),
          Direction = geometricObject.Pose.ToLocalDirection(ray.Direction),
          Length = ray.Length,
        };

        // Use the spatial partition of the mesh shape to compute all triangles where the 
        // AABB overlaps the ray.
        foreach (var triangleIndex in triangleMeshShape.Partition.GetOverlaps(localRay))
        {
          var triangle = triangleMeshShape.Mesh.GetTriangle(triangleIndex);

          // Check if ray intersects the triangle and remember the closest hit.
          float hitDistance;
          if (GeometryHelper.GetContact(localRay, triangle, false, out hitDistance)
              && hitDistance < closestHitDistance)
          {
            closestHitGeometricObject = geometricObject;
            closestHitTriangle = triangle;
            closestHitDistance = hitDistance;
          }
        }
      }

      // Draw hit triangle.
      if (closestHitGeometricObject != null)
        debugRenderer.DrawTriangle(closestHitTriangle, closestHitGeometricObject.Pose, Vector3F.One, Color.Red, true, true);
    }
Example #2
0
        public override void Update(GameTime gameTime)
        {
            // If an item in a spatial partition changes (e.g. if it moves or if the AABB changes) you
            // have to call
            //_spatialPartition.Invalidate(changedGeometryobject);
            // If many or all items have changed you can call
            //_spatialPartition.Invalidate();
            // After an item was invalidated, the spatial partition needs to be rebuilt. This happens
            // automatically when needed or when you call
            //_spatialPartition.Update(forceRebuild: false);

            // Get a ray which shoots forward.
            var cameraPose = GraphicsScreen.CameraNode.PoseWorld;
            var ray        = new Ray
            {
                Origin    = cameraPose.Position,
                Direction = cameraPose.ToWorldDirection(Vector3F.Forward),
                Length    = 100,
            };

            // Draw objects.
            var debugRenderer = GraphicsScreen.DebugRenderer;

            debugRenderer.Clear();
            foreach (var geometricObject in _spatialPartition)
            {
                debugRenderer.DrawObject(geometricObject, Color.LightGreen, false, false);
            }

            GeometricObject closestHitGeometricObject = null;
            Triangle        closestHitTriangle        = new Triangle();
            float           closestHitDistance        = float.PositiveInfinity;

            // Use the spatial partition to get all objects where the AABB overlaps the ray.
            foreach (var geometricObject in _spatialPartition.GetOverlaps(ray))
            {
                var triangleMeshShape = (TriangleMeshShape)geometricObject.Shape;

                // Transform the ray into the local space of the triangle mesh.
                var localRay = new Ray
                {
                    Origin    = geometricObject.Pose.ToLocalPosition(ray.Origin),
                    Direction = geometricObject.Pose.ToLocalDirection(ray.Direction),
                    Length    = ray.Length,
                };

                // Use the spatial partition of the mesh shape to compute all triangles where the
                // AABB overlaps the ray.
                foreach (var triangleIndex in triangleMeshShape.Partition.GetOverlaps(localRay))
                {
                    var triangle = triangleMeshShape.Mesh.GetTriangle(triangleIndex);

                    // Check if ray intersects the triangle and remember the closest hit.
                    float hitDistance;
                    if (GeometryHelper.GetContact(localRay, triangle, false, out hitDistance) &&
                        hitDistance < closestHitDistance)
                    {
                        closestHitGeometricObject = geometricObject;
                        closestHitTriangle        = triangle;
                        closestHitDistance        = hitDistance;
                    }
                }
            }

            // Draw hit triangle.
            if (closestHitGeometricObject != null)
            {
                debugRenderer.DrawTriangle(closestHitTriangle, closestHitGeometricObject.Pose, Vector3F.One, Color.Red, true, true);
            }
        }