namespace details { // I don't use glm vectors here because they're not constexpr, // but we don't need to do anything with them anyway, other // than printing, so it's not a problem. // Note that these are returned in the same order as the // voxel::direction enum constexpr std::array<std::array<int, 3>, 6> make_normals() { return { -1, 0, 0, // Left 1, 0, 0, // Right 0, -1, 0, // Down 0, 1, 0, // Up 0, 0, -1, // Back 0, 0, 1 // Front }; } struct face { size_t normal; std::array<size_t, 6> vertices; }; constexpr std::array<face, 6> make_faces() { return { // Left face: First triangle voxel::left, voxel::right_bottom_front, voxel::right_top_front , voxel::left_top_front , // Second triangle voxel::right_bottom_front, voxel::left_top_front , voxel::left_bottom_front , // Right face: First triangle voxel::right, voxel::left_bottom_back , voxel::left_top_back , voxel::right_top_back , // Second triangle voxel::left_bottom_back , voxel::right_top_back , voxel::right_bottom_back , // Bottom face: First triangle voxel::bottom, voxel::right_bottom_back , voxel::right_bottom_front, voxel::left_bottom_front , // Second triangle voxel::right_bottom_back , voxel::left_bottom_front , voxel::left_bottom_back , // Top face: First triangle voxel::top, voxel::right_top_front , voxel::right_top_back , voxel::left_top_back , // Second triangle voxel::right_top_front , voxel::left_top_back , voxel::left_top_front , // Back face: First triangle voxel::back, voxel::left_bottom_front , voxel::left_top_front , voxel::left_top_back , // Second triangle voxel::left_bottom_front , voxel::left_top_back , voxel::left_bottom_back , // Front face: First triangle voxel::front, voxel::right_bottom_back , voxel::right_top_back , voxel::right_top_front , // Second triangle voxel::right_bottom_back , voxel::right_top_front , voxel::right_bottom_front }; } constexpr auto normals = make_normals(); constexpr auto faces = make_faces(); class obj { public: void cube(voxel v) { auto c = v.corners<glm::vec3>(); _indexes.push_back(_vertices.size()); _vertices.insert(_vertices.end(), begin(c), end(c)); } void write(std::ostream &os) const { for(auto v : _vertices) { os << "v " << v.x << " " << v.y << " " << v.z << "\n"; } os << "\n"; for(auto n : normals) { os << "vn " << n[0] << " " << n[1] << " " << n[2] << "\n"; } for (size_t i : _indexes) { for(face f : faces) { for(size_t v = 0; v < f.vertices.size(); ++v) { if(v % 3 == 0) os << "\nf "; os << (f.vertices[v] + i + 1) << "//" << (f.normal + 1) << " "; } } } } private: std::vector<glm::vec3> _vertices; std::vector<size_t> _indexes; }; void obj_mesh(octree const&oc, std::ostream &out) { obj o; for(voxel v : oc) { assert(v.material() != voxel::unknown_material); if(v.material() != voxel::void_material) o.cube(v); } o.write(out); } void octree::mesh(mesh_t mesh_type, std::ostream &out) const { switch (mesh_type) { case obj: obj_mesh(*this, out); return; } assert(!"Unimplemented mesh type"); } } // namespace details
void Alaska::display(void) { //double kvector[2]; double klength,wkt; //////////////////alernativ below/////////// int yHalf = NY/2 + 1; for (int i = 0; i<yHalf; ++i) { //int yLine = i*NY; // Mirror the y line index for calculation of -k // The line below evalutes yLineMirr = y == 0 ? 0 : (mYSize-y)*mXSize; // by wrapping the heightmap, since it is periodic. //int yLineMirr = ((NY-i)% NY)*NY; for (int j = 0; j<NX; ++j) { //kvector[0]=2.0*PI*((float)i-.5*NX)/NX;//I was using these //kvector[1]=2.0*PI*((float)j-.5*NY)/NY; // kvector[0]=2.0*PI*((float)i-.5*NX)/MAX_WORLD_X;//but I think I should use these // kvector[1]=2.0*PI*((float)j-.5*NY)/MAX_WORLD_Y; //kvector[0]=hold_horizontal[i][j][0]; //kvector[1]=hold_horizontal[i][j][1]; // klength=sqrt(kvector[0]*kvector[0]+kvector[1]*kvector[1]); klength=hold_horizontal[i][j][2]; wkt = sqrt(klength * GRAV_CONSTANT) * dtime; // yLineMirr+mXSize-x is the index of -k //int kNegIndex = yLineMirr*NY + ((NY-j)% NY); // This is h~(K, t) from the Tessendorf paper. c[i][j].real= mH0[i][j].real*cos(wkt) + mH0[i][j].imag*sin(wkt) + mH0[NX - i-1][NY - j-1].real*cos(wkt) - mH0[NX - i-1][NY -j-1].imag*sin(wkt); c[i][j].imag= mH0[i][j].imag*cos(wkt) + mH0[i][j].real*sin(wkt) -mH0[NX - i-1][NY - j-1].imag*cos(wkt) - mH0[NX - i-1][NY -j-1].real*sin(wkt); // Store it for later transformation // h~(-K) = conj(h~(K)) if (i != yHalf-1) { c[NX - i-1][NY - j-1].imag= mH0[i][j].real*cos(wkt) + mH0[i][j].imag*sin(wkt) + mH0[NX - i-1][NY - j-1].real*cos(wkt) - mH0[NX - i-1][NY -j-1].imag*sin(wkt); c[NY - i-1][NY - j-1].real= mH0[i][j].imag*cos(wkt) + mH0[i][j].real*sin(wkt) -mH0[NX - i-1][NY - j-1].imag*cos(wkt) - mH0[NX - i-1][NY -j-1].real*sin(wkt); } } } //////////////////end alternative//////////// pre_choppy(); dir=-1; FFT2D(c, NX, NY, dir);// do the inverse FFT to get the surface ///////////////negative power term creation for (int i=0;i<NX;i++) { for (int j=0;j<NY;j++) { c[i][j].real *= float(neg1Pow(i+j)); // while we are looping, set up the final x,y values for display displayXY[i][j][0]=((double)i/NX)*MAX_WORLD_X+mDeltaX[i][j].imag; displayXY[i][j][1]=((double)j/NY)*MAX_WORLD_Y+mDeltaY[i][j].imag; } } make_normals(c); prep_loop(); //this loop loads the actual sea vertices }