//================================================================================================
// Plugin for EQUINOX-3D
//
// Light probe for realtime rendering
// - Spherical harmonics
// - Spherical gaussians
// - Preconvolved cubemaps
//
// AUTHOR:  Gabor Nagy
// DATE:    2023-Oct-09 23:09:14
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//================================================================================================
#ifndef _E3D_LightProbe_h
#define _E3D_LightProbe_h

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif

#define E3dLightProbeSH    0x0001
#define E3dLightProbeSG    0x0002
#define E3dLightProbePCCM  0x0004
#define E3dLightProbeALL   0x0007

#define E3dSGMapMULTI_THREADING  1

#define E3dSGFibonacciDirect          0x01
#define E3dSGFibonacciAdaptive        0x02
#define E3dSGFibonacciAdaptiveRandom  0x04

typedef struct
{
	E3dCoord3      Axis;
	float          Sharpness;
	float          Amplitude[3];
	float          CDFPosition;
} E3dSGLobe;

typedef struct
{
	EBool     Active;
	EList(, E3dSGLobe, Lobes);
	EIndex    NLobes, NLobesByUser;
	float     Sharpness;
	EpImage*  SrcIBLImage;   // SH is low-medium frequency, so there's no point integrating from, say a 4kx2k Image. We cache a lower-res version here to speed things up.
	EpImage*  DstIBLImage;   // IBL image reproduced from spherical-gaussians

	void*     NNLSSystemMatrix;

	uint16_t  GenerationMode;  // E3dSGFibonacciDirect, E3dSGFibonacciAdaptive;
// Adaptive mode
	EIndex    StartingNLobes;
	float     AmplitudeMin, AngleMax, AmplitudeRatioMin;
	EBool     InteractiveMerge;

} E3dSGLight;

typedef struct
{
	EBool     Active;
	int       NLevels, Level;
} E3dPCCMLight;

typedef struct E3dLightProbeInfo_S  E3dLightProbeInfo;


typedef struct
{
	EThreadSet1DCore;

	E3dLightProbeInfo*  ObjectComponent;
	EIndex              SizeX;
} EThreadSet1DLightProbeImage;


struct E3dLightProbeInfo_S
{
	E3dNodeComponentCore;

// E3dLightProbeInfo part
//
	char*            IBLFileName;

	EpImage*         IBLImage;           // Original light-map image

	EpExposure       Exposure;           // Tonemapper settings for displaying the images

// Spherical harmonics
//
	E3dSHLight       SHLight;

// Spherical gaussians
//
	E3dSGLight       SGLight;

// Preconvolved cubemaps
//
	E3dPCCMLight     PCCMLight;

	int              NumOfSamples;
	E3dOpticsClass*  OpticsClass;


	EBool            ProcessingRestart;

// For processing multiple IBL files into SH, SG etc.
	EList(, char*, IBLFileNames);

	EBool            Run;


// Multi-threading
//
	EThreadSet1DLightProbeImage  ThreadSet;

};


extern float  _LatScaleFactor(const int PSizeLon, const int PSizeLat, const int PLat);

extern void   _SGFitNNLeastSquaresCPP(E3dLightProbeInfo* PInfo, const EBool PShowProgress, const float* PSrcPixels, const int PNChannels,  const EIndex PSizeX, const EIndex PSizeY,  E3dSGLobe* PLobes, const int PNLobes);

extern void   _LightProbe_ProgressFunc(const float PCompleted, EPointer PCustomData, void (*PAbortCallback)(EPointer PCustomData), EPointer PAbortFuncCustomData);

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif	// _E3D_LightProbe_h
