Started functional decomposition for dynamic objects.
Fixed typo in last patch, where objects were using object_group_lod rather than object_lod.
This commit is contained in:
parent
8dc38a5198
commit
f71f4cf9ab
1 changed files with 88 additions and 55 deletions
|
@ -313,6 +313,83 @@ static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an object to a random location inside a triangle.
|
||||||
|
*
|
||||||
|
* @param p1 The first vertex of the triangle.
|
||||||
|
* @param p2 The second vertex of the triangle.
|
||||||
|
* @param p3 The third vertex of the triangle.
|
||||||
|
* @param center The center of the triangle.
|
||||||
|
* @param ROT The world-up rotation matrix.
|
||||||
|
* @param mat The material object.
|
||||||
|
* @param object_index The index of the dynamically-placed object in
|
||||||
|
* the material.
|
||||||
|
* @param branch The branch where the object should be added to the
|
||||||
|
* scene graph.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_object_to_triangle (sgVec3 p1, sgVec3 p2, sgVec3 p3, sgVec3 center,
|
||||||
|
sgMat4 ROT, FGNewMat * mat, int object_index,
|
||||||
|
ssgBranch * branch)
|
||||||
|
{
|
||||||
|
sgVec3 result;
|
||||||
|
|
||||||
|
random_pt_inside_tri(result, p1, p2, p3);
|
||||||
|
sgSubVec3(result, center);
|
||||||
|
sgMat4 OBJ_pos, OBJ;
|
||||||
|
sgMakeTransMat4(OBJ_pos, result);
|
||||||
|
sgCopyMat4(OBJ, ROT);
|
||||||
|
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);
|
||||||
|
branch->addKid(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a rotation matrix to align an object for the current lat/lon.
|
||||||
|
*
|
||||||
|
* By default, objects are aligned for the north pole. This code
|
||||||
|
* calculates a matrix to rotate them for the surface of the earth in
|
||||||
|
* the current location.
|
||||||
|
*
|
||||||
|
* TODO: there should be a single version of this method somewhere
|
||||||
|
* for all of SimGear.
|
||||||
|
*
|
||||||
|
* @param ROT The resulting rotation matrix.
|
||||||
|
* @param hdg_deg The object heading in degrees.
|
||||||
|
* @param lon_deg The longitude in degrees.
|
||||||
|
* @param lat_deg The latitude in degrees.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
makeWorldUpRotationMatrix (sgMat4 ROT, double hdg_deg,
|
||||||
|
double lon_deg, double lat_deg)
|
||||||
|
{
|
||||||
|
sgVec3 obj_right, obj_up;
|
||||||
|
sgSetVec3(obj_right, 0.0, 1.0, 0.0); // Y axis
|
||||||
|
sgSetVec3(obj_up, 0.0, 0.0, 1.0); // Z axis
|
||||||
|
sgMat4 ROT_lon, ROT_lat, ROT_hdg;
|
||||||
|
sgMakeRotMat4(ROT_lon, lon_deg, obj_up);
|
||||||
|
sgMakeRotMat4(ROT_lat, 90 - lat_deg, obj_right);
|
||||||
|
sgMakeRotMat4(ROT_hdg, hdg_deg, obj_up);
|
||||||
|
sgCopyMat4(ROT, ROT_hdg);
|
||||||
|
sgPostMultMat4(ROT, ROT_lat);
|
||||||
|
sgPostMultMat4(ROT, ROT_lon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_random_surface_objects (ssgLeaf *leaf,
|
gen_random_surface_objects (ssgLeaf *leaf,
|
||||||
ssgBranch *branch,
|
ssgBranch *branch,
|
||||||
|
@ -330,20 +407,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
|
||||||
float hdg_deg = 0.0; // do something here later
|
float hdg_deg = 0.0; // do something here later
|
||||||
|
|
||||||
|
|
||||||
// The object will be aligned for the north pole. This code
|
|
||||||
// calculates a matrix to rotate it to for the surface of the
|
|
||||||
// earth in the current location.
|
|
||||||
sgVec3 obj_right, obj_up;
|
|
||||||
sgSetVec3(obj_right, 0.0, 1.0, 0.0); // Y axis
|
|
||||||
sgSetVec3(obj_up, 0.0, 0.0, 1.0); // Z axis
|
|
||||||
sgMat4 ROT_lon, ROT_lat, ROT_hdg;
|
|
||||||
sgMakeRotMat4(ROT_lon, lon_deg, obj_up);
|
|
||||||
sgMakeRotMat4(ROT_lat, 90 - lat_deg, obj_right);
|
|
||||||
sgMakeRotMat4(ROT_hdg, hdg_deg, obj_up);
|
|
||||||
sgMat4 ROT;
|
sgMat4 ROT;
|
||||||
sgCopyMat4(ROT, ROT_hdg);
|
makeWorldUpRotationMatrix(ROT, hdg_deg, lon_deg, lat_deg);
|
||||||
sgPostMultMat4(ROT, ROT_lat);
|
|
||||||
sgPostMultMat4(ROT, ROT_lon);
|
|
||||||
|
|
||||||
if ( num > 0 ) {
|
if ( num > 0 ) {
|
||||||
short int n1, n2, n3;
|
short int n1, n2, n3;
|
||||||
|
@ -383,27 +448,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
|
||||||
|
|
||||||
// place an object each unit of area
|
// place an object each unit of area
|
||||||
while ( num > 1.0 ) {
|
while ( num > 1.0 ) {
|
||||||
random_pt_inside_tri( result, p1, p2, p3 );
|
add_object_to_triangle(p1, p2, p3, center,
|
||||||
sgSubVec3(result, center);
|
ROT, mat, j, location);
|
||||||
sgMat4 OBJ_pos, OBJ;
|
|
||||||
sgMakeTransMat4(OBJ_pos, result);
|
|
||||||
sgCopyMat4(OBJ, ROT);
|
|
||||||
sgPostMultMat4(OBJ, OBJ_pos);
|
|
||||||
ssgTransform * pos = new ssgTransform;
|
|
||||||
pos->setTransform(OBJ);
|
|
||||||
float obj_range = mat->get_object_lod(j);
|
|
||||||
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(j));
|
|
||||||
pos->addKid(range);
|
|
||||||
location->addKid(pos);
|
|
||||||
num -= 1.0;
|
num -= 1.0;
|
||||||
}
|
}
|
||||||
// for partial units of area, use a zombie door method to
|
// for partial units of area, use a zombie door method to
|
||||||
|
@ -412,27 +458,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
|
||||||
if ( num > 0.0 ) {
|
if ( num > 0.0 ) {
|
||||||
if ( sg_random() <= num ) {
|
if ( sg_random() <= num ) {
|
||||||
// a zombie made it through our door
|
// a zombie made it through our door
|
||||||
random_pt_inside_tri( result, p1, p2, p3 );
|
add_object_to_triangle(p1, p2, p3, center,
|
||||||
sgSubVec3(result, center);
|
ROT, mat, j, location);
|
||||||
sgMat4 OBJ_pos, OBJ;
|
|
||||||
sgMakeTransMat4(OBJ_pos, result);
|
|
||||||
sgCopyMat4(OBJ, ROT);
|
|
||||||
sgPostMultMat4(OBJ, OBJ_pos);
|
|
||||||
ssgTransform * pos = new ssgTransform;
|
|
||||||
pos->setTransform(OBJ);
|
|
||||||
float obj_range = mat->get_object_lod(j);
|
|
||||||
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(j));
|
|
||||||
pos->addKid(range);
|
|
||||||
location->addKid(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,6 +468,12 @@ gen_random_surface_objects (ssgLeaf *leaf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Scenery loaders.
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
// Load an Ascii obj file
|
// Load an Ascii obj file
|
||||||
ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t,
|
ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t,
|
||||||
ssgVertexArray *lights, const bool is_base)
|
ssgVertexArray *lights, const bool is_base)
|
||||||
|
|
Loading…
Add table
Reference in a new issue