WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Object.remove() (https://forum.worldviz.com/showthread.php?t=359)

Johannes 05-20-2005 10:52 AM

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

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

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

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.

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)

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

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

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:

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

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

#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

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'


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:

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)


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


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

#Restore next available avatar
vizact.sequence(vizact.waittime(4),RestoreAvatar)
#instead of using onkeydown
#vizact.onkeydown(' ',RestoreAvatar)



All times are GMT -7. The time now is 01:05 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Copyright 2002-2018 WorldViz LLC