00001 #include "DLODObject.h"
00002
00003 DLODObject::DLODObject (RawObject * raw): GraphicalObject (raw)
00004 {
00005 num_levels = 0;
00006 AddLevel (raw, 0.0f);
00007 }
00008
00009 DLODObject::~DLODObject ()
00010 {
00011
00012 }
00013
00014 void DLODObject::Draw (int time, Camera * camera, Camera * monitor, bool show_bounding_volume, int culling_mode, bool level_of_detail)
00015 {
00016 Position pos, camera_pos;
00017 int culling_result;
00018 bool rotation;
00019 int level;
00020
00021 Point origin;
00022 Point absolute_pos = {0.0f, 0.0f, 0.0f};
00023 float mod[16];
00024 float * inv;
00025 float camera_dist;
00026
00027
00028 if (!(position->IsDefined (time))) return;
00029
00030
00031 pos = position->GetPosition (time);
00032 camera_pos = camera->position->GetPosition (time);
00033
00034
00035 rotation = position->HasStaticRotation ();
00036
00037
00038 ApplyTransformation (pos, rotation);
00039
00040
00041 culling_result = CullObject (camera, monitor, culling_mode, show_bounding_volume);
00042
00043
00044 if (culling_result != C_OUTSIDE)
00045 {
00046 if (level_of_detail)
00047 {
00048 glGetFloatv (GL_MODELVIEW_MATRIX, mod);
00049 if (monitor == NULL)
00050 {inv = camera->GetInverseView ();}
00051 else
00052 {inv = monitor->GetInverseView ();}
00053
00054 origin.x = mod[12];
00055 origin.y = mod[13];
00056 origin.z = mod[14];
00057 Geometry::VectorMultiply (inv, origin, absolute_pos);
00058
00059 camera_dist = (camera_pos.x - absolute_pos.x) * ( camera_pos.x - absolute_pos.x) +
00060 (camera_pos.y - absolute_pos.y) * ( camera_pos.y - absolute_pos.y) +
00061 (camera_pos.z - absolute_pos.z) * ( camera_pos.z - absolute_pos.z);
00062
00063 for (level = 0; level < MAX_LEVEL; level++)
00064 {
00065 if (camera_dist > distances[level] && camera_dist < distances[level+1])
00066 {
00067 raw_obj[level]->Draw ();
00068 break;
00069 }
00070 }
00071 }
00072 else
00073 {
00074 raw_object->Draw ();
00075 }
00076 }
00077
00078
00079 UndoTransformation (pos, rotation);
00080 }
00081
00082 void DLODObject::AddLevel (RawObject * next_level, float distance)
00083 {
00084 if (num_levels == MAX_LEVEL)
00085 {printf ("Only %d levels of detail allowed per object!\n", MAX_LEVEL); return;}
00086
00087 raw_obj[num_levels] = next_level;
00088 distances[num_levels] = distance * distance;
00089 num_levels++;
00090 distances[num_levels] = INFINITE;
00091 }
00092
00093 DLODObject * DLODObject::GetClone ()
00094 {
00095 DLODObject * clone = new DLODObject (raw_object);
00096
00097 for (int index = 0; index < num_levels; index++)
00098 {clone->AddLevel (raw_obj[index], sqrt (distances[index]));}
00099
00100 return clone;
00101 }
00102
00103 void DLODObject::ComputeBoundingRadius ()
00104 {
00105 bounding_radius = raw_object->GetBoundingRadius ();
00106 }
00107
00108 void DLODObject::ComputeBoundingBox ()
00109 {
00110 bounding_box = raw_object->GetBoundingBox ();
00111 }
00112
00113 void DLODObject::PrintToConsole ()
00114 {
00115 printf ("Number of Levels: %d, infinity: %g\n", num_levels, MY_INFINITY);
00116 for (int index = 0; index < num_levels; index++)
00117 {printf ("Distance: %g\n", distances[index]);}
00118 }