#ifndef BARNESHUT_H #define BARNESHUT_H // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the BARNESHUT_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // BARNESHUT_API functions as being imported from a DLL, wheras this DLL sees symbols // defined with this macro as being exported. #ifdef BARNESHUT_EXPORTS #define BARNESHUT_API __declspec(dllexport) #else #define BARNESHUT_API __declspec(dllimport) #endif // **************************************** // ** GFLOAT // **************************************** // The basic numerical type for pretty much everything. typedef double GFLOAT; // **************************************** // ** POINT3 // **************************************** // A point somewhere in 3D space struct BARNESHUT_API POINT3 { GFLOAT x; GFLOAT y; GFLOAT z; POINT3 operator= (POINT3 &pt); void Init (void); }; // **************************************** // ** VECTOR3 // **************************************** typedef POINT3 VECTOR3; // **************************************** // ** INDEX // **************************************** // Child index. typedef unsigned INDEX; // **************************************** // ** BODY // **************************************** // Description of a planetary body //typedef struct tagBODY BODY; struct BARNESHUT_API BODY { GFLOAT m_dMass; POINT3 m_ptCenter; POINT3 m_ptCenterNext; VECTOR3 m_vVelocity; BODY operator= (BODY &b); BODY(); void Init (void); }; // **************************************** // ** NODE // **************************************** // A node in the Barnes-Hut tree, each node being either a planet, or a container for 8 child nodes. typedef struct NODE *PNODE, **PPNODE; struct NODE { NODE(); NODE(PNODE pnodeParent); ~NODE(); void Propagate (void); // Propagate the mass & location up the tree. void SetExtents (POINT3 ptOrigin, GFLOAT dWidth); PNODE m_pnodeParent; PNODE m_apnodeChild[8];// In accord w/ left-handed coordinates, // (x) Left to Right, (y) Bottom to Top, and (z) Front to Back, // with z varying first, meaning... // (0,0,0);(0,0,1);(0,1,0);(0,1,1);(1,0,0);(1,0,1);(1,1,0);(1,1,1) BOOL m_fChildren; // Rather than check each child!=NULL, we set this. // if fChildren==TRUE, then body data pertains to the children & subchildren. // If fChildren==FALSE, then this node is a body of its own (a leaf), // and then if body.dMass==0, it's an empty node. BODY m_body; // One body for current timestep, and one for next timestep. INDEX m_iBodyCurrent;// 0 or 1, this says which aBody[] is current, the other being next. VECTOR3 m_vForce; POINT3 m_ptOrigin; // Origin of the node-box GFLOAT m_dWidth; // Length of one side }; // **************************************** // ** CBarnesHut // **************************************** // This class is exported from the BarnesHut.dll class BARNESHUT_API CBarnesHut { PNODE m_pnodeUniverse; GFLOAT m_tStep; int m_iCalculations; int m_iTreeDepth; // Tree Functions void DestroyNode (PNODE pnode); HRESULT CreateNode (PNODE *pnode, PNODE pnodeParent, INDEX iChild, BODY bodyNew); HRESULT GetExtentsNode (PNODE pnode); HRESULT GetDrRatio (GFLOAT *dRatio, PNODE pnodeThis, PNODE pnodeThat); // DiameterOfNode / RadiusOfOrbit HRESULT ChildIndexFromPoint (INDEX *piChild, PNODE pnodeThis, POINT3 pt3); // Get which child the coordinates reside in. // Universe Functions void CalculateTimeStep (void); // Granularity of the time step depends on closest two bodies. void GetBodyListA (PNODE pnodeThis, BODY *aBody, int *pcBodies); void GetTreeDepthA (PNODE pnodeThis, int iTreeDepth); // Body Functions HRESULT GetForceFromNode (GFLOAT *pForce, PNODE pnodeThis, PNODE pnodeThat); void AdvanceNode (PNODE pNode); // Move a body one step forward void SumForces (PNODE pLeaf, PNODE pnodeThis); public: CBarnesHut (); CBarnesHut (int *pcAdded, BODY *aBody, int cBodies); ~CBarnesHut (); // Tree Functions // Universe Functions void GetBodyList (BODY *aBody, int *pcBodies); int GetTreeDepth (void); int GetNumberOfCalculations (void); // Body Functions void AdvanceUniverse (void); HRESULT AddBody (PNODE *ppnodeNew, PNODE pnodeThis, BODY body); // Add a body to the universe. HRESULT AddBodyList (int *cAdded, BODY *aBody, int cBodies); // Add an array of bodies. }; extern BARNESHUT_API int nBarnesHut; BARNESHUT_API int fnBarnesHut(void); #endif // BARNESHUT_H