@c -*-texinfo-*-
@node PropClass Hover, , PropClass ZoneMgr, Property Classes
@subsection Hover
@cindex pchover property class
@cindex pchover
@cindex @code{iPcHover}

The mesh property class can be used to assign a 3D model to an entity.
This property class defines a visual representation for an entity.
This property class, defines a hovering object when used in conjunction
with @samp{pcmechobject}.

@subsubheading Property Class Details

@itemize @bullet
@item @emph{Name}:
@samp{pchover}
@item @emph{Factory ID}:
@samp{cel.pcfactory.hover}
@item @emph{Interface}:
@code{iPcHover}
@item @emph{Header}:
@file{include/propclass/hover.h}
@end itemize

@subsubheading General Information

A Hovering object can be something like a hovercraft or a anti-gravity ship.
As well as hovering your object, it will also align it to the terrain, so
that as it goes down a hill, the ship will also tilt.

This property class requires you to load it with an entity, which has a
@samp{pcmesh} property class to act as the terrain it hovers over.

@subsubheading Setting the Terrain

There are 2 ways to set the terrain mesh in @samp{pchover}:

@itemize @bullet
@item
Assuming you have the @code{iPcMesh} object, call @code{iPcHover->SetWorldMesh(pcmeshobj)}
@item
Or you can use the entities name, as in @code{iPcHover->SetWorld("ent_level")}
@end itemize

This step is crucial, if you forget to do it the hovering system will not work.

@subsubheading Setting the Upthruster Function

Instead of using the default upthruster function, you may want to provide your
own reactionary calculator.

@example
// CEL Includes
#include "tools/stabiliser_dist.h"

class CustomUpthrusterFunction : public celStabiliserFunction
@{
public:
  float Force(celHoverObjectInfo obj_info)
  @{
    /* when the height of the object
        is less then 2, use an
        upthrust force of 8 */
    if (obj_info.height < 2)
      return 8.0;

    return 0.0;
  @}
@};
@end example

Then to insert into the property class you would do

@example
pchover->SetStabiliserFunction (new CustomUpthrusterFunction ());
@end example

At runtime, everytime the objects iPcHover is updated, your upthruster function
will get called with information with the objects information on its state.

@example
struct celHoverObjectInfo
@{
  /**
   * The height of the object above the
   * ground in along the world's y axis.
   */
  float height;

  /**
   * The vertical velocity of the object
   * along the objects local y axis.
   */
  float yvel;
@};
@end example

@subsubheading angular correction

This refers to the object correcting its angle as it flies over terrain (facing
downwards as it flies down hills).

The implementation of this is done by calculating the object's height at its
center and then calculating the height away from the center.
Using the differences in height and a bit of trigonmetry, you can see the angle
of the object relative to the terrain.

@itemize @bullet
@item
@code{iPcHover->SetAngularBeamOffset (float)} refers to how far away from the center of
the object the second height test is done.
Smaller values are better on more noisy terrain, but less accurate and more jerky,
whereas larger values are more likely to approximate (that small bump won't
get noticed).
Values like 0.5 are usually small enough to suffice.
@item
@code{iPcHover->SetAngularCorrectionStrength (float)} is how fast the object corrects
its rotation. High values and it will jerk extremely fast, smaller and it will hardly
re-align.
1.0 is normal.
@item
@code{iPcHover->SetAngularCutoffHeight (float)} is the height at which the angular
correction stops working - you obviously don't want a ship re-aligning itself with
terrain as its flying in the air.
@end itemize
