// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#pragma once

#include "../lights/light.isph"

struct ISPCTriangle
{
  int v0;                /*< first triangle vertex */
  int v1;                /*< second triangle vertex */
  int v2;                /*< third triangle vertex */
  int materialID;        /*< material of triangle */
};

struct ISPCQuad
{
  int v0;                /*< first triangle vertex */
  int v1;                /*< second triangle vertex */
  int v2;                /*< third triangle vertex */
  int v3;                /*< fourth triangle vertex */
};

enum ISPCType { TRIANGLE_MESH, SUBDIV_MESH, HAIR_SET, INSTANCE, GROUP, QUAD_MESH, LINE_SEGMENTS, CURVES };

struct ISPCGeometry
{
  ISPCType type;
};

struct ISPCTriangleMesh
{
  uniform ISPCGeometry geom;
  uniform Vec3fa* positions;    //!< vertex position array
  uniform Vec3fa* normals;       //!< vertex normal array
  uniform Vec2f* texcoords;     //!< vertex texcoord array
  uniform ISPCTriangle* triangles;  //!< list of triangles
  unsigned int numTimeSteps;
  unsigned int numVertices;
  unsigned int numTriangles;
  RTCScene scene;
  unsigned int geomID;
  unsigned int materialID;
};

struct ISPCQuadMesh
{
  uniform ISPCGeometry geom;
  uniform Vec3fa* positions;    //!< vertex position array
  uniform Vec3fa* normals;       //!< vertex normal array
  uniform Vec2f* texcoords;     //!< vertex texcoord array
  uniform ISPCQuad* quads;  //!< list of triangles
  unsigned int numTimeSteps;
  unsigned int numVertices;
  unsigned int numQuads;
  RTCScene scene;
  unsigned int geomID;
  unsigned int materialID;
};

struct ISPCSubdivMesh
{
  uniform ISPCGeometry geom;
  uniform Vec3fa* positions;       //!< vertex positions
  uniform Vec3fa* normals;         //!< face vertex normals
  uniform Vec2f* texcoords;        //!< face texture coordinates
  uniform int* position_indices;   //!< position indices for all faces
  uniform int* normal_indices;     //!< normal indices for all faces
  uniform int* texcoord_indices;   //!< texcoord indices for all faces
  RTCSubdivisionMode position_subdiv_mode;  
  RTCSubdivisionMode normal_subdiv_mode;
  RTCSubdivisionMode texcoord_subdiv_mode;
  uniform int* verticesPerFace;    //!< number of indices of each face
  uniform int* holes;              //!< face ID of holes
  uniform float* subdivlevel;      //!< subdivision level
  uniform Vec2i* edge_creases;          //!< crease index pairs
  uniform float* edge_crease_weights;   //!< weight for each crease
  uniform int* vertex_creases;          //!< indices of vertex creases
  uniform float* vertex_crease_weights; //!< weight for each vertex crease
  uniform int* face_offsets;
  unsigned int numTimeSteps;
  unsigned int numVertices;
  unsigned int numFaces;
  unsigned int numEdges;
  unsigned int numEdgeCreases;
  unsigned int numVertexCreases;
  unsigned int numHoles;
  unsigned int numNormals;
  unsigned int numTexCoords;
  unsigned int materialID;
  RTCScene scene;
  unsigned int geomID;
};

struct ISPCHair
{
  int vertex;
  int id;
};

struct ISPCLineSegments
{
  uniform ISPCGeometry geom;
  Vec3fa* positions; //!< control points (x,y,z,r)
  int* indices;      //!< for each segment, index to first control point
  unsigned int numTimeSteps;
  unsigned int numVertices;
  unsigned int numSegments;
  int materialID;
  RTCScene scene;
  unsigned int geomID;
};

struct ISPCHairSet
{
  uniform ISPCGeometry geom;
  Vec3fa* positions;  //!< hair control points (x,y,z,r)
  ISPCHair* hairs;    //!< for each hair, index to first control point
  unsigned int numTimeSteps;
  unsigned int numVertices;
  unsigned int numHairs;
  unsigned int materialID;
  RTCScene scene;
  unsigned int geomID;
  unsigned int tessellation_rate;
};

struct ISPCInstance
{
  uniform ISPCGeometry geom;
  uniform unsigned int geomID;
  uniform unsigned int numTimeSteps;
  uniform unsigned int align;
  AffineSpace3fa spaces[1];
};

struct ISPCGroup
{
  ISPCGeometry geom;
  ISPCGeometry** geometries;
  size_t numGeometries;
};

enum MaterialTy
{
  MATERIAL_OBJ,
  MATERIAL_THIN_DIELECTRIC,
  MATERIAL_METAL,
  MATERIAL_VELVET,
  MATERIAL_DIELECTRIC,
  MATERIAL_METALLIC_PAINT,
  MATERIAL_MATTE,
  MATERIAL_MIRROR,
  MATERIAL_REFLECTIVE_METAL,
  MATERIAL_HAIR
};

struct ISPCMaterial
{
  int ty;
  int align0,align1,align2;
  Vec3fa v[7];
};

struct MatteMaterial
{
  int ty;
  int align[3];

  Vec3fa reflectance;
};

struct MirrorMaterial
{
  int ty;
  int align[3];
  Vec3fa reflectance;
};

enum TEXTURE_FORMAT {
  Texture_RGBA8        = 1,
  Texture_RGB8         = 2,
  Texture_FLOAT32      = 3,
};

struct Texture {
  uniform int width;
  uniform int height;
  uniform int format;
  uniform int bytesPerTexel;
  uniform int width_mask;
  uniform int height_mask;
  void *uniform data;
};

struct OBJMaterial
{
  int ty;
  int align[3];

  int illum;             /*< illumination model */
  float d;               /*< dissolve factor, 1=opaque, 0=transparent */
  float Ns;              /*< specular exponent */
  float Ni;              /*< optical density for the surface (index of refraction) */

  Vec3fa Ka;              /*< ambient reflectivity */
  Vec3fa Kd;              /*< diffuse reflectivity */
  Vec3fa Ks;              /*< specular reflectivity */
  Vec3fa Kt;              /*< transmission filter */

  Texture* map_d;
  Texture* map_Kd;          /*< dummy */
  Texture* map_Displ;       /*< dummy */
};

struct MetalMaterial
{
  int ty;
  int align[3];

  Vec3fa reflectance;
  Vec3fa eta;
  Vec3fa k;
  float roughness;
};

struct ReflectiveMetalMaterial
{
  int ty;
  int align[3];

  Vec3fa reflectance;
  Vec3fa eta;
  Vec3fa k;
  float roughness;
};

struct VelvetMaterial
{
  int ty;
  int align[3];

  Vec3fa reflectance;
  Vec3fa horizonScatteringColor;
  float backScattering;
  float horizonScatteringFallOff;
};

struct DielectricMaterial
{
  int ty;
  int align[3];
  Vec3fa transmissionOutside;
  Vec3fa transmissionInside;
  float etaOutside;
  float etaInside;
};

struct ThinDielectricMaterial
{
  int ty;
  int align[3];
  Vec3fa transmission;
  Vec3fa transmissionFactor;
  float eta;
  float thickness;
};

struct MetallicPaintMaterial
{
  int ty;
  int align[3];
  Vec3fa shadeColor;
  Vec3fa glitterColor;
  float glitterSpread;
  float eta;
};

struct HairMaterial
{
  int ty;
  int align[3];
  Vec3fa Kr;
  Vec3fa Kt;
  float nx;
  float ny;
};

struct ISPCScene
{
  uniform ISPCGeometry* uniform* geometries;   //!< list of geometries
  uniform ISPCMaterial* materials;             //!< material list
  unsigned int numGeometries;                           //!< number of geometries
  unsigned int numMaterials;                            //!< number of materials

  uniform Light* uniform* lights;              //!< list of lights
  unsigned int numLights;                               //!< number of lights

}; // ISPCScene

unmasked extern "C" RTCScene ConvertScene (RTCDevice g_device, ISPCScene* uniform scene_in, uniform RTCSceneFlags sflags, uniform RTCAlgorithmFlags aflags, uniform RTCGeometryFlags gflags);
