Exemplo n.º 1
0
GLboolean select_segment_in_viewscreen(const GLfloat *a, const GLfloat *b) {
	/*
	 Return True is the segment is fully inside viewscreen
	 or cross the viewscreen
	 Viewscreen is  (-1,-1)(+1,+1) 
	 False if completly outside
	*/
	// Fast either point inside viewport
	if (select_point_in_viewscreen(a)) return true;
	if (select_point_in_viewscreen(b)) return true;
	// Using Liang-Barsky algorithm
	GLfloat vx, vy;
	vx=b[0]-a[0];
	vy=b[1]-a[1];
	GLfloat p[4] = {-vx, vx, -vy, vy};
	GLfloat q[4] = {a[0] + 1.0f, +1.0f - a[0], a[1] + 1.0f, +1.0f - a[1]};
	GLfloat u1 = 0.0f;
	GLfloat u2 = 1.0f;

	for (int i=0; i<4; i++) {
		if (p[i] == 0.0f) {
			if (q[i]<0.0f)
				return false;
		} else {
			GLfloat t =q[i] / p[i];
			if (p[i]<0.0) { 
                if(t>u2) return false;
                else if(u1<t)
                    u1 = t;
            }
			else if (p[i]>0.0) {
                if(t<u1) return false;
                else if (u2>t)
                    u2 = t;
            }
		}
	}
	return true;
}
Exemplo n.º 2
0
void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count, GLenum type, GLvoid * indices) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;

	GLushort *sind = (GLushort*)((type==GL_UNSIGNED_SHORT)?indices:NULL);
	GLuint *iind = (GLuint*)((type==GL_UNSIGNED_INT)?indices:NULL);

	GLsizei min, max;
	if(sind)
		getminmax_indices_us(sind, &max, &min, count);
	else
		getminmax_indices_ui(iind, &max, &min, count);
    max++;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 4, 0, max);
	GLfloat zmin=1e10f, zmax=-10e6f;
	int found = 0;
	for (int i=min; i<max; i++) {
		select_transform(vert+i*4);
		ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
	}

	#define FOUND()	{ 				\
		found = 1;					\
		glstate->selectbuf.hit = 1; \
		}

	if(sind) {
		for (int i=0; i<count; i++) {
			switch (mode) {
				case GL_POINTS:
					if (select_point_in_viewscreen(vert+sind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+sind[i]*4);
						FOUND();
					}
					break;
				case GL_LINES:
					if (i%2==1) {
						if (select_segment_in_viewscreen(vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_LINE_STRIP:
				case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
					if (i>0) {
						if (select_segment_in_viewscreen(vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLES:
					if (i%3==2) {
						if (select_triangle_in_viewscreen(vert+sind[(i-2)]*4, vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_STRIP:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+sind[(i-2)]*4, vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_FAN:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+sind[0]*4, vert+sind[(i-1)]*4, vert+sind[i]*4))
							ZMinMax(&zmin, &zmax, vert+sind[0]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
					}
					break;
				default:
					return;		// Should never go there!
			}
		} 
	} else {
		for (int i=0; i<count; i++) {
			switch (mode) {
				case GL_POINTS:
					if (select_point_in_viewscreen(vert+iind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+iind[i]*4);
						FOUND();
					}
					break;
				case GL_LINES:
					if (i%2==1) {
						if (select_segment_in_viewscreen(vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_LINE_STRIP:
				case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
					if (i>0) {
						if (select_segment_in_viewscreen(vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLES:
					if (i%3==2) {
						if (select_triangle_in_viewscreen(vert+iind[(i-2)]*4, vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_STRIP:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+iind[(i-2)]*4, vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_FAN:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+iind[0]*4, vert+iind[(i-1)]*4, vert+iind[i]*4))
							ZMinMax(&zmin, &zmax, vert+iind[0]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
					}
					break;
				default:
					return;		// Should never go there!
			}
		}
	}
	free(vert);
	if(found) {
		if (zmin<glstate->selectbuf.zmin) 	glstate->selectbuf.zmin=zmin;
		if (zmax>glstate->selectbuf.zmax) 	glstate->selectbuf.zmax=zmax;
	}

	#undef FOUND
}
Exemplo n.º 3
0
void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;
	if (glstate->selectbuf.buffer == NULL) return;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 4, 0, count+first);
	GLfloat zmin=1e10f, zmax=-1e10f;
	int found = 0;

	#define FOUND()	{ 				\
		found = 1;					\
		glstate->selectbuf.hit = 1; \
	}

    // transform the points
	for (int i=first; i<count+first; i++) {
		select_transform(vert+i*4);
		ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
    }
    // intersect with screen now
    GLfloat *vert2 = vert + first*4;
	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert2+i*4)) {
					ZMinMax(&zmin, &zmax, vert+i*4);
					FOUND();
				}
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_LINE_STRIP:
			case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
				if (i>0) {
					if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-2)*4);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-2)*4);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	if(found) {
		if (zmin<glstate->selectbuf.zmin) 	glstate->selectbuf.zmin=zmin;
		if (zmax>glstate->selectbuf.zmax) 	glstate->selectbuf.zmax=zmax;
	}
	#undef FOUND
}
Exemplo n.º 4
0
void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count, GLenum type, GLvoid * indices) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;

	GLushort *ind = (GLushort*)indices;

	GLsizei min, max;
	getminmax_indices(indices, &max, &min, count);
    max++;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 3, 0, max);
	GLfloat tmp[3];
	init_select();
	GLfloat zmin=1.0f, zmax=0.0f;
	for (int i=min; i<max; i++) {
		select_transform(vert+i*3);
		if (vert[i*3+2]<zmin) zmin=vert[i*3+2];
		if (vert[i*3+2]>zmax) zmax=vert[i*3+2];
	}
	if (zmin<0.0f) zmin = 0.0f;
	if (zmax>1.0f) zmax = 1.0f;

	#define FOUND()	{ 		\
		if (zmin<state.selectbuf.zmin) 	state.selectbuf.zmin=zmin;	\
		if (zmax>state.selectbuf.zmax) 	state.selectbuf.zmax=zmax;	\
		state.selectbuf.hit = 1; \
        free(vert);              \
        return;                  \
		}

	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert+ind[i]*3))
					FOUND();
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_LINE_STRIP:
			case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
				if (i>0) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[0]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	#undef FOUND
}
Exemplo n.º 5
0
void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;
	if (state.selectbuf.buffer == NULL) return;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 3, 0, count+first);
	GLfloat tmp[3];
	GLfloat zmin=1.0f, zmax=0.0f;
	init_select();

	#define FOUND()	{ 		\
		if (zmin<state.selectbuf.zmin) 	state.selectbuf.zmin=zmin;	\
		if (zmax>state.selectbuf.zmax) 	state.selectbuf.zmax=zmax;	\
		state.selectbuf.hit = 1;                        \
        free(vert);         \
        return;                                         \
		}
    // transform the points
	for (int i=first; i<count+first; i++) {
		select_transform(vert+i*3);
		if (vert[i*3+2]<zmin) zmin=vert[i*3+2];
		if (vert[i*3+2]>zmax) zmax=vert[i*3+2];
    }
    // intersect with screen now
    GLfloat *vert2 = vert + first*3;
	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert2+i*3))
					FOUND();
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_LINE_STRIP:
			case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
				if (i>0) {
					if (select_segment_in_viewscreen(vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*3, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*3, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	#undef FOUND
}