1 #include <GL/glew.h>
2 #include <wrap/gl/space.h>
3 #include <wrap/gl/trimesh.h>
4 #include <wrap/gl/splatting_apss/splatrenderer.h>
5 #include "impostor_definition.h"
6 #include "ocme_definition.h"
7 #include "ocme_extract.h"
8 #include "ocme_disk_loader.h"
9 #include <vcg/space/point4.h>
10 
11 
12 extern unsigned int generic_bool ;
13 int COff(const int & h);
14 
15 
DrawCellSel(CellKey & ck,int mode=0)16 void DrawCellSel ( CellKey & ck, int mode = 0 )
17 {
18 	vcg::Point3f p = ck.P3f();
19 	int  lev = ck.h;
20 	float stepf = ( lev>0 ) ? ( 1<<lev ) :  1.f/ ( float ) ( 1<< ( -lev ) ) ;
21 
22 	vcg::Box3f ubox;
23 	ubox.min=vcg::Point3f ( -0.5,-0.5,-0.5 );
24 	ubox.max=-ubox.min;
25 
26 
27 	vcg::Color4b c;
28 	c = c.Scatter ( 255,lev+127 );
29  	c.ColorRamp(-10.f,  10.f, lev );
30 	c[3] = 127;
31 	glColor( c );
32 
33 	glPushMatrix();
34 
35 	switch ( mode )
36 	{
37 		case 0:	glTranslatef ( ( p[0]+ 0.5 ) *stepf, ( p[1]+ 0.5 ) *stepf, ( p[2]+ 0.5 ) *stepf );
38 			glScalef ( stepf*0.1 ,stepf*0.1  ,stepf*0.1 );
39 			vcg::glBoxFlat ( ubox );
40 			break;
41 		case 1:;
42 		case 3: glTranslatef ( ( p[0]+ 0.5 ) *stepf, ( p[1]+ 0.5 ) *stepf, ( p[2]+ 0.5 ) *stepf );
43 			glScalef ( stepf ,stepf ,stepf );
44 			vcg::glBoxFlat ( ubox );
45 			break;
46 		case 2:	glTranslatef ( ( p[0]+ 0.5 ) *stepf, ( p[1]+ 0.5 ) *stepf, ( p[2]+ 0.5 ) *stepf );
47 			glScalef ( stepf*0.1 ,stepf*0.1  ,stepf*0.1 );
48 			GLUquadricObj*  q = gluNewQuadric();
49 			gluSphere (  q,1.0,10,10 );
50 			gluDeleteQuadric(q);
51 			break;
52 	}
53 
54 	glPopMatrix();
55 
56 }
57 
InitRender()58 void OCME::InitRender()
59 	{
60 		renderParams.one_level = false;
61 		renderParams.only_impostors = true;
62 		renderParams.visitOn = true;
63 		renderParams.render_subcells = false;
64 		renderParams.level = 0;
65 		renderParams.memory_limit_in_core = 500 * (1<<20);
66 		renderParams.memory_limit_video = 150 * (1<<20);
67 
68 		glEnable(GL_COLOR_MATERIAL);
69 		glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
70 
71 	}
72 
73 
IsToRefineScreenErr(Cell * & c,float & prio)74 bool OCME::IsToRefineScreenErr(Cell * & c, float & prio ){
75 	vcg::Point4f pos4;
76 	vcg::Point3f pos3;
77 	float scale;
78 	const CellKey & ck = c->key;
79 
80 	pos3 = ck.BBox3f().Center();
81 	memcpy(&pos4[0],&pos3[0],3*sizeof(float));pos4[3]=1.0;
82 
83 	scale = pow(mm.Determinant(),1/(float)3.0);
84 	pos4 = mm*pos4; // position of cube center in view space
85 
86 	float  dis0 = sqrt( pos4[0]*pos4[0] + pos4[1]*pos4[1]+ pos4[2]*pos4[2]);// distance viewer - center
87 	float dis = dis0 - ( ck.BBox3f().Diag()*0.5*scale);				  // distance viewer - closest point
88 
89 	vcg::Point4f prj = pm * vcg::Point4f(0,ck.BBox3f().Diag()* scale/2,-dis,1.0);
90 
91 	float projerr =0.5*vp[2]*prj[1]/prj[3]; // error on screen
92 
93 	prio = projerr;
94 	if(projerr<0) return true;
95 	return (projerr > 50.0);
96 }
97 
98 
IsInFrustum(Cell * c,vcg::Point3f * f,float & dist,bool bsphere_or_bbox)99 bool OCME::IsInFrustum(Cell * c, vcg::Point3f * f, float &dist, bool bsphere_or_bbox ){
100 		const vcg::Point3f pos3 = (bsphere_or_bbox)?c->key.BBox3f().Center():c->bbox.bbox3.Center();
101 
102 		const float radius =  ((bsphere_or_bbox)? c->key.BBox3f().Diag():c->bbox.bbox3.Diag())*0.5f;
103 
104 		vcg::Point3f n_l = ((f[6]-f[0])^(f[4]-f[0])).Normalize();
105 		dist = (pos3-f[0])*n_l-radius;
106 		if(dist > 0)
107 			return false;
108 
109 		vcg::Point3f n_r = ((f[5]-f[1])^(f[7]-f[1])).Normalize();
110 		dist = std::max<float>(dist ,(pos3-f[1])*n_r-radius);
111 
112 		if(dist > 0)
113 			return false;
114 
115 		vcg::Point3f n_t = ((f[7]-f[3])^(f[6]-f[3])).Normalize();
116 		dist = std::max<float>(dist ,(pos3-f[3])*n_t-radius);
117 
118 		if(dist > 0)
119 			return false;
120 
121 		vcg::Point3f n_b = ((f[4]-f[0])^(f[5]-f[0])).Normalize();
122 		dist = std::max<float>(dist ,(pos3-f[1])*n_b-radius);
123 
124 		if(dist > 0)
125 			return false;
126 
127 		vcg::Point3f n_n = ((f[3]-f[0])^(f[2]-f[0])).Normalize();
128 		dist = std::max<float>(dist ,(pos3-f[3])*n_n-radius);
129 
130 		if(dist > 0)
131 			return false;
132 
133 		vcg::Point3f n_f = ((f[6]-f[5])^(f[7]-f[5])).Normalize();
134 		dist = std::max<float>(dist ,(pos3-f[7])*n_f-radius);
135 
136 		if(dist > 0)
137 			return false;
138 
139 
140 		return true;
141 }
142 
Visit(std::vector<Cell * > & to_render)143 void OCME::Visit(std::vector<Cell*> &  to_render){
144  std::list<Cell*>::iterator ori;
145  for(ori = octree_roots.begin(); ori != octree_roots.end(); ++ori)
146 	 Visit((*ori)->key, to_render);
147 
148 }
Visit(CellKey root,std::vector<Cell * > & to_render)149 void OCME::Visit(CellKey root, std::vector<Cell*> & to_render){
150 
151 	float _dist;
152 	std::vector<Cell*> que;
153 	que.push_back(GetCell(root,false));
154 	std::vector<CellKey>   children;
155 	do{
156 		Cell * c = que.back();
157 		que.pop_back();
158 
159 		if(  IsToRefineScreenErr(c,c->rd->priority) && c->impostor->non_empty_children &&  IsInFrustum(c,this->frustum,_dist) ){
160 			children.clear();
161 			Children(c->key,children);
162 			for(unsigned int ci = 0; ci < 8 ; ++ci)
163 				if(c->impostor->non_empty_children & (1 << ci))// non empty	(save a GetCell ..useless..)
164 				{
165 					Cell * to_add = GetCell(children[ci],false);
166 					if(!to_add) continue;
167 					que.push_back(to_add);
168 					if ( !to_add->IsEmpty())
169 						if(!to_add->rd->to_render())
170 							{
171 								c->rd->to_render = FBool(& to_render_fbool);
172 								c->rd->to_render = true;
173 								to_render.push_back(to_add);
174 							}
175 				}
176 		}
177 		else
178 		{
179 			if(!c->rd->to_render())
180 			{
181 				c->rd->to_render = FBool(& to_render_fbool);
182 				c->rd->to_render = true;
183 				to_render.push_back(c);
184 			}
185 		}
186 	} while (!que.empty());
187 }
188 
189 
ConvertFrustumView2World(vcg::Point4f * fv,vcg::Point3f * fw)190 void OCME::ConvertFrustumView2World(vcg::Point4f * fv,vcg::Point3f * fw){
191 	vcg::Point4f p4;
192 	vcg::Matrix44f mm_inv,pm_inv;
193 	mm_inv = vcg::Inverse(mm);
194 	pm_inv = vcg::Inverse(pm);
195 
196 	//  bring the canonical view frustum in world space
197 	for(int i = 0 ; i <  8; ++i){
198 		 p4 =  (mm_inv * pm_inv * fv[i]).HomoNormalize()   ;
199 		 memcpy( &fw[i][0],  &p4[0], sizeof(float) * 3);
200 	}
201 }
202 
Select(std::vector<Cell * > & selected)203 void OCME::Select(std::vector<Cell*>  & selected){
204 		RAssert(MemDbg::CheckHeap(1));
205 		/* get the viewing parameters */
206 		glGetFloatv(GL_MODELVIEW_MATRIX,&mm[0][0]);
207 		vcg::Transpose(mm);
208 
209 		glGetFloatv(GL_PROJECTION_MATRIX,&pm[0][0]);
210 		vcg::Transpose(pm);
211 
212 		glGetIntegerv(GL_VIEWPORT,&vp[0]);
213 		ConvertFrustumView2World(this->sel_corners,this->sel_frustum);
214 
215 		std::vector<std::pair<float,Cell*> > selected_dist;
216 		float dist;
217 		for(unsigned int i = 0; i < cells_to_render.size(); ++i)
218 				if(IsInFrustum(cells_to_render[i],sel_frustum,dist,false))
219 					selected_dist.push_back(make_pair<float,Cell*>(dist,cells_to_render[i]));
220 		std::sort(selected_dist.begin(),selected_dist.end());
221 		for(unsigned int i = 0; i < selected_dist.size();++i)
222 			selected.push_back(selected_dist[i].second);
223 }
DeSelect(std::vector<Cell * > & selected)224 void OCME::DeSelect(std::vector<Cell*>  & selected){
225 }
226 
Render(int impostorRenderMode)227 void OCME::Render(int impostorRenderMode){
228 	bool useSplatting = (impostorRenderMode==0);
229 	bool useBox = (impostorRenderMode==2);
230 
231 	render_mutex.lock();
232 	RAssert(MemDbg::CheckHeap(1));
233 
234 	vcg::Color4b c;
235 
236 
237 	/* increase mark */
238 	++to_render_fbool;
239 
240 	/* get the viewing paramters */
241 	glGetFloatv(GL_MODELVIEW_MATRIX,&mm[0][0]);
242 	vcg::Transpose(mm);
243 
244 	glGetFloatv(GL_PROJECTION_MATRIX,&pm[0][0]);
245 	vcg::Transpose(pm);
246 
247 	glGetIntegerv(GL_VIEWPORT,&vp[0]);
248 
249 	/* update the frustum in world space */
250 	ConvertFrustumView2World(corners,this->frustum);
251 
252 	if(renderParams.visitOn){
253 		cells_to_render.clear();
254 		Visit(cells_to_render);
255 	}
256 	RAssert(MemDbg::CheckHeap(1));
257 
258 	if(!renderParams.only_impostors){
259 		for(unsigned int i = 0; i < cells_to_render.size(); ++i)
260 			if(cells_to_render[i]->face->Size())
261 				NeedCell(cells_to_render[i]);
262 
263 		stat.cells_to_render = cells_to_render.size();
264 
265 	}
266 
267 	RAssert(MemDbg::CheckHeap(1));
268  	::RemoveDuplicates(cells_to_render);
269 	std::vector<Impostor*> impostor_to_render;
270 	std::vector< std::vector<vcg::Point3f> *				>  positions;
271 	std::vector< std::vector<vcg::Point3f> *				>  normals;
272 	std::vector< std::vector<vcg::Point3<unsigned char> > *	>  colors;
273 	std::vector<float>    radiuses;
274 
275 	for(unsigned int i = 0; i < cells_to_render.size(); ++i)
276           if(!cells_to_render[i]->generic_bool())
277 		  { // generic_bool() == the cell is taken in editing
278           if(cells_to_render[i]->rd->renderCacheToken && cells_to_render[i]->rd->renderCacheToken->lock() )
279 		 {
280 				// c = c.Scatter ( 32,COff(cells_to_render[i]->key.h) );
281 				//glColor ( c );
282 
283 				default_renderer.m = &cells_to_render[i]->rd->Mesh();
284 
285 				if(vcg::tri::HasPerVertexColor(cells_to_render[i]->rd->Mesh()))
286 	//					default_renderer.Draw<vcg::GLW::DMPoints , vcg::GLW::CMPerVert, vcg::GLW::TMNone>();
287 					default_renderer.Draw<vcg::GLW::DMFlat , vcg::GLW::CMPerVert, vcg::GLW::TMNone>();
288 	//				default_renderer.DrawPointsBase<vcg::GLW::NMPerVert,vcg::GLW::CMPerVert>();
289 				else
290 //					default_renderer.Draw<vcg::GLW::DMPoints,vcg::GLW::CMLast,vcg::GLW::TMNone>();
291 					default_renderer.Draw<vcg::GLW::DMFlat,vcg::GLW::CMNone,vcg::GLW::TMNone>();
292 
293 				cells_to_render[i]->rd->renderCacheToken->unlock();
294 			}
295 		 else
296 		  {
297 			  if(!useSplatting){
298 				  if(useBox)
299 					  DrawCellSel(cells_to_render[i]->key,3);
300 				  else
301 					cells_to_render[i]->impostor->Render( 0);
302 			  }
303 			  else{
304 				  // impostor_to_render.push_back(cells_to_render[i]->impostor);
305 				  positions.push_back(&cells_to_render[i]->impostor->positionsV);
306 				  normals.push_back(&cells_to_render[i]->impostor->normalsV);
307 				  colors.push_back(&cells_to_render[i]->impostor->colorsV);
308 				  radiuses.push_back( CS( cells_to_render[i]->key.h)/Impostor::Gridsize());
309 			  }
310 			}
311 	}
312 
313 	 //for(std::vector<Impostor *  > :: iterator  i =impostor_to_render.begin(); i != impostor_to_render.end();++i)
314 		// (*i)->Render(this->renderParams.render_subcells);
315 	 if(useSplatting)
316 	 {
317 		 glPushAttrib(GL_ALL_ATTRIB_BITS);
318                  splat_renderer.Render(positions,normals,colors,radiuses,vcg::GLW::CMPerMesh,
319                          vcg::GLW::TMNone);
320 		 glPopAttrib();
321 	 }
322 
323 	 renderCache.controller.updatePriorities();
324 
325 	 render_mutex.unlock();
326  }
327 
328 
NeedCell(Cell * c)329 void OCME::NeedCell(Cell * c){
330 	this->renderCache.Req(c,c->rd->priority);
331 }
332 
StopAndFlushRendering()333 void OCME::StopAndFlushRendering(){
334 		render_mutex.lock();
335 		this->cells_to_render.clear();
336 		this->renderCache.controller.pause();
337 }
StartRendering()338 void OCME::StartRendering(){
339 		render_mutex.unlock();
340 }
341