Hi Victor, 

I think there is a bug in the IndexedVertexDomain.  
https://bitbucket.org/pyglet/pyglet/src/89bc2c4825e13a73ed156d3232159cb481aabc9d/pyglet/graphics/vertexdomain.py?at=default&fileviewer=file-view-default#vertexdomain.py-639

I saw some odd behavior before, but didn't have time to fully investigate 
it at the time. 
If you add a dozen indexed items to the domain, then delete one of the 
'middle' items, then any items added after the deleted item will either 
vanish or glitch.  

I'll see if I can put together a simple test script so that others can test 
this as well. If it is indeed a bug, then hopefully we can get some eyes on 
the code and find a fix. It's a little bit above my brain power :)



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.

Reply via email to