FTreeCoordinate.hpp 6.31 KB
Newer Older
1
// ===================================================================================
2 3 4 5 6 7 8 9
// Logiciel initial: ScalFmm Version 0.5
// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
// Propriétaires : INRIA.
// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
// Initial software: ScalFmm Version 0.5
// Co-authors: Olivier Coulaud, Bérenger Bramas.
// Owners: INRIA.
// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
10
// ===================================================================================
11 12
#ifndef FTREECOORDINATE_HPP
#define FTREECOORDINATE_HPP
13

14

15
#include "../Utils/FGlobal.hpp"
16 17 18
#include "../Containers/FBufferReader.hpp"
#include "../Containers/FBufferWriter.hpp"

19 20 21 22 23 24 25 26

/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FTreeCoordinate
* Please read the license
*
* This class represents tree coordinate. It is used to save
* the position in "box unit" (not system/space unit!).
27 28
* It is directly related to morton index, as interleaves
* bits from this coordinate make the morton index
29 30 31
*/
class FTreeCoordinate{
private:
32
    int data[3];	//< all box-th position
33 34 35

public:	
    /** Default constructor (position = {0,0,0})*/
36 37
    FTreeCoordinate() {
        data[0] = data[1] = data[2] = 0;
38 39 40 41 42 43 44 45
    }

    /**
        * Default constructor
        * @param inX the x
        * @param inY the y
        * @param inZ the z
        */
46 47 48 49
    explicit FTreeCoordinate(const int inX,const int inY,const int inZ) {
         data[0] = inX;
         data[1] = inY;
         data[2] = inZ;
50 51
    }

52 53 54 55 56 57
    explicit FTreeCoordinate(const int inPosition[3]) {
        data[0] = inPosition[0];
        data[1] = inPosition[1];
        data[2] = inPosition[2];
    }

58 59 60 61
    /**
	* Copy constructor
	* @param other the source class to copy
	*/
62 63 64 65
    FTreeCoordinate(const FTreeCoordinate& other) {
        data[0] = other.data[0];
        data[1] = other.data[1];
        data[2] = other.data[2];
66 67
    }

berenger-bramas's avatar
berenger-bramas committed
68 69 70 71
    /**
        * Copy constructor
        * @param other the source class to copy
        */
72 73 74 75
    FTreeCoordinate(const FTreeCoordinate& other, const int inOffset) {
        data[0] = other.data[0] + inOffset;
        data[1] = other.data[1] + inOffset;
        data[2] = other.data[2] + inOffset;
berenger-bramas's avatar
berenger-bramas committed
76 77
    }

78 79 80 81 82 83
    /**
	* Copy constructor
	* @param other the source class to copy
	* @return this a reference to the current object
	*/
    FTreeCoordinate& operator=(const FTreeCoordinate& other){
84 85 86
        data[0] = other.data[0];
        data[1] = other.data[1];
        data[2] = other.data[2];
87 88 89 90 91 92 93 94 95
        return *this;
    }

    /**
	* Position setter
        * @param inX the new x
        * @param inY the new y
        * @param inZ the new z
	*/
96
    void setPosition(const int inX,const int inY,const int inZ){
97 98 99
        data[0] = inX;
        data[1] = inY;
        data[2] = inZ;
100 101 102 103
    }

    /**
	* X Getter
104
        * @return data[0]
105
	*/
106
    int getX() const{
107
        return data[0];
108 109 110 111
    }

    /**
	* Y Getter
112
        * @return data[1]
113
	*/
114
    int getY() const{
115
        return data[1];
116 117 118 119
    }

    /**
	* Z Getter
120
        * @return data[2]
121
	*/
122
    int getZ() const{
123
        return data[2];
124 125 126 127 128 129
    }

    /**
	* X Setter, simply change x position
	* @param the new x
	*/
130
    void setX(const int inX){
131
        data[0] = inX;
132 133 134 135 136 137
    }

    /**
	* Y Setter, simply change y position
	* @param the new y
	*/
138
    void setY(const int inY){
139
        data[1] = inY;
140 141 142 143 144 145
    }

    /**
	* Z Setter, simply change z position
	* @param the new z
	*/
146
    void setZ(const int inZ){
147
        data[2] = inZ;
148 149 150 151 152 153 154 155 156 157 158 159
    }

    /**
	* To get the morton index of the current position
	* @complexity inLevel
	* @param inLevel the level of the component
	* @return morton index
	*/
    MortonIndex getMortonIndex(const int inLevel) const{
        MortonIndex index = 0x0LL;
        MortonIndex mask = 0x1LL;
        // the ordre is xyz.xyz...
160 161 162
        MortonIndex mx = data[0] << 2;
        MortonIndex my = data[1] << 1;
        MortonIndex mz = data[2];
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

        for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
            index |= (mz & mask);
            mask <<= 1;
            index |= (my & mask);
            mask <<= 1;
            index |= (mx & mask);
            mask <<= 1;

            mz <<= 2;
            my <<= 2;
            mx <<= 2;
        }

        return index;
    }

    /** This function set the position of the current object using a morton index
          * @param inIndex the morton index to compute position
          * @param the level of the morton index
          */
    void setPositionFromMorton(MortonIndex inIndex, const int inLevel){
        MortonIndex mask = 0x1LL;

187 188 189
        data[0] = 0;
        data[1] = 0;
        data[2] = 0;
190 191

        for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
192
            data[2] |= int(inIndex & mask);
193
            inIndex >>= 1;
194
            data[1] |= int(inIndex & mask);
195
            inIndex >>= 1;
196
            data[0] |= int(inIndex & mask);
197 198 199 200 201 202 203 204 205 206

            mask <<= 1;
        }

    }

    /** Test equal operator
          * @param other the coordinate to compare
          * @return true if other & current object have same position
          */
207
    bool operator==(const FTreeCoordinate& other) const {
208
        return data[0] == other.data[0] && data[1] == other.data[1] && data[2] == other.data[2];
209
    }
210 211 212 213 214

    /** To test difference
      *
      */
    bool operator!=(const FTreeCoordinate& other) const{
215
        return data[0] != other.data[0] || data[1] != other.data[1] || data[2] != other.data[2];
216
    }
217 218 219 220 221 222 223

    /**
     * Operator stream FTreeCoordinate to std::ostream
     * This can be used to simply write out a tree coordinate
     * @param[in,out] output where to write the coordinate
     * @param[in] inCoordinate the coordinate to write out
     * @return the output for multiple << operators
224 225 226
     */    
    template <class StreamClass>
    friend StreamClass& operator<<(StreamClass& output, const FTreeCoordinate& inCoordinate){
227 228 229 230
        output << "(" <<  inCoordinate.getX() << ", " << inCoordinate.getY() << ", " << inCoordinate.getZ() <<")";
        return output;  // for multiple << operators.
    }

231 232
    /** Save current object */
    void save(FBufferWriter& buffer) const {
233
        buffer << data[0] << data[1] << data[2];
234 235 236
    }
    /** Retrieve current object */
    void restore(FBufferReader& buffer) {
237
        buffer >> data[0] >> data[1] >> data[2];
238
    }
239 240 241 242 243 244
};



#endif //FTREECOORDINATE_HPP

245