// This code contains NVIDIA Confidential Information and is disclosed to you 
// under a form of NVIDIA software license agreement provided separately to you.
//
// Notice
// NVIDIA Corporation and its licensors retain all intellectual property and
// proprietary rights in and to this software and related documentation and 
// any modifications thereto. Any use, reproduction, disclosure, or 
// distribution of this software and related documentation without an express 
// license agreement from NVIDIA Corporation is strictly prohibited.
// 
// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Information and code furnished is believed to be accurate and reliable.
// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
// information or for any infringement of patents or other rights of third parties that may
// result from its use. No license is granted by implication or otherwise under any patent
// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
// This code supersedes and replaces all information previously supplied.
// NVIDIA Corporation products are not authorized for use as critical
// components in life support devices or systems without express written approval of
// NVIDIA Corporation.
//
// Copyright (c) 2008-2012 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.  


#ifndef PX_PHYSICS_EXTENSIONS_SIMPLE_FACTORY_H
#define PX_PHYSICS_EXTENSIONS_SIMPLE_FACTORY_H
/** \addtogroup extensions
  @{
*/

#include "common/PxPhysXCommon.h"
#include "foundation/PxTransform.h"
#include "foundation/PxPlane.h"

#ifndef PX_DOXYGEN
namespace physx
{
#endif

	class PxPhysics;
	class PxMaterial;
	class PxRigidActor;
	class PxRigidDynamic;
	class PxRigidStatic;
	class PxGeometry;

#ifndef PX_DOXYGEN
} // namespace physx
#endif


/** \brief simple method to create a PxRigidDynamic actor with a single PxShape. 

	\param[in] sdk the PxPhysics object
	\param[in] transform the global pose of the new object
	\param[in] geometry the geometry of the new object's shape, which must be a sphere, capsule, box or convex
	\param[in] material the material for the new object's shape
	\param[in] density the density of the new object. Must be greater than zero.
	\param[in] shapeOffset an optional offset for the new shape, defaults to identity

	\return a new dynamic actor with the PxRigidDynamicFlag, or NULL if it could 
	not be constructed

	@see PxRigidDynamic PxShapeFlag
*/

PX_C_EXPORT	physx::PxRigidDynamic*	PX_CALL_CONV	PxCreateDynamic(physx::PxPhysics& sdk,
																	const physx::PxTransform& transform,
																	const physx::PxGeometry& geometry,
																	physx::PxMaterial& material,
																	physx::PxReal density,
																	const physx::PxTransform& shapeOffset = physx::PxTransform::createIdentity());

/** \brief simple method to create a kinematic PxRigidDynamic actor with a single PxShape. 

	\param[in] sdk the PxPhysics object
	\param[in] transform the global pose of the new object
	\param[in] geometry the geometry of the new object's shape
	\param[in] material the material for the new object's shape
	\param[in] density the density of the new object. Must be greater than zero if the object is to participate in simulation.
	\param[in] shapeOffset an optional offset for the new shape, defaults to identity

	\note unlike PxCreateDynamic, the geometry is not restricted to box, capsule, sphere or convex. However, 
	kinematics of other geometry types may not participate in simulation collision and may be used only for
	triggers or scene queries of moving objects under animation control. In this case the density parameter
	will be ignored and the created shape will be set up as a scene query only shape (see #PxShapeFlag::eSCENE_QUERY_SHAPE)

	\return a new dynamic actor with the PxRigidDynamicFlag::eKINEMATIC set, or NULL if it could 
	not be constructed

	@see PxRigidDynamic PxShapeFlag
*/

PX_C_EXPORT	physx::PxRigidDynamic*	PX_CALL_CONV	PxCreateKinematic(physx::PxPhysics& sdk,
																	  const physx::PxTransform& transform,
																	  const physx::PxGeometry& geometry,
																	  physx::PxMaterial& material,
																	  physx::PxReal density,
																	  const physx::PxTransform& shapeOffset = physx::PxTransform::createIdentity());

/** \brief simple method to create a PxRigidStatic actor with a single PxShape. 

	\param[in] sdk the PxPhysics object
	\param[in] transform the global pose of the new object
	\param[in] geometry the geometry of the new object's shape
	\param[in] material the material for the new object's shape
	\param[in] shapeOffset an optional offset for the new shape, defaults to identity

	\return a new static actor, or NULL if it could not be constructed

	@see PxRigidStatic
*/

PX_C_EXPORT	physx::PxRigidStatic*	PX_CALL_CONV	PxCreateStatic(physx::PxPhysics& sdk,
																   const physx::PxTransform& transform,
																   const physx::PxGeometry& geometry,
																   physx::PxMaterial& material,
																   const physx::PxTransform& shapeOffset = physx::PxTransform::createIdentity());


/**
\brief create a static body by copying attributes from another rigid actor

The function clones a PxRigidDynamic as a PxRigidStatic. A uniform scale is applied. The following properties are copied:
- shapes
- actor flags 
- owner client and client behavior bits

The following are not copied and retain their default values:
- name
- joints or observers
- aggregate or scene membership
- user data

\note Transforms are not copied with bit-exact accuracy.

\param[in] physicsSDK - the physics SDK used to allocate the rigid static
\param[in] actor the rigid actor from which to take the attributes.
\param[in] transform the transform of the new static.

\return returns the newly-created rigid static

*/

PX_C_EXPORT physx::PxRigidStatic* PX_CALL_CONV PxCloneStatic(physx::PxPhysics& physicsSDK, 
															 const physx::PxTransform& transform,
															 const physx::PxRigidActor& actor);


/**
\brief create a dynamic body by copying attributes from an existing body

The following properties are copied:
- shapes
- actor flags and rigidDynamic flags
- mass, moment of inertia, and center of mass frame
- linear and angular velocity
- linear and angular damping
- maximum angular velocity
- position and velocity solver iterations
- sleep threshold
- contact report threshold
- dominance group
- owner client and client behavior bits

The following are not copied and retain their default values:
- name
- joints or observers
- aggregate or scene membership
- sleep timer
- user data

\note Transforms are not copied with bit-exact accuracy.

\param[in] physicsSDK PxPhysics - the physics SDK used to allocate the rigid static
\param[in] body the rigid dynamic to clone.
\param[in] transform the transform of the new dynamic

\return returns the newly-created rigid static

*/

PX_C_EXPORT	physx::PxRigidDynamic*	PX_CALL_CONV PxCloneDynamic(physx::PxPhysics& physicsSDK, 	 
																const physx::PxTransform& transform,
																const physx::PxRigidDynamic& body);


/** \brief create a plane actor. The plane equation is n.x + d = 0

	\param[in] sdk the PxPhysics object
	\param[in] plane a plane of the form n.x + d = 0
	\param[in] material the material for the new object's shape

	\return a new static actor, or NULL if it could not be constructed

	@see PxRigidStatic
*/

PX_C_EXPORT	physx::PxRigidStatic*	PX_CALL_CONV	PxCreatePlane(physx::PxPhysics& sdk,
																  const physx::PxPlane& plane,
																  physx::PxMaterial& material);


/**
\brief scale a rigid actor by a uniform scale

The geometry and relative positions of the actor are multiplied by the given scale value. If the actor is a rigid body or an
articulation link and the scaleMassProps value is true, the mass properties are scaled assuming the density is constant: the 
center of mass is linearly scaled, the mass is multiplied by the cube of the scale, and the inertia tensor by the fifth power of the scale. 

\param[in] actor a rigid actor
\param[in] scale the scale by which to multiply the actor
\param[in] scaleMassProps whether to scale the mass properties
*/

PX_C_EXPORT void PX_CALL_CONV PxScaleRigidActor(physx::PxRigidActor& actor, physx::PxReal scale, bool scaleMassProps = true);



/** @} */
#endif
