text: // Geometrical Primitives base abstract class
  // Written by Sergey Kosov in 2005 for Rendering Competition
  #pragma once
  
  #include "types.h"
  #include "IShader.h"
  #include "BoundingBox.h"
  
  namespace rt {
  	struct Ray;
  	
  	// ================================ Primitive Interface Class ================================
  	/**
  	 * @brief Geometrical Primitives (Prims) base abstract class
  	 * @ingroup modulePrimitive
  	 * @author Sergey G. Kosov, sergey.kosov@project-10.de
  	 */
  	class IPrim : public std::enable_shared_from_this<IPrim>
  	{
  	public:
  		/**
  		 * @brief Constructor
  		 * @param pShader Pointer to the shader to be applied for the primitive
  		 */
  		DllExport IPrim(const ptr_shader_t pShader) : m_pShader(pShader) {}
  		DllExport IPrim(const IPrim&) = delete;
  		DllExport virtual ~IPrim(void) = default;
  		DllExport const IPrim& operator=(const IPrim&) = delete;
  
  		/**
  		 * @brief Checks for intersection between ray \b ray and the primitive
  		 * @details If a valid intersection has been found with the primitive, it sets Ray::t to the distance to this intersection 
  		 * point (if current t < ray.t) and sets Ray::hit to point to the current primitive
  		 * @param[in,out] ray The ray (Ref. @ref Ray for details)
  		 * @retval true If and only if a valid intersection has been found in the interval (epsilon; Ray::t)
  		 * @retval false Otherwise
  		 */
  		DllExport virtual bool				intersect(Ray& ray) const = 0;
  		/**
  		 * @brief Checks for intersection between ray \b ray and the primitive
  		 * @details This function does not modify argeument \b ray and is used just to check if there is an intersection.
  		 * One may use this function for a fast check if the \b ray.org is occluded from a light source by a pritive.
  		 * @param ray The ray (Ref. @ref Ray for details)
  		 * @retval true If and only if a valid intersection has been found in the interval (epsilon; Ray::t)
  		 * @retval false Otherwise
  		 */
  		DllExport virtual bool				if_intersect(const Ray& ray) const = 0;
  		/**
  		 * @brief Performs affine transformation
  		 * @param T Transformation matrix (size: 4 x 4; type: CV_32FC1)
  		 */
  		DllExport virtual void				transform(const Mat& T) = 0;
  		/**
  		 * @brief Returns the origin point of the primitive
  		 * @return The origin point
  		 */
  		DllExport virtual Vec3f				getOrigin(void) const = 0;
  		/**
  		 * @brief Returns the normal vector of the primitive in the ray - primitive intercection point
  		 * @param ray Ray intersecting the primitive
  		 * @return The normalized normal of the primitive at the ray - primitive intersection point
  		 */
  		DllExport virtual Vec3f				getNormal(const Ray& ray) const = 0;
  		/**
  		* @brief Returns the  normal vector of the primitive in the ray - primitive intercection point
  		* @note In contrast to the @ref getNormal() method, this methods takes into account the possible normal interpolation along the primitive
  		* @param ray Ray intersecting the primitive
  		* @retunr The normalized normal of the primitive at the ray - primitive intersection point
  		*/
  		DllExport virtual Vec3f				getShadingNormal(const Ray& ray) const { return getNormal(ray); }
  		/**
  		 * @brief Returns the texture coordinates in the ray - primitive intercection point
  		 * @param ray Point at the surface
  		 * @return The texture coordinates
  		 */
  		DllExport virtual Vec2f				getTextureCoords(const Ray& ray) const = 0;
  		/**
  		 * @brief Returns the minimum axis-aligned bounding box, which contain the primitive
  		 * @returns The bounding box, which contain the primitive
  		 */
  		DllExport virtual CBoundingBox		getBoundingBox(void) const = 0;
  //		/**
  //		 * @brief Sets the new shader to the prim
  //		 * @param pShader Pointer to the shader to be applied for the prim
  //		 */
  //		DllExport void						setShader(const ptr_shader_t pShader) { m_pShader = pShader; }
  		/**
  		 * @brief Returns the primitive's shader
  		 * @return The pointer to the primitive's shader
  		 */
  		DllExport ptr_shader_t				getShader(void) const { return m_pShader; }
  		/**
  		 * @brief Sets a new name to the primitive
  		 * @param name The new name
  		 */
  		DllExport void						setName(const std::string& name) { m_name = name;}
  		/**
  		 * @brief Returns the name of the primitive
  		 * @return The name of the primitive
  		 */
  		DllExport std::string				getName(void) const { return m_name; }
  	
  	
  	private:
  		const ptr_shader_t	m_pShader;			///< Pointer to the sahder, see @ref  IShader
  		std::string			m_name;				///< Optional name of the primitive
  	};
  }
  