def test_tmatrix_mult(): from pyglet_helper.util import Tmatrix, Vertex _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 1] = 1.0 _tmatrix1.matrix[1, 0] = 1.0 _tmatrix1.matrix[0, 0] = 0.0 _tmatrix1.matrix[1, 1] = 0.0 _result = _tmatrix1*_tmatrix1 assert _result.matrix[0, 0] == 1.0 assert _result.matrix[1, 1] == 1.0 assert _result.matrix[0, 1] == 0.0 assert _result.matrix[1, 0] == 0.0 _result = 2.0*_tmatrix1 assert _result.matrix[0, 0] == 0.0 assert _result.matrix[1, 1] == 0.0 assert _result.matrix[0, 1] == 2.0 assert _result.matrix[1, 0] == 2.0 _result = _tmatrix1*2.0 assert _result.matrix[0, 0] == 0.0 assert _result.matrix[1, 1] == 0.0 assert _result.matrix[0, 1] == 2.0 assert _result.matrix[1, 0] == 2.0 _vert = Vertex([0, 1.0, 0, 1]) _result = _tmatrix1*_vert assert _result[0] == 1.0 assert _result[1] == 0.0
def material_matrix(self): """ Creates a transformation matrix for spherical objects :return: the transformation matrix :rtype: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([.5, .5, .5])) scale = self.scale out.scale(scale * (.5 / max(scale.x_component, max(scale.y_component, scale.z_component)))) return out
def material_matrix(self): """ Creates a transformation matrix scaled to the size of the axial object :return: the transformation matrix :return: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([.0005, .5, .5])) out.scale(self.scale * (.999 / max(self.scale.x_component, self.scale.y_component * 2))) out_vector = Vector([0, 1, 0]) out_vector = out_vector.rotate(angle=.5*pi) out = out * out_vector return out
def test_tmatrix_gl_calls(): from pyglet_helper.util import Tmatrix from numpy import zeros, identity # test with a vector _tmatrix1 = Tmatrix() _tmatrix1.gl_load() _tmatrix1.gl_mult() _out_mat = _tmatrix1.gl_modelview_get() assert (_tmatrix1.matrix == _out_mat).all() _out_mat = _tmatrix1.gl_modelview_get() assert (_tmatrix1.matrix == _out_mat).all() _out_mat = _tmatrix1.gl_texture_get() assert (zeros([4, 4]) == _out_mat).all() _out_mat = _tmatrix1.gl_color_get() assert (zeros(4) == _out_mat).all()
def test_tmatrix_inverse(): from pyglet_helper.util import Tmatrix _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 1] = 1.0 _tmatrix1.matrix[1, 0] = 0.0 _tmatrix1.matrix[0, 0] = 0.50 _tmatrix1.matrix[1, 1] = -0.50 _tmatrix1.inverse() assert _tmatrix1.matrix[0, 1] == 4.0 assert _tmatrix1.matrix[0, 0] == 2.0 assert _tmatrix1.matrix[1, 0] == 0.0 assert _tmatrix1.matrix[1, 1] == -2.0
def test_tmatrix_scale(): from pyglet_helper.util import Tmatrix, Vertex _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 0] = 0.0 _tmatrix1.matrix[1, 1] = 0.0 _tmatrix1.matrix[1, 0] = 1.0 _tmatrix1.matrix[0, 1] = 1.0 _vert = Vertex([0, 1.0, 0, 0.5]) _tmatrix1.scale(_vert) assert _tmatrix1.matrix[0, 0] == 0.0 assert _tmatrix1.matrix[1, 1] == 0.0 assert _tmatrix1.matrix[0, 1] == 0.0 assert _tmatrix1.matrix[3, 3] == 0.5
def test_tmatrix_origin(): from pyglet_helper.util import Tmatrix # test with a vector _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 0] = 0.50 _tmatrix1.matrix[1, 1] = 0.0 _tmatrix1.matrix[1, 0] = 2.0 _tmatrix1.matrix[0, 1] = 1.0 _tmatrix1.matrix[3, 0] = 1.0 _outvect = _tmatrix1.origin() assert _outvect[0] == 1.0 assert _outvect[1] == 0.0 assert _outvect[2] == 0.0
def test_tmatrix_mult(): from pyglet_helper.util import Tmatrix, Vertex _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 1] = 1.0 _tmatrix1.matrix[1, 0] = 1.0 _tmatrix1.matrix[0, 0] = 0.0 _tmatrix1.matrix[1, 1] = 0.0 _result = _tmatrix1 * _tmatrix1 assert _result.matrix[0, 0] == 1.0 assert _result.matrix[1, 1] == 1.0 assert _result.matrix[0, 1] == 0.0 assert _result.matrix[1, 0] == 0.0 _result = 2.0 * _tmatrix1 assert _result.matrix[0, 0] == 0.0 assert _result.matrix[1, 1] == 0.0 assert _result.matrix[0, 1] == 2.0 assert _result.matrix[1, 0] == 2.0 _result = _tmatrix1 * 2.0 assert _result.matrix[0, 0] == 0.0 assert _result.matrix[1, 1] == 0.0 assert _result.matrix[0, 1] == 2.0 assert _result.matrix[1, 0] == 2.0 _vert = Vertex([0, 1.0, 0, 1]) _result = _tmatrix1 * _vert assert _result[0] == 1.0 assert _result[1] == 0.0
def test_tmatrix_project(): from pyglet_helper.util import Tmatrix, Vertex _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 0] = 0.0 _tmatrix1.matrix[1, 1] = 0.0 _tmatrix1.matrix[1, 0] = 1.0 _tmatrix1.matrix[0, 1] = 1.0 _vert = Vertex([0, 1.0, 0, 0.5]) _outvert = _tmatrix1.project(_vert) assert _outvert[0] == 1.0 assert _outvert[1] == 0.0
def test_tmatrix_str(): from pyglet_helper.util import Tmatrix # test with a vector _tmatrix1 = Tmatrix() _tmatrix1.matrix[0, 0] = 0.50 _tmatrix1.matrix[1, 1] = 0.0 _tmatrix1.matrix[1, 0] = 2.0 _tmatrix1.matrix[0, 1] = 1.0 _tmatrix1.matrix[3, 0] = 1.0 _out_str = str(_tmatrix1) assert _out_str == "| 0.5 2.0 0.0 1.0|\n| 1.0 0.0 0.0 0.0|\n| 0.0 0.0 " \ "1.0 0.0|\n| 0.0 0.0 0.0 1.0|\n"
def test_tmatrix_times_v(): from pyglet_helper.util import Tmatrix, Vertex, Vector # test with a vector _tmatrix1 = Tmatrix() _vect = Vector([0.0, 1.0, 0.0]) _tmatrix1.matrix[0, 0] = 0.0 _tmatrix1.matrix[1, 1] = 0.0 _tmatrix1.matrix[1, 0] = 1.0 _tmatrix1.matrix[0, 1] = 1.0 _outvect = _tmatrix1.times_v(_vect) assert _outvect[0] == 1.0 assert _outvect[1] == 0.0 # test with a vertex _vert = Vertex([0, 1.0, 0, 0.5]) _outvect = _tmatrix1.times_v(_vert) assert _outvect[0] == 1.0 assert _outvect[1] == 0.0
def material_matrix(self): """ Creates a transformation matrix scaled to the size of the torus :return: the transformation matrix :return: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([.5, .5, .5])) out.scale(Vector([self.radius, self.radius, self.radius]) * (.5 / (self.radius + self.thickness))) return out
def material_matrix(self): """ Creates a transformation matrix for spherical objects :return: the transformation matrix :rtype: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([.5, .5, .5])) scale = self.scale out.scale(scale * (.5 / max( scale.x_component, max(scale.y_component, scale.z_component)))) return out
def material_matrix(self): """ Creates a transformation matrix for pyramid objects :return: the transformation matrix :rtype: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([0, .5, .5])) scale = Vector([self.axis.mag(), self.height, self.width]) out.scale(Vector([self.scale,self.scale,self.scale]) * (1.0 /max(scale.x_component, max(scale.y_component, scale.z_component)))) return out
def material_matrix(self): """ Creates a transformation matrix scaled to the size of the axial object :return: the transformation matrix :return: pyglet_helper.util.Tmatrix """ out = Tmatrix() out.translate(Vector([.0005, .5, .5])) out.scale( self.scale * (.999 / max(self.scale.x_component, self.scale.y_component * 2))) out_vector = Vector([0, 1, 0]) out_vector = out_vector.rotate(angle=.5 * pi) out = out * out_vector return out
def test_tmatrix_init(): from pyglet_helper.util import Tmatrix _tmatrix1 = Tmatrix() _tmatrix1.matrix[2, 3] = 1.0 _tmatrix2 = Tmatrix(_tmatrix1) assert _tmatrix2.matrix[2, 3] == 1.0
def model_world_transform(self, world_scale=0.0, object_scale=Vector([1, 1, 1])): """Performs scale, rotation, translation, and world scale (gcf) transforms in that order. :param world_scale: The global scaling factor. :type world_scale: float :param object_scale: The scaling to applied to this specific object :type object_scale: pyglet_helper.util.Vector :rtype: pyglet_helper.util.Tmatrix :returns: Returns a tmatrix that performs reorientation of the object from model orientation to world (and view) orientation. """ ret = Tmatrix() # A unit vector along the z_axis. z_axis = Vector([0, 0, 1]) if abs(self.axis.dot(self.up_vector) / self.up_vector.mag()**2.0) \ > 0.98: # Then axis and up are in (nearly) the same direction: therefore, # try two other possible directions for the up vector. if abs(self.axis.norm().dot(Vector([-1, 0, 0]))) > 0.98: z_axis = self.axis.cross(Vector([0, 0, 1])).norm() else: z_axis = self.axis.cross(Vector([-1, 0, 0])).norm() else: z_axis = self.axis.cross(self.up_vector).norm() y_axis = z_axis.cross(self.axis).norm() x_axis = self.axis.norm() ret.x_column(x_axis) ret.y_column(y_axis) ret.z_column(z_axis) w_column = world_scale*self.pos ret.w_column(w_column) ret.w_row() ret.scale(object_scale * world_scale, 1) return ret
def render(self, scene): """ Render the arrow on the current view. :param scene: The view to render the model into. :type scene: pyglet_helper.objects.View """ mat = Material() if self.degenerate: return self.init_model(scene) self.color.gl_set(self.opacity) _head_width, _shaft_width, _len, _head_length = \ self.effective_geometry(1.0) if self.mat and self.mat.get_shader_program(): model_material_loc = self.mat.get_shader_program().\ get_uniform_location(scene, "model_material") else: model_material_loc = -1 # Render the shaft and the head in back to front order (the shaft is in # front of the head if axis points away from the camera) shaft = self.axis.dot(scene.camera - (self.pos + self.axis * (1 - _head_length / _len))) < 0 gl.glPushMatrix() self.model_world_transform(scene.gcf).gl_mult() for part in range(0, 2): if part == shaft: gl.glScaled(_len - _head_length, _shaft_width, _shaft_width) gl.glTranslated(0.5, 0, 0) if model_material_loc >= 0: model_mat = Tmatrix() scale = 1.0 / max(_len, _head_width) _translation_magnitude = (_len - _head_length) * scale *\ 0.5 model_mat.translate( Vector([_translation_magnitude, 0.5, 0.5])) model_mat.scale( Vector([(_len - _head_length), _shaft_width, _shaft_width]) * scale) mat.get_shader_program().\ set_uniform_matrix(scene, model_material_loc, model_mat) scene.box_model.gl_render() gl.glTranslated(-0.5, 0, 0) gl.glScaled(1 / (_len - _head_length), 1 / _shaft_width, 1 / _shaft_width) else: gl.glTranslated(_len - _head_length, 0, 0) gl.glScaled(_head_length, _head_width, _head_width) if model_material_loc >= 0: model_mat = Tmatrix() _scale = 1.0 / max(_len, _head_width) model_mat.translate( Vector([(_len - _head_length) * _scale, 0.5, 0.5])) model_mat.scale( Vector([_head_length, _head_width, _head_width]) * _scale) mat.get_shader_program().\ set_uniform_matrix(scene, model_material_loc, model_mat) scene.pyramid_model.gl_render() gl.glScaled(1 / _head_length, 1 / _head_width, 1 / _head_width) gl.glTranslated(-_len + _head_length, 0, 0) gl.glPopMatrix()
def __init__(self, gcf=1.0, view_width=800, view_height=600, anaglyph=False, coloranaglyph=False, forward_changed=False, gcf_changed=False, lod_adjust=0, tan_hfov_x=0, tan_hfov_y=0, enable_shaders=True, background_color=Rgb()): """ :param gcf: The global scaling factor, a coefficient applied to all objects in the view :type gcf: float :param view_width: The width of the viewport in pixels. :type view_width: int :param view_height: The height of the viewport in pixels. :type view_height: int :param anaglyph: If True, the scene will be rendered in anaglyph stereo mode. :type anaglyph: bool :param coloranaglyph: If True, the scene will be rendered in coloranaglyph stereo mode. :type coloranaglyph: bool :param forward_changed: True if the forward vector changed since the last rending operation. :type forward_changed: bool :param gcf_changed: True if the global scaling factor changed since the last render cycle. :type gcf_changed: bool :param lod_adjust: The level-of-detail. :type lod_adjust: int :param tan_hfov_x: The tangent of half the horizontal field of view. :type tan_hfov_x: int :param tan_hfov_y: The tangent of half the vertical field of view. :type tan_hfov_y: int :param enable_shaders: If True, shader programs will be allowed :type enable_shaders: bool :param background_color: The scene's background color :type background_color: pyglet_helper.util.Rgb """ # The position of the camera in world space. self.camera = Vector() # The direction the camera is pointing - a unit vector. self.forward = Vector() # The center of the scene in world space. self.center = Vector() # The true up direction of the scene in world space. self.up_vector = Vector() self.view_width = view_width self.view_height = view_height self.forward_changed = forward_changed self.gcf = gcf # The vector version of the Global Scaling Factor, for scene.uniform=0 self.gcfvec = Vector() self.gcf_changed = gcf_changed self.lod_adjust = lod_adjust self.anaglyph = anaglyph self.coloranaglyph = coloranaglyph self.tan_hfov_x = tan_hfov_x self.tan_hfov_y = tan_hfov_y self.box_model = DisplayList() self.sphere_model = [DisplayList()] * 6 self.cylinder_model = [DisplayList()] * 6 self.cone_model = [DisplayList()] * 6 self.pyramid_model = DisplayList() self.camera_world = Tmatrix() self.background_color = background_color self.lights = [] self.enable_shaders = enable_shaders self.screen_objects = [] self.is_setup = False self.setup()
def model_world_transform(self, world_scale=0.0, object_scale=Vector([1, 1, 1])): """Performs scale, rotation, translation, and world scale (gcf) transforms in that order. :param world_scale: The global scaling factor. :type world_scale: float :param object_scale: The scaling to applied to this specific object :type object_scale: pyglet_helper.util.Vector :rtype: pyglet_helper.util.Tmatrix :returns: Returns a tmatrix that performs reorientation of the object from model orientation to world (and view) orientation. """ ret = Tmatrix() # A unit vector along the z_axis. z_axis = Vector([0, 0, 1]) if abs(self.axis.dot(self.up_vector) / self.up_vector.mag()**2.0) \ > 0.98: # Then axis and up are in (nearly) the same direction: therefore, # try two other possible directions for the up vector. if abs(self.axis.norm().dot(Vector([-1, 0, 0]))) > 0.98: z_axis = self.axis.cross(Vector([0, 0, 1])).norm() else: z_axis = self.axis.cross(Vector([-1, 0, 0])).norm() else: z_axis = self.axis.cross(self.up_vector).norm() y_axis = z_axis.cross(self.axis).norm() x_axis = self.axis.norm() ret.x_column(x_axis) ret.y_column(y_axis) ret.z_column(z_axis) w_column = world_scale * self.pos ret.w_column(w_column) ret.w_row() ret.scale(object_scale * world_scale, 1) return ret