#1
|
|||
|
|||
Object.remove()
As in the beginning (see posting in old collision thread from 01-31-2005 05:19 PM) I'm again having problems with
object.remove() In my reset function I want to remove all the balls. for objects in ballBasket: objects.i=endI*slowDown objects.remove() for ball0503 in ballBasket: print ball0503 del ball0503 for ball0503 in ballBasket: print ball0503 The last print still gives me: <__main__.Ball instance at 0x00FD7DA0> <__main__.Ball instance at 0x00FD7E68> <__main__.Ball instance at 0x00FD7DA0> <__main__.Ball instance at 0x00FD7E68> The balls do not appear in the scene but they still seem to be there... Johannes P.S. Does someone have the Open Scene Graph plugin for 3D Studio 6 (I know that there exists one for 3DS 5 but not 6). |
#2
|
|||
|
|||
Regarding 3D Studio Max plug-ins, we will be releasing updated versions of the 3rd party osgExp plug-in that can be used to export directly from Max to Vizard. We will have both a Max 5 and Max 6 version available. You should find it on our download page by the Wed. next week.
|
#3
|
|||
|
|||
Hi,
When you call del ball0503 you are deleting the reference to the variable ball0503. However, the list still contains a reference to the ball. To delete the list you would need to do the following: Code:
del ballBasket[:] |
#4
|
|||
|
|||
Thanks for the answer and explanation
Johannes! |
#5
|
|||
|
|||
If an object as for example the balls have other wrl-files associated with them, these do not get deleted when the object itself gets deleted?!
class ball... self.node = viz.add('../resources/joNew/050305_ballRed.WRL') self.fGravityArrow= viz.add('../resources/joNew/arrow.WRL') So I guess I would have to use an array for the gravity-Arrows (put them in) and later delete it as (del (gravityArrow[:]) described by you? Johannes |
#6
|
|||
|
|||
Hi,
I don't understand. How are self.node and self.fGravityArrow associated? They seem to be two separate objects. |
#7
|
|||
|
|||
They belong to the same object, so why don't they get deleted if I delete the object?
|
#8
|
|||
|
|||
Hi,
Vizard objects are not deleted unless you explicitly delete them. So when your custom class is deleted you need to manually delete all the Vizard objects it contains. When you create a python class you can override a function which will be called when the object is deleted. Example: Code:
class MyObject: def __del__(self): #This is called when the object is deleted self.node.remove() self.fGravityArrow.remove() |
#9
|
|||
|
|||
!. All right, thank you. But do I not have to write del self.node and
del self.fGravityArrow as remove only removes it from the scene? I'm confused, sorry. 2. I'm still having crashes when I use Version 2.51c with stereo and fullscreen. I'm trying to play without the next 30 minutes to find out why. Johannes |
#10
|
|||
|
|||
Hi,
isolated a short piece of code that causes Vizard 2.51 on my machine to crash. Code:
# coding: UTF-8 import viz import vizmat import time import math import sys import vizinfo viz._AddNode(viz.VizNode(-1)) #cull = viz.add('cull.dlm') tracking=1 secondLight=0 remote=0 if tracking==0: viz.go() #viz.go(viz.ANAGLYPHIC) #viz.go(viz.QUAD_BUFFER) view = viz.get(viz.MAIN_VIEWPOINT) view.translate(2.5009684562683105, 1.013837456703186, -0.24669347703456879)#1.3269580602645874, 1.013837456703186, -0.55598777532577515) #view.translate(0.051076151430606842, 0.89280927181243896, -1.1567113399505615) view.spinto(0,1,0,-90,450) else: view = viz.get(viz.MAIN_VIEWPOINT) viz.go(viz.PROMPT) headPPT = viz.add('vizppt.dls') data = headPPT.get() v = viz.add('intersense.dls') viz.tracker() if (secondLight==1): fistPPT = viz.add('vizppt.dls') fistPPT.command(6,'',1,1,1) viz.eyeheight(-0.3) What do I need to change? Johannes |
#11
|
|||
|
|||
Hi,
Have you tried commenting out the sensors? |
#12
|
|||
|
|||
Hi,
sure, if I comment out everything it will work . No, seriously: # headPPT = viz.add('vizppt.dls') # data = headPPT.get() # v = viz.add('intersense.dls') solves the problem but I guess I somehow need this or not?! As I said, worked in the old version. Have you been able to replicate this error on your machine? Johannes |
#13
|
|||
|
|||
Hi,
I ran your script without any crashes, but I don't have any sensors connected. This is why I believe the problem comes from one of the sensors. Keep uncommenting the sensor code one line at a time until the crash appears. This will help isolate the problem. |
#14
|
|||
|
|||
Hi,
it is this line that matters: v = viz.add('intersense.dls') Without it it works, with it it does not. Best, Johannes P.S. If possible, please end my confusion form Post 119: All right, thank you. But do I not have to write del self.node and del self.fGravityArrow as remove only removes it from the scene? I'm confused, sorry. 2. If it is not possible to fix the problem with the crash, I could install the old Version again or live with it for a few days... Have a great evening. Last edited by Johannes; 05-24-2005 at 03:23 PM. |
#15
|
|||
|
|||
Hi,
Do you have the intersense server program running? Also, when you connect to the intersense have you tried explicitly declaring which port to connect to? For example, if you know the intersense is connected on COM1 then do the following: Code:
PORT_INTERSENSE = 1 v = viz.add('intersense.dls') |
#16
|
|||
|
|||
Thank you, this worked! Also thank you for the explanation!
Best, Johannes |
#17
|
|||
|
|||
Intersection with a ghost
Hi,
because colissions can not work prcecise enough I'm developing a workaround: After each time-step my moving objects also calculate where they would be at the next timestep. If there would be a colission with some object or beween two movin objects I set the next Position to that colissionPosition... The problem I have right now is right at the beginning: Code:
for object in collidablesBall: info=object.intersect(ball0503.actualPos.get(), ball0503.nextPos.get()) if info.intersected: Problem: Also the balls I remove are not in the collidablesBall Array they trigger a intersect printout. Second - they are removed from the scene and still do that?! Can removed objects still trigger an intersect-Event? Other possibility: I will go through it and look if I have some invisible Objects somewhere. Johannes |
#18
|
|||
|
|||
Hi,
Removed objects and invisible objects cannot trigger intersections. From the code you posted, the only object that can be returned from the intersect call is object. Can you modify your code to the following and see if "WARNING" is printed out? Code:
for object in collidablesBall: info=object.intersect(ball0503.actualPos.get(), ball0503.nextPos.get()) if info.intersected: if info.object != object: print 'WARNING' |
#19
|
|||
|
|||
Hi,
sorry, found the mistake. ball0503.actualPos.get(), ball0503.nextPos.get() stayed the same after the ball was caught. So always the glider came back to that position it triggered again an intersect-event. Sorry for bothering you, Johannes |
#20
|
|||
|
|||
My workaround seems to have a problem:
What I do: After each time-step my moving objects also calculate where they would be at the next timestep. If there is a colission (measured by the intersection of the line between actualPos towards nextPos and the object) with some object or beween two moving objects I set the next Position to that intersectionPosition... Problem: info=object.intersect(ball0503.actualPos.get(), ball0503.nextPos.get()) uses only the acutual position of the object. If the object itself is moving it will not be there in the next step. So it would actually be good to have a "ghost-object" e.g. info=ghost-Object.intersect(ball...) but as invisible objects do not trigger intersections i have to think about another idea.... How would you improve the accuracy of the vizard-collissions? The problem with the normal colissions is for example when there is a lot of load on the CPU the colission get's recognized too late, so the object is already outside of the possible space... If you then turn velocity (reflect...) in the opposite direction it will have a colission at the next timestep again so it will turn around again (outside the possible space)... Hope I made my problem clear... Johannes |
#21
|
|||
|
|||
Hi,
There is a way to have invisible objects trigger intersections. Instead of setting the visiblity of the object, disable rendering on the object. Example: Code:
#Don't render the object, but allow it to be susceptible to collisions and picking object.disable(viz.RENDERING) |
#22
|
|||
|
|||
1. Thank you, yes I will try the object.disable(viz.RENDERING)...
2. @ perform an intersect test on each object instead of all at once: a) If I understand you right you mean something like info = viz.intersect(ball0503.actualPos.get(), ball0503.nextPos.get()) b) Reason: Because some objects should not trigger an intersection event e.g. ball-traces of other balls... Would it save CPU-time to do the above and use if info.object == glider if info.object != traceBall... Have a good evening, Johannes |
#23
|
|||
|
|||
Hi,
That's what object.disable(viz.COLLISION) is for. |
#24
|
|||
|
|||
Similar Question
I am also trying to remove items using object.remove. First, I add 4 avatars (NUM_AVATARS) to an array. They will be removed as they are shot by the user. The problem I'm having is how to add them again if one of them is taken off. I have the 4 avatars, but I would like for them to be added to the array once they have been shot (causing a remove). I was thinking of saying something like "if the number of array elements is not 4, add another avatar". Can I do this and if so, how. Also, would this be the best way to go about doing this. Here is what I have so far.
Code:
Create avatars coming from the front for i in range(NUM_AVATARS): newX = -math.cos(-2*i+15) * 2 newZ = math.sin(i^2+1) * 2 male = viz.add('male.cfg') #male.face(facepic) male.translate(newX,-10,newZ) male.rotate(90,-10,0) #we might be able to use this type of declaration when we need to decide who is safe to shoot and who isn't male.SafeIndicator = 1 avatars.append(male) #Save avatar in list print "avatar indicator is", male.SafeIndicator #Two differnt options for moving avatars #Create a walk action that will randomly select a location between (-5,-5) and (5,5) RandomWalkAction = vizact.walkto(vizact.randfloat(-5,5),court,vizact.randfloat(-10,5)) #Create a walk action that will randomly select a location between (-5,-5) and (5,5) WalkForever = vizact.sequence(vizact.walkto(vizact.randfloat(-2,5),0,vizact.randfloat(-10,5)),viz.FOREVER) def walkAvatar(starter): global court walk = starter.walkto(0,court,-10.5,1,0,2) #Clear all the avatar's actions, reposition it, and start the walk action starter.clear(viz.ALL) # starter.translate(duckBeginPos) # starter.rotate(duckBeginOri) starter.act(walk) #Add walk action to avatar #starter.add(WalkForever) #Add walk action to avatar when spacebar is pressed #vizact.onkeydown(' ',starter.add,RandomWalkAction) if avatars[0] or avatars[1] or avatars[2] or avatars[3] == 0: print 'empty avatar at avatar' avatars.append(male) walkAvatar(male) print 'avatar added' |
#25
|
|||
|
|||
Hi,
I'm not exactly sure what you are trying to do. The code you provided does not reference any remove command. Can you be more specific to what you are trying to do? Also, for future reference can you create a new thread when asking questions on the forum. |
#26
|
|||
|
|||
The code to remove is here:
Code:
def onmousedown(button): global index if button == viz.MOUSEBUTTON_LEFT: node = viz.pick() #Get object that was clicked if node in avatars: #Check if object is one of the avatars node.clear(viz.ALL) node.clear(viz.CURRENT_ACTION) node.execute(7) #Execute the "shot" animation #Create action to wait for the animation duration then freeeze the avatar WaitThenFreeze = vizact.sequence( vizact.waittime(node.getduration(7)-.14), vizact.speed_node(0)) #vizact.sequence(vizact.waittime(2),avatars.remove(male),1) node.add(WaitThenFreeze) #Add the action to the avatar node.clear(viz.ALL) node.clear(viz.CURRENT_ACTION) node.add(vizact.waittime(1)) node.add(vizact.call(node.remove)) index = index - 1 if index == 0 : print 'new index is',index for i in range(NUM_AVATARS): newX = -math.cos(-2*i+15) * 2 newZ = math.sin(i^2+1) * 2 male = viz.add('male.cfg') #male.face(facepic) male.translate(newX,-10,newZ) male.rotate(90,-10,0) #we might be able to use this type of declaration when we need to decide who is safe to shoot and who isn't male.SafeIndicator = 1 avatars.append(male) #Save avatar in list print "avatar indicator is", male.SafeIndicator viz.callback(viz.MOUSEDOWN_EVENT,onmousedown) |
#27
|
|||
|
|||
Hi,
I'm still not clear on what you are trying to accomplish. Calling object.remove() will permanently remove the object. Once it is removed you can't use it anymore. If you only plan on having 4 avatars at a time, I suggest you add them all at the beginning of your script. Then instead of removing them permanently, just make them invisible. Then when you want to reuse them later on make them visible again. I would provide sample code if you explained exactly what you want to do. |
#28
|
|||
|
|||
Ok, what happens is that this is a shooting scenario where the subject is presented with a new avatar every certain interval of time (say 2 seconds). Currently, this occurs until 4 avatars have appeared. Now, each time a user shoots an avatar, I would like for the avatar to fall, disappear, and be ready to restart from the original position. We have not decided whether this should happen automatically or if they should re-appear after a stimulus (say keyboard entry). We are leaning towards the re-appearing happening automatically. I thought I would have to remove the avatar from the array and re-append him after he was removed. Am I looking at this the wrong way?
|
#29
|
|||
|
|||
Hi,
That sounds fine. Here is really simple script that allows you to click an avatar. When it is clicked it will fall to the ground and disappear. Press the spacebar to bring the next available avatar back to life. What you want is something like the RemoveAvatar and RestoreAvatar functions. Instead of calling the function in response to a keyboard press you can call it in response to a stimuli or whatever you want. Let me know if this isn't what you wanted: Code:
import viz viz.go() avatars = [] dead_list = [] #Create six avatars for i in range(6): male = viz.add('male.cfg') male.translate(i,0,0) male.rotate(180,0,0) male.state(1) avatars.append(male) #Save avatar in list def RemoveAvatar(avatar): avatar.visible(0) #Hide avatar avatar.speed(1) #Restore speed avatars.remove(avatar) #Remove from list dead_list.append(avatar) #Add to dead list def RestoreAvatar(): if len(dead_list): avatar = dead_list.pop() #Ressurrect dead avatar avatar.visible(1) #Make it visible avatars.append(avatar) #Add it to avatar list def onmousedown(button): if button == viz.MOUSEBUTTON_LEFT: node = viz.pick() #Get object that was clicked if node in avatars: #Check if object is one of the avatars node.execute(7) #Execute the "shot" animation #Create action to wait for the animation duration then freeeze the avatar WaitThenFreeze = vizact.sequence( vizact.waittime(node.getduration(7)-0.2), vizact.speed_node(0) ) node.add(WaitThenFreeze) #Add the action to the avatar RemoveAvatarAction = vizact.call(RemoveAvatar,node) node.add(RemoveAvatarAction) #Add action to remove avatar viz.callback(viz.MOUSEDOWN_EVENT,onmousedown) #Restore next available avatar vizact.onkeydown(' ',RestoreAvatar) #Move viewpoint so that all avatars are visible viz.move(2.5,0,-10) #Disable mouse navigation viz.mouse(0) |
#30
|
|||
|
|||
Works great. I did however want to ask you, is there a way to say "if the number of avatars does not equal 4, restore the avatar. I tried using
Code:
#Restore next available avatar vizact.sequence(vizact.waittime(4),RestoreAvatar) #instead of using onkeydown #vizact.onkeydown(' ',RestoreAvatar) |
Thread Tools | |
Display Modes | Rate This Thread |
|
|