/** @brief OpenSimの Terrain用Mesher.SculptMesherを参考にしている. @file TerrainMesher.cpp @author Fumi.Iseki, K.Suzuki @date 2014 10/ @sa http://opensimulator.org/ @sa http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?OpenSim%2Fr32file @sa OpenSim/Region/Physics/Meshing/SculptMesh.cs */ #include "TerrainMesher.h" using namespace jbxl; /////////////////////////////////////////////////////////////////////////////////////////////// // TerrainMesh Class // void TerrainMesh::init(void) { clear(); bound_left = true; bound_right = true; bound_top = true; bound_bottom = true; xsize = 256; ysize = 256; max_height = -HUGE_VALF; min_height = HUGE_VALF; seabed = TERRAIN_MESH_SEABED_LEVEL; } // void TerrainMesh::clear(void) { clear_data(); clear_image(); } // void TerrainMesh::clear_data(void) { coords.clear(); normals.clear(); uvs.clear(); terrainTriIndex.clear(); terrainTriArray.clear(); } // void TerrainMesh::clear_image(void) { int rnum = (int)terrainImage.size(); for (int i=0; i grd) { if (grd.isNull() || grd.zs!=1) return false; xsize = grd.xs; ysize = grd.ys; float height; for (int j=0; j((float)i, (float)j, height)); if (height>max_height) max_height = height; if (height shift, bool autoseabed) { clear_data(); if (terrainImage.size()==0) { PRINT_MESG("TerrainMesh::GenerateMeshData(): WARNING: image data size is 0!\n"); return; } int xs = (int)terrainImage[0].size(); int ys = (int)terrainImage.size(); int oxs = xs; int oys = ys; int stx = 0; int sty = 0; if (autoseabed && min_height<=max_height) seabed = min_height - 1.0f; // X方向境界処理 // Left if (bound_left) { Vector left (0.0f, 0.0f, seabed); for (int j=0; j right(xs-1.0f, 0.0f, seabed); for (int j=0; j top(0.0f, 0.0f, seabed); TERRAIN_VECTOR_ARRAY topSeabed; topSeabed.push_back(top); for (int i=1; i bottom(0.0f, ys-1.0f, seabed); TERRAIN_VECTOR_ARRAY bottomSeabed; bottomSeabed.push_back(bottom); for (int i=1; i(0.0f, 0.0f, 0.0f)); uvs.push_back(UVMap(du*(i+stx), dv*(j+sty))); if (i>0 && j>0) { FacetTriIndex t1, t2; t1.mlt_set(p1, p4, p3); t2.mlt_set(p1, p2, p4); terrainTriIndex.push_back(t1); terrainTriIndex.push_back(t2); } } } if (autoseabed) { // 海底面処理 int cnum = (int)coords.size(); // データ(頂点)の数 FacetTriIndex s1, s2; s1.mlt_set(cnum, cnum+2, cnum+3); s2.mlt_set(cnum, cnum+3, cnum+1); terrainTriIndex.push_back(s1); terrainTriIndex.push_back(s2); coords.push_back(Vector(0.0f, 0.0f, seabed)); coords.push_back(Vector((float)xsize, 0.0f, seabed)); coords.push_back(Vector(0.0f, (float)ysize, seabed)); coords.push_back(Vector((float)xsize, (float)ysize, seabed)); for (int i=0; i<4; i++) { normals.push_back(Vector(0.0f, 0.0f, 0.0f)); uvs.push_back(UVMap(0.0f, 0.0f)); } } ComputeTriNormals(); SetupTriArray(shift); } void TerrainMesh::ComputeTriNormals(void) { int tnum = (int)terrainTriIndex.size(); for (int i=0; i normal = indx.SurfaceNormal(&coords); normals[indx.n1] = normals[indx.n1] + normal; normals[indx.n2] = normals[indx.n2] + normal; normals[indx.n3] = normals[indx.n3] + normal; } int nnum = (int)normals.size(); for (int i=0; i shift) { int size = (int)coords.size(); for (int i=0; i