// implementation of special world class for the 3DTool Dll


//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING
//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING
//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING
//// WARNING                                                                          WARNING
//// WARNING                                                                          WARNING
//// WARNING                     SuperObjects are not destroyed !!!!!                 WARNING
//// WARNING                                                                          WARNING
//// WARNING                                                                          WARNING
//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING
//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING
//// WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING

#ifdef ACTIVE_EDITOR

#include "stdafx.h"

#define D_State_Define
#define HieFriend

#include "ACP_Base.h"
#include "incGam.h"
#include "Itf.h"
//#include "HIE.h"

#include "T3DWorld.hpp"

inline POS_tdxHandleToPosition M_AllocMatrix()
{
	POS_tdxHandleToPosition hPos = (POS_tdxHandleToPosition) malloc (sizeof (POS_tdstCompletePosition) );
	POS_fn_vSetIdentityMatrix(hPos);

	return hPos;
}

//#define M_AllocMatrix()                     ((POS_tdxHandleToPosition) malloc (sizeof (POS_tdstCompletePosition)))

//#define M_AllocMatrix()                     POS_fn_hCreateMatrix(POS_C_xCompletePosition);

#define M_GetCopyOfSuperObject(p_oSprObj)   (p_oSprObj) -> GetMainWorld() -> GetInterface() -> GetCopyOfSuperObject(p_oSprObj)

#define M_ForEachSuperObjectChild( p_oSprObjFather, p_oSprObjChild )							\
            for( p_oSprObjChild = p_oSprObjFather -> GetSuperObjectFirstChild() ;				\
                 p_oSprObjChild ;																\
                 p_oSprObjChild = p_oSprObjFather -> GetSuperObjectNextChild( p_oSprObjChild ) )

#define M_T3DDeleteSuperObject( p_oSO, bWithEngine )\
{													\
	if( p_oSO )										\
	{												\
		if( p_oSO -> GetStruct() )					\
			p_oSO -> SetObject( NULL );				\
		if( ! bWithEngine )							\
			p_oSO -> SetSuperObjectStruct( NULL );	\
		p_oSO -> fn_bUnValidate();					\
		/*delete p_oSO;*/							\
	}												\
}

#define M_T3DStepSize	10
#define M_T3DInitSize	50
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//--------------------------------------------------------------------------------
// constructor :
//--------------------------------------------------------------------------------
Tool3D_World::Tool3D_World(CPA_MainWorld *_p_oMainWorld)
             :CPA_World(_p_oMainWorld, TRUE)

{
    CPA_SuperObject *p_Root = _p_oMainWorld -> GetInterface() -> GetCopyOfSuperObject( _p_oMainWorld -> GetWorld() -> GetRoot() );
    POS_tdxHandleToPosition hMatrix;
// fbolefeysot - 01/07/98{
//    CHN_tdxHandleToChannelArray  hChannelArray;
//END fbolefeysot}
    //CHN_tdxHandleToCASList  hCAList;
    //CHN_tdxHandleToUCCList  hUCCList;

    p_Root -> SetObject(_p_oMainWorld -> GetWorld() -> GetRoot() -> GetObject());
    hMatrix = HIE_fn_hGetSuperObjectMatrix(p_Root -> GetStruct());
    POS_fn_vSetIdentityMatrix(hMatrix);

    p_Root -> SetEditProtected( TRUE );
    fn_vSetRoot(p_Root);

    // init values
    m_eWorldType            = C_eNone;
    m_p_oRootFromAnim       = NULL;
    //
	m_oListOfSO . RemoveAll();
	m_xLastSOUsedPosition = NULL;

    m_p_oBaseFromAnim       = NULL;
    m_p_oDLLPO              = NULL;
    m_p_oInterface          = NULL;

    m_p_stEngineObject      = (tdstEngineObject *) malloc( sizeof( struct tdstEngineObject_ ) );
    memset( m_p_stEngineObject, 0, sizeof(struct tdstEngineObject_) );
    fn_v3dDataAlloc( m_p_stEngineObject );
		//
// fbolefeysot - 01/07/98{
//    fn_vInitCSOList( & hCSOList, );
//END fbolefeysot}
//    fn_vInitCASList( & hCAList );
    //fn_vInitUCCList( & hUCCList );
		//
// fbolefeysot - 01/07/98{
    fn_v3dDataSetChannelSOList( m_p_stEngineObject -> h_3dData, NULL );
	fn_v3dDataSetFirstActiveChannel(m_p_stEngineObject -> h_3dData, NULL );
	m_stState.p_stAnim = NULL;
//END fbolefeysot}
//    fn_v3dDataSetChannelActivationList( m_p_stEngineObject -> h_3dData, hCAList );
    //fn_v3dDataSetChannelUnderControlList( m_p_stEngineObject -> h_3dData, hUCCList );
}

//--------------------------------------------------------------------------------
// Destructor :
//--------------------------------------------------------------------------------
Tool3D_World::~Tool3D_World()
{
	CPA_SuperObject *p_oSO;

    M_T3DDeleteSuperObject( GetRoot(), TRUE );

    fn_vSetRoot( NULL );
	while( ! m_oListOfSO . IsEmpty() )
	{
		p_oSO = m_oListOfSO . RemoveHead();
		if( p_oSO )
			M_T3DDeleteSuperObject( p_oSO, FALSE );
	}

    free(m_p_stEngineObject);
}

//--------------------------------------------------------------------------------
// Description :
//--------------------------------------------------------------------------------
BOOL Tool3D_World::mfn_bAcceptModif(CPA_ObjectDLLBase *pDLLBase)
{
    if( (m_eWorldType == C_eGridActor) || (m_eWorldType == C_eGridList) )
        return ( pDLLBase && ( ( pDLLBase -> GetName() == C_szDLLZDxName ) ||
                               ( pDLLBase -> GetName() == C_szDLLGeometryName )
                             )
               );
    else
        return ( pDLLBase && pDLLBase -> GetName() == C_szDLLZDxName );
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from an actor
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateHierarchyFromActor(CPA_SuperObject *_p_oSprObj)
{
    ASSERT(0);
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from a superobject
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateHierarchyFromSuperObject(CPA_SuperObject *_p_oSprObj)
{
    mfn_vCreateHierarchyFromObject( _p_oSprObj -> GetObject() );
    //
    m_eWorldType            = C_eSuperObject;
    m_p_oRootFromAnim       = NULL;
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from an object
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateHierarchyFromObject(CPA_BaseObject *_p_oObject)
{
    POS_tdxHandleToPosition hMatrix;
    MTH3D_tdstVector        stCenter;

    m_eWorldType            = C_eObject;
    m_p_oRootFromAnim       = NULL;
    // create new SuperObject
    CPA_SuperObject *p_oNewSprObj  = M_GetCopyOfSuperObject( GetRoot() );
    // set object of new SuperObject
    p_oNewSprObj -> SetObject( _p_oObject );
    //
    p_oNewSprObj -> SetEditProtected( FALSE );
    // add new SuperObject to Hierarchy
    fn_vInsertSuperObjectInNewWorld( p_oNewSprObj, GetRoot(), FALSE );
    // center object
    hMatrix = HIE_fn_hGetSuperObjectMatrix(p_oNewSprObj -> GetStruct());
    POS_fn_vSetIdentityMatrix(hMatrix);
    if( mfn_bComputeCenterAndRadiusBoundingBox( p_oNewSprObj, &stCenter ) )
    {
        MTH3D_tdstVector stTranslation;

        POS_fn_vGetTranslationVector( hMatrix, &stTranslation );
        MTH3D_M_vSubVector(&stTranslation, &stTranslation, &stCenter);
        POS_fn_vSetTranslationVector( hMatrix, &stTranslation );
    }
    POS_fn_vNormalizeMatrix(hMatrix);
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from an actor to a grid view
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateGridHierarchyFromActor(CPA_SuperObject *_p_oSprObj)
{
    m_eWorldType            = C_eGridActor;
    m_p_oRootFromAnim       = NULL;
    // create new hierarchy
    mfn_vLinearizeHierarchy( GetRoot(), _p_oSprObj);
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from a list of objects to a grid view
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateGridHierarchyFromList(CPA_List<CPA_BaseObject> *_p_oList, CPA_MainWorld *_p_oMainWorld)
{
    m_eWorldType            = C_eGridList;
    m_p_oRootFromAnim       = NULL;
    // create new hierarchy
    POSITION stPos = _p_oList -> GetHeadPosition();
    while(stPos)
    {
        CPA_BaseObject      *p_Object  = _p_oList -> GetNext( stPos );
        //??? CPA_SuperObject *pLastSprObj   = p_Object -> GetSuperObject();
        CPA_SuperObject *pSuper_Object = _p_oMainWorld -> GetInterface() -> GetNewSuperObject(E_ss_NoSave);
        // save link
        // create the matrix of the super object
		POS_tdstCompletePosition	*p_stPos;

		p_stPos = M_AllocMatrix();
		POS_fn_vSetIdentityMatrix(p_stPos);
        HIE_fn_vSetSuperObjectMatrix(pSuper_Object -> GetStruct () , p_stPos);

		p_stPos = M_AllocMatrix();
		POS_fn_vSetIdentityMatrix(p_stPos);
        pSuper_Object -> GetStruct () -> hGlobalMatrix =  p_stPos;

        POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectMatrix (pSuper_Object -> GetStruct ()));
        POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectGlobalMatrix (pSuper_Object -> GetStruct ()));
        //
        pSuper_Object->SetObject(p_Object);
        // add superobject to new world
        fn_vInsertSuperObjectInNewWorld( pSuper_Object, GetRoot(), FALSE );
    }
}

//--------------------------------------------------------------------------------
// Description : create a new hierarchy from an objects Table
//--------------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateGridHierarchyFromTable(CPA_BaseObject *_p_oTable, CPA_MainWorld *_p_oMainWorld)
{
    CPA_List<CPA_BaseObject> oList;
    long lNbObjects;

    lNbObjects = _p_oMainWorld -> fn_lFindObjects( &oList, "", C_szPhysicalObjectTypeName, _p_oTable );
    if( lNbObjects )
        mfn_vCreateGridHierarchyFromList( &oList, _p_oMainWorld );
}

// ----------------------------------------------------------------------------
// Description : Fill world with VWOI (NEW)
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vCreateViewerHierarchyFromVWOIList(CPA_List<tdst_VW_ObjInfo> *_p_oListOfVWOI, CPA_MainWorld *_p_oMainWorld)
{
    m_p_oRootFromAnim       = NULL;
    m_eWorldType            = C_eViewer;
    // create new hierarchy
    POSITION stPos = _p_oListOfVWOI -> GetHeadPosition();
    while(stPos)
    {
        CPA_SuperObject     *p_oLastFather = _p_oListOfVWOI -> GetNext(stPos) -> m_p_oSuperObject;
        CPA_BaseObject      *p_oObject     = p_oLastFather -> GetObject();
        CPA_SuperObject     *p_oNewFather  = _p_oMainWorld -> GetInterface() -> GetNewSuperObject(E_ss_NoSave);
        // add super object
        // create the matrix of the super object

		POS_tdstCompletePosition	*p_stPos;

		p_stPos = M_AllocMatrix();
		POS_fn_vSetIdentityMatrix(p_stPos);
		HIE_fn_vSetSuperObjectMatrix(p_oNewFather -> GetStruct () , p_stPos);

		p_stPos = M_AllocMatrix();
		POS_fn_vSetIdentityMatrix(p_stPos);
        p_oNewFather -> GetStruct () -> hGlobalMatrix = p_stPos;

        POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectMatrix (p_oNewFather -> GetStruct ()));
        POS_fn_vSetIdentityMatrix(HIE_fn_hGetSuperObjectGlobalMatrix (p_oNewFather -> GetStruct ()));
        p_oNewFather -> SetObject(p_oObject);
        // add SuperObject to new hierarchy
        fn_vInsertSuperObjectInNewWorld( p_oNewFather, GetRoot(), FALSE );
        // duplicate child hierarchy
        mfn_vDuplicateHierarchy( p_oNewFather, p_oLastFather);
    }
    // compute position of objects
    mfn_vComputeSuperObjectPosFromViewer();
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

/*-----------------------------------------------------------------------------
 *  Description : create hierarchy (SO+O) using anim, frame and objects table
 *---------------------------------------------------------------------------*/
CPA_SuperObject *Tool3D_World::mfn_p_oCreateHierarchyFromAnim(CPA_SuperObject *_p_oSprObjActor)
{
    HIE_tdxHandleToSuperObject      hSO             = _p_oSprObjActor -> GetStruct();
    MS_tdxHandleTo3dData            h3dData         = M_GetMSHandle( hSO, 3dData );
    MS_tdxHandleTo3dData            h3dDataCopy     = m_p_stEngineObject -> h_3dData;
    tdxHandleToState                hState          = fn_h3dDataGetCurrentState( h3dData ) ? fn_h3dDataGetCurrentState( h3dData )
																						   : fn_h3dDataGetInitialState( h3dData );
    struct tdstAnim3d_              *p_stAnim       = hState ? fn_p_stGetAnimInState( hState ) : NULL;
    unsigned short                  uwFrame         = fn_uw3dDataGetCurrentFrame( h3dData );
    POS_tdxHandleToPosition         hMatrix;
    MTH3D_tdstVector                stCenter;
// fbolefeysot - 01/07/98{
    CHN_tdxHandleToChannelArray     hChannelArray;
//END fbolefeysot}
    //CHN_tdxHandleToCASList          hCAList;
    //CHN_tdxHandleToUCCList          hUCCList;

//Stefan Dumitrean 1-06-98
	if( !p_stAnim )
		return NULL;
//End Stefan Dumitrean 1-06-98

    m_eWorldType = C_eAnimOK;

    // create new SuperObject that will be put in T3D world
    CPA_SuperObject *p_oNewSprObj  = M_GetCopyOfSuperObject( _p_oSprObjActor );
    // T3D world actor object is the same as the main world actor object
    p_oNewSprObj -> SetObject( _p_oSprObjActor -> GetObject() );
    // duplicate 3dData structure in a safe variable
    memcpy(h3dDataCopy,h3dData,fn_ul3dDataSizeOf());
//	fn_v3dDataCopyClone( m_p_stEngineObject, (tdstEngineObject *)HIE_fn_hGetSuperObjectObject( hSO ) );

	// clear channel array
//    fn_vInitCSOList(&hChannelArray,fn_ul3dDataGetNumberOfChannels(h3dData));
    // copy the original channel array and first active channel in the safe structure
//	fn_v3dDataSetChannelSOList( h3dDataCopy, fn_h3dDataGetChannelSOList(h3dData) );
//	fn_v3dDataSetFirstActiveChannel(h3dDataCopy,fn_h3dDataGetFirstActiveChannel(h3dData));
//	fn_p_st3dDataGetCurrentFrame(h3dDataCopy)->p_stArrayOfElts3d = fn_p_st3dDataGetCurrentFrame(h3dData)->p_stArrayOfElts3d;
    
	// reset dynamic datas
    fn_v3dDataSetChannelSOList(h3dData,NULL);
	fn_v3dDataSetFirstActiveChannel(h3dData,NULL);
	fn_p_st3dDataGetCurrentFrame(h3dData)->p_stArrayOfElts3d = NULL;
	fn_p_st3dDataGetCurrentFrame(h3dData)->stHierarchy.ulNbOfCouples = 0;
	fn_p_st3dDataGetCurrentFrame(h3dData)->stHierarchy.d_stCouples= NULL;
	fn_v3dDataSetSizeOfArrayOfElts3d(h3dData,0);
	fn_v3dDataSetCurrentState(h3dData,&m_stState);

    // put the new SuperObject into T3D world
    fn_vInsertSuperObjectInNewWorld( p_oNewSprObj, GetRoot(), FALSE );

    // save SO tht is in the T3D world
	m_p_oRootFromAnim = p_oNewSprObj;
    // save SO that is in the real world
	m_p_oBaseFromAnim = _p_oSprObjActor;
    // init used values
    m_p_oDLLPO = GetRoot() -> GetMainWorld() -> GetObjectDLLWithName( C_szDLLPhysicalObjectName );
    m_p_oInterface = GetRoot() -> GetMainWorld() -> GetInterface();

    // center object
    hMatrix = HIE_fn_hGetSuperObjectMatrix(p_oNewSprObj -> GetStruct());
    POS_fn_vSetIdentityMatrix(hMatrix);
    if( mfn_bComputeCenterAndRadiusBoundingBox( p_oNewSprObj, &stCenter ) )
    {
        MTH3D_tdstVector stTranslation;

        POS_fn_vGetTranslationVector( hMatrix, &stTranslation );
        MTH3D_M_vSubVector(&stTranslation, &stTranslation, &stCenter);
        POS_fn_vSetTranslationVector( hMatrix, &stTranslation );
    }
    POS_fn_vNormalizeMatrix(hMatrix);

//	uwFrame %= p_stAnim -> uwNumberOfFrames;
//    fn_v3dDataSetCurrentFrame( h3dData, uwFrame );
	
	mfn_vUpdateHierarchyFromAnim(p_stAnim,fn_uw3dDataGetCurrentFrame(M_GetMSHandle(hSO,3dData)));

	return p_oNewSprObj;
}

/*-----------------------------------------------------------------------------
 *  Description : update hierarchy (SO+O) using anim, frame and objects table
 *---------------------------------------------------------------------------*/
void Tool3D_World::mfn_vUpdateHierarchyFromAnim(struct tdstAnim3d_* _p_stAnim, unsigned short _uwFrame)
{
    //
    HIE_tdxHandleToSuperObject hSO = m_p_oRootFromAnim -> GetStruct();

    m_eWorldType = C_eAnimTemp;
    // clear editor hierarchy
    mfn_vClearHierarchy( m_p_oRootFromAnim );
    // construct engine hierarchy
    fn_v3dDataSetCurrentFrame( M_GetMSHandle( hSO, 3dData ), _uwFrame );
	fn_p_st3dDataGetCurrentFrame(M_GetMSHandle(hSO,3dData))->p_stAnim = NULL;
	fn_v3dDataSetFlagModifState(M_GetMSHandle(hSO,3dData),TRUE);
	if (fn_h3dDataGetCurrentState(M_GetMSHandle(hSO,3dData))->p_stAnim == NULL)
		fn_h3dDataGetCurrentState(M_GetMSHandle(hSO,3dData))->p_stAnim = _p_stAnim;
	PLA_fn_bDoFirstInitOfAnimPlayerForCharacter(hSO, _p_stAnim);
    // encapsulate with editor object
    mfn_vFillHierarchyWithEngineAnim( m_p_oRootFromAnim, TRUE );
    //
    m_p_oInterface -> fn_vChangeWorld();
}

/*-----------------------------------------------------------------------------
 *  Description : update hierarchy (SO) using anim, frame and objects table
 *---------------------------------------------------------------------------*/
void Tool3D_World::mfn_vPlayAnim(struct tdstAnim3d_* _p_stAnim, unsigned short _uwFrame)
{
    HIE_tdxHandleToSuperObject hSO = m_p_oRootFromAnim -> GetStruct();
    //
    m_eWorldType = C_eAnimTemp;
    // clear editor hierarchy
    mfn_vClearHierarchy( m_p_oRootFromAnim );
    // construct engine hierarchy
    fn_v3dDataSetCurrentFrame( M_GetMSHandle( hSO, 3dData ), _uwFrame );
	fn_p_st3dDataGetCurrentFrame(M_GetMSHandle(hSO,3dData))->p_stAnim = NULL;
    PLA_fn_vInitAllChildInHeapNewAnim( hSO, _p_stAnim, _uwFrame );
    PLA_fn_vDoFrame( _p_stAnim, _uwFrame, hSO );
    // encapsulate with editor object
    mfn_vFillHierarchyWithEngineAnim( m_p_oRootFromAnim, FALSE );
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Description : Remove world and delete all SuperObjects created
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vResetWorld(void)
{
    if( (m_eWorldType == C_eAnimTemp) || (m_eWorldType == C_eAnimOK) )
    {
        //
        HIE_tdxHandleToSuperObject hSO          = m_p_oRootFromAnim -> GetStruct();
        MS_tdxHandleTo3dData       h3dData      = M_GetMSHandle( hSO, 3dData );
        MS_tdxHandleTo3dData       h3dDataCopy  = m_p_stEngineObject -> h_3dData;
// fbolefeysot - 01/07/98{
        CHN_tdxHandleToChannelArray hChannelArray;
//END fbolefeysot}
        //CHN_tdxHandleToCASList     hCAList;
        //CHN_tdxHandleToUCCList     hUCCList;
//		PLA_fn_vDesInitAllChildOfCharacter(hSO,(struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hSO));
        
//		hChannelArray = fn_h3dDataGetChannelSOList( h3dData );
//        fn_vFreeCSOList( & hChannelArray/*, fn_ul3dDataGetNumberOfChannels(h3dData)*/);

//        fn_v3dDataSetChannelSOList( h3dData, NULL );
//		fn_v3dDataSetFirstActiveChannel( h3dData, NULL );

        fn_v3dDataCopyClone( (tdstEngineObject *)HIE_fn_hGetSuperObjectObject( hSO ), m_p_stEngineObject );
	    memcpy(h3dData,h3dDataCopy,fn_ul3dDataSizeOf());

// fbolefeysot - 01/07/98{
//END fbolefeysot}
//        hCAList  = fn_h3dDataGetChannelActivationList(h3dData);
        //hUCCList = fn_h3dDataGetChannelUnderControlList(h3dData);
        // restore list on Real Actor
//        fn_v3dDataSetChannelSOList( h3dData, fn_h3dDataGetChannelSOList(h3dDataCopy) );
//		fn_v3dDataSetFirstActiveChannel(h3dData,fn_h3dDataGetFirstActiveChannel(h3dDataCopy ));
//		fn_p_st3dDataGetCurrentFrame(h3dData)->p_stArrayOfElts3d = fn_p_st3dDataGetCurrentFrame(h3dDataCopy)->p_stArrayOfElts3d;
        //fn_v3dDataSetChannelActivationList( h3dData, fn_h3dDataGetChannelActivationList(h3dDataCopy) );
        //fn_v3dDataSetChannelUnderControlList( h3dData, fn_h3dDataGetChannelUnderControlList(h3dDataCopy) );
		// reinit list on local backup structure
// fbolefeysot - 01/07/98{
//END fbolefeysot}
//        fn_vFreeCASList( & hCAList );
        //fn_vFreeUCCList( & hUCCList );
		//
// fbolefeysot - 01/07/98{
//        fn_vInitCSOList( & hCSOList );
//END fbolefeysot}
//        fn_vInitCASList( & hCAList );
        //fn_vInitUCCList( & hUCCList );
		//
// fbolefeysot - 01/07/98{
//        fn_v3dDataSetChannelSOList( h3dDataCopy, NULL );
//		fn_v3dDataSetFirstActiveChannel( h3dDataCopy, NULL );
//		fn_p_st3dDataGetCurrentFrame(h3dDataCopy)->p_stArrayOfElts3d = NULL;
//END fbolefeysot}
//        fn_v3dDataSetChannelActivationList( h3dDataCopy, hCAList );
        //fn_v3dDataSetChannelUnderControlList( h3dDataCopy, hUCCList );
        //

        mfn_vClearHierarchy( m_p_oRootFromAnim, TRUE );
        m_p_oRootFromAnim -> Isolate( FALSE );
		fn_vUpdateListObjects(m_p_oRootFromAnim, E_lum_Delete, FALSE);
    }
    else
    {
        // delete New Hierarchy
        mfn_vResetHierarchy( GetRoot() );
    }
    m_p_oRootFromAnim     = NULL;
    m_eWorldType          = C_eNone;
}

//--------------------------------------------------------------------------------
// protected functions
//--------------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Description : Duplicate Hierarchy from _p_oPreviousFather to _p_oNewFather
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vDuplicateHierarchy(CPA_SuperObject *_p_oNewFather, CPA_SuperObject *_p_oPreviousFather)
{
    CPA_SuperObject *p_oEdChild;

    M_ForEachSuperObjectChild( _p_oPreviousFather, p_oEdChild )
    {
        // create new SuperObject
        CPA_SuperObject *p_oNewSprObj  = M_GetCopyOfSuperObject(p_oEdChild);
        // set object of new SuperObject
        p_oNewSprObj -> SetObject( p_oEdChild -> GetObject() );
        // add new SuperObject to Hierarchy
        fn_vInsertSuperObjectInNewWorld( p_oNewSprObj, _p_oNewFather, FALSE );
        // Duplicate child Hierarchy
        mfn_vDuplicateHierarchy( p_oNewSprObj, p_oEdChild );
    }
}

// ----------------------------------------------------------------------------
// Description : Duplicate Hierarchy from _p_oPreviousFather to _p_oNewFather
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vLinearizeHierarchy(CPA_SuperObject *_p_oNewFather, CPA_SuperObject *_p_oPreviousFather)
{
    CPA_SuperObject *p_oEdChild;

    M_ForEachSuperObjectChild( _p_oPreviousFather, p_oEdChild )
    {

// jt 19/8/97
// Pour éviter de traiter les super-objets correspondant à des canaux
// J'ai un cas ou les matrices du super objet ne sont pas correctement allouées -> plantage
// Il y a surement mieux à faire.
		if (p_oEdChild->GetObject())
		{
// end jt 19/8/97

			// create new SuperObject
			CPA_SuperObject *p_oNewSprObj  = M_GetCopyOfSuperObject(p_oEdChild);
			// unprotect SuperObject
			p_oNewSprObj -> SetEditProtected( FALSE );
			// set object of new SuperObject
			p_oNewSprObj -> SetObject( p_oEdChild -> GetObject() );
			// add new SuperObject to Hierarchy
			fn_vInsertSuperObjectInNewWorld( p_oNewSprObj, _p_oNewFather, FALSE );
			// Duplicate child Hierarchy
			mfn_vLinearizeHierarchy( _p_oNewFather, p_oEdChild );


// jt 19/8/97
		}
// end jt 19/8/97

	}
}

// ----------------------------------------------------------------------------
// Description : Delete all SuperObjects from hierarchy
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vDeleteHierarchy( CPA_SuperObject *_p_oFather )
{
    // delete child
    CPA_SuperObject *p_oEdChild = _p_oFather -> GetSuperObjectFirstChild();
    while ( p_oEdChild )
    {
        CPA_SuperObject *p_oChild = p_oEdChild;
        // next child
        p_oEdChild = _p_oFather -> GetSuperObjectNextChild( p_oEdChild );
        // delete
        mfn_vDeleteHierarchy( p_oChild );
    }
    // remove from hierarchy
    fn_vDeleteSuperObjectInNewWorld( _p_oFather, FALSE ) ;
    // delete father
	M_T3DDeleteSuperObject( _p_oFather, TRUE );
}

// ----------------------------------------------------------------------------
// Description : compute max sphere box
// ----------------------------------------------------------------------------
MTH_tdxReal Tool3D_World::m_fn_vComputeMaxSphereBoxRadius(void)
{
    MTH_tdxReal xMaxSphereBoxRadius = 0;

    CPA_SuperObject *p_oEdChild;
    M_ForEachSuperObjectChild( GetRoot(), p_oEdChild )
	{
        MTH_tdxReal xRadius = m_fn_xGetSphereBoxRadius( p_oEdChild );
        xMaxSphereBoxRadius = MTH_M_xMax( xMaxSphereBoxRadius, xRadius );
	}

    return xMaxSphereBoxRadius;
}

// ----------------------------------------------------------------------------
// Description : compute radius of object sphere box (with his child)
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vComputeSuperObjectPosFromViewer(void)
{
    // compute max sphere box radius
    MTH_tdxReal xRadius = MTH_M_xMul(m_fn_vComputeMaxSphereBoxRadius() , 100 );
    short       wIndex  = 0;

    CPA_SuperObject *p_oEdChild;
    M_ForEachSuperObjectChild( GetRoot(), p_oEdChild )
	{
        POS_tdxHandleToPosition hMatrix;
        MTH3D_tdstVector        st3DCenter,st3DPosition;
        MTH3D_tdstVector        stTranslation;

        MTH3D_M_vSetVectorElements(&st3DPosition, MTH_M_xMul(xRadius,wIndex) , 0 , 0 );
        hMatrix = HIE_fn_hGetSuperObjectMatrix(p_oEdChild->GetStruct());
        POS_fn_vSetIdentityMatrix(hMatrix);

        // get translation vector
        POS_fn_vGetTranslationVector( hMatrix, &stTranslation );

        // First, centred with sphere box center
        if( m_fn_bGetSphereBoxCenter( p_oEdChild, &st3DCenter ) )
        {
            MTH3D_M_vSubVector(&stTranslation, &stTranslation, &st3DCenter);
        }
        // Second, place the object
        MTH3D_M_vAddVector(&stTranslation, &stTranslation, &st3DPosition);

        // set translation vector
        POS_fn_vSetTranslationVector( hMatrix, &stTranslation );

        // Force the absolute matrix to be recalculated
        POS_fn_vNormalizeMatrix(hMatrix);

        wIndex++;
	}
    HIE_fn_vInvalidateAllGlobalMatrices();
}

//--------------------------------------------------------------------------------------
//  Compute the sphere box radius of an object
//--------------------------------------------------------------------------------------
MTH_tdxReal Tool3D_World::m_fn_xGetSphereBoxRadius(CPA_SuperObject *_p_oSprObj)
{
    MTH_tdxReal xResult;

    if( mfn_bComputeCenterAndRadiusBoundingBox( _p_oSprObj, NULL, &xResult ) )
        return xResult;
    else
        return 0;
}

//--------------------------------------------------------------------------------------
//  Compute the sphere box center of an object
//--------------------------------------------------------------------------------------
BOOL Tool3D_World::m_fn_bGetSphereBoxCenter(CPA_SuperObject *_p_oSprObj, MTH3D_tdstVector *_p_stCenter)
{
    CPA_BaseObject *p_oObject = _p_oSprObj -> GetObject();

    if( p_oObject )
    {
        MTH_tdxReal xResult;

        ACP_tdxHandleOfObject hObj = ((CPA_ObjectDLLBase*)p_oObject -> GetEditor()) -> fn_hGetBoundingVolume( p_oObject );
        if( hObj )
        {
            GEO_fn_vGetInfoFromGeometricSphere( _p_stCenter, &xResult, hObj );
            return TRUE;
        }
    }
    return FALSE;
}

// ----------------------------------------------------------------------------
// Compute center of Bounding Box from geometric object
// ----------------------------------------------------------------------------

BOOL Tool3D_World::mfn_bComputeCenterAndRadiusBoundingBox(CPA_SuperObject *_p_oSprObj, MTH3D_tdstVector *_p_stCenter /*=NULL*/, MTH_tdxReal *_xRadius /*=NULL*/)
{
    CPA_BaseObject *p_oObject = (_p_oSprObj) ? _p_oSprObj -> GetObject() : NULL;



    if( p_oObject )
    {
        MTH_tdxReal       xResult;
        MTH3D_tdstVector  stCenter;

        ACP_tdxHandleOfObject hObj = ((CPA_ObjectDLLBase*)p_oObject -> GetEditor()) -> fn_hGetBoundingVolume( p_oObject );
        if( hObj )
        {
            GEO_fn_vGetInfoFromGeometricSphere( &stCenter, &xResult, hObj );

            if( _p_stCenter )
            {
                POS_tdxHandleToPosition hMatrix;
			    MTH3D_M_vNullVector( _p_stCenter );
                hMatrix = HIE_fn_hGetSuperObjectMatrix(_p_oSprObj->GetStruct());
                POS_fn_vMulMatrixVertex( _p_stCenter, hMatrix, &stCenter );
            }
            if( _xRadius )
                *_xRadius = xResult;
            return TRUE;
        }
    }
    return FALSE;
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 20/08/97
//
// Description : reset hierarchy from given root
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vResetHierarchy(CPA_SuperObject *_p_oRootSO)
{
    // delete New Hierarchy
    CPA_SuperObject *p_oEdChild = _p_oRootSO -> GetSuperObjectFirstChild();
    while ( p_oEdChild )
    {
        CPA_SuperObject *_p_oChild = p_oEdChild;
        p_oEdChild = _p_oRootSO -> GetSuperObjectNextChild( p_oEdChild );
        // delete child hierarchy
        mfn_vDeleteHierarchy( _p_oChild );
    }
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 20/08/97
//
// Description :
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vFillHierarchyWithEngineAnim( CPA_SuperObject *_p_oRootSO, BOOL _bWithObject /*=TRUE*/ )
{
	m_xLastSOUsedPosition = m_oListOfSO . GetHeadPosition();
	//
	if( _p_oRootSO && _p_oRootSO -> GetStruct() )
		mfn_vFillHierarchy( _p_oRootSO, _bWithObject );
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 20/08/97
//
// Description :
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vFillHierarchy( CPA_SuperObject *_p_oRootSO, BOOL _bWithObject /*=TRUE*/ )
{
    HIE_tdxHandleToSuperObject  hSO;
    HIE_tdxHandleToSuperObject  hSOChild;
    long                        lIndex;
    tdxHandleToVoid             hObject;
    CPA_BaseObject              *p_oObject;
    CPA_SuperObject             *p_oSO;

    ASSERT( _p_oRootSO && _p_oRootSO -> GetStruct() );

    hSO = _p_oRootSO -> GetStruct();
    lIndex = 0;
    HIE_M_ForEachChildOf( hSO, hSOChild, lIndex )
    {
        // SO
		if( m_xLastSOUsedPosition )
		{
			p_oSO = m_oListOfSO . GetNext( m_xLastSOUsedPosition );
			p_oSO -> SetSuperObjectStruct( hSOChild );
		}
		else
		{
			p_oSO = m_p_oInterface -> GetNewSuperObject( hSOChild, E_ss_NoSave );
			m_oListOfSO . AddTail( p_oSO );
		}
		ASSERT( p_oSO );
        _p_oRootSO -> AddANewChild( p_oSO, FALSE );
		fn_vUpdateListObjects( p_oSO, E_lum_Insert, FALSE);
        // Object
        if ( _bWithObject )
        {
            if( HIE_fn_ulGetSuperObjectType( hSOChild ) == HIE_C_ulPO )
            {
                hObject = HIE_fn_hGetSuperObjectObject( hSOChild );
                p_oObject = hObject ? m_p_oDLLPO -> GetBaseObject( hObject, C_szPhysicalObjectTypeName ) : NULL;
                p_oSO -> SetObject( p_oObject );
            }
        }
        // hierarchy
		if( p_oSO && p_oSO -> GetStruct() )
			mfn_vFillHierarchy( p_oSO, _bWithObject );
    }
}

// ----------------------------------------------------------------------------
//  Author      : MT
//  Creation    : 21/08/97
//
// Description :
// ----------------------------------------------------------------------------
void Tool3D_World::mfn_vClearHierarchy( CPA_SuperObject *_p_oRootSO, BOOL _bDelete /*=FALSE*/ )
{
    CPA_SuperObject *p_oSO;
	POSITION xPos;

	xPos = m_oListOfSO . GetHeadPosition();
	while( xPos )
	{
		p_oSO = m_oListOfSO . GetNext( xPos );
		p_oSO -> Isolate( FALSE );
		fn_vUpdateListObjects( p_oSO, E_lum_Delete, FALSE);
		if( _bDelete )
        {
            M_T3DDeleteSuperObject( p_oSO , FALSE );
        }
	}
	m_xLastSOUsedPosition = m_oListOfSO . GetHeadPosition();
}

#endif //ACTIVE_EDITOR