python gluLookAt for first person camera - python

i'm new to openGL and i'm trying to move the camera as a first person shooter game. i want to use gluLookAt for movement and looking around the scene, but i can't figure out the camera part
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity()
glu.gluLookAt(current_player.position[0], current_player.position[1] ,
current_player.position[2], look_at_position[0], look_at_position[1], 0,
0, 1 ,0)
the look_at_position is the mouse position but i can't calculate the last value so i put temporarily as 0
i just want to know how to move the player and the camera using the glLookAt.

Works the same as glm::lookAt(). First argument is the position you are viewing from (you are correct), then the position you are looking at, and then the up vector (also correct). Here's what I invoke:
//this code is in the mouse callback, both yaw and pitch are mouse inputs
glm::vec3 front;
glm::vec3 right;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront = glm::normalize(front);
front.x = cos(glm::radians(yaw));
front.z = sin(glm::radians(yaw));
movementFront = glm::normalize(front);
//this is in int main()
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);

Related

Moving the cursor in relation to a certain fix-point in Python

is there any possibility to move the cursor in Python with % starting from a certain coordinate like (1,1)?
I am using pyautogui atm to automate and I thought it would be quite convenient if this is independent from the monitor size making it universal.
Thanks for your help in advance!
It's possible indirectly. As detailed at the top of the Mouse Control Functions page of the documentation, you can get the screen size using the size() function (which returns a tuple of (X, Y)). You can then do the math to figure out how many screen pixels equal the percentage you're looking for, then call moveTo() to go there.
# script to move mouse 50% to the right and down
import pyautogui as pag
percentage = 0.5
cur_X, cur_Y = pag.position() # current X and Y coordinates
size_X, size_Y = pag.size() # screen size
goto_X = (size_X - cur_X) * percentage + cur_X # current location plus half
goto_Y = (size_Y - cur_Y) * percentage + cur_Y # the distance to the edge
pag.moveTo(goto_X, goto_Y, 1) # move to new position, taking 1 second

Rotate Rect along line

First project in qt.
I'm having trouble translating/rotating a rect along a line. Basically i would want to align the rect with the position of the line. When i change position of the circle the rect should translate along the line. See images below.
What i have at the moment
w_len = len(str(weight)) / 3 * r + r / 3
weight_v = Vector(r if w_len <= r else w_len, r)
weight_rectangle = QRectF(*(mid - weight_v), *(2 * weight_v))
painter.drawRect(weight_rectangle)
*mid is just a vector with coordinates at half of the link , weight_v is a vector based on the text size.
Any pointers , should i look at adding a translate to the painter ? Whenever i try to add translation to the painter it breaks the other shapes as well.
t = QTransform()
t.translate(-5 ,-5)
t.rotate(90)
painter.setTransform(t)
painter.drawRect(weight_rectangle)
painter.resetTransform()
Update:
With below answer i was able to fix the rotation. Many thanks, looks like my text is not displaying correctly.
I have the following code:
painter.translate(center_of_rec_x, center_of_rec_y);
painter.rotate(- link_paint.angle());
rx = -(weight_v[0] * 0.5)
ry = -(weight_v[1] )
new_rec = QRect(rx , ry, weight_v[0], 2 * weight_v[1])
painter.drawRect(QRect(rx , ry, weight_v[0] , 2 * weight_v[1] ))
painter.drawText(new_rec, Qt.AlignCenter, str(weight))
Update2:
All is fine , was a mistake in my code. I was taking the wrong link angle.
Thx.
Rotation is always done according to the origin point (0, 0), so you need to translate to the origin point of the rotation and then apply it.
Also, when applying any temporary change to the painter, save() and restore() should be used: in this way the current state of the painter is stored, and that state will be restored afterwards (including any transformation applied in the meantime). Painter states can be nested, and one could save multiple times to apply multiple "layers" of painter state modifications. Just remember that the all states must be restored to the base status before releasing (ending) the painter.
Since you didn't provide an MRE, I created a small widget to show how this works:
class AngledRect(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setMinimumSize(200, 200)
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
contents = self.contentsRect()
# draw a line from the top left to the bottom right of the widget
line = QtCore.QLineF(contents.topLeft(), contents.bottomRight())
qp.drawLine(line)
# save the current state of the painter
qp.save()
# translate to the center of the painting rectangle
qp.translate(contents.center())
# apply an inverted rotation, since the line angle is counterclockwise
qp.rotate(-line.angle())
# create a rectangle that is centered at the origin point
rect = QtCore.QRect(-40, -10, 80, 20)
qp.setPen(QtCore.Qt.white)
qp.setBrush(QtCore.Qt.black)
qp.drawRect(rect)
qp.drawText(rect, QtCore.Qt.AlignCenter, '{:.05f}'.format(line.angle()))
qp.restore()
# ... other painting...
For simple transformations, using translate and rotate is usually enough, but the above is almost identical to:
transform = QtGui.QTransform()
transform.translate(contents.center().x(), contents.center().y())
transform.rotate(-line.angle())
qp.save()
qp.setTransform(transform)
# ...

Pyglet. How to change picture(animate) for vertices dynamically. OpenGL

Environment:
Python: 3.6.6
pyglet version: 1.3.2
Code base:
abstract_model.py
import pyglet
def get_texture_group(file, order_group_index):
texture = pyglet.image.load(file).texture
order_group = pyglet.graphics.OrderedGroup(order_group_index)
return pyglet.graphics.TextureGroup(texture, order_group)
class AbstractModel(object):
def _create_as_vertex(self):
v_x = self.cell_data.get("x") * 32
v_y = self.cell_data.get("y") * -1 * 32
texture_group = self.map_type_iamge.get(self.cell_data.get("t"))
x_offset = self.x_offset * self.scale
x, y, z = v_x + x_offset, v_y, self.z
x_ = (texture_group.texture.width * self.scale + x_offset + v_x)
y_ = (texture_group.texture.height * self.scale + v_y)
tex_coords = ('t2f', (0, 0, 1, 0, 1, 1, 0, 1))
self.vertices = self.batch.add(
4, pyglet.gl.GL_QUADS,
texture_group,
('v3f', (x, y, z,
x_, y, z,
x_, y_, z,
x, y_, z)),
tex_coords)
def _animate(self, dt):
# lets assume that I have list of pyglet.graphics.TextureGroup
# and they should somehow be drawn one after other
print("I need change image. dt=", dt, self)
pyglet.clock.schedule_once(self._animate, 1)
ground3d.py
import os
import pyglet
import settings
from models import abstract_model
GROUND_DIR = os.path.join(settings.STATIC_DIR, "ground")
order_group_index = 0
map_type_iamge = {
1: abstract_model.get_texture_group(os.path.join(GROUND_DIR, "w1.png"), order_group_index),
2: abstract_model.get_texture_group(os.path.join(GROUND_DIR, "t1.png"), order_group_index),
1001: abstract_model.get_texture_group(os.path.join(GROUND_DIR, "t1_direction.png"), order_group_index),
}
class Ground3D(abstract_model.AbstractModel):
def __init__(self, cell_data, batch):
self.batch = batch
self.cell_data = cell_data
self.map_type_iamge = map_type_iamge
self.scale = 1
self.x_offset = 0
self.z = 0
self.entity = None
self._create_as_vertex()
pyglet.clock.schedule_once(self._animate, 1)
Explanation:
I have models(just flat rect for an example) which should be placed on 3 dimensions. And these models should be animated, like picture_1, after second picture_2, ... etc.
As I understood from my previous question using pyglet.sprite.Sprite() in 3D batch is not a good idea.
Question:
How I can change pictures(using TextureGroup or any other approaches) on self.vertices?
Or which arroach/classes I use use to implement it. I can't find any examples for such (as for my simple vision) usual case as animation for some flat models in 3 dimensions.
There are many example about rotating/moving/resizing of vertices, but how to build a correct question(is animation aspect) for getting answer in google - I don't know.
PS: If you, reader, have any usefull links on this subject(for pyglet or just for OpenGL) I would be very appreciated you share this link(s) in comment.
Texture coordinates.
You should have a single texture atlas for all frames of all different things that are animated ever.
Preferably, everything should have same animation speed and same amount of frames all the time.
Let's say there's two sprites that have 2 frames for entire animation, and they are stored in 64x64 texture atlas. (EDIT: sorry for ambiguity, 64x64 PIXELS, just because it could imply that we have 64x64 tile atlas, same everywhere else where I mention this)
Now, you need to have a global timer with global value which indicates current animation frame, not game frame. It should be independent of framerate.
Said value should be updated every once in a while at your desired speed like this:
current_frame = (current_frame + 1) % animation_length
Since we have 2 frames in this example, it will turn out like this:
# init
animation_length = 2
current_frame = 0
# updates:
current_frame = (0 + 1) % 2 # 1 % 2 -> 1
current_frame = (1 + 1) % 2 # 2 % 2 -> 0
...
Now, you need to update UV's of all your sprites only when the frame changes.
UV's start from left right and go from 0 to 1 (as far as I remember, for the sake of this example, they do, shhh).
Since we have 2 frames each, we can calculate "tiles" in the UV coordinates like this:
tile_width = 1.0 / frames # 2 frames each, width will be 0.5
tile_height = 1.0 / sprites # 2 sprites each, height will be 0.5 too, perfect
Now, on first frame, you generate your UV's like normal, you just take vertical ID or something, and use tile_height * sprite_id to get current V coordinate, and your U is calculated like tile_width * current_frame.
This assumes that you already have sprite batching so what you do is go over every sprite on update, and basically just recalculate new UV's with new frame, meaning all sprites change their frame to the next one, yay!
If you want to have systems that are independent of eachother, say, very slow animations for some, and faster for others, you'll need different sprite batches or proper calculation on from where to where you need to update UV's in vertex buffer array. Everything else is exactly the same, except now current_frame won't be global but rather contained, preferebly in some list or separate object that manages timers for animations.
You don't need to change anything in your shaders, they just need right UV's for the frames and you're set.
By the way, this is very basic, you could apply some logic yourself so you could instead have 16x16 grid of 32x32 pixels in your texture, each line of sprites having 4 different animations, these could be either sprite's states (attack, run, etc), but how you do it is entirely on you, most importantly, get it to work. Goodluck.
But if you do it the way I said, then state will be another integer, and UV for state, assuming all states have exactly the same width, it would be like this:
state_width = 1 / states
tile_width = 1 / (states * frames_per_state)
U = state_width * current_state + tile_width * current_frame
Now, one issue arises, player could start his animation at the last attack frame.
It's normal, entities with actions should all have individual timers, what I described above, is for tons of sprites that are just background, like grass. Now when you divided it up, you could have a proper way to reset current frame to 0 when new state is assigned.
If your entities are objects, you could write proper methods that recalculate UV's every time you rebuild the sprite batch using those sprites, and then timers itselves could be contained in objects.
We need to draw something? Check animation state, has it changed, no? Send UV's that were calculated before, otherwise, wait a bit, we need to recalculate, only then add those to VBO, and well, render your thing, in the end, it will appear as if you have animations, even though really, it's just a simple, but great UV manipulation.
Goodluck.

Moving a circle in an elliptical pattern in tkinter

Okay so I'd like to make a circle move in an elliptical pattern with a button in tkinter. I previously made it move back and forth 10px at a time but I have no idea how to make it go in an ellipse
My back and forth code looks like this:
from Tkinter import *
def ball(gd, hb):
global x1, y1
x1, y1 = x1+gd, y1+hb
can1.coords(oval1,x1, y1, x1+30, y1+30)
def move():
global direction
if x1 + 30 == 250:
direction = -1
elif x1 == 0:
direction = 1
ball(direction*10, 0)
x1 , y1, direction = 0, 125, 1
root = Tk()
can1 = Canvas(root,height = 250, width =250, bg = 'black')
oval1= can1.create_oval(x1,y1,x1+30,y1+30, width=2, fill='orange')
can1.pack()
Button(root, text ='Move Ball', command = move).pack()
root.mainloop()
Any ideas would help me, I just need to be pointed in the right direction
Option 1
Okay so if you have meant that you just want to have an elliptical shape all the time you can use x1,y1,x1+60,y1+30 instead of x1+30,y1+30.
Option 2
If you have meant to reshape the ball like the ball bounces you have to think about some factors.
When should it happen. => Direction change
What do I have to modify => based on that: how a oval shape is defined you can easily say that if the ball touches the max width ( in your case x = 250) that you have to stretch out the opposite coordinates (oval1,x1, y1, x1+60, y1+30), with y1 ignored because you are just moving on the x-axis.
How do I stretch => See my Image
It also shows that you may use the sinus to achieve what you want. Like adding him on top of the desired coordinates. So everywhere the "Point" should move faster adding the sinus on top might does the trick.
That was my idea. Just a quick one. Maybe tomorrow I will find a better one. If you have questions just comment.

Tetris [PyGame] - Let the shapes fall

I'm trying to clone the Tetris game and already have PyGame pick a random shape and display it. I drew an array-backed grid and 'told' PyGame to draw colored squares in certain cells in order to get the cells.
def iShape():
grid [0][5] = 3
grid [0][6] = 3
grid [0][7] = 3
grid [0][8] = 3
pygame.init()
this tells the system on which cell of the grid it will draw the square in order to get the shape.
def draw():
allShapes = ['''all Shapes that I defined''']
pick = random.choice (allShapes)
... #otherstuff
if pick == iShape:
if grid[row][column] == 3:
color = orange
#draw the squares
I have been trying to think of how I could let the shapes fall slowly so the player can move/rotate them before they hit the ground but none of my ideas work out. Does anyone have a suggestion?
try to create a def called clock or tick(anything) and have that control the drop speed. or you could youse the in built python timer by doin inport mathand there is a command to have times so you could have then drop a pice of the grid every second or something like that sry about the brightness
I've found a Tetris clone called Tetromino online. I can't quite say it will work as it probably uses a different code style, but you could get an idea from it. Its at the link https://inventwithpython.com/pygame/chapter7.html

Categories