From 5d2c640f1ac34dcc7cbe2f971849b58e2ed58d78 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 17 Jul 2002 21:00:54 +0000 Subject: [PATCH] Fix some minor inconsistencies and inefficiencies: - no extra nodes are created at all if the material has no random objects defined - the range selector is place correctly under the transformation - there is only one range selector for each object type in each triangle (experimental -- doesn't seem to make a difference in speed or memory) This patch removes Curt's patch that randomized ranges slightly, since individual random objects no longer have their own range selectors. It also leaves the object-group-range value unused, for now. --- src/Objects/obj.cxx | 136 ++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index ba81c0efa..a3ca51c92 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -342,18 +342,7 @@ add_object_to_triangle (sgVec3 p1, sgVec3 p2, sgVec3 p3, sgVec3 center, sgPostMultMat4(OBJ, OBJ_pos); ssgTransform * pos = new ssgTransform; pos->setTransform(OBJ); - float obj_range = mat->get_object_lod(object_index); - float range_div = (sg_random() * obj_range); - if (range_div < 0.0000001) { - // avoid a divide by zero error - range_div = 1.0; - } - float random_range = 160.0 * obj_range / range_div + obj_range; - float ranges[] = {0, random_range}; - ssgRangeSelector *range = new ssgRangeSelector; - range->setRanges(ranges, 2); - range->addKid(mat->get_object(object_index)); - pos->addKid(range); + pos->addKid(mat->get_object(object_index)); branch->addKid(pos); } @@ -397,73 +386,94 @@ gen_random_surface_objects (ssgLeaf *leaf, float lat_deg, const string &material_name) { + float hdg_deg = 0.0; // do something here later + + // First, look up the material + // for this surface. FGNewMat * mat = material_lib.find(material_name); if (mat == 0) { SG_LOG(SG_INPUT, SG_ALERT, "Unknown material " << material_name); return; } - int num = leaf->getNumTriangles(); - float hdg_deg = 0.0; // do something here later + // If the material has no randomly-placed + // objects, return now. + int num_objects = mat->get_object_count(); + if (num_objects < 1) + return; + // If the surface has no triangles, return + // now. + int num_tris = leaf->getNumTriangles(); + if (num_tris < 1) + return; + // Make a rotation matrix to align the + // object for this point on the earth's + // surface. sgMat4 ROT; makeWorldUpRotationMatrix(ROT, hdg_deg, lon_deg, lat_deg); - if ( num > 0 ) { - short int n1, n2, n3; - float *p1, *p2, *p3; - sgVec3 result; + short int n1, n2, n3; + float *p1, *p2, *p3; + sgVec3 result; - // generate a repeatable random seed - p1 = leaf->getVertex( 0 ); - unsigned int seed = (unsigned int)p1[0]; - sg_srandom( seed ); + // generate a repeatable random seed + p1 = leaf->getVertex( 0 ); + unsigned int seed = (unsigned int)p1[0]; + sg_srandom( seed ); + + // Iterate through all the triangles + for ( int i = 0; i < num_tris; ++i ) { + leaf->getTriangle( i, &n1, &n2, &n3 ); + p1 = leaf->getVertex(n1); + p2 = leaf->getVertex(n2); + p3 = leaf->getVertex(n3); + double area = sgTriArea( p1, p2, p3 ); - int num_objects = mat->get_object_count(); - for ( int i = 0; i < num; ++i ) { - leaf->getTriangle( i, &n1, &n2, &n3 ); - p1 = leaf->getVertex(n1); - p2 = leaf->getVertex(n2); - p3 = leaf->getVertex(n3); - double area = sgTriArea( p1, p2, p3 ); // Set up a single center point for LOD - sgVec3 center; - sgSetVec3(center, - (p1[0] + p2[0] + p3[0]) / 3.0, - (p1[1] + p2[1] + p3[1]) / 3.0, - (p1[2] + p2[2] + p3[2]) / 3.0); - ssgTransform * location = new ssgTransform; - sgMat4 TRANS; - sgMakeTransMat4(TRANS, center); - location->setTransform(TRANS); - - for (int j = 0; j < num_objects; j++) { - double num = area / mat->get_object_coverage(j); - float ranges[] = {0, mat->get_object_group_lod(j)}; - ssgRangeSelector * lod = new ssgRangeSelector; - lod->setRanges(ranges, 2); - lod->addKid(location); - branch->addKid(lod); + sgVec3 center; + sgSetVec3(center, + (p1[0] + p2[0] + p3[0]) / 3.0, + (p1[1] + p2[1] + p3[1]) / 3.0, + (p1[2] + p2[2] + p3[2]) / 3.0); + + // Set up a transformation to the center + // point, so that everything else can + // be specified relative to it. + ssgTransform * location = new ssgTransform; + sgMat4 TRANS; + sgMakeTransMat4(TRANS, center); + location->setTransform(TRANS); + branch->addKid(location); + + // Iterate through all the objects. + for (int j = 0; j < num_objects; j++) { + double num = area / mat->get_object_coverage(j); + float ranges[] = {0, mat->get_object_lod(j)}; + ssgRangeSelector * lod = new ssgRangeSelector; + lod->setRanges(ranges, 2); + location->addKid(lod); + ssgBranch * objects = new ssgBranch; + lod->addKid(objects); - // place an object each unit of area - while ( num > 1.0 ) { - add_object_to_triangle(p1, p2, p3, center, - ROT, mat, j, location); - num -= 1.0; - } - // for partial units of area, use a zombie door method to - // create the proper random chance of an object being created - // for this triangle - if ( num > 0.0 ) { - if ( sg_random() <= num ) { - // a zombie made it through our door - add_object_to_triangle(p1, p2, p3, center, - ROT, mat, j, location); - } - } - } + // place an object each unit of area + while ( num > 1.0 ) { + add_object_to_triangle(p1, p2, p3, center, + ROT, mat, j, objects); + num -= 1.0; + } + // for partial units of area, use a zombie door method to + // create the proper random chance of an object being created + // for this triangle + if ( num > 0.0 ) { + if ( sg_random() <= num ) { + // a zombie made it through our door + add_object_to_triangle(p1, p2, p3, center, + ROT, mat, j, objects); + } } + } } } -- 2.39.5