// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page qtquick3dphysics-shapes-bodies.html
\title Qt Quick 3D Physics Shapes and Bodies
\brief An overview of Qt Quick 3D Physics objects and their physical shapes

The objects in the simulation are represented by any of the following four types of bodies: \l{StaticRigidBody}, \l{DynamicRigidBody}, \l{CharacterController} and \l{TriggerBody}. The physical shape of a body is represented by subtypes of \l CollisionShape.

\section1 Shapes

A collision shape is used to define the physical shape and extent of an
object for the purposes of the physics simulation. The collision shape
will typically be simpler than the object's visual appearance.

There are some predefined shapes built into the engine: \l BoxShape,
\l CapsuleShape, \l SphereShape, and \l PlaneShape. Handling of these shapes is
optimized, so simulation using them will typically perform better.

In addition, there are custom shapes that are defined by data: \l ConvexMeshShape,
\l HeightFieldShape, and \l TriangleMeshShape. These allow more flexibility at the expense
of performance.

\section1 Bodies

A \l {PhysicsBody}{body} represents a physical object in the simulation. These bodies interact and
collide with each other. The two main types are \e{static bodies} (\l StaticRigidBody) and \e{dynamic bodies} (\l DynamicRigidBody). The
physical shape of a body is specified by a list of shapes. The effective shape is the \e union of
these shapes. The relative position of the shapes is fixed: the bodies are \e rigid.

\section2 Dynamic body

Dynamic bodies are able to move. The \l{DynamicRigidBody::isKinematic}{isKinematic} property
determines how it moves. When \c isKinematic is \c true, the body is positioned explicitly by
modifying the \l{DynamicRigidBody::kinematicPosition}{kinematicPosition} and
\l{DynamicRigidBody::kinematicRotation}{kinematicRotation} properties. When \c isKinematic is \c false, the
object is controlled by the simulation: it will fall under gravity, and bounce off other objects.

When \isKinematic is \c true, all shapes are allowed. However, non-kinematic bodies are more
restricted: only \e convex shapes can be used. These are the pre-defined shapes \l BoxShape,
\l CapsuleShape, and \l SphereShape; and the custom shape \l ConvexMeshShape. This does not mean
that it is impossible to have a non-convex physical geometry: several convex shapes can be combined
for a single body. The \l {Qt Quick 3D Physics - Compound Shapes Example}{Compound Shapes Example}
shows how to form ring-shaped bodies based on convex shapes.

\section2 Static body

Static bodies do not move. They represent the environment in which the other bodies move. Note that it is technically possible to move a static body, but the physical simulation will behave unexpectedly. In particular, a dynamic body that has entered a resting position on a static body will not be awoken if the static body moves. This means the dynamic body will remain in the same position even if the static body is moved.

\section2 Character controller

The \l {CharacterController} type is a special case. It represents a character that moves through
the environment. One typical use case is a first-person view where the \l {QtQuick3D::Camera}{camera}
is a child of the  character controller, and its movement is controlled by keyboard/mouse or gamepad.

\section2 Trigger body

There is also the \l {TriggerBody} type which is another special case. As opposed to the other bodies it is not a physical body, meaning it does not interact in collision with other bodies. As the name suggests it is only used to trigger actions when another body enters or leaves its volume as defined by its collision shapes. If another body has \l {PhysicsNode::sendTriggerReports} {sendTriggerReports} set to \c true and its collision volume enters a \l {TriggerBody} the \l{TriggerBody::bodyEntered} {bodyEntered} signal is emitted.

The following table shows a summary of the different types of bodies, how they interact and can be used:

\table
\header
    \li Body
    \li Interaction
    \li Allowed shapes
\row
    \li \l {StaticRigidBody}
    \li Does not move
    \li All shapes
\row
    \li \l {DynamicRigidBody} with \l{DynamicRigidBody::isKinematic}{isKinematic} \c true
    \li Positioned programatically. Influences dynamic bodies. Stopped by nothing.
    \li All shapes
\row
    \li \l {DynamicRigidBody} with  \l{DynamicRigidBody::isKinematic}{isKinematic} \c false
    \li Fully controlled by simulation
    \li Limited shapes
\row
    \li \l {CharacterController}
    \li Moved programatically. Influences dynamic bodies. Stopped by static bodies.
    \li Only a single \l CapsuleShape
\row
    \li \l {TriggerBody}
    \li None
    \li All shapes
\endtable

\section1 Physics Materials

The \l PhysicsMaterial type specifies how an object behaves when it collides with another. The
\l {PhysicsMaterial::dynamicFriction}{dynamicFriction} and \l {PhysicsMaterial::staticFriction}{staticFriction}
properties determine how slippery the object is, and \l {PhysicsMaterial::restitution}{restitution}
determines how bouncy it is.
*/
