#include <inttypes.h>
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <vector>
#include <iostream>
#include <memory>
#include <time.h>
struct ChunkId {
int low;
int high;
};
using FloatArray = float*;// std::unique_ptr<float[]>;
class OctaTerrain {
private:
float RADIUS;
int MAX_Z;
float DETAIL_LEVEL;
std::vector<int64_t> existChunksId;
std::vector<float*> existChunksVertices;
FloatArray cameraPosition;
float theta = M_PI / 2;
float phi = M_PI / 2;
public:
OctaTerrain(float radius, int max_z, float detail) {
RADIUS = radius;
MAX_Z = max_z;
DETAIL_LEVEL = detail;
cameraPosition = FloatArray(new float[3]{ RADIUS,0,0 });
}
FloatArray toPoint(float lat, float lon) {
return FloatArray(new float[3]{
RADIUS * (float)cos(lat) * (float)sin(lon),
RADIUS * (float)sin(lat),
RADIUS * (float)cos(lat) * (float)cos(lon)
});
}
float distance(FloatArray &a, FloatArray &b) {
return sqrt(pow(a[0] - b[0], 2) + pow(a[1] - b[1], 2) + pow(a[2] - b[2], 2));
}
bool needDivide(FloatArray &v1, FloatArray &coords, int z) {
FloatArray v2 = toPoint(coords[0], coords[1]);
if (distance(v1, v2) < pow(DETAIL_LEVEL / z, 2)) {
delete[] v2;
return true;
}
delete[] v2;
return false;
}
FloatArray getChunkCenter(FloatArray &p1, FloatArray &p2, FloatArray &p3) {
return FloatArray(new float[2]{ (p1[0] + p2[0] + p3[0]) / 3,(p1[1] + p2[1] + p3[1]) / 3 });
}
/*
int64_t increaseIdLevel(int64_t id) {
return id + ((int64_t)0x1 << 7 * 8);
}
int getIdLevel(int64_t id) {
return id >> 7 * 8;
}
int64_t setIdSide(int side) {
return (int64_t)side << 6 * 8;
}
int getIdSide(int64_t id) {
return (id >> 6 * 8) & 0xffff;
}
int64_t setIdIndex(int64_t id, int index) {
return id | ((int64_t)index << getIdLevel(id) * 2);
}
*/
int k = 0;
void addChunk(FloatArray &p1, FloatArray &p2, FloatArray &p3, int z){//int64_t id) {
//int z = getIdLevel(id);
FloatArray center = getChunkCenter(p1, p2, p3);
if (z < MAX_Z && needDivide(cameraPosition, center, z)) {
FloatArray p12(new float[2]{ (p1[0] + p2[0]) / 2,(p1[1] + p2[1]) / 2 });
FloatArray p23(new float[2]{ (p2[0] + p3[0]) / 2,(p2[1] + p3[1]) / 2 });
FloatArray p31(new float[2]{ (p1[0] + p2[0]) / 2,p1[0] == M_PI ? p3[1] : (p3[1] + p1[1]) / 2 });
// Align the longitude of the right side along the edge for the upper triangles
//id = increaseIdLevel(id);
z++;
addChunk(p1, p12, p31, z);// setIdIndex(id, 0));
addChunk(p12, p23, p31, z);// setIdIndex(id, 1));
addChunk(p12, p2, p23, z);// setIdIndex(id, 2));
addChunk(p31, p23, p3, z);// setIdIndex(id, 3));
//delete[] center,p12,p23,p31;
return;
}
//delete[] center;
k++;
// existChunksId.push_back(id);
}
void addSide(int id) {
float latScalar = (id>3 ? -1 : 1);
float lonScalar = id % 4;
FloatArray p1(new float[2]{ latScalar*theta, lonScalar*phi });
FloatArray p2(new float[2]{ 0.0,lonScalar*phi });
FloatArray p3(new float[2]{ 0.0,(lonScalar + 1)*phi });
addChunk(p1, p2, p3, 0);// setIdSide(id));
//delete[] p1, p2, p3;
}
void generate(float x, float y, float z) {
cameraPosition = FloatArray(new float[3]{ x,y,z });
existChunksId.clear();
addSide(1);
// addSide(1);
// for(int i = 0; i<8;i++)
// addSide(i);
printf("%d", k);// existChunksId.size());
}
std::vector<ChunkId> getIds() {
std::vector<ChunkId> v;
// std::sort(existChunksId.begin(), existChunksId.end());
for (const int64_t& i : existChunksId) {
ChunkId chunk;
chunk.high = i >> 32;
chunk.low = i & 0xffffffff;
v.push_back(chunk);
}
return v;
}
};
int main() {
auto terrain = new OctaTerrain(1,20,1);
time_t start, end;
time(&start);
terrain->generate(1.002,0,0);
time(&end);
double dif = difftime(end, start);
printf("\n%lf\n", dif);
std::cin.get();
return 0;
}
Ко всем new есть соответствующие delete[], но с ними очищается только половина памяти (с имеющимися параметрами в generate: без delete[] съедает больше 400 МБ, с delete[] - 210.
Использую VS C++ 2015