Exemplo n.º 1
0
class Viewer(object):
    def __init__(self):
        """ Initialize the viewer. """
        self.init_interface()
        self.init_opengl()
        self.init_scene()
        self.init_interaction()
        init_primitives()

    def init_interface(self):
        """ initialize the window and register the render function """
        glutInit()
        glutInitWindowSize(640, 480)
        glutCreateWindow("3D Modeller")
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
        glutDisplayFunc(self.render)

    def init_interaction(self):
        """ init user interaction and callbacks """
        self.interaction = Interaction()
        self.interaction.register_callback('pick', self.pick)
        self.interaction.register_callback('move', self.move)
        self.interaction.register_callback('place', self.place)
        self.interaction.register_callback('rotate_color', self.rotate_color)
        self.interaction.register_callback('scale', self.scale)

    def init_scene(self):
        """ initialize the scene object and initial scene """
        self.scene = Scene()
        self.initial_scene()

    def init_opengl(self):
        """ initialize the opengl settings to render the scene """
        self.inverseModelView = numpy.identity(4)
        self.modelView = numpy.identity(4)

        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)

        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_COLOR_MATERIAL)
        glClearColor(1.0, 1.0, 1.0, 0.0)

    def main_loop(self):
        glutMainLoop()

    def render(self):
        """ The render pass for the scene """
        self.init_view()

        # Enable lighting and color
        glEnable(GL_LIGHTING)

        glClearColor(0.4, 0.4, 0.4, 0.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Load the modelview matrix from the current state of the trackball
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        loc = self.interaction.translation
        glTranslated(-loc[0], -loc[1], -loc[2])
        glMultMatrixf(self.interaction.trackball.matrix)

        # store the inverse of the current modelview.
        currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
        self.modelView = numpy.transpose(currentModelView)
        self.inverseModelView = inv(numpy.transpose(currentModelView))

        # render the scene. This will call the render function for each object in the scene
        self.scene.render()

        # draw the grid
        glDisable(GL_LIGHTING)
        glCallList(G_OBJ_PLANE)
        glPopMatrix()

        # flush the buffers so that the scene can be drawn
        glFlush()

    def init_view(self):
        """ initialize the projection matrix """
        xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)
        aspect_ratio = float(xSize) / float(ySize)

        # load the projection matrix. Always the same
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

        glViewport(0, 0, xSize, ySize)
        gluPerspective(70, aspect_ratio, 0.1, 1000.0)
        glTranslated(0, 0, -15)

    def initial_scene(self):
        cube_node = Cube()
        cube_node.translate(2, 0, 2)
        cube_node.color_index = 2
        self.scene.add_node(cube_node)

        sphere_node = Sphere()
        sphere_node.translate(-2, 0, 2)
        sphere_node.color_index = 3
        self.scene.add_node(sphere_node)

        sphere_node_2 = Sphere()
        sphere_node_2.translate(-2, 0, -2)
        sphere_node_2.color_index = 1
        self.scene.add_node(sphere_node_2)

    def get_ray(self, x, y):
        """ Generate a ray beginning at the near plane, in the direction that the x, y coordinates are facing
            Consumes: x, y coordinates of mouse on screen
            Return: start, direction of the ray """
        self.init_view()

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # get two points on the line.
        start = numpy.array(gluUnProject(x, y, 0.001))
        end = numpy.array(gluUnProject(x, y, 0.999))

        # convert those points into a ray
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)

    def pick(self, x, y):
        """ Execute pick of an object. Selects an object in the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.pick(start, direction, self.modelView)

    def move(self, x, y):
        """ Execute a move command on the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.move(start, direction, self.inverseModelView)

    def place(self, shape, x, y):
        """ Execute a placement of a new primitive into the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def rotate_color(self, forward):
        """ Rotate the color of the selected Node. Boolean 'forward' indicates direction of rotation. """
        self.scene.rotate_color(forward)

    def scale(self, up):
        """ Scale the selected Node. Boolean up indicates scaling larger."""
        self.scene.scale(up)
Exemplo n.º 2
0
class Viewer(object):
    def __init__(self):
        """ Initialize the viewer. """
        self.init_interface()
        self.init_opengl()
        self.init_scene()
        self.init_interaction()
        init_primitives()

    def init_interface(self):
        """ initialize the window and register the render function """
        glutInit()
        glutInitWindowSize(640, 480)
        glutCreateWindow("3D Modeller")
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
        glutDisplayFunc(self.render)

    def init_interaction(self):
        """ init user interaction and callbacks """
        self.interaction = Interaction()
        self.interaction.register_callback('pick', self.pick)
        self.interaction.register_callback('move', self.move)
        self.interaction.register_callback('place', self.place)
        self.interaction.register_callback('rotate_color', self.rotate_color)
        self.interaction.register_callback('scale', self.scale)

    def init_scene(self):
        """ initialize the scene object and initial scene """
        self.scene = Scene()
        self.initial_scene()

    def init_opengl(self):
        """ initialize the opengl settings to render the scene """
        self.inverseModelView = numpy.identity(4)
        self.modelView = numpy.identity(4)

        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)

        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_COLOR_MATERIAL)
        glClearColor(1.0, 1.0, 1.0, 0.0)

    def main_loop(self):
        glutMainLoop()

    def render(self):
        """ The render pass for the scene """
        self.init_view()

        # Enable lighting and color
        glEnable(GL_LIGHTING)

        glClearColor(0.4, 0.4, 0.4, 0.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Load the modelview matrix from the current state of the trackball
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        loc = self.interaction.translation
        glTranslated(-loc[0], -loc[1], -loc[2])
        glMultMatrixf(self.interaction.trackball.matrix)

        # store the inverse of the current modelview.
        currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
        self.modelView = numpy.transpose(currentModelView)
        self.inverseModelView = inv(numpy.transpose(currentModelView))

        # render the scene. This will call the render function for each object in the scene
        self.scene.render()

        # draw the grid
        glDisable(GL_LIGHTING)
        glCallList(G_OBJ_PLANE)
        glPopMatrix()

        # flush the buffers so that the scene can be drawn
        glFlush()

    def init_view(self):
        """ initialize the projection matrix """
        xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)
        aspect_ratio = float(xSize) / float(ySize)

        # load the projection matrix. Always the same
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

        glViewport(0, 0, xSize, ySize)
        gluPerspective(70, aspect_ratio, 0.1, 1000.0)
        glTranslated(0, 0, -15)

    def initial_scene(self):
        cube_node = Cube()
        cube_node.translate(2, 0, 2)
        cube_node.color_index = 2
        self.scene.add_node(cube_node)

        sphere_node = Sphere()
        sphere_node.translate(-2, 0, 2)
        sphere_node.color_index = 3
        self.scene.add_node(sphere_node)

        sphere_node_2 = Sphere()
        sphere_node_2.translate(-2, 0, -2)
        sphere_node_2.color_index = 1
        self.scene.add_node(sphere_node_2)

    def get_ray(self, x, y):
        """ Generate a ray beginning at the near plane, in the direction that the x, y coordinates are facing
            Consumes: x, y coordinates of mouse on screen
            Return: start, direction of the ray """
        self.init_view()

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # get two points on the line.
        start = numpy.array(gluUnProject(x, y, 0.001))
        end = numpy.array(gluUnProject(x, y, 0.999))

        # convert those points into a ray
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)

    def pick(self, x, y):
        """ Execute pick of an object. Selects an object in the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.pick(start, direction, self.modelView)

    def move(self, x, y):
        """ Execute a move command on the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.move(start, direction, self.inverseModelView)

    def place(self, shape, x, y):
        """ Execute a placement of a new primitive into the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def rotate_color(self, forward):
        """ Rotate the color of the selected Node. Boolean 'forward' indicates direction of rotation. """
        self.scene.rotate_color(forward)

    def scale(self, up):
        """ Scale the selected Node. Boolean up indicates scaling larger."""
        self.scene.scale(up)
Exemplo n.º 3
0
class Viewer(object):
    def __init__(self):
        """ Initialize the viewer. """
        #初始化接口,创建窗口并注册渲染函数
        self.init_interface()
        #初始化opengl的配置
        self.init_opengl()
        #初始化3d场景
        self.init_scene()
        #初始化交互操作相关的代码
        self.init_interaction()
        init_primitives()

    def init_interface(self):
        """ 初始化窗口并注册渲染函数 """
        glutInit()
        glutInitWindowSize(640, 480)
        glutCreateWindow(b"3D Modeller")
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
        #注册窗口渲染函数
        glutDisplayFunc(self.render)

    def init_opengl(self):
        """ 初始化opengl的配置 """
        #模型视图矩阵
        self.inverseModelView = numpy.identity(4)
        #模型视图矩阵的逆矩阵
        self.modelView = numpy.identity(4)

        #开启剔除操作效果
        glEnable(GL_CULL_FACE)
        #取消对多边形背面进行渲染的计算(看不到的部分不渲染)
        glCullFace(GL_BACK)
        #开启深度测试
        glEnable(GL_DEPTH_TEST)
        #测试是否被遮挡,被遮挡的物体不予渲染
        glDepthFunc(GL_LESS)
        #启用0号光源
        glEnable(GL_LIGHT0)
        #设置光源的位置
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))
        #设置光源的照射方向
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))
        #设置材质颜色
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_COLOR_MATERIAL)
        #设置清屏的颜色
        glClearColor(0.4, 0.4, 0.4, 0.0)

    def init_scene(self):
        #创建一个场景实例
        self.scene = Scene()
        #初始化场景内的对象
        self.create_sample_scene()

    def create_sample_scene(self):
        '''
        cube_node = Cube()
        cube_node.translate(2, 2, 2)
        cube_node.color_index = 1
        self.scene.add_node(cube_node)

        sphere_node = Sphere()
        sphere_node.translate(2, 0, 2)
        sphere_node.color_index = 3
        self.scene.add_node(sphere_node)

        hierarchical_node = SnowFigure()
        hierarchical_node.translate(-2, 0, -2)
        self.scene.add_node(hierarchical_node)

        three_pyramid = ThreePyramid()
        three_pyramid.translate(0,10,0)
        three_pyramid.scale(4)
        three_pyramid.color_index=5
        self.scene.add_node(three_pyramid)
        '''
        man = Man()
        man.translate(0, 0, 0)
        man.scale(8)
        man.color_index = 1
        self.scene.add_node(man)

    def init_interaction(self):
        self.interaction = Interaction()
        self.interaction.register_callback('pick', self.pick)
        self.interaction.register_callback('move', self.move)
        self.interaction.register_callback('place', self.place)
        self.interaction.register_callback('rotate_color', self.rotate_color)
        self.interaction.register_callback('scale', self.scale)

    def pick(self, x, y):
        """ 是否被选中以及哪一个被选中交由Scene下的pick处理 """
        start, direction = self.get_ray(x, y)
        self.scene.pick(start, direction, self.modelView)

    def move(self, x, y):
        start, direction = self.get_ray(x, y)
        self.scene.move_selected(start, direction, self.inverseModelView)

    def place(self, shape, x, y):
        start, direction = self.get_ray(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def rotate_color(self, forward):
        """ 更改选中节点的颜色 """
        pass

    def scale(self, up):
        """ 改变选中节点的大小 """
        pass

    def main_loop(self):
        #程序主循环开始
        glutMainLoop()

    def render(self):
        #初始化投影矩阵
        self.init_view()

        #启动光照
        glEnable(GL_LIGHTING)
        #清空颜色缓存与深度缓存
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        #设置模型视图矩阵,这节课先用单位矩阵就行了。
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        glMultMatrixf(self.interaction.trackball.matrix)

        # 存储ModelView矩阵与其逆矩阵之后做坐标系转换用
        currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
        self.modelView = numpy.transpose(currentModelView)
        self.inverseModelView = inv(numpy.transpose(currentModelView))
        #渲染场景
        self.scene.render()

        #每次渲染后复位光照状态
        glDisable(GL_LIGHTING)
        glCallList(G_OBJ_PLANE)
        glPopMatrix()
        #把数据刷新到显存上
        glFlush()

    def init_view(self):
        """ 初始化投影矩阵 """
        xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)
        #得到屏幕宽高比
        aspect_ratio = float(xSize) / float(ySize)

        #设置投影矩阵
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

        #设置视口,应与窗口重合
        glViewport(0, 0, xSize, ySize)
        #设置透视,摄像机上下视野幅度70度
        #视野范围到距离摄像机1000个单位为止。
        gluPerspective(70, aspect_ratio, 0.1, 1000.0)
        #摄像机镜头从原点后退15个单位
        glTranslated(0, 0, -15)

    def get_ray(self, x, y):
        """
        返回光源和激光方向
        """
        self.init_view()

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # 得到激光的起始点
        start = numpy.array(gluUnProject(x, y, 0.001))
        end = numpy.array(gluUnProject(x, y, 0.999))

        # 得到激光的方向
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)
Exemplo n.º 4
0
class Viewer(object):
	def __init__(self):
		self.init_interface()
		self.init_opengl()
		self.init_scene()
		self.init_interaction()
		init_primitives()
		
	def init_nogrid(self):
		self.init_interface()
		self.init_opengl()
		self.init_scene()
		self.init_interaction()
		init_primitives_nogrid()

	def init_interface(self):
		global winid
		glutInit()
		glutInitWindowSize(640, 480)
		glutInitWindowPosition(100,100)
		winid = glutCreateWindow("3D Modeller")
		glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA)
		glutDisplayFunc(self.render)

	def init_opengl(self):
		self.inverseModelView = numpy.identity(4)
		self.modelView = numpy.identity(4)

		glEnable(GL_CULL_FACE)
		glCullFace(GL_BACK)
		glEnable(GL_DEPTH_TEST)
		glDepthFunc(GL_LESS)
		glEnable(GL_LIGHT0)

		glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0,0,1,0))
		glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0,0,-1))
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
		glEnable(GL_COLOR_MATERIAL)

		glClearColor(0.5, 0.5, 0.5, 0.0)

	def init_scene(self):
		self.scene = Scene()
		self.create_sample_scene()

	def create_sample_scene(self):
		cube_node = Cube()
		cube_node.translate(2, 0, 2)
		cube_node.color_index = 1
		self.scene.add_node(cube_node)

		sphere_node = Sphere()
		sphere_node.color_index = 2
		sphere_node.translate(2,2,0)
		#sphere_node.scale(4)
		self.scene.add_node(sphere_node)
		
		cylinder_node = Cylinder()
		cylinder_node.color_index = 3
		cylinder_node.translate(0,-2,2)
		self.scene.add_node(cylinder_node)
		
		tetrahedron_node = Tetrahedron()
		tetrahedron_node.color_index = 4
		tetrahedron_node.translate(2,-2,-2)
		self.scene.add_node(tetrahedron_node)

		hierarchical_node = SnowFigure()
		hierarchical_node.translate(-2, 0, -2)
		#hierarchical_node.scale(2)
		self.scene.add_node(hierarchical_node)

	def init_interaction(self):
		self.interaction = Interaction()
		self.interaction.register_callback('pick', self.pick)
		self.interaction.register_callback('move', self.move)
		self.interaction.register_callback('place', self.place)
		self.interaction.register_callback('rotate_color', self.rotate_color)
		self.interaction.register_callback('scale', self.scale)
		self.interaction.register_callback('close', self.close)
		self.interaction.register_callback('reset', self.reset)
		self.interaction.register_callback('nogrid', self.nogrid)

	def pick(self, x, y):
		start, direction = self.get_ray(x, y)
		self.scene.pick(start, direction, self.modelView)

	def move(self, x, y):
		start, direction = self.get_ray(x, y)
		self.scene.move_selected(start, direction, self.inverseModelView)

	def place(self, shape, x, y):
		start, direction = self.get_ray(x, y)
		self.scene.place(shape, start, direction, self.inverseModelView)

	def rotate_color(self, forward):
		self.scene.rotate_selected_color(forward)

	def scale(self, up):
		self.scene.scale_selected(up)

	def main_loop(self):
		glutMainLoop()

	def render(self):
		self.init_view()

		glEnable(GL_LIGHTING)
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

		glMatrixMode(GL_MODELVIEW)
		glPushMatrix()
		glLoadIdentity()
		loc = self.interaction.translation
		glTranslated(loc[0], loc[1], loc[2])
		glMultMatrixf(self.interaction.trackball.matrix)

		currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
		self.modelView = numpy.transpose(currentModelView)
		self.inverseModelView = inv(numpy.transpose(currentModelView))

		self.scene.render()

		glDisable(GL_LIGHTING)
		glCallList(G_OBJ_PLANE)
		glPopMatrix()

		glFlush()

	def init_view(self):
		xSize, ySize = glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT)
		aspect_ratio = float(xSize) / float(ySize)

		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()

		glViewport(0, 0, xSize, ySize)
		gluPerspective(70, aspect_ratio, 0.1, 1000.0)
		glTranslate(0, 0, -15)

	def get_ray(self, x, y):
		self.init_view()

		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()

		start = numpy.array(gluUnProject(x, y, 0.001))
		end = numpy.array(gluUnProject(x, y, 0.999))

		direction = end - start
		direction = direction / norm(direction)

		return (start, direction)

	def close(self):
		global winid
		glutDestroyWindow(winid)
		sys.exit()

	def reset(self):
		self.init_scene()
		
	def nogrid(self, grid):
		global winid
		glutDestroyWindow(winid)
		if grid:
			self.__init__()
		else:
			self.init_nogrid()
Exemplo n.º 5
0
class Viewer(object):
    def __init__(self):
        """ Initialize the viewer. """

        self.init_interface()

        self.init_opengl()
        self.init_scene()

        self.init_interaction()
        init_primitives()
        make_plane()

    def init_interface(self):

        glutInit()
        glutInitWindowSize(640, 480)
        glutCreateWindow("3D Modeller")
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
        #register render function
        glutDisplayFunc(self.render)

    def init_opengl(self):

        #model view matrix
        self.inverseModelView = numpy.identity(4)
        #its anti-matrix
        self.modelView = numpy.identity(4)

        #open tichu effect
        glEnable(GL_CULL_FACE)
        #to not rend invisible part
        glCullFace(GL_BACK)
        #open depth test
        glEnable(GL_DEPTH_TEST)
        #objects being covered ot to rend
        glDepthFunc(GL_LESS)
        #open light 0
        glEnable(GL_LIGHT0)
        #to set the position of light
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))
        #to set the direction that light sheds at
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))
        #to set material color
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_COLOR_MATERIAL)
        #set the color of a clear-screen
        glClearColor(0.4, 0.4, 0.4, 0.0)

    def init_interaction(self):
        self.interaction = Interaction()
        self.interaction.register_callback('pick', self.pick)
        self.interaction.register_callback('move', self.move)
        self.interaction.register_callback('place', self.place)
        self.interaction.register_callback('rotate_color', self.rotate_color)
        self.interaction.register_callback('scale', self.scale)

    def move(self, x, y):
        #move the chosen point
        start, direction = self.get_ray(x, y)
        self.scene.move_selected(start, direction, self.inverseModelView)

    def place(self, shape, x, y):
        """ put a new node at the mouse's location"""
        start, direction = self.get_ray(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def rotate_color(self, forward):
        """change the color of chosen node"""
        pass

    def scale(self, up):
        """change the size of the chosen node"""
        pass

    def main_loop(self):
        glutMainLoop()

    def render(self):
        #init shadow matrix
        self.init_view()

        #open light
        glEnable(GL_LIGHTING)

        #clear color and depth caches
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        #set model view matrix(danwei matrix is ok)
        #set trackball's rotate matrix as Modelview
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()

        #replace now-matrix with hengdeng matrix
        glLoadIdentity()
        glMultMatrixf(self.interaction.trackball.matrix)

        #save Modelview matrix, later change system with anti-matrix
        currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
        self.modelView = numpy.transpose(currentModelView)
        self.inverseModelView = inv(numpy.transpose(currentModelView))

        #rend the scene
        self.scene.render()

        #after each shadow , huifu light state
        glDisable(GL_LIGHTING)
        glPopMatrix()

        glFlush()

    def init_view(self):
        """init shadow matrix"""
        xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)
        #get screen's kuangaobi
        aspect_ratio = float(xSize) / float(ySize)

        #set shadow matrix
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

        #set viewport, should be chonghe with window
        glViewport(0, 0, xSize, ySize)

        #set toushi, eyesight width 70 degree, 1000 distance fron camare
        gluPerspective(70, aspect_ratio, 0.1, 1000.0)

        #jinftou back 15 distances from o
        glTranslated(0, 0, -15)

    def init_scene(self):
        self.scene = Scene()
        self.create_sample_scene()

    def create_sample_scene(self):
        cube_node = Cube()
        cube_node.translate(2, 0, 2)
        cube_node.color_index = 1
        self.scene.add_node(cube_node)

        # to create a ball
        sphere_node = Sphere()
        # to set the ball's color
        sphere_node.color_index = 3
        sphere_node.translate(-2, 0, 2)

        #to put the ball in the scene.Default middle of view
        self.scene.add_node(sphere_node)

        #to add a snowman
        hierarchical_node = SnowFigure()
        hierarchical_node.translate(-2, 0, -2)
        self.scene.add_node(hierarchical_node)

        init_primitives()

    def get_ray(self, x, y):
        self.init_view()

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        start = numpy.array(gluUnProject(x, y, 0.001))
        end = numpy.array(gluUnProject(x, y, 0.999))
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)

    def pick(self, x, y):

        start, direction = self.get_ray(x, y)
        self.scene.pick(start, direction, self.modelView)
Exemplo n.º 6
0
class Viewer(object):
    def __init__(self):
        """ Initialize the viewer. """
        self.init_interface()
        self.init_opengl()
        self.init_scene()
        self.init_camera()
        self.init_interaction()
        init_primitives() # makes lists of primitive objects defined
        # self.rosnode = rospy.init_node('viewer', anonymous=False)
        # self.rossub = rospy.Subscriber('/viewer/posetopic', PoseStamped, self.roscallback)
        # self.rate = rospy.Rate(100.);

    # def roscallback(self,data):
    #     node = self.scene.get_node(data.header.frame_id)
    #     # embed()
    #     if not node == None:
    #         node.set_pose(data.pose.position.x,data.pose.position.y,data.pose.position.z,
    #             data.pose.orientation.w,data.pose.orientation.x,data.pose.orientation.y,data.pose.orientation.z)
    #         px,py,pz = GroundtoGraphics((data.pose.position.x,data.pose.position.y,data.pose.position.z))
    #         self.interaction.LookAttarget = [px,py,pz];
    #         glutPostRedisplay()

    def init_interface(self):
        """ initialize the window and register the render function """
        glutInit()
        glutInitWindowSize(640, 480)
        glutCreateWindow("3D Modeller")
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
        glutDisplayFunc(self.render) # top level render call
        glutIdleFunc(self.ROSsleep)

    # def ROSsleep(self):
    #     self.rate.sleep()

    def init_opengl(self):
        """ initialize the opengl settings to render the scene """
        self.inverseModelView = numpy.identity(4)
        self.modelView = numpy.identity(4)

        glEnable(GL_CULL_FACE)
        glCullFace(GL_BACK)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)

        glEnable(GL_LIGHT0)
        # put some initial lighting
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))  
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable(GL_COLOR_MATERIAL)
        glClearColor(0.4, 0.4, 0.4, 0.0)

    def init_camera(self):
        self.Camera = Camera();
        self.Camera.CameraMode = 'Trackball';       

    def init_scene(self):
        """ initialize the scene object and initial scene """
        self.scene = Scene()
        # self.create_sample_scene()

    def create_sample_scene(self):
        cube_node = Cube()
        cube_node.translate(2, 0, 2)
        cube_node.color_index = 1
        self.scene.add_node(cube_node)

        sphere_node = Sphere()
        sphere_node.translate(-2, 0, 2)
        sphere_node.color_index = 3
        self.scene.add_node(sphere_node)

        hierarchical_node = SnowFigure()
        hierarchical_node.translate(-2, 0, -2)
        self.scene.add_node(hierarchical_node)

    def create_scene(self):
        self.create_sample_scene();
        
    def init_interaction(self):
        """ init user interaction and callbacks """
        self.interaction = Interaction()
        self.interaction.register_callback('pick', self.pick)
        self.interaction.register_callback('move', self.move)
        self.interaction.register_callback('place', self.place)
        self.interaction.register_callback('rotate_color', self.rotate_color)
        self.interaction.register_callback('scale', self.scale)
        self.interaction.register_callback('close',self.close)
        self.interaction.register_callback('setCameraMode',self.setCameraMode)

    def main_loop(self):
        glutMainLoop()

    def render(self):
        """ The render pass for the scene """
        self.init_view()

        glEnable(GL_LIGHTING)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Load the modelview matrix from the current state of the trackball
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        tar = self.interaction.LookAttarget;
        self.Camera.target = (tar[0],tar[1],tar[2])
        if self.Camera.CameraMode == 'Trackball':
            loc = self.Camera.position;
            #Camera.position
            glTranslated(-loc[0], -loc[1], -loc[2])
            glMultMatrixf(self.interaction.trackball.matrix)
        elif self.Camera.CameraMode == 'LookAt':
            # embed()
            self.Camera.point()
        elif self.Camera.CameraMode == 'LookAtFollow':
            self.Camera.follow()
            self.Camera.point()
        else:
            glMultMatrixf(self.interaction.trackball.matrix) # by default revert to trackball if mode is set incorrectly

        # store the inverse of the current modelview.
        currentModelView = numpy.array(glGetFloatv(GL_MODELVIEW_MATRIX))
        self.modelView = numpy.transpose(currentModelView)
        self.inverseModelView = inv(numpy.transpose(currentModelView))

        # render the scene. This will call the render function for each object in the scene
        self.scene.render()

        # draw the grid
        glDisable(GL_LIGHTING)
        glCallList(G_OBJ_PLANE)
        glPopMatrix()

        # flush the buffers so that the scene can be drawn
        glFlush()

    def init_view(self):
        """ initialize the projection matrix """
        # xSize, ySize = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)
        # aspect_ratio = float(xSize) / float(ySize)
        self.Camera.ViewportSetup()
        # load the projection matrix. Always the same
        # glMatrixMode(GL_PROJECTION)
        # glLoadIdentity()

        # glViewport(0, 0, xSize, ySize)
        # gluPerspective(70, aspect_ratio, 0.1, 1000.0)
        # glTranslated(0, 0, -15)

    def get_ray(self, x, y):
        """ Generate a ray beginning at the near plane, in the direction that the x, y coordinates are facing
            Consumes: x, y coordinates of mouse on screen
            Return: start, direction of the ray """
        self.init_view()

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # get two points on the line.
        start = numpy.array(gluUnProject(x, y, 0.001))
        end = numpy.array(gluUnProject(x, y, 0.999))

        # convert those points into a ray
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)

    def pick(self, x, y):
        """ Execute pick of an object. Selects an object in the scene. """
        start, direction = self.get_ray(x, y)
        self.interaction.node_selected = self.scene.pick(start, direction, self.modelView)

    def place(self, shape, x, y):
        """ Execute a placement of a new primitive into the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def move(self, x, y):
        """ Execute a move command on the scene. """
        start, direction = self.get_ray(x, y)
        self.scene.move_selected(start, direction, self.inverseModelView)

    # def ROSHandler(self,ind,pose):
    #     self.scene.set_pose(ind,pose)

    def rotate_color(self, forward):
        """ Rotate the color of the selected Node. Boolean 'forward' indicates direction of rotation. """
        self.scene.rotate_selected_color(forward)

    def scale(self, up):
        """ Scale the selected Node. Boolean up indicates scaling larger."""
        self.scene.scale_selected(up)

    def setCameraMode(self,mode):
        self.Camera.CameraMode = mode;

    def close(self):
        # embed()
        glutDestroyWindow(glutGetWindow())
        # embed()
        sys.exit() # How do I clean up memory resources before exiting? Is it needed, or handled by destroywindow