X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Ftgdb%2FSGTexturedTriangleBin.hxx;h=3df4280a123afb824bbc93fa5053736daa912cd3;hb=2cc2a857a2cc2daff30601e0f8f697c768dd5b30;hp=bbeb6244c518e207fe19b616f0004693b1c90cf1;hpb=0c9013e60e5d7a9762fdd93180d02725d6873e57;p=simgear.git diff --git a/simgear/scene/tgdb/SGTexturedTriangleBin.hxx b/simgear/scene/tgdb/SGTexturedTriangleBin.hxx index bbeb6244..3df4280a 100644 --- a/simgear/scene/tgdb/SGTexturedTriangleBin.hxx +++ b/simgear/scene/tgdb/SGTexturedTriangleBin.hxx @@ -128,9 +128,12 @@ public: SGVec3f offsetVector = offset*normalize(normal); // generate a light point for each unit of area + while ( coverage < unit ) { + float a = mt_rand(&seed); float b = mt_rand(&seed); + if ( a + b > 1 ) { a = 1 - a; b = 1 - b; @@ -142,6 +145,102 @@ public: } } } + + // Computes and adds random surface points to the points list for tree + // coverage. + void addRandomTreePoints(float wood_coverage, + float tree_density, + float wood_size, + std::vector& points) + { + unsigned num = getNumTriangles(); + for (unsigned i = 0; i < num; ++i) { + triangle_ref triangleRef = getTriangleRef(i); + SGVec3f v0 = getVertex(triangleRef[0]).vertex; + SGVec3f v1 = getVertex(triangleRef[1]).vertex; + SGVec3f v2 = getVertex(triangleRef[2]).vertex; + SGVec3f normal = cross(v1 - v0, v2 - v0); + + // Compute the area + float area = 0.5f*length(normal); + if (area <= SGLimitsf::min()) + continue; + + // For partial units of area, use a zombie door method to + // create the proper random chance of a point being created + // for this triangle + float unit = area + mt_rand(&seed)*wood_coverage; + + int woodcount = (int) (unit / wood_coverage); + + for (int j = 0; j < woodcount; j++) { + + if (wood_size < area) { + // We need to place a wood within the triangle and populate it + + // Determine the center of the wood + float x = mt_rand(&seed); + float y = mt_rand(&seed); + + // Determine the size of this wood in m^2, and the number + // of trees in the wood + float ws = wood_size + wood_size * (mt_rand(&seed) - 0.5f); + unsigned total_trees = ws / tree_density; + float wood_length = sqrt(ws); + + // From our wood size, work out the fraction on the two axis. + // This will be used as a factor when placing trees in the wood. + float x_tree_factor = wood_length / length(v1 -v0); + float y_tree_factor = wood_length / length(v2 -v0); + + for (unsigned k = 0; k <= total_trees; k++) { + + float a = x + x_tree_factor * (mt_rand(&seed) - 0.5f); + float b = y + y_tree_factor * (mt_rand(&seed) - 0.5f); + + + // In some cases, the triangle side lengths are so small that the + // tree_factors become so large as to make placing the tree within + // the triangle almost impossible. In this case, we place them + // randomly across the triangle. + if (a < 0.0f || a > 1.0f) a = mt_rand(&seed); + if (b < 0.0f || b > 1.0f) b = mt_rand(&seed); + + if ( a + b > 1.0f ) { + a = 1.0f - a; + b = 1.0f - b; + } + + float c = 1.0f - a - b; + + SGVec3f randomPoint = a*v0 + b*v1 + c*v2; + + points.push_back(randomPoint); + } + } else { + // This triangle is too small to contain a complete wood, so just + // distribute trees across it. + unsigned total_trees = area / tree_density; + + for (unsigned k = 0; k <= total_trees; k++) { + + float a = mt_rand(&seed); + float b = mt_rand(&seed); + + if ( a + b > 1.0f ) { + a = 1.0f - a; + b = 1.0f - b; + } + + float c = 1.0f - a - b; + + SGVec3f randomPoint = a*v0 + b*v1 + c*v2; + points.push_back(randomPoint); + } + } + } + } + } void addRandomPoints(float coverage, std::vector& points) @@ -210,25 +309,25 @@ public: triangle_ref triangle = triangles[i]; if (indexMap[triangle[0]] == invalid) { indexMap[triangle[0]] = vertices->size(); - vertices->push_back(getVertex(triangle[0]).vertex.osg()); - normals->push_back(getVertex(triangle[0]).normal.osg()); - texCoords->push_back(getVertex(triangle[0]).texCoord.osg()); + vertices->push_back(toOsg(getVertex(triangle[0]).vertex)); + normals->push_back(toOsg(getVertex(triangle[0]).normal)); + texCoords->push_back(toOsg(getVertex(triangle[0]).texCoord)); } deFacade.push_back(indexMap[triangle[0]]); if (indexMap[triangle[1]] == invalid) { indexMap[triangle[1]] = vertices->size(); - vertices->push_back(getVertex(triangle[1]).vertex.osg()); - normals->push_back(getVertex(triangle[1]).normal.osg()); - texCoords->push_back(getVertex(triangle[1]).texCoord.osg()); + vertices->push_back(toOsg(getVertex(triangle[1]).vertex)); + normals->push_back(toOsg(getVertex(triangle[1]).normal)); + texCoords->push_back(toOsg(getVertex(triangle[1]).texCoord)); } deFacade.push_back(indexMap[triangle[1]]); if (indexMap[triangle[2]] == invalid) { indexMap[triangle[2]] = vertices->size(); - vertices->push_back(getVertex(triangle[2]).vertex.osg()); - normals->push_back(getVertex(triangle[2]).normal.osg()); - texCoords->push_back(getVertex(triangle[2]).texCoord.osg()); + vertices->push_back(toOsg(getVertex(triangle[2]).vertex)); + normals->push_back(toOsg(getVertex(triangle[2]).normal)); + texCoords->push_back(toOsg(getVertex(triangle[2]).texCoord)); } deFacade.push_back(indexMap[triangle[2]]); }