PDA

View Full Version : Object.remove()


Johannes
05-20-2005, 10:52 AM
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).

tobin
05-20-2005, 12:20 PM
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.

farshizzo
05-23-2005, 11:17 AM
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:del ballBasket[:]

Johannes
05-23-2005, 04:37 PM
Thanks for the answer and explanation
Johannes!

Johannes
05-24-2005, 11:10 AM
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

farshizzo
05-24-2005, 11:13 AM
Hi,

I don't understand. How are self.node and self.fGravityArrow associated? They seem to be two separate objects.

Johannes
05-24-2005, 12:14 PM
They belong to the same object, so why don't they get deleted if I delete the object?

farshizzo
05-24-2005, 12:28 PM
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:class MyObject:
def __del__(self):
#This is called when the object is deleted
self.node.remove()
self.fGravityArrow.remove()

Johannes
05-24-2005, 12:36 PM
!. 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

Johannes
05-24-2005, 12:51 PM
Hi,
isolated a short piece of code that causes Vizard 2.51 on my machine to crash.



# 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)




It does it on two different computers. If I use tracking=0 it works fine. Also worked fine in the older Version.

What do I need to change?

Johannes

farshizzo
05-24-2005, 01:58 PM
Hi,

Have you tried commenting out the sensors?

Johannes
05-24-2005, 02:39 PM
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

farshizzo
05-24-2005, 03:10 PM
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.

Johannes
05-24-2005, 03:18 PM
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.

farshizzo
05-24-2005, 03:33 PM
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:PORT_INTERSENSE = 1
v = viz.add('intersense.dls')

Calling del on a Vizard object has no effect in regards to the graphics scene. del is simply a python command that undeclares a variable. You do not need to call del on self.node or self.fGravityArrow. That will automatically be done when you call del on the object which contains them. However, if you want to delete them from the graphics scene, then you must call the remove() function.

Johannes
05-25-2005, 11:20 AM
Thank you, this worked! Also thank you for the explanation!

Best,
Johannes

Johannes
06-09-2005, 01:28 PM
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:

for object in collidablesBall:

info=object.intersect(ball0503.actualPos.get(), ball0503.nextPos.get())
if info.intersected:



I also remove certain balls from the scene.

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

farshizzo
06-09-2005, 02:05 PM
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? for object in collidablesBall:
info=object.intersect(ball0503.actualPos.get(), ball0503.nextPos.get())
if info.intersected:
if info.object != object:
print 'WARNING'

Johannes
06-09-2005, 02:54 PM
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

Johannes
06-09-2005, 03:20 PM
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

farshizzo
06-09-2005, 03:51 PM
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:#Don't render the object, but allow it to be susceptible to collisions and picking
object.disable(viz.RENDERING)

Also, why do you perform an intersect test on each object separately, instead of doing them all at once? This would save you a lot of CPU time, especially if you have a lot of objects.

Johannes
06-09-2005, 04:27 PM
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

farshizzo
06-09-2005, 05:07 PM
Hi,

That's what object.disable(viz.COLLISION) is for. :)

betancourtb82
03-01-2006, 12:48 PM
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.

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'

farshizzo
03-01-2006, 01:13 PM
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.

betancourtb82
03-01-2006, 01:16 PM
The code to remove is here:

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)

farshizzo
03-01-2006, 01:20 PM
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.

betancourtb82
03-01-2006, 01:27 PM
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?

farshizzo
03-01-2006, 01:50 PM
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: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)

betancourtb82
03-07-2006, 09:43 AM
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 #Restore next available avatar
vizact.sequence(vizact.waittime(4),RestoreAvatar)
#instead of using onkeydown
#vizact.onkeydown(' ',RestoreAvatar)

farshizzo
03-08-2006, 10:13 AM
vizact.sequence only accepts actions. RestoreAvatar is not an action, it is a regular python function. To turn it into an action you need to do the following:vizact.sequence(vizact.waittime(4),vizac t.call(RestoreAvatar))