Here is a simple script that should illustrate the issue. The top row of
objects exhibits the proper behavior.
import pyglet
from pyglet.gl import *
from random import randint
window = pyglet.window.Window(720, 480)
batch = pyglet.graphics.Batch()
label = pyglet.text.Label("Press a key to delete the 5th item", x=10, y=460)
info1 = pyglet.text.Label("Non Indexed Quads:", x=10, y=270)
info2 = pyglet.text.Label("Indexed Quads:", x=10, y=120)
def make_indexed_quad(x, y, width=50, height=50):
verts = [x, y, x + width, y, x + width, y + height, x, y + height]
color1 = (randint(10, 255), randint(10, 255), randint(10, 255)) * 2
color2 = (randint(10, 255), randint(10, 255), randint(10, 255)) * 2
return batch.add_indexed(4, GL_TRIANGLES, None, [0, 1, 2, 0, 2, 3],
('v2f', verts), ('c3B', color1 + color2))
def make_quad(x, y, width=50, height=50):
verts = [x, y, x + width, y, x + width, y + height, x, y + height]
color1 = (randint(10, 255), randint(10, 255), randint(10, 255)) * 2
color2 = (randint(10, 255), randint(10, 255), randint(10, 255)) * 2
return batch.add(4, GL_QUADS, None, ('v2f', verts), ('c3B', color1 +
color2))
@window.event
def on_draw():
window.clear()
batch.draw()
label.draw()
info1.draw()
info2.draw()
@window.event
def on_key_press(key, mod):
if len(quads) > 4:
quads.pop(4).delete()
indexed_quads.pop(4).delete()
quads = []
indexed_quads = []
for i in range(11):
x = (i * 60) + 10
indexed_quads.append(make_indexed_quad(x, 50))
quads.append(make_quad(x, 200))
pyglet.app.run()
On Monday, January 29, 2018 at 3:39:38 AM UTC+9, Wasp Corporation wrote:
>
> Hi,
>
> I can't get to solve my problem and need help.
>
> I am simulating a bunch of particules (which are sphere). Each time I want
> to add a sphere, I call the function new_sphere which return me the
> vertex_list after it has been added to the batch (called b_sphere). I store
> each vertex list object in a list (sphere[ ] ) so I can access it later.
> When two particules touch themselves, I first delete the vertex_list from
> the batch them the object from the list :
>
> sphere[update.todel[i]].delete()
> sphere.pop(update.todel[i])
>
> Then I add another bigger sphere to simulate the "fusion" of the two
> previous ones :
>
> primitive.new_phere(sphere, b_sphere, int(update.new[j][0]), 2,
> update.new[j][1][0],
> update.new[j][1][1],
> update.new[j][1][2], (1.,0.3,0.2) )
>
> But when I do that, sometimes it works, sometimes it creates artefacts.
> For example, one of the sphere will stop moving (instead of disappear) and
> be partially deleted, while only one quarter of the new sphere will appear
> and continue to move as expected.
>
> Here is a larger view of my code :
>
> def init():
> print("___ primitive initialization ___")
> # The Axis (z is reverse with OpenGL)
> axis_x = primitive.Box(b_axis, 1000,0.1,0.1,
> color=('c3f',(1.,0.,0.)*4))
> axis_y = primitive.Box(b_axis, 0.1,1000,0.1,
> color=('c3f',(0.,1.,0.)*4))
> axis_z = primitive.Box(b_axis, 0.1,0.1,-1000,
> color=('c3f',(0.,0.,1.)*4))
>
> global nb_sphere
> global sphere
> global b_sphere
>
> nb_sphere = 3
>
> random.seed(a=None) # initial random seed
>
> for i in range(nb_sphere):
> primitive.new_phere(sphere, b_sphere, d_min, 2,
> random.gauss(0, sparsity),
> random.gauss(0, sparsity),
> random.gauss(0, sparsity))
>
> @window.event
> def on_draw():
> global b_sphere
>
> window.set2d()
> fps_display.draw()
>
> window.set3d()
> window.push(window.player.pos,window.player.rot)
>
> b_sphere.draw()
> b_axis.draw()
>
> glPopMatrix()
>
>
> # called every frame
> def update(dt):
>
> global nb_sphere
> global sphere
> global b_sphere
>
> test = 0
> update = Object()
> todel_sorted = []
> sparsity = 0.1
>
> for i in range(nb_sphere): # update every sphere from the batch
>
> move = (random.gauss(0, sparsity), random.gauss(0, sparsity),
> random.gauss(0, sparsity))
> primitive.translate( sphere[i], move )
>
> # detect collisions between particules
> if nb_sphere > 1:
>
> #cg_engine.gravity()
> update = cg_engine.collision(sphere, b_sphere, nb_sphere)
>
> # delete olds particules
> for i in range(len(update.todel)):
> print("delete sphere index %d" %update.todel[i])
> sphere[update.todel[i]].delete()
> sphere.pop(update.todel[i])
> nb_sphere -= 1
>
> # append new particules
> for j in range(len(update.new)):
>
> primitive.new_phere(sphere, b_sphere, int(update.new[j][0]), 2,
> update.new[j][1][0],
> update.new[j][1][1],
> update.new[j][1][2], (1.,0.3,0.2) )
>
> nb_sphere += 1
>
> window.update(dt) # update player & view
>
>
> # detect a collision between two sphere and return and object containing
> info to delete and create new ones
> def collision(sphere, b_sphere, nb_sphere):
>
> nb_collision = 0
>
> update = Object()
>
> update.todel = []
> update.new = []
>
> for i in range(nb_sphere):
> for j in range(i+1, nb_sphere):
>
> # first find center of the sphere 1 and radius
> c_sphere_i = numpy.array([
> ( sphere[i].vertices[0]+sphere[i].vertices[3] ) / 2,
> ( sphere[i].vertices[1]+sphere[i].vertices[4] ) / 2,
> ( sphere[i].vertices[2]+sphere[i].vertices[5] ) / 2])
> r_sphere_i = sphere[i].vertices[0] - c_sphere_i[0]
>
> # first find center of the sphere 2 and radius
> c_sphere_j = numpy.array([
> ( sphere[j].vertices[0]+sphere[j].vertices[3] ) / 2,
> ( sphere[j].vertices[1]+sphere[j].vertices[4] ) / 2,
> ( sphere[j].vertices[2]+sphere[j].vertices[5] ) / 2])
> r_sphere_j = sphere[j].vertices[0] - c_sphere_j[0]
>
> # get distance between them
> d = numpy.square(
> ( c_sphere_i[0] - c_sphere_j[0] )**2 +
> ( c_sphere_i[1] - c_sphere_j[1] )**2 +
> ( c_sphere_i[2] - c_sphere_j[2] )**2 )
>
> # get sum of the radius
> sum_radius = round(r_sphere_i + r_sphere_j, 0)
>
> # if two particules are close enough
> if( d < sum_radius ):
> ++nb_collision
> print("=== new collision !")
>
> # store index of the particules to delete
> update.todel.append(i)
> update.todel.append(j)
>
> new_radius = round( ( 2 * (( r_sphere_i + r_sphere_j )**3)
> )**(1./3) )
> print(new_radius)
>
> # ponderated by the respective radius of the particules
> influ_i = r_sphere_i / d
> influ_j = r_sphere_j / d
> new_center = numpy.array([
> (c_sphere_i[0]*influ_i) + (c_sphere_j[0]*influ_j),
> (c_sphere_i[1]*influ_i) + (c_sphere_j[1]*influ_j),
> (c_sphere_i[2]*influ_i) + (c_sphere_j[2]*influ_j) ])
>
> # store info about the new particules we should create
> update.new.append( [sum_radius, new_center] )
>
> nb_collision += 1
>
> update.todel = sorted(update.todel, reverse=True)
> update.todel = [ii for n,ii in enumerate(update.todel) if ii not in
> update.todel[:n]]
>
> return update
>
>
> I am still learning python so this is probably not a very good code. I
> know I shouldn't be using global variable, I will fix this later.
> Do you have any idea about what is causing this problem ? Here are some
> photos :
>
>
> <https://lh3.googleusercontent.com/-jS_o6sROgB4/Wm4YYJRP9NI/AAAAAAAAAoo/F40em5d4PtQNtCSXHJexK8JqAw7kdtBewCLcBGAs/s1600/Screenshot%2Bfrom%2B2018-01-28%2B13-35-52.png>
>
>
> <https://lh3.googleusercontent.com/-1Gm8VE20P7M/Wm4YcKrWOHI/AAAAAAAAAos/DevBy5WxpMoTKbxG0zM7ogqc-ktO1pkYgCLcBGAs/s1600/Screenshot%2Bfrom%2B2018-01-28%2B13-35-49.png>
>
>
> <https://lh3.googleusercontent.com/-22Pkcrv26UM/Wm4YftbNtMI/AAAAAAAAAow/HaWsGkRALuotbT1mKHpbA7YQoTmPnJMHACLcBGAs/s1600/Screenshot%2Bfrom%2B2018-01-28%2B13-34-57.png>
>
> Thank you,
>
> Victor
>
>
--
You received this message because you are subscribed to the Google Groups
"pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.