

//
// Irrlicht Wrapper for Imperative Languages
// Frank Dodd (2006)
//
// Additional Work
// Michael Taupitz (2006)
//
// This wrapper DLL encapsulates a sub-set of the features of the powerful
// Irrlicht 3D Graphics Engine exposing the Object Oriented architecture and
// providing a functional 3D SDK for languages that are not object oriented.
//
// This source was created with the help of the great examples in the Irrlicht
// SDK and the excellent Irrlicht documentation. This software was developed
// using the GCC compiler and Code::Blocks IDE
//

/* ////////////////////////////////////////////////////////////////////////////
includes
*/
#include "irrlichtwrapper.h"


/* ////////////////////////////////////////////////////////////////////////////
global variables
*/

/* ////////////////////////////////////////////////////////////////////////////
external variables
*/
extern IrrlichtDevice *device;
extern IVideoDriver* driver;
extern ISceneManager* smgr;
extern IGUIEnvironment* guienv;


// Espacially wanted from Xperience2003
// Usefull for all aout there
// Author : Xaron

/**
 * @brief guided missile steering helper function
 *
 * @param missilePosition - current absolute position of the missile
 * @param missileRotation - current absolute rotation of the missile
 * @param targetPosition  - current absolute target position
 * @param oversteer       - oversteer factor in degrees
 *
 * @return targetPitchRoll - delta pitch (x) and delta roll (z) values to the target
 *
 *******************************************************************************************************/
core::vector3df getToTargetPitchRoll( const core::vector3df& missilePosition, const core::vector3df& missileRotation, const core::vector3df& targetPosition, float oversteer = 0.0f )
{
  core::matrix4 rotMatrix, invRotMatrix;
  rotMatrix.setRotationDegrees( missileRotation );
  core::vector3df targetPitchRoll( 0.0f, 0.0f, 0.0f );
  // get the current missile direction
  core::vector3df currentMissileTargetVec( 0.0f, 0.0f, 1.0f );

  // get the vector to the target (from the missile position)
  core::vector3df missileTargetVec = ( targetPosition - missilePosition ).normalize();
  // invert the rotation matrix to transform the target vector into the missile's local space
  rotMatrix.getInverse( invRotMatrix );
  // transform the target vector into missile's local space
  invRotMatrix.rotateVect( missileTargetVec );
  // compute the roll angle to the target
  float deltaRoll = atan2f( missileTargetVec.Y, missileTargetVec.X ) * core::RADTODEG - 90.0f;
  if( deltaRoll < 0.0f )
    deltaRoll += 360.0f;
  if( deltaRoll >= 360.0f )
    deltaRoll -= 360.0f;

  if( deltaRoll > 180.0f )
    deltaRoll -= 360.0f;

  // compute the pitch angle to the target
  float deltaPitch = acosf( currentMissileTargetVec.dotProduct( missileTargetVec ) )
    * core::RADTODEG + oversteer;

  targetPitchRoll.X = -deltaPitch;
  targetPitchRoll.Z = deltaRoll;

  return targetPitchRoll;
}


/* ////////////////////////////////////////////////////////////////////////////
Global Function Declarations

all of the below functions are declared as C functions and are exposed without
any mangled names so that they can be easily imported into imperative
languages like FreeBasic
*/
extern "C"
{

/* ////////////////////////////////////////////////////////////////////////////
SCENE NODE FUNCTIONS
*/


/****f* Nodes/IrrGetNodeParent
* NAME
*    IrrGetNodeParent - get the parent of this node
* SYNOPSIS
*    IrrGetNodeParent(*node.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
* FUNCTION
*   Get the parent of this node.
* RESULT
*    #Null if there is no parent, otherwise the pointer to the Parent-Node
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeParent(*node.l)
*/
STATIC_EXPORT ISceneNode* DLL_EXPORT IrrGetNodeParent( ISceneNode* node )
{
    return node->getParent();
}

/****f* Nodes/IrrGetNodeID
* NAME
*    IrrGetNodeID - get the ID of this node
* SYNOPSIS
*    IrrGetNodeID(*node.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
* FUNCTION
*   get the ID of this node
* RESULT
*    ID of this Node
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeID(*node.l)
*/
STATIC_EXPORT int DLL_EXPORT IrrGetNodeID( ISceneNode* node )
{
    return node->getID();
}

/****f* Nodes/IrrSetNodeID
* NAME
*    IrrSetNodeID - set the ID of this node
* SYNOPSIS
*    IrrSetNodeID(*node.l, id.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   id.l                - id for this node
* FUNCTION
*   set the ID of this node
* RESULT
*    Nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeID(*node.l, id.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeID( ISceneNode* node, int id )
{
    node->setID(id);
}

/****f* Nodes/IrrGetNodeName
* NAME
*    IrrGetNodeName - get the Name of this node
* SYNOPSIS
*    IrrGetNodeName(*node.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
* FUNCTION
*   get the Name of this node
* EXAMPLE
*   nodeName.s = PeekS( IrrGetNodeName(*myNode) )
* RESULT
*    Pointer to the String with the NodeName.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeName(*node.l)
*/
STATIC_EXPORT const char* DLL_EXPORT IrrGetNodeName( ISceneNode* node )
{
    return node->getName();
}

/****f* Nodes/IrrSetNodeName
* NAME
*    IrrSetNodeName - set the Name of this node
* SYNOPSIS
*    IrrSetNodeName(*node.l, nodeName.s)
* INPUTS
*   *node.l             - pointer to a Scene Node
* FUNCTION
*   set the Name of this node
* RESULT
*    Nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeName(*node.l, nodeName.p-ascii)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeName( ISceneNode* node, const char* name )
{
    node->setName(name);
}

/****f* Nodes/IrrDebugDataVisible
* NAME
*    IrrDebugDataVisible - change debuginfo for this node
* SYNOPSIS
*    IrrDebugDataVisible(*node.l, bVisible.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   bVisible.l          - #True if Debug Infos should rendered, otherwise #False
* FUNCTION
*   render debugging information for nodes to the display
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrDebugDataVisible(*node.l, bVisible.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrDebugDataVisible( ISceneNode* node, bool visible )
{
//    node->setDebugDataVisible( visible );

/*
EDS_OFF  No Debug Data ( Default ).
EDS_BBOX  Show Bounding Boxes of SceneNode.
EDS_NORMALS  Show Vertex Normals.
EDS_SKELETON  Shows Skeleton/Tags.
EDS_MESH_WIRE_OVERLAY  Overlays Mesh Wireframe.
EDS_HALF_TRANSPARENCY  Temporary use transparency Material Type.
EDS_BBOX_BUFFERS  Show Bounding Boxes of all MeshBuffers.
EDS_FULL
*/
    if (visible)
        node->setDebugDataVisible( EDS_BBOX );
    else
        node->setDebugDataVisible( EDS_OFF );
}

/****f* Nodes/IrrSetNodeMaterialTexture
* NAME
*    IrrSetNodeMaterialTexture - Sets the texture
* SYNOPSIS
*    IrrSetNodeMaterialTexture(*node.l, *texture.l, index.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   *texture.l          - pointer to a texture (loaded with IrrGetTexture() )
*   index.l             - Layer of texture to be set. Must be a value greater or equal than 0 and smaller than 4
* FUNCTION
*   Sets the texture of the specified layer in all materials of this scene node to the new texture.
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeMaterialTexture(*node.l, *texture.l, index.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeMaterialTexture ( ISceneNode* node, ITexture *texture, int iIndex )
{
//    printf("%02d iIndex\n",iIndex);
    node->setMaterialTexture( iIndex, texture );
}


/****f* Nodes/IrrSetNodeMaterialFlag
* NAME
*    IrrSetNodeMaterialFlag - Sets Material flag
* SYNOPSIS
*    IrrSetNodeMaterialFlag(*node.l, flag.l, bEnable.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   flag.l              - Flag to Set/Unset
*   bEnable.l           - Enable/Disable Materialflag (#True or #False)
* FUNCTION
*   Sets the flag for the material. To see which Falgs are allowed see at
*   #IR_EMF_*  Enums.
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeMaterialFlag(*node.l, flag.l, bEnable.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeMaterialFlag( ISceneNode* vptrNode, E_MATERIAL_FLAG uiFlag, bool boValue )
{
        vptrNode->setMaterialFlag(uiFlag, boValue );

}

/****f* Nodes/IrrSetNodeMaterialType
* NAME
*    IrrSetNodeMaterialType - Sets Material type
* SYNOPSIS
*    IrrSetNodeMaterialType(*node.l, type.l)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   type.l              - Type of the Material
* FUNCTION
*   Sets the type of the material. To see which Types are possible see at
*   #IR_EMT_*  Enums.
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeMaterialType(*node.l, type.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeMaterialType( ISceneNode* node, E_MATERIAL_TYPE uiType )
{
       node->setMaterialType(uiType);
}

/****f* Nodes/IrrSetNodePosition
* NAME
*    IrrSetNodePosition - Sets position of the Node
* SYNOPSIS
*    IrrSetNodePosition(*node.l, x.f, y.f, z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   x.f,y.f,z.f         - position of the node
* FUNCTION
*   Sets the position of the Node
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodePosition(*node.l, x.f, y.f, z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodePosition ( ISceneNode* node, float X, float Y,  float Z )
{
    // reposition the model
    node->setPosition  ( vector3df(X,Y,Z));
}

/****f* Nodes/IrrSetNodeRotation
* NAME
*    IrrSetNodeRotation - Sets rotation of the Node
* SYNOPSIS
*    IrrSetNodeRotation(*node.l, x.f, y.f, z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   x.f,y.f,z.f         - rotation of the node
* FUNCTION
*   Sets the rotation of the Node
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeRotation(*node.l, x.f, y.f, z.f)
*/

STATIC_EXPORT void DLL_EXPORT IrrSetNodeRotation ( ISceneNode* node, float iX, float iY, float iZ )
{
    node->setRotation (vector3df(iX,iY,iZ));
}

/****f* Nodes/IrrSetNodeScale
* NAME
*    IrrSetNodeScale - Sets scale of the Node
* SYNOPSIS
*    IrrSetNodeScale(*node.l, x.f, y.f, z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   x.f,y.f,z.f         - scale of the node
* FUNCTION
*   Sets the scale of the Node
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeScale(*node.l, x.f, y.f, z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeScale ( IAnimatedMeshSceneNode* node, float fX, float fY, float fZ )
{
    node->setScale (vector3df(fX,fY,fZ));
}


/****f* Nodes/IrrGetNodeScale
* NAME
*    IrrGetNodeScale - Get scale of the Node
* SYNOPSIS
*    IrrGetNodeScale(*node.l, *x.f, *y.f, *z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   *x.f,*y.f,*z.f      - return the scale of the node
* FUNCTION
*   Gets the scale of the Node
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeScale(*node.l, *x.f, *y.f, *z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeScale ( IAnimatedMeshSceneNode* node, float &fX, float &fY, float &fZ )
{
    vector3df vec = node->getScale();
    fX = vec.X;
    fY = vec.Y;
    fZ = vec.Z;
}



/****f* Nodes/IrrGetNodePosition
* NAME
*    IrrGetNodePosition - Get position of the Node
* SYNOPSIS
*    IrrGetNodePosition(*node.l, *x.f, *y.f, *z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   *x.f,*y.f,*z.f      - pointer to floats where the position is stored
* FUNCTION
*   Get the Position of the Node.
*   It is important to know, that the result of this function is stored
*   in the input-variables ! See the Example below.
* EXAMPLE
*   IrrGetNodePosition(*myNode, @myX.f,@myY.f,@myZ.f,)
*   Debug("X="+strf(myX) )
*   Debug("Y="+strf(myY) )
*   Debug("Z="+strf(myX) )
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodePosition(*node.l, *x.f, *y.f, *z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodePosition ( IAnimatedMeshSceneNode* node, float &X, float &Y,  float &Z )
{
    // get the model position the model
    vector3df vect;
    vect = node->getPosition();
    X = vect.X;
    Y = vect.Y;
    Z = vect.Z;
}

/****f* Nodes/IrrGetNodeRotation
* NAME
*    IrrGetNodeRotation - Get rotation of the Node
* SYNOPSIS
*    IrrGetNodeRotation(*node.l, *x.f, *y.f, *z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   *x.f,*y.f,*z.f      - pointer to floats where the rotation is stored
* FUNCTION
*   Get the rotation of the Node.
*   It is important to know, that the result of this function is stored
*   in the input-variables ! See the Example below.
* EXAMPLE
*   IrrGetNodeRotation(*myNode, @myX.f,@myY.f,@myZ.f,)
*   Debug("X="+strf(myX) )
*   Debug("Y="+strf(myY) )
*   Debug("Z="+strf(myX) )
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeRotation(*node.l, *x.f, *y.f, *z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeRotation ( IAnimatedMeshSceneNode* node, float &X, float &Y,  float &Z )
{
    vector3df vect;
    vect = node->getRotation();
    X = vect.X;
    Y = vect.Y;
    Z = vect.Z;
}

/****f* Nodes/IrrGetNodeAbsolutePosition
* NAME
*    IrrGetNodeAbsolutePosition - Get absolute position of the Node
* SYNOPSIS
*    IrrGetNodeAbsolutePosition(*node.l, *x.f, *y.f, *z.f)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   *x.f,*y.f,*z.f      - pointer to floats where the absolute position is stored
* FUNCTION
*   Get the absolute position of the Node.
*   It is important to know, that the result of this function is stored
*   in the input-variables ! See the Example below.
* EXAMPLE
*   IrrGetNodeAbsolutePosition(*myNode, @myX.f,@myY.f,@myZ.f,)
*   Debug("X="+strf(myX) )
*   Debug("Y="+strf(myY) )
*   Debug("Z="+strf(myX) )
* RESULT
*    nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeAbsolutePosition(*node.l, *x.f, *y.f, *z.f)
*/

STATIC_EXPORT void DLL_EXPORT IrrGetNodeAbsolutePosition ( ISceneNode* node, float &X, float &Y,  float &Z )
{
    vector3df vect;
    vect = node->getAbsolutePosition();
    X = vect.X;
    Y = vect.Y;
    Z = vect.Z;
}


/****f* Nodes/IrrGetMS3DJointNode
* NAME
*    IrrGetMS3DJointNode - Get the Joint as Node
* SYNOPSIS
*    *jointNode.l = IrrGetMS3DJointNode(*node.l, JointName.s)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   JointName.s         - Name of the Joint
* FUNCTION
*   Returns a pointer to a child node, wich has the same transformation as the corresponding joint,
*   if the mesh in this scene node is a ms3d mesh. Otherwise 0 is returned. With this method it
*   is possible to attach scene nodes to joints more easily. In this way, it is for example possible
*   to attach a weapon to the left hand of an animated model. This example shows how.
* EXAMPLE
*   *handNode.l = IrrGetMS3DJointNode(*myNode, "LeftHand")
*   IrrAddChildToParent(*weaponNode.l,*handNode.l)
* RESULT
*   Returns a pointer to the scene node which represents the joint with the specified name.
*   Returns 0 if the contained mesh is not an ms3d mesh or the name of the joint could not be found.
* NOTE
*   Please note that the SceneNode returned by this method may not exist before this call and is created by it.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetMS3DJointNode(*node.l, JointName.p-ascii)
*/
STATIC_EXPORT ISceneNode *DLL_EXPORT IrrGetMS3DJointNode ( IAnimatedMeshSceneNode* node, char *node_name )
{
    return node->getMS3DJointNode( node_name );
}


/****f* Nodes/IrrGetDirectXJointNode
* NAME
*    IrrGetDirectXJointNode -  Get the Joint as Node
* SYNOPSIS
*    *jointNode.l = IrrGetDirectXJointNode(*node.l, JointName.s)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   JointName.s         - Name of the Joint
* FUNCTION
*   Returns a pointer to a child node, wich has the same transformation as the corresponding joint,
*   if the mesh in this scene node is a ms3d mesh. Otherwise 0 is returned. With this method it
*   is possible to attach scene nodes to joints more easily. In this way, it is for example possible
*   to attach a weapon to the left hand of an animated model. This example shows how.
* EXAMPLE
*   *handNode.l = IrrGetDirectXJointNode(*myNode, "LeftHand")
*   IrrAddChildToParent(*weaponNode.l,*handNode.l)
* RESULT
*   Returns a pointer to the scene node which represents the joint with the specified name.
*   Returns 0 if the contained mesh is not an ms3d mesh or the name of the joint could not be found.
* NOTE
*   Please note that the SceneNode returned by this method may not exist before this call and is created by it.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetDirectXJointNode(*node.l, JointName.p-ascii)
*/
STATIC_EXPORT ISceneNode *DLL_EXPORT IrrGetDirectXJointNode ( IAnimatedMeshSceneNode* node, char *node_name )
{
    return node->getXJointNode( node_name );
}

/****f* Nodes/IrrGetB3DJointNode
* NAME
*    IrrGetB3DJointNode - Get the Joint as Node
* SYNOPSIS
*    *jointNode.l = IrrGetB3DJointNode(*node.l, JointName.s)
* INPUTS
*   *node.l             - pointer to a Scene Node
*   JointName.s         - Name of the Joint
* FUNCTION
*   Returns a pointer to a child node, wich has the same transformation as the corresponding joint,
*   if the mesh in this scene node is a ms3d mesh. Otherwise 0 is returned. With this method it
*   is possible to attach scene nodes to joints more easily. In this way, it is for example possible
*   to attach a weapon to the left hand of an animated model. This example shows how.
* EXAMPLE
*   *handNode.l = IrrGetB3DJointNode(*myNode, "LeftHand")
*   IrrAddChildToParent(*weaponNode.l,*handNode.l)
* RESULT
*   Returns a pointer to the scene node which represents the joint with the specified name.
*   Returns 0 if the contained mesh is not an ms3d mesh or the name of the joint could not be found.
* NOTE
*   Please note that the SceneNode returned by this method may not exist before this call and is created by it.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetB3DJointNode(*node.l, JointName.p-ascii)
*/
STATIC_EXPORT ISceneNode *DLL_EXPORT IrrGetB3DJointNode ( IAnimatedMeshSceneNode* node, char *node_name )
{
    return node->getJointNode( node_name );
}

/****f* Nodes/IrrAddChildToParent
* NAME
*    IrrAddChildToParent - Get the Joint as Node
* SYNOPSIS
*    IrrAddChildToParent(*nodeChild.l, *nodeParent)
* INPUTS
*   *nodeChild.l        - pointer to a Scene Node
*   *nodeParent.l        - pointer to a Scene Node
* FUNCTION
*   Adds a child to this scene node. If the scene node already has got a parent, it is removed from there as child.
* EXAMPLE
*   *handNode.l = IrrGetB3DJointNode(*myNode, "LeftHand")
*   IrrAddChildToParent(*weaponNode.l,*handNode.l)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrAddChildToParent(*nodeChild.l, *nodeParent)
*/
STATIC_EXPORT void DLL_EXPORT IrrAddChildToParent ( ISceneNode *child, ISceneNode *parent )
{
    parent->addChild(child);
}

/****f* Nodes/IrrAddNodeShadow
* NAME
*    IrrAddNodeShadow - add a stencil shadow to an node
* SYNOPSIS
*    *shadowNode.l = IrrAddNodeShadow(*node.l, [ bZfailmethod.l, infinity.f ])
* INPUTS
*   *node.l        - pointer to a Scene Node
*   bZfailmethod.l - if set to #True, the shadow will use the zfail method, if not, zpass is used
*   infinity.f     - Value used by the shadow volume algorithm to scale the shadow volume.
* FUNCTION
*   Add a shadow volume scene node as child of this node and returns a pointer to it.
*   The shadow can be rendered using the ZPass or the zfail method. ZPass is a little bit faster
*   because the shadow volume creation is easier, but with this method there occur ugly looking
*   artifacs when the camera is inside the shadow volume. These error do not occur with the ZFail method.
* EXAMPLE
*   *shadowNode.l = IrrAddNodeShadow(*Node.l)
* RESULT
*   pointer to a scene node
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrAddNodeShadow(*node.l, bZfailmethod.l=#False, infinity.f=10000.00)
*/
STATIC_EXPORT void *  DLL_EXPORT IrrAddNodeShadow( IAnimatedMeshSceneNode* node, bool bZfailmethod=true, f32 infinity=10000.00f )
{
	// add shadow
	return (void*) node->addShadowVolumeSceneNode(-1,bZfailmethod,infinity);
}


/****f* Nodes/IrrSetNodeVisibility
* NAME
*    IrrSetNodeVisibility - set whether a node is visible or not
* SYNOPSIS
*   IrrSetNodeVisibility(*node.l, bVisible.l)
* INPUTS
*   *node.l     - pointer to a Scene Node
*   bVisible.l  - if set to #True, the Node is Visible, otherwise not.
* FUNCTION
*   Sets if the node should be visible or not. All children of this node won't be visible too.
* EXAMPLE
*   IrrSetNodeVisibility(*Node.l,#False)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeVisibility(*node.l, bVisible.l)
*/

STATIC_EXPORT void DLL_EXPORT IrrSetNodeVisibility( IAnimatedMeshSceneNode* node, bool visible )
{
    // set the speed of playback in the animation
    node->setVisible( visible );
}

/****f* Nodes/IrrGetNodeVisibility
* NAME
*    IrrGetNodeVisibility - get whether a node is visible or not
* SYNOPSIS
*   isVisible.l = IrrGetNodeVisibility(*node.l)
* INPUTS
*   *node.l     - pointer to a Scene Node
* FUNCTION
*   Sets if the node should be visible or not. All children of this node won't be visible too.
* EXAMPLE
*   isVisible.l = IrrGetNodeVisibility(*Node.l)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeVisibility(*node.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrGetNodeVisibility( IAnimatedMeshSceneNode* node)
{
    return node->isVisible( );
}

/****f* Nodes/IrrRemoveNode
* NAME
*    IrrRemoveNode - delete this node from the scene
* SYNOPSIS
*   IrrRemoveNode(*node.l)
* INPUTS
*   *node.l     - pointer to a Scene Node
* FUNCTION
*   Removes this scene node from the scene, deleting it.
* EXAMPLE
*   IrrRemoveNode(*Node.l)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrRemoveNode(*node.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrRemoveNode ( IAnimatedMeshSceneNode* node )
{
    // delete the node from the scene
    node->remove();
}

/****f* Nodes/IrrSetNodeMaterialShininess
* NAME
*    IrrSetNodeMaterialShininess - set the shininess of a material
* SYNOPSIS
*   IrrSetNodeMaterialShininess(*node.l,materialID.l, shininess.f)
* INPUTS
*   *node.l     - pointer to a Scene Node
*   materialID.l - Id of the Material
*   shininiess.f - Value affecting the size of specular highlights. A value of 20 is common.
* FUNCTION
*   Sets the Shininess-Value of a the Material with the given ID.
* EXAMPLE
*   IrrSetNodeMaterialShininess(*Node.l,0,25.0)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeMaterialShininess(*node.l,materialID.l, shininess.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeMaterialShininess( ISceneNode *vptrNode, int materialID, float Shininess )
{
    vptrNode->getMaterial(materialID).Shininess = Shininess; // set size of specular highlights
}


/****f* Nodes/IrrGetNodeMaterial
* NAME
*    IrrGetNodeMaterial - get the material
* SYNOPSIS
*   *mat.l = IrrGetNodeMaterial(*node.l,materialID.l)
* INPUTS
*   *node.l     - pointer to a Scene Node
*   materialID.l - Id of the Material
* FUNCTION
*   Get the material with the id from the Node.
*   This is usefull, if you wnat to change something with the
*   Material-Functions.
* EXAMPLE
*   *mat.l = IrrGetNodeMaterial(*Node.l,0)
* RESULT
*   nothing
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeMaterial(*node.l,materialID.l)
*/
STATIC_EXPORT void DLL_EXPORT * IrrGetNodeMaterial( ISceneNode *vptrNode, int materialID )
{
    return (& vptrNode->getMaterial(materialID) );
}

/****f* Nodes/IrrGetNodeMaterialCount
* NAME
*    IrrGetNodeMaterialCount - get the material count
* SYNOPSIS
*   matCount.l = IrrGetNodeMaterialCount(*node.l)
* INPUTS
*   *node.l     - pointer to a Scene Node
* FUNCTION
*   Get the material count from the Node.
* EXAMPLE
*   matCount.l = IrrGetNodeMaterialCount(*Node.l)
* RESULT
*   count of the material
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeMaterialCount(*node.l)
*/
STATIC_EXPORT int DLL_EXPORT  IrrGetNodeMaterialCount( ISceneNode *vptrNode )
{
    return vptrNode->getMaterialCount();
}


/****f* Nodes/IrrGetToTargetPitchRoll
* NAME
*    IrrGetToTargetPitchRoll - get the material count
* SYNOPSIS
*   IrrGetToTargetPitchRoll(*sourceNode.l, *targetNode.l, *x.f, *y.f, *z.f)
* INPUTS
*   *sourceNode.l     - pointer to a Scene Node that act as Source (maybe the Rocket)
*   *targetNode.l     - pointer to a Scene Node to point at (maybe a enemy)
*   *x.f,*y.f,*z.f    - targetPitchRoll : delta pitch (x) and delta roll (z) values to the target
* FUNCTION
*   guided missile steering helper function
* EXAMPLE
*   IrrGetToTargetPitchRoll(*rocketNode,*destinationNode, @x.f,@y.f,@z.f )
* RESULT
*   nothing
* NOTES
*   This wraps a Mathod, found in the Irrlicht-Forum
*   Author of the Method is : Xaron
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetToTargetPitchRoll(*sourceNode.l, *targetNode.l, *x.f, *y.f, *z.f)
*/

// Here the Wrapper:
STATIC_EXPORT void DLL_EXPORT  IrrGetToTargetPitchRoll( ISceneNode *sourceNode, ISceneNode *targetNode, float &X, float &Y,  float &Z )
{
    vector3df pitchroll = getToTargetPitchRoll(sourceNode->getPosition(),sourceNode->getRotation(), targetNode->getPosition());
    X = pitchroll.X;
    Y = pitchroll.Y;
    Z = pitchroll.Z;
}


// Now we move the Nodes....
// It is easier for me and the most people in PB, if it is already
// here implemented...
// Thanx to Zeuss in the Irrlicht-Forum !

/****f* Nodes/IrrMoveNodeForward
* NAME
*    IrrMoveNodeForward - moves a node forward to the direction it faces
* SYNOPSIS
*   IrrMoveNodeForward(*node.l, speed.f)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   speed.f     - speed to move
* FUNCTION
*   Use this to move your Node forward to the Diretion it faces !
*   with a negative-value, the node moves backwards
* EXAMPLE
*   IrrMoveNodeForward(*rocketNode,1.0)
* RESULT
*   nothing
* NOTES
*   Thanx to Zeuss in the Irrlicht-Forum !
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrMoveNodeForward(*node.l, speed.f)
*/

STATIC_EXPORT void DLL_EXPORT IrrMoveNodeForward( ISceneNode *node, float speed )
{
   matrix4 Mat = node->getRelativeTransformation();
//   core::vector3df Forwards   (Mat.M[0], Mat.M[1], Mat.M[2] );
   core::vector3df Forwards   (Mat[0], Mat[1], Mat[2] );
   node->setPosition(node->getPosition() + (Forwards * speed ));
}

/****f* Nodes/IrrMoveNodeRight
* NAME
*    IrrMoveNodeRight - moves a node right
* SYNOPSIS
*   IrrMoveNodeRight(*node.l, speed.f)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   speed.f     - speed to move
* FUNCTION
*   Use this to move your Node right. Use a negative value (speed) to move to the left !
* EXAMPLE
*   IrrMoveNodeRight(*rocketNode,1.0)
* RESULT
*   nothing
* NOTES
*   Thanx to Zeuss in the Irrlicht-Forum !
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrMoveNodeRight(*node.l, speed.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrMoveNodeRight( ISceneNode *node, float speed )
{
   matrix4 Mat = node->getRelativeTransformation();
//   core::vector3df Right      (Mat.M[8], Mat.M[9], Mat.M[10] );
   core::vector3df Right      (Mat[8], Mat[9], Mat[10] );
   node->setPosition(node->getPosition() + (Right * speed ));
}

/****f* Nodes/IrrMoveNodeUp
* NAME
*    IrrMoveNodeUp - moves a node up
* SYNOPSIS
*   IrrMoveNodeUp(*node.l, speed.f)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   speed.f     - speed to move
* FUNCTION
*   Use this to move your Node up.
*   if speed is negative, the node moves down !
* EXAMPLE
*   IrrMoveNodeUp(*rocketNode,1.0)
* RESULT
*   nothing
* NOTES
*   Thanx to Zeuss in the Irrlicht-Forum !
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrMoveNodeUp(*node.l, speed.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrMoveNodeUp( ISceneNode *node, float speed )
{
   matrix4 Mat = node->getRelativeTransformation();
//   core::vector3df Up         (Mat.M[4], Mat.M[5], Mat.M[6] );
   core::vector3df Up         (Mat[4], Mat[5], Mat[6] );
   node->setPosition(node->getPosition() + (Up * speed ));
}


/****f* Nodes/IrrSetNodeAutomaticCulling
* NAME
*    IrrSetNodeAutomaticCulling - Enables or disables automatic culling based on the bounding box
* SYNOPSIS
*   IrrSetNodeAutomaticCulling(*node.l, bCull.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   bColl.l     - If #True, automatic culling is enabled. If #False, it is disabled.
* FUNCTION
*   Enables or disables automatic culling based on the bounding box.
*   Automatic culling is enabled by default. Note that not all SceneNodes support culling
*   (the billboard scene node for example) and that some nodes always cull their geometry
*   because it is their only reason for existance, for example the OctreeSceneNode.
* EXAMPLE
*   IrrSetNodeAutomaticCulling(*node,#False)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAutomaticCulling(*node.l, bCull.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAutomaticCulling( ISceneNode *node, bool cull )
{
/*
EAC_OFF
EAC_BOX
EAC_FRUSTUM_BOX
EAC_FRUSTUM_SPHERE
*/

//    node->setAutomaticCulling(cull);
    node->setAutomaticCulling(EAC_FRUSTUM_BOX);
}


/****f* Nodes/IrrSetNodeDebugData
* NAME
*    IrrSetNodeDebugData - Sets if debug data like bounding boxes should be drawn.
* SYNOPSIS
*   IrrSetNodeDebugData(*node.l, bDebug.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   bDebug.l    - If #True, a bounding box is drawed. If #False, not..
* FUNCTION
*   Sets if debug data like bounding boxes should be drawn.
*   Please note that not all scene nodes support this feature
* EXAMPLE
*   IrrSetNodeDebugData(*node,#False)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeDebugData(*node.l, bDebug.l)
*/

STATIC_EXPORT void DLL_EXPORT IrrSetNodeDebugData( ISceneNode *node, bool bdebug )
{
    if (node)
    {
        if (bdebug)
            node->setDebugDataVisible(EDS_BBOX);
        else
            node->setDebugDataVisible(EDS_OFF);
    }
}

/****f* Nodes/IrrIsNodeDebugData
* NAME
*    IrrIsNodeDebugData - returns the debugFlag
* SYNOPSIS
*   debug.l = IrrIsNodeDebugData(*node.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
* FUNCTION
*   returns the debugFlag
* EXAMPLE
*   debug.l = IrrIsNodeDebugData(*node)
* RESULT
*   #True, if the DebugData is visible (a bounded box is drawn around the Object)
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrIsNodeDebugData(*node.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrIsNodeDebugData( ISceneNode *node )
{
    irr::scene::E_DEBUG_SCENE_TYPE debugtype = node->isDebugDataVisible();

    if (debugtype != EDS_OFF)
        return true;
    return false;
}


/****f* Nodes/IrrSetNodeAllMaterialShininess
* NAME
*    IrrSetNodeAllMaterialShininess - change the Shinines
* SYNOPSIS
*   IrrSetNodeAllMaterialShininess(*node.l, shininess.f)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   shininess.f - new value for Shininess
* FUNCTION
*   Sometimes you want to change the Shininess for all matrials of a node, so
*   you can use this Function instead walking self through each material.
* EXAMPLE
*   IrrSetNodeAllMaterialShininess(*node,20.00)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAllMaterialShininess(*node.l, shininess.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAllMaterialShininess( ISceneNode *vptrNode, float Shininess )
{
    s32 count = vptrNode->getMaterialCount();
    for(int ii=0;ii<count;ii++)
        vptrNode->getMaterial(ii).Shininess = Shininess; // set size of specular highlights
}

/****f* Nodes/IrrSetNodeAllMaterialDiffuseColor
* NAME
*    IrrSetNodeAllMaterialDiffuseColor - change the Shinines
* SYNOPSIS
*   IrrSetNodeAllMaterialDiffuseColor(*node.l, alpha.l, red.l, green.l, blue.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   alpha.l,red.l,green.l,blue.l - new Diffuse Color
* FUNCTION
*   Sometimes you want to change the Diffuse-Color for all matrials of a node, so
*   you can use this Function instead walking self through each material.
* EXAMPLE
*   IrrSetNodeAllMaterialDiffuseColor(*node,128,128,128,128)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAllMaterialDiffuseColor(*node.l, alpha.l, red.l, green.l, blue.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAllMaterialDiffuseColor( ISceneNode *vptrNode, s32 alpha, s32 red, s32 green, s32 blue )
{
    s32 count = vptrNode->getMaterialCount();
    for(int ii=0;ii<count;ii++)
        vptrNode->getMaterial(ii).DiffuseColor = SColor(alpha,red,green,blue); // set size of specular highlights
}

/****f* Nodes/IrrSetNodeAllMaterialSpecularColor
* NAME
*    IrrSetNodeAllMaterialSpecularColor - change the Specular
* SYNOPSIS
*   IrrSetNodeAllMaterialSpecularColor(*node.l, alpha.l, red.l, green.l, blue.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   alpha.l,red.l,green.l,blue.l - new Specular Color
* FUNCTION
*   Sometimes you want to change the Specular-Color for all matrials of a node, so
*   you can use this Function instead walking self through each material.
* EXAMPLE
*   IrrSetNodeAllMaterialSpecularColor(*node,128,128,128,128)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAllMaterialSpecularColor(*node.l, alpha.l, red.l, green.l, blue.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAllMaterialSpecularColor( ISceneNode *vptrNode, s32 alpha, s32 red, s32 green, s32 blue )
{
    s32 count = vptrNode->getMaterialCount();
    for(int ii=0;ii<count;ii++)
        vptrNode->getMaterial(ii).SpecularColor = SColor(alpha,red,green,blue); // set size of specular highlights
}

/****f* Nodes/IrrSetNodeAllMaterialEmissiveColor
* NAME
*    IrrSetNodeAllMaterialEmissiveColor - change the Emissive
* SYNOPSIS
*   IrrSetNodeAllMaterialEmissiveColor(*node.l, alpha.l, red.l, green.l, blue.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   alpha.l,red.l,green.l,blue.l - new Emissive Color
* FUNCTION
*   Sometimes you want to change the Emissive-Color for all matrials of a node, so
*   you can use this Function instead walking self through each material.
* EXAMPLE
*   IrrSetNodeAllMaterialEmissiveColor(*node,128,128,128,128)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAllMaterialEmissiveColor(*node.l, alpha.l, red.l, green.l, blue.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAllMaterialEmissiveColor( ISceneNode *vptrNode, s32 alpha, s32 red, s32 green, s32 blue )
{
    s32 count = vptrNode->getMaterialCount();
    for(int ii=0;ii<count;ii++)
        vptrNode->getMaterial(ii).EmissiveColor = SColor(alpha,red,green,blue); // set size of specular highlights
}

/****f* Nodes/IrrSetNodeAllMaterialAmbientColor
* NAME
*    IrrSetNodeAllMaterialAmbientColor - change the Ambient
* SYNOPSIS
*   IrrSetNodeAllMaterialAmbientColor(*node.l, alpha.l, red.l, green.l, blue.l)
* INPUTS
*   *Node.l     - pointer to a Scene Node
*   alpha.l,red.l,green.l,blue.l - new Ambient Color
* FUNCTION
*   Sometimes you want to change the Ambient-Color for all matrials of a node, so
*   you can use this Function instead walking self through each material.
* EXAMPLE
*   IrrSetNodeAllMaterialAmbientColor(*node,128,128,128,128)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeAllMaterialAmbientColor(*node.l, alpha.l, red.l, green.l, blue.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrSetNodeAllMaterialAmbientColor( ISceneNode *vptrNode, s32 alpha, s32 red, s32 green, s32 blue )
{
    s32 count = vptrNode->getMaterialCount();
    for(int ii=0;ii<count;ii++)
        vptrNode->getMaterial(ii).AmbientColor = SColor(alpha,red,green,blue); // set size of specular highlights
}


/****f* Nodes/IrrGetNodeCenter
* NAME
*    IrrGetNodeCenter - Get the Center of a Node
* SYNOPSIS
*   IrrGetNodeCenter(*node.l, *x.f,*y.f,*z.f)
* INPUTS
*   *Node.l         - pointer to a Scene Node
*   *x.f,*y.f,*z.f  - returns the center of the node
* FUNCTION
*   Get the Center of a Node, based on the bounding box.
* EXAMPLE
*   IrrGetNodeCenter(*node,@centerX.f,@centerY.f,,@centerZ.f)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeCenter(*node.l, *x.f,*y.f,*z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeCenter( ISceneNode *vptrNode, float &x,float &y,float &z )
{
    vector3df center = vptrNode->getBoundingBox().getCenter();
    x = center.X;
    y = center.Y;
    z = center.Z;
}

/****f* Nodes/IrrGetNodeCenterTransformed
* NAME
*    IrrGetNodeCenterTransformed - Get the Center of a Node
* SYNOPSIS
*   IrrGetNodeCenterTransformed(*node.l, *x.f,*y.f,*z.f)
* INPUTS
*   *Node.l         - pointer to a Scene Node
*   *x.f,*y.f,*z.f  - returns the center of the node
* FUNCTION
*   Returns the center of a axis aligned, transformed and animated absolute bounding box of this node.
* EXAMPLE
*   IrrGetNodeCenterTransformed(*node,@centerX.f,@centerY.f,,@centerZ.f)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeCenterTransformed(*node.l, *x.f,*y.f,*z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeCenterTransformed( ISceneNode *vptrNode, float &x,float &y,float &z )
{
    vector3df center = vptrNode->getTransformedBoundingBox().getCenter();
    x = center.X;
    y = center.Y;
    z = center.Z;
}

/****f* Nodes/IrrGetNodeExtent
* NAME
*    IrrGetNodeExtent - returns extend of the node
* SYNOPSIS
*   IrrGetNodeExtent(*node.l, *x.f,*y.f,*z.f)
* INPUTS
*   *Node.l         - pointer to a Scene Node
*   *x.f,*y.f,*z.f  - returns the center of the node
* FUNCTION
*   returns extend of the node, based on the bounding bonx
* EXAMPLE
*   IrrGetNodeExtent(*node,@X.f,@Y.f,,@Z.f)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeExtent(*node.l, *x.f,*y.f,*z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeExtent( ISceneNode *vptrNode, float &x,float &y,float &z )
{
    vector3df center = vptrNode->getBoundingBox().getExtent();
    x = center.X;
    y = center.Y;
    z = center.Z;
}

/****f* Nodes/IrrGetNodeExtentTransformed
* NAME
*    IrrGetNodeExtentTransformed - returns extend of the node
* SYNOPSIS
*   IrrGetNodeExtentTransformed(*node.l, *x.f,*y.f,*z.f)
* INPUTS
*   *Node.l         - pointer to a Scene Node
*   *x.f,*y.f,*z.f  - returns the center of the node
* FUNCTION
*   returns extend of the node, based on the bounding bonx
* EXAMPLE
*   IrrGetNodeExtentTransformed(*node,@X.f,@Y.f,,@Z.f)
* RESULT
*   nothing
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeExtentTransformed(*node.l, *x.f,*y.f,*z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrGetNodeExtentTransformed( ISceneNode *vptrNode, float &x,float &y,float &z )
{
    vector3df center = vptrNode->getTransformedBoundingBox().getExtent();
    x = center.X;
    y = center.Y;
    z = center.Z;
}

/****f* Nodes/IrrRemoveAllChilds
* NAME
*    IrrRemoveAllChilds - removes all childs of a SceneNode
* SYNOPSIS
*   IrrRemoveAllChilds(*node.l)
* INPUTS
*   *Node.l         - pointer to a Scene Node
* FUNCTION
*   removes all childrens of the Scenen-Node.
*   You can use this also to clear the whole Scene and remove
*   all Childs of the Root-Scenen-Node
* EXAMPLE
*   IrrRemoveAllChilds(*node)
* RESULT
*   nothing
* NOTES
*
* HISTORY
*   Added in Version 1.05 by M.Taupitz
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrRemoveAllChilds(*node.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrRemoveAllChilds( ISceneNode *vptrNode)
{
    vptrNode->removeAll();
}



/****f* Nodes/IrrGetNodeChildCount
* NAME
*    IrrGetNodeChildCount - returns the number of Cilds for the node
* SYNOPSIS
*   childs.l = IrrGetNodeChildCount(*node.l)
* INPUTS
*   *Node.l         - pointer to a Scene Node
* FUNCTION
*   returns the muber of childrens. You can us this Function
*   and with IrrGetNodeChildAt() to iterate through the Nodes.
* EXAMPLE
*   childs.l = IrrGetNodeChildCount(*node)
* RESULT
*   number of childrens
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeChildCount(*node.l)
*/
STATIC_EXPORT int DLL_EXPORT IrrGetNodeChildCount( ISceneNode *vptrNode)
{
    return vptrNode->getChildren().getSize();
}

/****f* Nodes/IrrGetNodeChildAt
* NAME
*    IrrGetNodeChildAt - Get a child at a position in list
* SYNOPSIS
*   childs.l = IrrGetNodeChildAt(*node.l, index.l)
* INPUTS
*   *Node.l         - pointer to a Scene Node
* FUNCTION
*   Get a child at a position in list
*   it is not the same as using iterator as normal.
*   maybe later we can offer a Callback, that is called for
*   each node.....
* EXAMPLE
*   childs.l = IrrGetNodeChildCount(*node)
*   For i= 0 To childs-1
*       *child_node.l = IrrGetNodeChildAt(*node.i)
*       .. maybe check for something ..
*   Next
* RESULT
*   pointer to the Child-Node
* NOTES
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrGetNodeChildAt(*node.l, index.l)
*/
STATIC_EXPORT void*  DLL_EXPORT IrrGetNodeChildAt( ISceneNode *vptrNode, s32 index)
{
    list<ISceneNode*> Children = vptrNode->getChildren();
    int childCount=0;
    list<ISceneNode*>::Iterator it = Children.begin();
    for (; it != Children.end(); ++it)
    {
        if (childCount == index)
            return (void* )(*it);
        childCount++;
    }
    return NULL;
}


/*
  IrrSetNodeMaterialType(*SceneNode, #IRR_EMT_TRANSPARENT_VERTEX_ALPHA)
  IrrSetNodeMaterialFlag(*SceneNode, #IRR_EMF_BACK_FACE_CULLING, #False)
  IrrSetNodeVertexColors( *SceneNode, 120,255,255,255)
*/

/****f* Nodes/IrrSetNodeVertexColors
* NAME
*    IrrSetNodeVertexColors - Sets the alpha vertex color value
* SYNOPSIS
*   IrrSetNodeVertexColors(*node.l, alpha.l,red.l,green.l,blue.l)
* INPUTS
*   *Node.l                      - pointer to a Scene Node
*   alpha.l,red.l,green.l,blue.l - VertexColors
* FUNCTION
*   Sets the alpha vertex color value of the whole mesh to a new value.
* EXAMPLE
*   IrrSetNodeVertexColors(*node,255,128,128,128)
* RESULT
*   nothing
* NOTES
*   You can use this function to make a node transparent. best works for
*   Billboards.
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrSetNodeVertexColors(*node.l, alpha.l,red.l,green.l,blue.l)
*/
STATIC_EXPORT void  DLL_EXPORT IrrSetNodeVertexColors( IAnimatedMeshSceneNode *vptrNode, s32 alpha,s32 red, s32 green,s32 blue)
{
    smgr->getMeshManipulator()->setVertexColors( vptrNode->getMesh()->getMesh(0), video::SColor( alpha, red, green, blue ) );
}


#define IRR_ROTATE_NODE_BY_YX    0
#define IRR_ROTATE_NODE_BY_XZ    1
#define IRR_ROTATE_NODE_BY_YZ    2

/****f* Nodes/IrrRotateNodeByCenter
* NAME
*    IrrRotateNodeByCenter - rotates around a point
* SYNOPSIS
*   IrrRotateNodeByCenter(*node.l, mode.l, degrees.d, x.f,y.f,z.f)
* INPUTS
*   *Node.l                      - pointer to a Scene Node
*   mode.l   - Is  the Rotation Mode :
*                   #IRR_ROTATE_NODE_BY_XY
*                   #IRR_ROTATE_NODE_BY_XZ
*                   #IRR_ROTATE_NODE_BY_YZ
*   degrees.d   - degrees of the rotation
*   x.f,y.f,z.f - the center to rotate around.
* FUNCTION
*   To rotate a Node around a specific point (pivot), you can use this
*   function.
* EXAMPLE
*   IrrRotateNodeByCenter(*node,#IRR_ROTATE_NODE_BY_XY, 32.0, 0,0,0))
* RESULT
*   nothing
* NOTES
*
* HISTORY
*   Added for Version 1.05 by M.Taupitz
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrRotateNodeByCenter(*node.l, mode.l, degrees.d, x.f,y.f,z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrRotateNodeByCenter(IMeshSceneNode* node, int mode, f64 degrees,  f32 x, f32 y, f32 z)
{
    vector3df nodePos = (vector3df)node->getPosition();
    switch (mode)
    {
        case IRR_ROTATE_NODE_BY_YX:
            nodePos.rotateXYBy(degrees, vector3df(x,y,z));
            break;
        case IRR_ROTATE_NODE_BY_XZ:
            nodePos.rotateXZBy(degrees, vector3df(x,y,z));
            break;
        case IRR_ROTATE_NODE_BY_YZ:
            nodePos.rotateYZBy(degrees, vector3df(x,y,z));
            break;
    }
    node->setPosition(nodePos);
}

// Get the Center of a Node
/****f* Nodes/IrrRotateNodeByNode
* NAME
*    IrrRotateNodeByNode - rotates around a other node
* SYNOPSIS
*   IrrRotateNodeByNode(*node.l, mode.l, degrees.d, *rotNode.l)
* INPUTS
*   *Node.l                      - pointer to a Scene Node
*   mode.l   - Is  the Rotation Mode :
*                   #IRR_ROTATE_NODE_BY_XY
*                   #IRR_ROTATE_NODE_BY_XZ
*                   #IRR_ROTATE_NODE_BY_YZ
*   degrees.d   - degrees of the rotation
*   *rotNode.l  - The node, to rotate around
* FUNCTION
*   To rotate a Node around a specific point (pivot), you can use this
*   function.
* EXAMPLE
*   IrrRotateNodeByNode(*node,#IRR_ROTATE_NODE_BY_XY, 32.0, *myStarNode.l)
* RESULT
*   nothing
* NOTES
*
* HISTORY
*   Added for Version 1.05 by M.Taupitz
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrRotateNodeByNode(*node.l, mode.l, degrees.d, *rotNode.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrRotateNodeByNode(IMeshSceneNode* node, int mode, f64 degrees, IMeshSceneNode* rotNode)
{
    vector3df nodePos = (vector3df)node->getPosition();
    vector3df nodeCenter = (vector3df)rotNode->getBoundingBox().getCenter();
    switch (mode)
    {
        case IRR_ROTATE_NODE_BY_YX:
            nodePos.rotateXYBy(degrees, nodeCenter);
            break;
        case IRR_ROTATE_NODE_BY_XZ:
            nodePos.rotateXZBy(degrees, nodeCenter);
            break;
        case IRR_ROTATE_NODE_BY_YZ:
            nodePos.rotateYZBy(degrees, nodeCenter);
            break;
    }
    node->setPosition(nodePos);
}


/****f* Nodes/IrrCloneNode
* NAME
*    IrrCloneNode - clone node
* SYNOPSIS
*   *node = IrrCloneNode(*node , *parentNode [=#Null])
* INPUTS
*   *Node.l    - pointer to a Scene Node
*   *parentNode.l    - pointer to a Scene Node
* FUNCTION
*   Creates a clone of this scene node and its children.
* EXAMPLE
*   *clone = IrrCloneNode(*node)
* RESULT
*   Pointer to a new Scnene-Node if success, otherwise #Null
* HISTORY
*   Added for Version 1.06 by M.Taupitz
*
****
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrCloneNode(*node, *parentNode=#Null)
*/
STATIC_EXPORT void  * DLL_EXPORT IrrCloneNode(ISceneNode* node,ISceneNode* parent=0 )
{
    if (node)
        return node->clone(parent);
    return NULL;
}


/*
 - It is now possible to clone single scene nodes (ISceneNode::clone()) and to create copies
   of a whole scene graph (ISceneManager::createNewSceneManager(cloneContent=true);
*/


/* ////////////////////////////////////////////////////////////////////////////
all of the above functions are declared as C functions and are exposed without
any mangled names
*/
}
