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.