/* ##C_FILE#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FILE :          ISI_ISI.c
 
DESCRIPTION :   ISI accessors, loading, saving, creating, deleting.
 
VERSION :       1.00 / David Fournier
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
 
/* ##INCLUDE#----------------------------------------------------------------------------
                          Includes Files
---------------------------------------------------------------------------------------*/
 
/*For game material*/
#include "GMT/GmtHandl.h"
 
#include "ACP_base.h"
/*memory management of geometry.*/
#include "GEO.h"
 
#include "GLI.h"
 
#include "SCR.h"
#include "COL.h"
#include "SPO.h"
 
/*IPO*/
#include "PCS.h"
#include "PO.h"
#include "IPO.h"
 
/*PATH NAME*/
#include "DPT.h"
 
#if !defined(U64)
/*#include "BIN.h"*/
#endif /* U64 */
 
#include "ISI\ISI_Ext.h"
#include "ISI\Specif\ISI_Func.h"
#include "ISI_Int.h"
 
/* ##CONSTANTE#--------------------------------------------------------------------------
                          Constantes declaration
---------------------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_
#define ISI_C_BUFFER_SIZE 128*1024 /* Max size of a RLI ?*/
#endif /* _FIRE_DEADCODE_U64_ */
 
 
/* ##GLOBVAR#----------------------------------------------------------------------------
                          Globale variable declaration
---------------------------------------------------------------------------------------*/
 
#if !defined(U64)
/*Link Table*/
SCR_tdst_Link_Table ISI_stLinkTable;
#endif /* U64 */
 
/* ##FUNCDEF#----------------------------------------------------------------------------
                          Functions definition
---------------------------------------------------------------------------------------*/
 
#if !defined(U64)
SCR_tde_Anl_ReturnValue ISI_fn_xLoadISI(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType);
#endif /* U64 */
/*End of Prototypes*/
 
 
#include "Specif\ISI_Func.cxx"
 
 
/* ##-########################### 
   ## Creating / Deleting
   ############################## */
 
/* ##F===================================================================================
NAME :          ISI_vInitLoad
DESCRIPTION :   Function to initialise the script loading
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
void ISI_vInitLoad(void)
{
#if !defined(U64)
  SCR_fn_v_RdL0_RegisterCallback("ISI", ISI_fn_xLoadISI, SCR_CRC_c_RdL0_ForSection);
  SCR_fn_v_RdL0_RegisterCallback("IS2", ISI_fn_xLoadISI2, SCR_CRC_c_RdL0_ForSection);
  SCR_fn_v_Link_InitTable(&ISI_stLinkTable);
#endif /* U64 */
}
 
/* ##F===================================================================================
NAME :          ISI_fn_hCreateISILOD
DESCRIPTION :   Create an ISI level of detail.
INPUT : _hISI       = Handle to ISI.
        _xNumISILOD = Level of detail number.
        _xNbRLI     = Number of RLI.
OUTPUT : Return table of RLI.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ISI_tdstColor *ISI_fn_hCreateISILOD(ACP_tdxHandleToRadiosity _hISI
       ,ACP_tdxIndex _xNumISILOD,ACP_tdxIndex _xNbRLI)
{
  ACP_tdxIndex xI;
  ISI_tdstColor *p_stTabCol;
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
 
  hCpyISI->d_stISILOD[_xNumISILOD].xNbVertexRLI=_xNbRLI;
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeISI , MMG_C_lSubTypeLOD , 0 );
  GEO_M_CPAMalloc(p_stTabCol,ISI_tdstColor *, sizeof(ISI_tdstColor)*_xNbRLI, E_uwGEONotEnoughtMemory);
  hCpyISI->d_stISILOD[_xNumISILOD].d_stVertexRLI=p_stTabCol;
  for(xI=0;xI<_xNbRLI;xI++)
  {
    p_stTabCol[xI].xRed=0;
    p_stTabCol[xI].xGreen=0;
    p_stTabCol[xI].xBlue=0;
    p_stTabCol[xI].xAlpha=0;
  }
 
  return p_stTabCol;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_hCreateISI
DESCRIPTION :   Create ISI structure.
INPUT : _xNbISILOD  = Number of level of detail.
OUTPUT : handle to ISI.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ACP_tdxHandleToRadiosity ISI_fn_hCreateISI(ACP_tdxIndex _xNbISILOD)
{
  ISI_HandleToISI hISI;
  ACP_tdxIndex xI;
 
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeISI , MMG_C_lSubTypeStruct , 0 );
  GEO_M_CPAMalloc(hISI,ISI_HandleToISI,sizeof(struct ISI_tdstISI_),E_uwGEONotEnoughtMemory);
  hISI->xNbISILOD=_xNbISILOD;
 
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeISI , MMG_C_lSubTypeArray , 0 );
  GEO_M_CPAMalloc(hISI->d_stISILOD,ISI_tdstISILOD *, sizeof(ISI_tdstISILOD)*_xNbISILOD, E_uwGEONotEnoughtMemory);
  for(xI=0;xI<_xNbISILOD;xI++)
  {
    hISI->d_stISILOD[xI].xNbVertexRLI=0;
    hISI->d_stISILOD[xI].d_stVertexRLI=NULL;
  }
 
  return (ACP_tdxHandleToRadiosity)hISI;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_vFreeISI
DESCRIPTION :   Free an ISI structure.
INPUT : _hISI  = handle to ISI.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
#ifndef _FIRE_DEADCODE_U64_
void ISI_fn_vFreeISI(ACP_tdxHandleToRadiosity _hISI)
{
  ISI_HandleToISI hCpyISI;
  ACP_tdxIndex xI;
 
  hCpyISI=(ISI_HandleToISI)_hISI;
 
  for(xI=0;xI<hCpyISI->xNbISILOD;xI++)
  {
    if (hCpyISI->d_stISILOD[xI].d_stVertexRLI)
      GEO_M_CPAFree(hCpyISI->d_stISILOD[xI].d_stVertexRLI);
  }
  GEO_M_CPAFree(hCpyISI->d_stISILOD);
  GEO_M_CPAFree(hCpyISI);
}
#endif /* _FIRE_DEADCODE_U64_ */
 
 
/* ##-########################### 
   ## Accessors
   ############################## */
 
/* ##F===================================================================================
NAME :          ISI_ColISIToGEO
DESCRIPTION :   Convert a ISI_tdstColor in GEO_tdstColor.
INPUT : GEOCol  = table of GEO color.
        ISICol  = table of ISI color.
        ulNbr   = number of color.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
#define ISI_xColorCompInvFac 0.00390625f   /* 1/ISI_tdxColorCompFac = 1/256*/
 
void ISI_ColISIToGEO(GEO_tdstColor *GEOCol ,ISI_tdstColor *ISICol,unsigned long ulNbr)
{
	
	float				*p_fGeo, *p_fLastGeo;
	ISI_tdxColorComp	*p_xIsi;
 
	p_fGeo		= (float *) GEOCol;
	p_fLastGeo	= (float *) (GEOCol + ulNbr);
	p_xIsi		= (ISI_tdxColorComp *) ISICol;
 
	for (; p_fGeo < p_fLastGeo;)
	{
		*p_fGeo++ = *p_xIsi++ * ISI_xColorCompInvFac;
		*p_fGeo++ = *p_xIsi++ * ISI_xColorCompInvFac;
		*p_fGeo++ = *p_xIsi++ * ISI_xColorCompInvFac;
		*p_fGeo++ = *p_xIsi++ * ISI_xColorCompInvFac;
	}
  
	/*
	while (ulNbr--)
	{
		GEOCol->xR = MTH_M_xLongToFloat((long)ISICol->xRed)	  * ISI_xColorCompInvFac;
		GEOCol->xG = MTH_M_xLongToFloat((long)ISICol->xGreen) * ISI_xColorCompInvFac;
		GEOCol->xB = MTH_M_xLongToFloat((long)ISICol->xBlue)  * ISI_xColorCompInvFac;
		GEOCol->xA = MTH_M_xLongToFloat((long)ISICol->xAlpha) * ISI_xColorCompInvFac;
		GEOCol++;
		ISICol++;
	}
	*/
}
 
/* ##F===================================================================================
NAME :          ISI_ColGEOToISI
DESCRIPTION :   Convert a GEO_tdstColor in ISI_tdstColor.
INPUT : ISICol  = table of ISI color.
        GEOCol  = table of GEO color.
        ulNbr   = number of color.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
void ISI_ColGEOToISI(ISI_tdstColor *ISICol , GEO_tdstColor *GEOCol,unsigned long ulNbr)
{
  long R,G,B,A;
  while (ulNbr--)
  {
    R=MTH_M_xFloatToLong(GEOCol->xR*ISI_tdxColorCompFac);
    G=MTH_M_xFloatToLong(GEOCol->xG*ISI_tdxColorCompFac);
    B=MTH_M_xFloatToLong(GEOCol->xB*ISI_tdxColorCompFac);
    A=MTH_M_xFloatToLong(GEOCol->xA*ISI_tdxColorCompFac);
    if (R<ISI_tdxColorCompMin) R=ISI_tdxColorCompMin;
    else if (R>ISI_tdxColorCompMax) R=ISI_tdxColorCompMax;
    if (G<ISI_tdxColorCompMin) G=ISI_tdxColorCompMin;
    else if (G>ISI_tdxColorCompMax) G=ISI_tdxColorCompMax;
    if (B<ISI_tdxColorCompMin) B=ISI_tdxColorCompMin;
    else if (B>ISI_tdxColorCompMax) B=ISI_tdxColorCompMax;
    if (A<ISI_tdxColorCompMin) A=ISI_tdxColorCompMin;
    else if (A>ISI_tdxColorCompMax) A=ISI_tdxColorCompMax;
    ISICol->xRed  =(ISI_tdxColorComp)R;
    ISICol->xGreen=(ISI_tdxColorComp)G;
    ISICol->xBlue =(ISI_tdxColorComp)B;
    ISICol->xAlpha=(ISI_tdxColorComp)A;
    GEOCol++;
    ISICol++;
  }
}
 
 
#ifndef _FIRE_DEADCODE_U64_
/* ##F===================================================================================
NAME :          ISI_fn_xGetNbLOD
DESCRIPTION :   Return the number of LOD.
INPUT : _hISI  = handle to ISI.
OUTPUT : Number of LOD.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ACP_tdxIndex ISI_fn_xGetNbLOD(ACP_tdxHandleToRadiosity _hISI)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
  
  return hCpyISI->xNbISILOD;
}
 
 
/* ##F===================================================================================
NAME :          ISI_fn_xGetNbVertexRLILOD
DESCRIPTION :   Return the number of RLI for one LOD.
INPUT : _hISI       = handle to ISI.
        _xNumISILOD = LOD number.
OUTPUT : Number of RLI in the LOD.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ACP_tdxIndex ISI_fn_xGetNbVertexRLILOD(ACP_tdxHandleToRadiosity _hISI,ACP_tdxIndex _xNumISILOD)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
  
  return hCpyISI->d_stISILOD[_xNumISILOD].xNbVertexRLI;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_dGetVertexRLILOD
DESCRIPTION :   Return the table of RLI for one LOD.
INPUT : _hISI       = handle to ISI.
        _xNumISILOD = LOD number.
OUTPUT : Table of RLI.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ISI_tdstColor *ISI_fn_dGetVertexRLILOD(ACP_tdxHandleToRadiosity _hISI,ACP_tdxIndex _xNumISILOD)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
  
  return hCpyISI->d_stISILOD[_xNumISILOD].d_stVertexRLI;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_xGetNbVertexRLI
DESCRIPTION :   Return the number of RLI for the first LOD.
INPUT : _hISI       = handle to ISI.
OUTPUT : Number of RLI for the first LOD.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ACP_tdxIndex ISI_fn_xGetNbVertexRLI(ACP_tdxHandleToRadiosity _hISI)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
  
  return hCpyISI->d_stISILOD[0].xNbVertexRLI;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_dGetVertexRLI
DESCRIPTION :   Return the table of RLI for the first LOD.
INPUT : _hISI       = handle to ISI.
OUTPUT : Table of RLI for the first LOD.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
ISI_tdstColor *ISI_fn_dGetVertexRLI(ACP_tdxHandleToRadiosity _hISI)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
  
  return hCpyISI->d_stISILOD[0].d_stVertexRLI;
}
 
/* ##F===================================================================================
NAME :          ISI_fn_vSetVertexRLILOD
DESCRIPTION :   Change RLI of one vertex for one LOD.
INPUT : _hISI       = handle to ISI.
        _p_stColor  = adress of ISI color for setting.
        _xNumISILOD = LOD number in the ISI.
        _xIndex     = RLI number in the LOD.
OUTPUT : Table of RLI for the first LOD.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
void ISI_fn_vSetVertexRLILOD(ACP_tdxHandleToRadiosity _hISI, ISI_tdstColor *_p_stColor,
                             ACP_tdxIndex _xNumISILOD, ACP_tdxIndex _xIndex)
{
  ISI_HandleToISI hCpyISI;
  
  hCpyISI=(ISI_HandleToISI)_hISI;
 
  hCpyISI->d_stISILOD[_xNumISILOD].d_stVertexRLI[_xIndex]=*_p_stColor;
}
 
#endif /* _FIRE_DEADCODE_U64_ */
 
/* ##F===================================================================================
NAME :          ISI_fn_vAmbientLight
DESCRIPTION :   Add ambient light to all RLI, create RLI if they not exist.
INPUT : _hSuperObject = hierarchie for lighting.
        _xDR          = red intensity.
        _xDG          = green intensity.
        _xDB          = blue intensity.
=========================================================================================
LAST MODIFICATIONS : 20/11/97 David Fournier : New commentary form.
=======================================================================================*/
void ISI_fn_vAmbientLight(HIE_tdxHandleToSuperObject _hSuperObject,
                          MTH_tdxReal _xDR,
                          MTH_tdxReal _xDG,
                          MTH_tdxReal _xDB)
{
  HIE_tdxHandleToSuperObject hchildSO;
  ACP_tdxHandleOfObject hPhysicalObject;
  ACP_tdxIndex xI,xNumISILOD,xNbVertexRLI;
  ACP_tdxHandleToRadiosity hISI;
  ISI_HandleToISI hCpyISI;
  GEO_tdstColor GEOColInt;
  ISI_tdstColor *d_stVertexRLI;
  MTH_tdxReal xTemp;
  long			lType;
  
  HIE_M_ForEachChildOf(_hSuperObject,hchildSO,xI)
  {
    ISI_fn_vAmbientLight(hchildSO,_xDR,_xDG,_xDB);
  }
  
  lType = HIE_fn_ulGetSuperObjectType(_hSuperObject);
  if(lType & ( HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
  {
    hISI=IPO_fn_hGetRadiosity((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSuperObject));
    
    if(!hISI)
    {
      GEO_tdxHandleToVisualSet hVisuSet;
      ACP_tdxIndex xNbLod;
 
      hVisuSet=PO_fn_hGetVisualSet(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSuperObject)));
      xNbLod=(short)GLI_lGetVisualSetNumbertOfLOD(hVisuSet);
      if (xNbLod>2) xNbLod=2;
      hISI=ISI_fn_hCreateISI(xNbLod);
      IPO_fn_vSetRadiosity((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSuperObject),hISI);
 
      for(xNumISILOD=0;xNumISILOD<xNbLod;xNumISILOD++)
      {
        GLI_vGetVisualSetLOD(hVisuSet,xNumISILOD,&xTemp,&hPhysicalObject);
        ISI_fn_hCreateISILOD(hISI,xNumISILOD,hPhysicalObject->xNbPoints);
      }
    }
    
    hCpyISI=(ISI_HandleToISI)hISI;
 
    /* For all LOD.*/
    for(xNumISILOD=0;xNumISILOD<hCpyISI->xNbISILOD;xNumISILOD++)
    {
      xNbVertexRLI=hCpyISI->d_stISILOD[xNumISILOD].xNbVertexRLI;
      d_stVertexRLI=hCpyISI->d_stISILOD[xNumISILOD].d_stVertexRLI;
      /* For all RLI of the LOD.*/
      for(xI=0;xI<xNbVertexRLI;xI++)    
      {
        ISI_ColISIToGEO(&GEOColInt , d_stVertexRLI+xI,1);
        GEOColInt.xR+=MTH_M_xRealToFloat(_xDR);
        GEOColInt.xG+=MTH_M_xRealToFloat(_xDG);
        GEOColInt.xB+=MTH_M_xRealToFloat(_xDB);
        ISI_ColGEOToISI(d_stVertexRLI+xI , &GEOColInt,1);
      }
    }
  }
}
 
/* ##F===================================================================================
NAME :          ISI_hComputeBlendRLI
DESCRIPTION :   compute a blend between two ISI.
INPUT : hRLI1      = first table 
				hRLI2      = second table
				xNumISILOD = number of the affected LOD
				xPercent   = percentage of the second table in the result (i.e : there is 1-xPercent
										 of the first table in the result)
OUTPUT: handle of ISI
=========================================================================================
LAST MODIFICATIONS : 17/02/98 Jean-Marc Drouaud 
=======================================================================================*/
ACP_tdxHandleToRadiosity ISI_hComputeBlendRLI ( ACP_tdxHandleToRadiosity hRLI1, 
																							  ACP_tdxHandleToRadiosity hRLI2,
																								ACP_tdxIndex xNumISILOD, 
																								MTH_tdxReal xPercent ) {
	ACP_tdxHandleToRadiosity hReturnRad = NULL ;
  ISI_HandleToISI hBlendISI, hISI1, hISI2 ;
  ACP_tdxIndex xI, xNbVertex ;
  ISI_tdstColor *p_stBlendTabCol, *p_stTabCol1, *p_stTabCol2;
	MTH_tdxReal xPercentComplement ;
 
  hISI1 = (ISI_HandleToISI)hRLI1 ;
	hISI2 = (ISI_HandleToISI)hRLI2 ;
 
	hBlendISI = ISI_fn_hCreateISI (hISI1->xNbISILOD) ;
	hReturnRad = (ISI_HandleToISI)hBlendISI ;
 
	xNbVertex	= hISI1->d_stISILOD[xNumISILOD].xNbVertexRLI ;
 
  hBlendISI->d_stISILOD[xNumISILOD].xNbVertexRLI = xNbVertex ;
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeISI , MMG_C_lSubTypeBlendRLI , 0 );
  GEO_M_CPAMalloc( p_stBlendTabCol, ISI_tdstColor *, 
									 sizeof(ISI_tdstColor) * xNbVertex, 
									 E_uwGEONotEnoughtMemory);
  hBlendISI->d_stISILOD[xNumISILOD].d_stVertexRLI=p_stBlendTabCol;
 
 
	p_stTabCol1 = hISI1->d_stISILOD[xNumISILOD].d_stVertexRLI ;
	p_stTabCol2 = hISI2->d_stISILOD[xNumISILOD].d_stVertexRLI ;
 
	xPercentComplement = (float)1.0 - xPercent ;
  for(xI=0;xI<xNbVertex;xI++)
  {
    p_stBlendTabCol[xI].xRed  = (short)(p_stTabCol1[xI].xRed*xPercentComplement + p_stTabCol2[xI].xRed*xPercent) ;
    p_stBlendTabCol[xI].xGreen= (short)(p_stTabCol1[xI].xGreen*xPercentComplement + p_stTabCol2[xI].xGreen*xPercent) ;
    p_stBlendTabCol[xI].xBlue = (short)(p_stTabCol1[xI].xBlue*xPercentComplement + p_stTabCol2[xI].xBlue*xPercent) ;
    p_stBlendTabCol[xI].xAlpha= (short)(p_stTabCol1[xI].xAlpha*xPercentComplement+ p_stTabCol2[xI].xAlpha*xPercent) ;
  }
	return (hReturnRad) ;
}
/*END ANNECY JMD }*/
 
