Adding a new engine to PAL is a relatively straight forward process. The difficulty in implementing a PAL wrapper for the engine depends on how similar the physics engines interface is to PAL. The simplest approach to implementing a new engine is to start with just the physics engine abstraction, a box, and a plane. From this point, other geometries, bodies, and terrain types can be easily added. Implementing materials, constraints and compound bodies is then advised before finally implementing sensors, actuators and vehicles.
To get a good overview of PAL it would be advisable to inspect the PAL implementation for an engine that you are already familiar with. Generally implementing functionality for PAL is straight-forward. There are only a few parts of the functionality that PAL configures or performs behind the scenes. These are the management of materials and the assignment of geometries to bodies.
Implementing the bodies and geometries can be done independently, however if the physics engine that you are developing the PAL interface for does not support this distinction you can directly implement a PAL Box, Sphere or Capsule. Most modern engines support a separate geometry representation. For these engines it is important to understand the oder in which a body is initialized. In this example we will examine the palSphere, however it is the same process for all bodies.
^ topThe first thing to implement is the palPhysics system.
class palCUSTOMPhysics: public palPhysics {
public:
palCUSTOMPhysics();
virtual void Init(Float gravity_x, Float gravity_y, Float gravity_z);
virtual void Cleanup();
protected:
virtual void Iterate(Float timestep);
FACTORY_CLASS(palCUSTOMPhysics,palPhysics,CUSTOM,1)
};
It is advisable to include a public pointer to the underlying physics systems implementation (such as the world) to allow application developers to easily extend the PAL functionality for the specific physics system.
At this point, only the Init and Iterate methods need to be implemented, the Cleanup can be implemented at a later stage.
Once we have our physics system we can concentrate on our next task: implementing the geometry, body, sphere geometry and sphere body for the engine. Again, depending on the engine we are implementing we can choose to follow PAL's full abstraction hierarchy and implement the geometry separately from the sphere geometry, or not.
In the case of following the full hierarchy we can inherit from palGeometry, however we must use virtual inheritance as palSphereGeometry also inherits from palGeometry.
class palCUSTOMGeometry : virtual public palGeometry {
public:
palCUSTOMGeometry();
~palCUSTOMGeometry();
};
class palCUSTOMSphereGeometry : public palSphereGeometry , public palCUSTOMGeometry {
public:
palCUSTOMSphereGeometry();
virtual void Init(palMatrix4x4 &pos, Float radius, Float mass);
protected:
FACTORY_CLASS(palCUSTOMSphereGeometry,palSphereGeometry,CUSTOM,1)
};
Alternatively if an abstraction for the geometry is not supported then the engines sphere geometry can be implemented directly as follows:
class palCUSTOMSphereGeometry : public palSphereGeometry {
public:
palCUSTOMSphereGeometry();
virtual void Init(palMatrix4x4 &pos, Float radius, Float mass);
protected:
FACTORY_CLASS(palCUSTOMSphereGeometry,palSphereGeometry,CUSTOM,1)
};
The next step is to define how we will implement the body. At this point we only require the ability to get and set the bodies location, and all other methods can be left blank for later implementation.
class palCUSTOMBody : virtual public palBody {
public:
palCUSTOMBody();
virtual void SetPosition(palMatrix4x4& location);
virtual palMatrix4x4& GetLocationMatrix();
};
Note that we do not have a factory class implementation, as a palBody can not be constructed directly. This is done to ensure more compatibility with engines that do not support the geometry/body abstraction paradigm.
^ topAfter implementing the physics, body and geometry we are ready to implement a sphere body. The first step is to call the palSphere initialization method if the geometry/body abstraction is supported. The PAL sphere initialization function creates a palSphereGeometry and adds it to a the geometries attached to the body. It then calls the initialization method for the geometry.
palFactoryObject *pFO=PF->CreateObject("palSphereGeometry");
palSphereGeometry *m_pGeom = dynamic_cast(pFO);
m_Geometries.push_back(m_pGeom);
SetGeometryBody(m_pGeom);
m_pGeom->Init(m_mLoc,radius,mass);
Thus when the engines PAL sphere is implemented we are only required to call the palSphere initialization function, and then we can use the geometries array (m_Geometries[0]
) directly.
void palCUSTOMSphere::Init(Float x, Float y, Float z, Float radius, Float mass) {
palSphere::Init(x,y,z,radius,mass);
//code to build a body using x,y,z,mass and m_Geometries[0] goes here.
palCUSTOMGeometry *pCg=dynamic_cast (m_Geometries[0]);
//you may need access to the geometry for this engines implementation, achieved as illustrated above.
}