WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Stop for... loop (https://forum.worldviz.com/showthread.php?t=267)

 Johannes 01-10-2005 06:45 AM

Properties of Objects

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:
Code:

```for i in range(100):     if i == 50:         break```
About 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:
Code:

`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.
Code:

```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,info.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:

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)

Does not work.
Best,
Johannes

Here is the full changed Program
import viz
import vizmat

viz.go()

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.
Code:

```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,info.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.scale(3,3,3)
ground.collidePlane()
box.collideBox()
box.disable(viz.DYNAMICS)

dome.texture(env)
box1.collideBox()
box1.disable(viz.DYNAMICS)

box2.collideBox()
box2.disable(viz.DYNAMICS)

box3.collideBox()
box3.disable(viz.DYNAMICS)
rHandBox.collideBox()
rHandBox.disable(viz.DYNAMICS)
rHandBox.enable(viz.COLLIDE_NOTIFY)
#tweak the position of the box to cover the hand

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

def onCollideBegin(g):
if g.obj1 == rHandBox:
if g.obj2 == box:
box.color(viz.RED)
viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegi n)

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

def onCollideBegin(e):
if e.obj1 == rHandBox:
if e.obj2 == box1:
box1.color(viz.BLUE)
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.
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 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,onCollideBegin)```

 All times are GMT -7. The time now is 09:00 PM.