How to get things to render in loop?


#1

I have been making a simulation or the n body problem and i have found that when i use a while loop and update the position at each step of the while loop it crashes. If i use a for loop it renders its position where it should be at the end of the for loop.

Here is the code:

import direct.directbase.DirectStart
from direct.showbase import DirectObject
from direct.interval.IntervalGlobal import *
from direct.gui.DirectGui import *
from direct.showbase.DirectObject import DirectObject
import time
import sys
import math

global masses
global dt
global models
global xcel
global xcel2
xcel = []
xcel2 = []
models = []
masses = []
positions = []
velocities = []
dt = 0.001

class mass(DirectObject):
	def __init__(self):
		base.setBackgroundColor(0, 0, 0)
		camera.setPos ( 0, -100, 0 )         
		camera.setHpr ( 0, 0, 0 )

	def createMass(self, name, mass, pos, vel):
		self.name = name
		self.mass = mass
		self.pos = pos
		positions.append(pos)
		global positions
		self.vel = vel
		velocities.append(vel)
		global velocities
		
	def scaleRenderTexture(self, scale, tex):
		self.model = loader.loadModel("models/sphere")
		self.model.reparentTo(render)
		texture = loader.loadTexture("models/" + tex)
		self.model.setTexture(texture, 1)
		self.model.setPos(self.pos[0], self.pos[1], self.pos[2])
		self.model.setScale(scale)
		masses.append(self.mass)
		models.append(self.model)


				
class sun(mass):
	def __init__(self):
		mass.__init__(self)
		self.createMass( 'sun', 1988920, [0, 0, 0], [0, 0, 0])
		self.scaleRenderTexture(1, 'sun.jpg')
		
class mercury(mass):
	def __init__(self):
		mass.__init__(self)
		self.createMass( 'mercury', 0.3302, [3.241862599523176, -5.623459942709265, -0.7569237943021074], [3.246868365706273*0.000001, 2.673977456413460*0.000001, -7.943396297475591*0.00000001])
		self.scaleRenderTexture(0.5, 'mercury.jpg')
		
class venus(mass):
	def __init__(self):
		mass.__init__(self)
		self.createMass('venus', 4.8685, [-1.034106071554218*10, -3.026887560710919, 5.553453628782571*0.1], [9.607057270995346*0.0000001, 9.607057270995346*0.000001, -1.017130175803783*0.0000001])
		self.scaleRenderTexture(1, 'venus.jpg')

class earth(mass):
	def __init__(self):
		self.createMass('earth', 5.9736, [-1.156305861637755*10, -9.663398491949379, 3.476874978550299*0.0001], [ 1.862492028315679*0.000001, -2.296083935603351*0.000001, 9.235729792600083*0.00000000001])
		self.scaleRenderTexture(1, 'earth.jpg')
		
class moon(mass):
	def __init__(self):
		mass.__init__(self)
		self.createMass('moon', 0.07349, [-1.159098389232509*10, -9.637310345944113, -2.989940894073912*0.001], [1.798178987142885*0.000001, -2.375339761912065*0.000001, -2.207441445869889*0.000000001])
		self.scaleRenderTexture(0.5, 'moon.jpg')
		
class mars(mass):
	def __init__(self):
		self.createMass('mars', 0.64185, [-2.422905158679938*10, -3.744196041373893, 5.164753385142086*0.1], [ 4.606798644725879*0.0000001, -2.187755639279240*0.000001, -5.715066713235196*0.00000001])
		self.scaleRenderTexture(1, 'mars.jpg')
		
class jupiter(mass):
	def __init__(self):
		self.createMass('jupiter', 1898.6, [4.622321051914394*10,  5.871875615908649*10, -1.278226639349561], [-1.043365341857297*0.000001, 8.709856358914491*0.0000001, 1.972500372665064*0.00000001])
		self.scaleRenderTexture(1, 'jupiter.jpg')
		
class saturn(mass):
	def __init__(self):
		self.createMass('saturn', 568.46, [-1.301371599111853*100, -6.476615242349228*10, 6.307409695374766], [3.772024323255900*0.0000001, -8.663132035152103*0.0000001, 5.618951648515438*0.00000000001])
		self.scaleRenderTexture(1, 'saturn.jpg')
		
class uranus(mass):
	def __init__(self):
		self.createMass('uranus', 86.832, [2.992063464452280*100, 2.476994299596707*10, -3.783759032649831], [-6.199323493736431*0.000000001, 6.475569300476019*0.0000001, 3.210008048765792*0.000000001])
		self.scaleRenderTexture(1, 'uranus.jpg')
		
class neptune(mass):
	def __init__(self):
		self.createMass('neptune', 102.43, [ 3.919464564967463*100, -2.185268039220477*100, -4.530872464442687], [2.601721469279150*0.0000001, 4.785231712545664*0.0000001, -1.579822877152521*0.000000001])
		self.scaleRenderTexture(1, 'neptune.jpg')
		
class pluto(mass):
	def __init__(self):
		self.createMass('pluto', 0.0125, [ 6.480526105894912*10, -4.765510811963443*100, 3.226311175584855*10], [5.496347900202217*0.0000001, -3.260693806903501*0.00000001, -1.558804760367132*0.0000001])
		self.scaleRenderTexture(0.5, 'pluto.jpg')
		
def calcA(bodies):
	s = [0,0,0]
	me = [0,0,0]
	v = [0,0,0]
	e = [0,0,0]
	mo = [0,0,0]
	ma = [0,0,0]
	ju = [0,0,0]
	s = [0,0,0]
	u = [0,0,0]
	n = [0,0,0]
	p = [0,0,0]
	xcel = [s, me, v, e, mo, ma, ju, s, u, n, p]
	xcel2 = xcel
	aX = 0
	aY = 0
	aZ = 0
	for i in range(len(masses)):
		xcel[i] = [aX, aY, aZ]
		aX = 0
		aY = 0
		aZ = 0
		for j in range(len(masses)):
				if i!=j:
					a = models[i].getPos()
					b = models[j].getPos()
					rx = b[0]-a[0]
					ry = b[1]-a[1]
					rz = b[2]-a[2]
					r = math.sqrt(rx*rx+ry*ry+rz*rz)
					xRatio = rx/(ry+rz)
					yRatio = ry/(rx+rz)
					zRatio = rz/(rx+ry)
					acceleration = (9.81*float(masses[i]))/(r*r)
					aX = aX + acceleration*xRatio
					aY = aY + acceleration*yRatio
					aZ = aZ + acceleration*zRatio
					
	return(xcel)

def calcNextPos(models, xcel, velocities, dt):
	for i in range(len(models)):
		for j in range(3):
			positions[i][j] = positions[i][j] + velocities[i][j]*dt + xcel[i][j]*0.5*dt*dt
	updatePos(positions)
			
def calcNextVel(velocities, xcel, xcel2, dt):
	for i in range(len(models)):
		for j in range(3):
			velocities[i][j] = velocities[i][j] + 0.5*(xcel[i][j] + xcel2[i][j])*dt
	xcel = xcel2
	
	
def updatePos(positions):
	for i in range(len(models)):
		for j in range(3):	
			models[i].setPos(positions[i][0], positions[i][1], positions[i][2])
	
bodies = []		
sun = sun()
mercury = mercury()	
venus = venus()
earth = earth()	
moon = moon()
mars = mars()	
jupiter = jupiter()
saturn = saturn()

uranus = uranus()
neptune = neptune()
pluto = pluto()	
xcel = calcA(bodies)

def mainLoop(xcel, models, masses, velocities):
	calcNextPos(models, xcel, velocities, dt)
	xcel2 = calcA(bodies)
	calcNextVel(velocities, xcel, xcel2, dt)
	
	
run()

Please if anyone could give me some help, as i dont quit understand how im supposed to call the mainLoop() with it crashing.

Thanks


#2

The two things i have tried are:

while True:
    mainLoop(xcel, models, masses, velocities)

This crashes, i have also tried it a time delay in there but it still crashes.

for i in range(100):
    mainLoop(xcel, models, masses, velocities)

This takes a while a second or two to respond then it renders all the objects where they should be, but it isn’t animated for each time step.


#3

Hi, I think you’d better update your application status inside a task; this is a common approach in Panda. Otherwise, if you really want to use a main loop, you’d better work with the Panda’s one.