]> git.tdb.fi Git - libs/gl.git/blob - source/render/zsortedscene.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / render / zsortedscene.cpp
1 #include <msp/core/algorithm.h>
2 #include "camera.h"
3 #include "renderer.h"
4 #include "zsortedscene.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 void ZSortedScene::add(Renderable &r)
12 {
13         auto i = lower_bound(content, &r);
14         if(i==content.end() || *i!=&r)
15         {
16                 content.insert(i, &r);
17                 for(auto &kvp: sorted_cache)
18                         kvp.second.push_back(&r);
19         }
20 }
21
22 void ZSortedScene::remove(Renderable &r)
23 {
24         auto i = lower_bound(content, &r);
25         if(i!=content.end() && *i==&r)
26         {
27                 content.erase(i);
28                 sorted_cache.clear();
29         }
30 }
31
32 void ZSortedScene::set_order(SortOrder o)
33 {
34         order = o;
35 }
36
37 void ZSortedScene::set_reference(DepthReference r)
38 {
39         reference = r;
40 }
41
42 void ZSortedScene::setup_frame(Renderer &renderer)
43 {
44         for(Renderable *r: content)
45                 r->setup_frame(renderer);
46 }
47
48 void ZSortedScene::finish_frame()
49 {
50         for(Renderable *r: content)
51                 r->finish_frame();
52 }
53
54 void ZSortedScene::render(Renderer &renderer, Tag tag) const
55 {
56         if(content.empty())
57                 return;
58
59         const Camera *camera = renderer.get_camera();
60         if(!camera)
61         {
62                 for(Renderable *r: content)
63                         r->render(renderer, tag);
64                 return;
65         }
66
67         vector<SortedRenderable> &cache = sorted_cache[camera];
68         if(cache.empty() && !content.empty())
69         {
70                 cache.reserve(content.size());
71                 cache.insert(cache.end(), content.begin(), content.end());
72         }
73
74         const Vector3 &camera_pos = camera->get_position();
75         const Vector3 &look_dir = camera->get_look_direction();
76         float radius_factor = reference-1.0f;
77         float sign = 1.0f-order*2.0f;
78
79         for(SortedRenderable &r: cache)
80         {
81                 r.in_frustum = camera->is_in_frustum(*r.renderable);
82                 if(!r.in_frustum)
83                         continue;
84
85                 if(const Matrix *matrix = r.renderable->get_matrix())
86                 {
87                         if(const Geometry::BoundingSphere<float, 3> *bsphere = r.renderable->get_bounding_sphere())
88                                 r.depth = dot(*matrix*bsphere->get_center()-camera_pos, look_dir)+bsphere->get_radius()*radius_factor;
89                         else
90                                 r.depth = dot(*matrix*Vector3()-camera_pos, look_dir);
91                         r.depth *= sign;
92                 }
93                 else
94                         r.depth = 0;
95         }
96
97         for(auto i=cache.begin(), j=i; i!=cache.end(); ++i)
98                 if(i->in_frustum)
99                 {
100                         if(i!=j)
101                                 swap(*i, *j);
102
103                         if(j!=cache.begin() && *j<*(j-1))
104                         {
105                                 SortedRenderable sr = *j;
106                                 auto k = j-1;
107                                 *j = *k;
108                                 while(k!=cache.begin() && sr<*(k-1))
109                                 {
110                                         *k = *(k-1);
111                                         --k;
112                                 }
113                                 *k = sr;
114                         }
115
116                         ++j;
117                 }
118
119         for(auto i=cache.begin(); (i!=cache.end() && i->in_frustum); ++i)
120                 i->renderable->render(renderer, tag);
121 }
122
123 } // namespace GL
124 } // namespace Msp