source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp @ 1071

Revision 1071, 3.2 KB checked in by gumbau, 18 years ago (diff)
Line 
1/*==========================================================================
2 *      (C) 2006 Universitat Jaume I
3 *==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *==========================================================================
6 *      CONTENT:
7 *
8 *
9 *      @file   GeoLodManager.cpp
10 *===========================================================================*/
11
12#include "GeoLodManager.h"
13#include "GeoLodObject.h"
14
15namespace Geometry
16{
17        class lodobj_idpos_node_t
18        {
19        public:
20                lodobj_idpos_node_t(LodObject *o):lodobj(o),must_recalculate_distance(true),dist2cam(0.0f){}
21                LodObject *lodobj;
22                float dist2cam; // used to index the lodobj in the other map
23                bool must_recalculate_distance;
24                bool operator < (const lodobj_idpos_node_t &o) const { return (lodobj->GetUniqueID()<o.lodobj->GetUniqueID()); }
25        };
26}
27
28using namespace Geometry;
29
30LodManager::LodManager(float near, float far, const Geometry::Vector3 &campos)
31:targetFPS(30),camera_changed(true),camera_pos(campos),
32 near_range(near),far_range(far)
33{
34}
35
36void Geometry::LodManager::AddLodObj(LodObject * o, const Geometry::Vector3 &p)
37{
38        float dist = CalculateDistToCamera(p); 
39        lodobj_dists[dist] = lodobj_dist_node_t(o);
40        UpdateLODObjectPos(o,p);
41}
42
43
44void Geometry::LodManager::UpdateLOD(void)
45{
46        // recalculate distances if have to
47        if (camera_changed)
48        {
49                // if the camera has changed, recalculate all lodobject distances to it         
50                lodobj_dists.clear();
51                for (std::map<Geometry::lodobj_idpos_node_t,Geometry::Vector3>::iterator it = lodobj_pos.begin(); it != lodobj_pos.end(); it++)
52                {
53                        const lodobj_idpos_node_t & posnode = it->first;
54                        const Vector3 & pos = it->second;
55                        float newdist = CalculateDistToCamera(pos);
56                        lodobj_dists[newdist] = lodobj_dist_node_t(posnode.lodobj);
57                }
58                camera_changed=false;
59        }
60        else
61        {
62                // if any of the objects changed its position, the distance must be recalculated
63                for (std::map<Geometry::lodobj_idpos_node_t,Geometry::Vector3>::iterator it = lodobj_pos.begin(); it != lodobj_pos.end(); it++)
64                {
65                        const lodobj_idpos_node_t & posnode = it->first;
66                        if (posnode.must_recalculate_distance)
67                        {
68                                const Vector3 & pos = it->second;
69                                float newdist = CalculateDistToCamera(pos);
70                                lodobj_dists[newdist] = lodobj_dist_node_t(posnode.lodobj);
71/*                              lodobj_dists.erase(it);*/
72                        }
73                }
74        }
75
76        // select a tree to change its LOD
77        float random_dist = SelectRandomDistance();
78        std::map<float,Geometry::lodobj_dist_node_t>::iterator nearest = lodobj_dists.upper_bound(random_dist);
79}
80
81void Geometry::LodManager::UpdateCamera(const Geometry::Vector3 &p)
82{
83        camera_pos = p;
84        camera_changed = true;
85}
86
87void Geometry::LodManager::UpdateLODObjectPos(LodObject *o, const Geometry::Vector3 &p)
88{
89        lodobj_pos[lodobj_idpos_node_t(o)] = p;
90}
91
92
93float Geometry::LodManager::CalculateDistToCamera(const Geometry::Vector3 &p) const
94{
95        return camera_pos.dotProduct(p);
96}
97
98float Geometry::LodManager::SelectRandomDistance(void) const
99{
100        float linear_01 = (float)rand()/(float)RAND_MAX;
101        float exp_01 = linear_01*linear_01;
102        float real_dist = exp_01*near_range + (1.0f-exp_01)*far_range;
103        return real_dist;
104}
Note: See TracBrowser for help on using the repository browser.