// © Copyright 2008 Vladimir Frolov, Moscow State University Graphics & Media Lab
#pragma once
#define RTLIB_GUARDIAN


#define BLOCK_SIZE_X 8
#define BLOCK_SIZE_Y 8
#define WARP_SIZE 32

#define Z_ORDER_BLOCK_SIZE 16

#define SORT_BLOCK_SIZE 256

#define KD_TREE_TRAVERSAL_BLOCK_SIZE 256
#define INTERSECTION_BLOCK_SIZE 64

#define HRT_RAY_MISS 0xFFFFFFFE
#define HRT_RAY_HIT 0xFFFFFFFF

#ifndef ACCEL_STRUCT_GUARDIAN
  #include "AccelerationStructure.h" 
#endif


#ifndef MATERIAL_GUARDIAN
  #include "Material.h"
#endif

#ifndef LIGHT_GUARDIAN
  #include "Light.h"
#endif

namespace RAYTR
{

enum RAY_TYPES {EYE_RAY,
				        SHADOW_RAY,
				        REFLECTED_RAY,
				        REFRACTED_RAY};

enum ACCELERATION_STRUCRURES {ACCEL_STRUCT_KD_TREE, 
                              ACCEL_STRUCT_BVH,
                              ACCEL_STRUCT_HIERARHICAL_GRID};


__align__(16) struct Hit_Half1
{
  universal_call int GetMaterialId() const { return material_id; }
  universal_call void SetMaterialId(int a_id) { material_id = a_id; }

  float3 pos;

//protected:
  int material_id;
};

__align__(16) struct Hit_Half2
{
  //int GetMaterialId() const { return (packed_data && 0x000000FF); }
  //int GetObjectType() const { return (packed_data && 0x0000FF00) >> 8; }
  
  universal_call int GetTextureId()  const { return packed_data; } 
  universal_call void SetTextureId(int a_id) { packed_data = a_id; } 

  float3 norm;

//protected:
  int packed_data;
};


class Hit
{
public:

	enum { TRIANGLE = 0,
		   SPHERE   = 1,
		   BOX      = 2,
		   NONE};
};


/////////////////////////////////
struct __align__(8) Lite_Hit2
{
  inline universal_call void SetObjectId(unsigned int a_id)
  { object_id = ( a_id & 0x3FFFFFFF) | (object_id & 0xC0000000); }

  inline universal_call unsigned int GetObjectId() const
  { return object_id & 0x3FFFFFFF; }

  inline universal_call void SetObjectType(unsigned char a_type)
  { object_id = ( ((a_type << 30) & 0xC0000000) | (object_id & 0x3FFFFFFF) ) ; }

  inline universal_call unsigned char GetObjectType() const
  { return (object_id & 0xC0000000) >> 30; }

  enum { TRIANGLE = Hit::TRIANGLE,
    SPHERE   = Hit::SPHERE,
    BOX      = Hit::BOX,
    NONE		= Hit::NONE};

  //protected:

  float t;
  unsigned int  object_id; // we can use 2 bits of object_id to store object_type
};


/////////////////////////////////
struct __align__(8) BVH_Leaf 
{
  int   offset;
  float t;
};


}


using namespace RAYTR;

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

enum HRT_ERROR_CODES
{ 
		HRT_NO_MEMORY_AVALIABLE = 1,
		HRT_INCORRECT_SIZE = 2,
		HRT_ZERO_SIZE = 3,
    HRT_INCORRECT_INTERNAL_PARAMETER = 4,
		HRT_UNEXPECTED_FUNCTION_FAIL = 5
};
