PDA

View Full Version : Stop for... loop


Johannes
01-10-2005, 06:45 AM
Hi,
how can I find out, which properties objects posess?


I'm trying to built a collide-function for objects as you did in the duckcourt example.

There you used a object-function called collidemesh


court.collidemesh()

Thanks for helping,
Johannes

P.S. Found an answer to end my loop.

Johannes
01-10-2005, 07:40 AM
To check for collision I tried:

collidables=[]
myroom.collidemesh()
collidables.append(myroom)
ball.collidesphere(0.25)
collidables.append(ball)



and in my move function I checked in every step:

for objects in collidables:
#Perform the collision check with the object
info = ball.collidingwith(object,1)
if info.intersected:

#Set the balls new vector to the reflection vector
#ball.vector = viz.Vector(vizmat.ReflectionVector(ball.vector,inf o.normalVector))
vY=-vY

But did not work yet?!

farshizzo
01-10-2005, 08:59 AM
Hi,

The break statement will cause a for/while loop to exit. Example:for i in range(100):
if i == 50:
breakAbout the collision problem, have you checked that a collision is actually reported? Try placing a print statement inside the if info.intersected clause.

Johannes
01-10-2005, 09:35 AM
Sorry for the break-question - found it just a minute after that (so I reEdited the question).

@collision:

1. How do I know that I have the possibility to call myroom.collidemesh()
(object - property, did not see it in stage or pop up)


2. No, I did not get an intersect.intersected (placed the print statement).

Thank you,
Johannes

farshizzo
01-10-2005, 09:56 AM
Hi,

The collide functions are not finalized yet, so they are currently undocumented. If you have any questions on a specific command just let me know.

I can't tell what is going wrong since I can't see the entire script. Are the ball and room the only objects you are checking collision with? If so, then don't bother creating a collidable list, just check for collisions between the two explicitly:info = ball.collidingwith(myroom,1)

Johannes
01-10-2005, 03:59 PM
A. The ball and the room are the only ones but soon there will be more objects then I will need it anyway.
So if my room is called myroom and my ball is called ball why does this not work?
This is the important part:

collidables=[]
myroom.collidemesh()
collidables.append(myroom)
ball.collidesphere(0.25)
collidables.append(ball)


and in then in the move function I checked:

for objects in collidables:
#Perform the collision check with the object
info = ball.collidingwith(object,1)
if info.intersected:

Could the reason be, that myroom does not have a 'collidemesh'? This is basically my first question - how can I find out, which properties objects posess?
-----
B. Does info.normalVector give me the Normal to the object-surface the ball hit?
-----

C. Is there a function to do a complete stop and restart of the program by typing a certain key (it must basically be the same as typing the run-button in your program) e.g.

def mykeyboard(key):
if key == 'r':
viz.resetProgram()

Johannes

farshizzo
01-10-2005, 04:15 PM
Hi,

A. collidemesh tells vizard that all collision tests with the object should be performed with the underlying geometry mesh. What kind of object is myroom? Are you getting any error messages? Is the ball actually intersecting with the room mesh when your code is called? Are you executing the code inside a director function? If so, have you tried executing it elsewhere, like in timer or keyboard callback? Sorry for all the dumb questions, but I just want to make sure I know excactly what is going on.

B. Yes, info.normalVector returns the normal of the collision surface.

C. No, Vizard doesn't currently have this command.

Johannes
01-10-2005, 04:29 PM
>What kind of object is myroom?

It is the room from the getting-started tutorial.

>Are you getting any error messages?
No

>Is the ball actually intersecting with the room mesh when your code is called?

yes

> Are you executing the code inside a director function?

yes

>If so, have you tried executing it elsewhere, like in timer or keyboard callback?

Have not tried this yet. What kind of sense would this make? In the end I anyway need it in a director function or not? But I agree with you, in the duckcourt.py where this code is used it was called in a timer-function (no director) (Line 213)

>Sorry for all the dumb questions, but I just want to make sure I know excactly what is going on.

Sure! I really appreciate your help.
Have a good evening,
Johannes

Johannes
01-10-2005, 04:31 PM
If I should post the example I'm working on, just tell me.
I guess I will have to do this as a zip file because of the ressource-files

farshizzo
01-10-2005, 04:51 PM
Hi,

Can you try out the following sample script. It is a really simple script that has a ball bouncing around the room you are using. The calculations are done inside a director function. Let me know if this works for you.import viz
import vizmat
viz.go()

myroom = viz.add('room.wrl')
ball = viz.add('ball.wrl')

myroom.collidemesh()
ball.collidesphere(0.25)
ball.vector = viz.Vector(1,1,1)
ball.translate(0,1,0)

def moveball():

while 1:

#Perform the collision check with the room
info = ball.collidingwith(myroom,1)
if info.intersected:

#Set the balls new vector to the reflection vector
ball.vector = viz.Vector(vizmat.ReflectionVector(ball.vector,inf o.normalVector))

#Create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)

#Check dot product of velocity and normal
if ball.vector * normal < 0:
ball.vector *= -1

#Get the balls current position
pos = ball.get(viz.POSITION)

#Calculate the balls future position based on its velocity
futurePos = pos + (ball.vector * 0.02)
ball.translate(futurePos.get())

viz.waittime(0.01)

viz.director(moveball)

Johannes
01-10-2005, 05:09 PM
I will try this tomorrow morning, thank you very much (I'm already at home)!

I will also develop a graph to visualize the velocity vs. time...
Guess best would be to use the 'on-the-fly' functions for drawing the coordinate system and the dots or would you recommend something else?

Have a great evening,
Johannes

Johannes
01-11-2005, 06:02 AM
Tried your example. Works, but it is only good for the case of one ball. Tried to change it (see below) to fit the more general purpose of more balls and objects:

I added after ball.translate(0,1,0):

collidables=[]
collidables.append(myroom)
collidables.append(ball)



I repaced info = ball.collidingwith(myroom,1) with

for objects in collidables:
#Perform the collision check with the object
info = ball.collidingwith(object,1)

and adjusted the indent.
Does not work.
Best,
Johannes

Here is the full changed Program
import viz
import vizmat

viz.go()

myroom = viz.add('../resources/models/room.wrl')
ball = viz.add('../resources/models/ball.wrl')


myroom.collidemesh()
ball.collidesphere(0.25)
ball.vector = viz.Vector(1,1,1)
ball.translate(0,1,0)

collidables=[]
collidables.append(myroom)
collidables.append(ball)

def moveball():
while 1:
info = ball.collidingwith(myroom,1)
#Perform the collision check with the room
if info.intersected:
#Set the balls new vector to the reflection vector
ball.vector = viz.Vector(vizmat.ReflectionVector(ball.vector,inf o.normalVector))
#Create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)
#Check dot product of velocity and normal
if ball.vector * normal < 0:
ball.vector *= -1
#Get the balls current position
pos = ball.get(viz.POSITION)
#Calculate the balls future position based on its velocity
futurePos = pos + (ball.vector * 0.02)
ball.translate(futurePos.get())
viz.waittime(0.01)
viz.director(moveball)

Johannes
01-11-2005, 06:05 AM
Sorry that it did not post the program with the Indentation. How can I do post it better next time?
Johannesi

tobin
01-11-2005, 06:48 AM
Use the code tags. You can access them by clicking the # symbol above, and then copy-pasting between the tags.

farshizzo
01-11-2005, 09:32 AM
Hi,

Try the following script. I changed it so that every time the spacebar is pressed a new ball is created in the room with a random velocity direction. This script will only work with version 2.5 and above. It uses a list of collidable objects similar to what you are using. I hope this is similar enough to what you are doing, if not let me know.import viz
import vizmat
import time
viz.go()

#List of collidable objects
collidable = []

#Create a room
myroom = viz.add('room.wrl')
myroom.collidemesh()
collidable.append(myroom)

def moveball(ball):

#Used to calculate elpased time between each iteration
tick = time.clock()

while 1:

for object in collidable:

#Don't check for collisions with the same object
if object == ball:
continue

#Perform the collision check with the room
info = ball.collidingwith(object,1)
if info.intersected:

#Set the balls new vector to the reflection vector
ball.vector = viz.Vector(vizmat.ReflectionVector(ball.vector,inf o.normalVector))

#Create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)

#Check dot product of velocity and normal
if ball.vector * normal < 0:
ball.vector *= -1

#Get the balls current position
pos = ball.get(viz.POSITION)

#Calculate the balls future position based on its velocity and elapsed time
curtick = time.clock()
futurePos = pos + (ball.vector * (curtick-tick))
tick = curtick
ball.translate(futurePos.get())

viz.waittime(0.01)

def onkeydown(key):
if key == ' ':
#Create a ball with random velocity vector
ball = viz.add('ball.wrl')
ball.collidesphere(0.25)
ball.vector = viz.Vector(vizmat.GetRandom(-1,1),vizmat.GetRandom(-1,1),vizmat.GetRandom(-1,1))
ball.vector.normalize()
ball.vector *= 2
ball.translate(0,1,0)
collidable.append(ball)
viz.director(moveball,ball)

viz.callback(viz.KEYDOWN_EVENT,onkeydown)

Johannes
01-11-2005, 10:09 AM
Thank you very much. I'm not through reading it, but trying it I experienced that if I create a lot of balls, the intersect does not work any more. Balls fly away into space.

I will read it through after lunch.

Johannes
01-11-2005, 12:22 PM
Read through it. I did not find out, why balls can escape out of the room.

You used time.clock() - I use time.time() to get my start-time from. Both is more accurate than using the normal timer-function. Guess the only difference is this: On Windows, time.clock() has microsecond granularity but time.time()'s granularity is 1/60th of a second; on Unix, time.clock() has 1/100th of a second granularity and time.time() is much more precise.

vizmat.ReflectionVector: great that this seems to be built in. Is there any doc available how you do it? Guess you kind of transform the coordinate system, so the normal vector is (e.g) the y axis of the new system. Then you figure out, how the incoming vector is defined in this new coordinate system and change (multiply with -1) the coordinate that is similar to the y (normal vector / axis of coordinate system2). Then you have the new direction and transform it back to the normal coordinate system. (Maybe there is an easier / better way, this is just how I would do it).

So I did not find the reason, why balls jump out. It could be, that if there are too many balls, the loop is just not fast enought to fire off an intersection-event and so the ball flies through. If this is the case we would have to adjust waittime if ther were too much balls - or what do you think about balls escaping?

Thank you for helping me, I learned a lot,
Johannes

P.S. I did not find out yet, why it did not work with the old example but I will see (in case you have an idea?, but don't bother I will anyway mail again, if I run into problems matching the two files)

farshizzo
01-11-2005, 12:45 PM
Hi,

As you suggested, the problem is that there are too many balls. The number of collision tests performed increases exponentially with each ball that is added. This increases the amount of time between each iteration, which in turn allows the ball to poke through the walls.

The builtin timer function actually uses a very accurate time routine, however it is limited by the frame rate of the application.

Here is the equation used to calculate the reflection vector. There are various sources on the internet that go into detailed explanations on how this equation is derived.

R - Reflection vector
V - Incoming vector
N - Normal vector

R = V - (2 * V dot N) N

Johannes
01-11-2005, 02:53 PM
Thank you!

SUJITH_KJ
03-31-2014, 12:34 AM
hey... in my following code, collision is not detected wen the avatar walks to (0,0,5) wen i press the 'w' key. After that wen i press 'c' key the avatar walks to (0,0,15) and collision is detected this time. May i know why this is happening. Thanks a lot...


code:

import viz
import vizact
viz.phys.enable()
viz.setMultiSample(4)
viz.fov(60)
viz.go()
male = viz.addAvatar('vcc_male.cfg')
male.scale(3,3,3)
ground = viz.add('tut_ground.wrl')
ground.collidePlane()
box = viz.add('box.wrl',scale=[2,2,2],pos=(0,0,5),color = viz.BLUE)
box.collideBox()
box.disable(viz.DYNAMICS)

env=viz.add(viz.ENVIRONMENT_MAP,'sky.jpg')
dome = viz.add('skydome.dlc')
dome.texture(env)
box1 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(0,0,15),color = viz.RED)
box1.collideBox()
box1.disable(viz.DYNAMICS)

box2 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(-10,0,0),color = viz.RED)
box2.collideBox()
box2.disable(viz.DYNAMICS)

box3 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(-20,0,0),color = viz.RED)
box3.collideBox()
box3.disable(viz.DYNAMICS)
rHandBox = viz.add('box.wrl',scale=[1,1,1])
rHandBox.collideBox()
rHandBox.disable(viz.DYNAMICS)
rHandBox.enable(viz.COLLIDE_NOTIFY)
rHandLink = viz.link( male.getBone('Bip01 R Foot') , rHandBox )
#tweak the position of the box to cover the hand
rHandLink.preTrans([0.05,-0.5,0])


def wukavatar():
walk1 = vizact.walkTo([0,0,5])
male.addAction(walk1)
vizact.onkeydown('w',wukavatar)


def onCollideBegin(g):
if g.obj1 == rHandBox:
if g.obj2 == box:
box.color(viz.RED)
textScreen = viz.addText('Press a',parent=viz.ORTHO,pos=[400,500,0],fontSize=50)
viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegi n)



def walkAvatars():
walk2 = vizact.walkTo([0,0,15])
male.addAction(walk2)
vizact.onkeydown('c',walkAvatars)



def onCollideBegin(e):
if e.obj1 == rHandBox:
if e.obj2 == box1:
box1.color(viz.BLUE)
textScreen = viz.addText('Press a',parent=viz.ORTHO,pos=[400,500,0],fontSize=50)
viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegi n)

Frank Verberne
04-01-2014, 01:53 AM
The code did what it was supposed to do. Collision was detected when walking to (0,0,5), but you did not tell Vizard to do anything. Now it prints 'collision detected!' whenever the rHandBox collides with something. In your original code you had two identical onCollideBegin functions, one of which was obsolete. See the code below.
import viz
import vizact
viz.phys.enable()
viz.setMultiSample(4)
viz.fov(60)
viz.go()
male = viz.addAvatar('vcc_male.cfg')
male.scale(3,3,3)
ground = viz.add('tut_ground.wrl')
ground.collidePlane()
box = viz.add('box.wrl',scale=[2,2,2],pos=(0,0,5),color = viz.BLUE)
box.collideBox()
box.disable(viz.DYNAMICS)

env=viz.add(viz.ENVIRONMENT_MAP,'sky.jpg')
dome = viz.add('skydome.dlc')
dome.texture(env)
box1 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(0,0,15),color = viz.RED)
box1.collideBox()
box1.disable(viz.DYNAMICS)

box2 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(-10,0,0),color = viz.RED)
box2.collideBox()
box2.disable(viz.DYNAMICS)

box3 = viz.add('box.wrl',scale=[1.5,1.5,1.5],pos=(-20,0,0),color = viz.RED)
box3.collideBox()
box3.disable(viz.DYNAMICS)
rHandBox = viz.add('box.wrl',scale=[1,1,1])
rHandBox.collideBox()
rHandBox.disable(viz.DYNAMICS)
rHandBox.enable(viz.COLLIDE_NOTIFY)
rHandLink = viz.link( male.getBone('Bip01 R Foot') , rHandBox )
#tweak the position of the box to cover the hand
rHandLink.preTrans([0.05,-0.5,0])

def wukavatar():
walk1 = vizact.walkTo([0,0,5])
male.addAction(walk1)

vizact.onkeydown('w',wukavatar)

def walkAvatars():
walk2 = vizact.walkTo([0,0,15])
male.addAction(walk2)

vizact.onkeydown('c',walkAvatars)

def onCollideBegin(e):
if e.obj1 == rHandBox:
print 'collision detected!'
if e.obj2 == box1:
box1.color(viz.BLUE)
textScreen = viz.addText('Press a',parent=viz.ORTHO,pos=[400,500,0],fontSize=50)

viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegi n)