def test_operators_matrix44(self): m1 = Matrix44.identity() m2 = Matrix44.from_x_rotation(0.5) # add self.assertTrue( np.array_equal( m1 + m2, matrix44.create_identity() + matrix44.create_from_x_rotation(0.5))) # subtract self.assertTrue( np.array_equal( m1 - m2, matrix44.create_identity() - matrix44.create_from_x_rotation(0.5))) # multiply self.assertTrue( np.array_equal( m1 * m2, matrix44.multiply(matrix44.create_identity(), matrix44.create_from_x_rotation(0.5)))) # divide self.assertRaises(ValueError, lambda: m1 / m2) # inverse self.assertTrue( np.array_equal( ~m2, matrix44.inverse(matrix44.create_from_x_rotation(0.5))))
def test_operators_matrix44(self): m1 = Matrix44.identity() m2 = Matrix44.from_x_rotation(0.5) # add self.assertTrue(np.array_equal(m1 + m2, matrix44.create_identity() + matrix44.create_from_x_rotation(0.5))) # subtract self.assertTrue(np.array_equal(m1 - m2, matrix44.create_identity() - matrix44.create_from_x_rotation(0.5))) # multiply self.assertTrue(np.array_equal(m1 * m2, matrix44.multiply(matrix44.create_from_x_rotation(0.5), matrix44.create_identity()))) # divide self.assertRaises(ValueError, lambda: m1 / m2) # inverse self.assertTrue(np.array_equal(~m2, matrix44.inverse(matrix44.create_from_x_rotation(0.5)))) # == self.assertTrue(Matrix44() == Matrix44()) self.assertFalse(Matrix44() == Matrix44([1. for n in range(16)])) # != self.assertTrue(Matrix44() != Matrix44([1. for n in range(16)])) self.assertFalse(Matrix44() != Matrix44())
def test_operators_matrix33(self): m1 = Matrix44.identity() m2 = Matrix33.from_x_rotation(0.5) # add self.assertTrue(np.array_equal(m1 + m2, matrix44.create_identity() + matrix44.create_from_x_rotation(0.5))) # subtract self.assertTrue(np.array_equal(m1 - m2, matrix44.create_identity() - matrix44.create_from_x_rotation(0.5))) # multiply self.assertTrue(np.array_equal(m1 * m2, matrix44.multiply(matrix44.create_identity(), matrix44.create_from_x_rotation(0.5)))) # divide self.assertRaises(ValueError, lambda: m1 / m2)
def test_m44_q_equivalence(self): """Test for equivalance of matrix and quaternion rotations. Create a matrix and quaternion, rotate each by the same values then convert matrix<->quaternion and check the results are the same. """ m = matrix44.create_from_x_rotation(np.pi / 2.) mq = quaternion.create_from_matrix(m) q = quaternion.create_from_x_rotation(np.pi / 2.) qm = matrix44.create_from_quaternion(q) self.assertTrue( np.allclose(np.dot([1., 0., 0., 1.], m), [1., 0., 0., 1.])) self.assertTrue( np.allclose(np.dot([1., 0., 0., 1.], qm), [1., 0., 0., 1.])) self.assertTrue( np.allclose(quaternion.apply_to_vector(q, [1., 0., 0., 1.]), [1., 0., 0., 1.])) self.assertTrue( np.allclose(quaternion.apply_to_vector(mq, [1., 0., 0., 1.]), [1., 0., 0., 1.])) np.testing.assert_almost_equal(q, mq, decimal=5) np.testing.assert_almost_equal(m, qm, decimal=5)
def test_create_from_x_rotation(self): mat = matrix44.create_from_x_rotation(np.pi / 2.) self.assertTrue( np.allclose(np.dot([1., 0., 0., 1.], mat), [1., 0., 0., 1.])) self.assertTrue( np.allclose(np.dot([0., 1., 0., 1.], mat), [0., 0., -1., 1.])) self.assertTrue( np.allclose(np.dot([0., 0., 1., 1.], mat), [0., 1., 0., 1.]))
def update_view_matrix(self): self.viewMatrix = matrix44.multiply( matrix44.create_from_x_rotation(math.radians(self.pitch)), matrix44.create_from_y_rotation(math.radians(self.yaw))) self.viewMatrix = matrix44.multiply( self.viewMatrix, matrix44.create_from_translation( Vector3([0, 0, -self.distanceFromPlayer.actual])))
def rotated_x(): quat = quaternion.create_from_x_rotation( math.pi ) result = matrix44.create_from_quaternion( quat ) expected = matrix44.create_from_x_rotation( math.pi ) self.assertTrue( numpy.allclose( result, expected ), "Matrix44 from quaternion incorrect with PI rotation about X" )
def rotated_x(): mat = matrix44.create_from_x_rotation( math.pi ) vec = vector3.unit.y result = matrix44.apply_to_vector( mat, vec ) expected = -vec self.assertTrue( numpy.allclose( result, expected ), "Matrix44 apply_to_vector incorrect with rotation about X" )
def model_matrix(terrain): translation_matrix = np.matrix([[1, 0, 0, terrain.x], [0, 1, 0, 0], [0, 0, 1, terrain.z], [0, 0, 0, 1]]) rotation_matrix_x = matrix44.create_from_x_rotation(np.radians(0)) rotation_matrix_y = matrix44.create_from_y_rotation(np.radians(0)) rotation_matrix_z = matrix44.create_from_z_rotation(np.radians(0)) scale_matrix = matrix44.create_from_scale([1, 1, 1]) tx = matrix44.multiply(translation_matrix, rotation_matrix_x) txy = matrix44.multiply(tx, rotation_matrix_y) tr = matrix44.multiply(txy, rotation_matrix_z) model_matrix = matrix44.multiply(tr, scale_matrix) return model_matrix
def view_matrix(camera): translation_matrix = np.matrix([[1, 0, 0, -camera.position[0]], [0, 1, 0, -camera.position[1]], [0, 0, 1, -camera.position[2]], [0, 0, 0, 1]]) rotation_matrix_x = matrix44.create_from_x_rotation( np.radians(camera.pitch)) rotation_matrix_y = matrix44.create_from_y_rotation( np.radians(camera.yaw)) rotation_matrix_z = matrix44.create_from_z_rotation( np.radians(camera.roll)) rot = np.dot(rotation_matrix_x, np.dot(rotation_matrix_y, rotation_matrix_z)) txy = matrix44.multiply(rot, translation_matrix) view_matrix = matrix44.multiply(txy, rotation_matrix_z) return view_matrix
def model_matrix(thing): translation_matrix = np.matrix([[1, 0, 0, thing.position[0]], [0, 1, 0, thing.position[1]], [0, 0, 1, thing.position[2]], [0, 0, 0, 1]]) rotation_matrix_x = matrix44.create_from_x_rotation( np.radians(thing.rotX)) rotation_matrix_y = matrix44.create_from_y_rotation( np.radians(thing.rotY)) rotation_matrix_z = matrix44.create_from_z_rotation( np.radians(thing.rotZ)) scale_matrix = matrix44.create_from_scale(thing.scale) tx = matrix44.multiply(translation_matrix, rotation_matrix_x) txy = matrix44.multiply(tx, rotation_matrix_y) tr = matrix44.multiply(txy, rotation_matrix_z) model_matrix = matrix44.multiply(tr, scale_matrix) return model_matrix
def test_m44_q_equivalence(self): """Test for equivalance of matrix and quaternion rotations. Create a matrix and quaternion, rotate each by the same values then convert matrix<->quaternion and check the results are the same. """ m = matrix44.create_from_x_rotation(np.pi / 2.) mq = quaternion.create_from_matrix(m) q = quaternion.create_from_x_rotation(np.pi / 2.) qm = matrix44.create_from_quaternion(q) self.assertTrue(np.allclose(np.dot([1.,0.,0.,1.], m), [1.,0.,0.,1.])) self.assertTrue(np.allclose(np.dot([1.,0.,0.,1.], qm), [1.,0.,0.,1.])) self.assertTrue(np.allclose(quaternion.apply_to_vector(q, [1.,0.,0.,1.]), [1.,0.,0.,1.])) self.assertTrue(np.allclose(quaternion.apply_to_vector(mq, [1.,0.,0.,1.]), [1.,0.,0.,1.])) np.testing.assert_almost_equal(q, mq, decimal=5) np.testing.assert_almost_equal(m, qm, decimal=5)
def test_operators_matrix44(self): q = Quaternion() m = Matrix44.from_x_rotation(0.5) # add self.assertRaises(ValueError, lambda: q + m) # subtract self.assertRaises(ValueError, lambda: q - m) # multiply self.assertTrue( np.array_equal( q * m, quaternion.cross( quaternion.create(), quaternion.create_from_matrix( matrix44.create_from_x_rotation(0.5))))) # divide self.assertRaises(ValueError, lambda: q / m)
def test_rotation( self ): """ Rotation and Inheritance """ # we'll add a child to a root node # we'll move the child # rotate the root # and check the child is where it should be # the child should be moved somewhere that will # make it easy to check root = SceneNode( '/root' ) child = SceneNode( '/child' ) root.add_child( child ) # # Rotate 180 deg (1 * pi) about the Y axis (yaw) # root.transform.object.rotate_y( math.pi ) identity = matrix44.identity() root_matrix = matrix44.create_from_y_rotation( math.pi ) # root object test_axis( self, root.transform.object, root_matrix ) test_axis( self, root.transform.inertial, identity ) test_axis( self, root.world_transform.object, root_matrix ) test_axis( self, root.world_transform.inertial, identity ) child_matrix = matrix44.identity() test_axis( self, child.transform.object, child_matrix ) test_axis( self, child.transform.inertial, identity ) test_axis( self, child.world_transform.object, root_matrix ) test_axis( self, child.world_transform.inertial, identity ) # check the node matrix matches what we're seeing in # the transform axis values self.assertTrue( numpy.allclose( root.transform.matrix, root_matrix ), "Root Local Matrix incorrect" ) self.assertTrue( numpy.allclose( root.world_transform.matrix, root_matrix ), "Root RootMatrix incorrect" ) self.assertTrue( numpy.allclose( child.transform.matrix, identity ), "Child Local Matrix incorrect" ) self.assertTrue( numpy.allclose( child.world_transform.matrix, root_matrix ), "Child RootMatrix incorrect" ) # # Rotate 180 deg (1 * pi) about the X axis (pitch) # # rotate 180 deg / 1pi about the x axis (pitch) child.transform.object.rotate_x( math.pi ) child_matrix = matrix44.multiply( matrix44.create_from_x_rotation( math.pi ), child_matrix ) child_world = matrix44.multiply( child_matrix, root_matrix ) # root object test_axis( self, root.transform.object, root_matrix ) test_axis( self, root.transform.inertial, identity ) test_axis( self, root.world_transform.object, root_matrix ) test_axis( self, root.world_transform.inertial, identity ) test_axis( self, child.transform.object, child_matrix ) test_axis( self, child.transform.inertial, identity ) test_axis( self, child.world_transform.object, child_world ) test_axis( self, child.world_transform.inertial, identity ) # check the node matrix matches what we're seeing in # the transform axis values self.assertTrue( numpy.allclose( root.transform.matrix, root_matrix ), "Root Local Matrix incorrect" ) self.assertTrue( numpy.allclose( root.world_transform.matrix, root_matrix ), "Root RootMatrix incorrect" ) self.assertTrue( numpy.allclose( child.transform.matrix, child_matrix ), "Child Local Matrix incorrect" ) self.assertTrue( numpy.allclose( child.world_transform.matrix, child_world ), "Child RootMatrix incorrect" )
def test_create_from_inverse_of_quaternion(self): q = quaternion.create_from_x_rotation(np.pi / 2.0) result = matrix44.create_from_inverse_of_quaternion(q) self.assertTrue(np.allclose(result, matrix44.create_from_x_rotation(-np.pi / 2.0)))
def test_multiply_rotation(self): m1 = matrix44.create_from_x_rotation(np.pi) m2 = matrix44.create_from_y_rotation(np.pi / 2.0) result = matrix44.multiply(m1, m2) self.assertTrue(np.allclose(result, np.dot(m1,m2)))
def test_create_from_x_rotation(self): mat = matrix44.create_from_x_rotation(np.pi / 2.) self.assertTrue(np.allclose(np.dot([1.,0.,0.,1.], mat), [1.,0.,0.,1.])) self.assertTrue(np.allclose(np.dot([0.,1.,0.,1.], mat), [0.,0.,-1.,1.])) self.assertTrue(np.allclose(np.dot([0.,0.,1.,1.], mat), [0.,1.,0.,1.]))
def test_multiply_rotation(self): m1 = matrix44.create_from_x_rotation(np.pi) m2 = matrix44.create_from_y_rotation(np.pi / 2.0) result = matrix44.multiply(m1, m2) self.assertTrue(np.allclose(result, np.dot(m1, m2)))
def rotate(self, xrot, yrot, zrot): xrot_mat = matrix44.create_from_x_rotation(radians(xrot)) yrot_mat = matrix44.create_from_y_rotation(radians(yrot)) zrot_mat = matrix44.create_from_z_rotation(radians(zrot)) self.rotation_matrix = xrot_mat * yrot_mat * zrot_mat
def test_apply_to_vector_x_rotation(self): mat = matrix44.create_from_x_rotation(np.pi) result = matrix44.apply_to_vector(mat, [0., 1., 0.]) np.testing.assert_almost_equal(result, [0., -1., 0.], decimal=5)
def main(): # initialize glfw if not glfw.init(): return w_width, w_height = 1280, 720 aspect_ratio = w_width / w_height window = glfw.create_window(w_width, w_height, "My OpenGL window", None, None) if not window: glfw.terminate() return glfw.make_context_current(window) glfw.set_window_size_callback(window, window_resize) # positions texture_coords cube = [-0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 0.0, 0.5, 0.5, -0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 1.0, -0.5, -0.5, 0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 0.0, 1.0] cube = numpy.array(cube, dtype=numpy.float32) indices = [0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11, 8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 23, 20] indices = numpy.array(indices, dtype=numpy.uint32) vertex_shader = """ #version 330 in layout(location = 0) vec3 position; in layout(location = 1) vec2 texture_cords; uniform mat4 vp; uniform mat4 model; out vec2 textures; void main() { gl_Position = vp * model * vec4(position, 1.0f); textures = texture_cords; } """ fragment_shader = """ #version 330 in vec2 textures; out vec4 color; uniform sampler2D tex_sampler; void main() { color = texture(tex_sampler, textures); } """ shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER), OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER)) VBO = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, cube.itemsize * len(cube), cube, GL_STATIC_DRAW) EBO = glGenBuffers(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.itemsize * len(indices), indices, GL_STATIC_DRAW) # position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) # textures glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(12)) glEnableVertexAttribArray(1) crate = TextureLoader.load_texture("resources/images/planks_brown_10_diff_1k.jpg") metal = TextureLoader.load_texture("resources/images/green_metal_rust_diff_1k.jpg") brick = TextureLoader.load_texture("resources/images/castle_brick_07_diff_1k.jpg") glUseProgram(shader) glClearColor(0.5, 0.1, 0.2, 1.0) glEnable(GL_DEPTH_TEST) view = matrix44.create_from_translation(Vector3([0.0, 0.0, -4.0])) projection = matrix44.create_perspective_projection_matrix(45.0, aspect_ratio, 0.1, 100.0) vp = matrix44.multiply(view, projection) vp_loc = glGetUniformLocation(shader, "vp") model_loc = glGetUniformLocation(shader, "model") # cube_positions = [(1.0, 0.0, 0.0), (2.0, 5.0, -15.0), (-1.5, -1.2, -2.5), (-8.8, -2.0, -12.3)] cube_positions = [(1.0, 0.0, 0.0), (2.0, 5.0, -15.0), (-1.5, -1.2, -2.5), (-8.8, -2.0, -12.3), (-2.0, 2.0, -5.5), (-4.0, 2.0, -3.0)] # cube_positions = [(-1.5, 1.0, -0.5), (0.0, 1.0, -0.5), (1.5, 1.0, -0.5), (-1.5, -1.0, -0.5), (0.0, -1.0, -0.5), (1.5, -1.0, -0.5)] glUniformMatrix4fv(vp_loc, 1, GL_FALSE, vp) while not glfw.window_should_close(window): glfw.poll_events() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) time = glfw.get_time() rot_x = matrix44.create_from_x_rotation(sin(time) * 2) rot_y = matrix44.create_from_y_rotation(time * 0.5) rot_z = matrix44.create_from_z_rotation(time) for i in range(len(cube_positions)): model = matrix44.create_from_translation(cube_positions[i]) if i < 2: glBindTexture(GL_TEXTURE_2D, crate) rotX = matrix44.multiply(rot_x, model) glUniformMatrix4fv(model_loc, 1, GL_FALSE, rotX) elif i == 2 or i == 3: glBindTexture(GL_TEXTURE_2D, metal) rotY = matrix44.multiply(rot_y, model) glUniformMatrix4fv(model_loc, 1, GL_FALSE, rotY) else: glBindTexture(GL_TEXTURE_2D, brick) rotZ = matrix44.multiply(rot_z, model) glUniformMatrix4fv(model_loc, 1, GL_FALSE, rotZ) glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None) glfw.swap_buffers(window) glfw.terminate()
def init(): global shaderProgram global vao global vbo global model global idMod global view global idView global projection global idProj global idColor global idLight global idLightPos global idViewPos global posCam glClearColor(0, 0, 0, 0) vertex_code = readShaderFile('cuboLuz.vp') fragment_code = readShaderFile('cuboLuz.fp') # compile shaders and program vertexShader = shaders.compileShader(vertex_code, GL_VERTEX_SHADER) fragmentShader = shaders.compileShader(fragment_code, GL_FRAGMENT_SHADER) shaderProgram = shaders.compileProgram(vertexShader, fragmentShader) # cria um vao vao = GLuint(0) glGenVertexArrays(1, vao) glBindVertexArray(vao) # dados do objeto q serao passados para o shaders (vertices e vetores normais) vertices = np.array(readVertexData(), dtype='f') print("vertices:", len(vertices) // 6) print(vertices) vbo = glGenBuffers(1) # gera vbos glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, False, 6 * sizeof(GLfloat), ctypes.c_void_p(3 * sizeof(GLfloat))) # vertices glVertexAttribPointer(1, 3, GL_FLOAT, False, 6 * sizeof(GLfloat), ctypes.c_void_p(0)) # vertores normais # habilita os atributos glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) # cria a matriz de transformação model = matrix44.create_identity() #ratacoes rotY = matrix44.create_from_y_rotation(math.radians(45)) rotx = matrix44.create_from_x_rotation(math.radians(45)) rotT = matrix44.multiply(rotY, rotx) model = matrix44.multiply(model, rotT) posCam = [0.0, 0.0, 0.0] view = matrix44.create_look_at(posCam, [0.0, 0.0, -0.1], [0.0, 1.0, 0.0]) projection = matrix44.create_orthogonal_projection(-2.0, 2.0, -2.0, 2.0, 2.0, -2.0) # amplia a visao print(f'Model:\n{model}\n') print(f'View:\n{view}\n') print(f'Projection:\n{projection}\n') # atribui uma variavel uniforme para cada matriz idMod = glGetUniformLocation(shaderProgram, "model") idView = glGetUniformLocation(shaderProgram, "view") idProj = glGetUniformLocation(shaderProgram, "projection") # iluminação idColor = glGetUniformLocation(shaderProgram, "objectColor") idLight = glGetUniformLocation(shaderProgram, "lightColor") idLightPos = glGetUniformLocation(shaderProgram, "lightPos") idViewPos = glGetUniformLocation(shaderProgram, "viewPos") # Note that this is allowed, the call to glVertexAttribPointer registered VBO # as the currently bound vertex buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0) # Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs) glBindVertexArray(0)
def test_create_from_inverse_of_quaternion(self): q = quaternion.create_from_x_rotation(np.pi / 2.0) result = matrix44.create_from_inverse_of_quaternion(q) self.assertTrue( np.allclose(result, matrix44.create_from_x_rotation(-np.pi / 2.0)))
def test_operators_matrix44(self): q = Quaternion() m = Matrix44.from_x_rotation(0.5) # add self.assertRaises(ValueError, lambda: q + m) # subtract self.assertRaises(ValueError, lambda: q - m) # multiply self.assertTrue(np.array_equal(q * m, quaternion.cross(quaternion.create(), quaternion.create_from_matrix(matrix44.create_from_x_rotation(0.5))))) # divide self.assertRaises(ValueError, lambda: q / m)
def test_apply_to_vector_x_rotation(self): mat = matrix44.create_from_x_rotation(np.pi) result = matrix44.apply_to_vector(mat, [0.,1.,0.]) np.testing.assert_almost_equal(result, [0.,-1.,0.], decimal=5)