![]() |
#1
|
|||
|
|||
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. Last edited by Johannes; 01-10-2005 at 07:39 AM. |
#2
|
|||
|
|||
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?! Last edited by Johannes; 01-10-2005 at 07:43 AM. |
#3
|
|||
|
|||
Hi,
The break statement will cause a for/while loop to exit. Example: Code:
for i in range(100): if i == 50: break |
#4
|
|||
|
|||
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 |
#5
|
|||
|
|||
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) |
#6
|
|||
|
|||
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 |
#7
|
|||
|
|||
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. |
#8
|
|||
|
|||
>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 |
#9
|
|||
|
|||
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 |
#10
|
|||
|
|||
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) |
#11
|
|||
|
|||
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 |
#12
|
|||
|
|||
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) |
#13
|
|||
|
|||
Sorry that it did not post the program with the Indentation. How can I do post it better next time?
Johannesi |
#14
|
|||
|
|||
Use the code tags. You can access them by clicking the # symbol above, and then copy-pasting between the tags.
|
#15
|
|||
|
|||
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) |
#16
|
|||
|
|||
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. |
#17
|
|||
|
|||
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) |
#18
|
|||
|
|||
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 |
#19
|
|||
|
|||
Thank you!
|
#20
|
|||
|
|||
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) |
#21
|
|||
|
|||
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) |
![]() |
Thread Tools | |
Display Modes | Rate This Thread |
|
|