PDA

View Full Version : Picking up Vizard Objects on mouse down with collisions


pwsnow
09-12-2012, 08:42 AM
I'm trying to pick up vizard objects using a vizshape sphere as an end effector.

Because I have multiple objects I'm using onCollideBegin to grab the objects when the end effect collides with the object to be picked up. This work fine but the end effector doesn't let go of the object and it is automatic, however I want to be able to pick up objects when I touch them and hold them as long as the left mouse button is pressed. Releasing the object once the left mouse button is released. I have the below code in my updateview method:

def onCollideBegin(e):
#while vizact.whilemousedown(viz.MOUSEBUTTON_LEFT):
if e.obj1 == sphere:
if e.obj2 == cube:
link = viz.grab(sphere,cube)
#viz.playSound( 'crashNew.wav' )

libc.haDeviceSendString(dev, "set myDamper enable",response)
if e.obj2 == cube2:
link = viz.grab(sphere,cube2)
libc.haDeviceSendString(dev, "set myDamper enable",response)
if e.obj2 == ball:
link = viz.grab(sphere,ball)
libc.haDeviceSendString(dev, "set myDamper enable",response)
viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegi n)

#vizact.whilemousedown(viz.MOUSEBUTTON_LEFT,onColl ideBegin)

def onCollideEnd(e):
if e.obj1 == sphere:
if e.obj2 == cube:
link = None
libc.haDeviceSendString(dev, "set myDamper disable",response)
if e.obj2 == cube2:
link = None
libc.haDeviceSendString(dev, "set myDamper disable",response)
if e.obj2 == ball:
link = None
libc.haDeviceSendString(dev, "set myDamper disable",response)
viz.callback(viz.COLLIDE_END_EVENT,onCollideEnd)




vizact.onmousedown(viz.MOUSEBUTTON_LEFT,onCollideB egin)
#vizact.whilemousedown(viz.MOUSEBUTTON_LEFT,onColl ideBegin)
vizact.onmouseup(viz.MOUSEBUTTON_LEFT,onCollideEnd )
#vizact.whilemouseup(viz.MOUSEBUTTON_LEFT,onCollid eEnd)

Because def onCollideBegin/End is using an event how would I "wrap up" these two methods with the mouse down/up?

Many thanks.

Jeff
09-13-2012, 03:49 PM
Here's an example that uses viz.phys.intersectNode to determine if the hand and object are intersecting. If they are intersecting and the mouse event occurs the object will be grabbed:
import viz
import vizact
import vizmat
import viztracker

viz.setMultiSample(4)
viz.fov(60)
viz.go()

piazza = viz.add('piazza.osgb')

#Add crates marker for participant to walk to
crate1 = viz.addChild('crate.osgb',pos=[-0.3,0.3,4],scale=[0.6,0.6,0.6])
crate2 = crate1.clone(pos=[0.35,0.3,4],euler=[5,0,0],scale=[0.6,0.6,0.6])
crate3 = crate1.clone(pos=[0.3,0.9,4.1],euler=[-5,0,0],scale=[0.6,0.6,0.6])

arrow = viz.addChild('arrow.wrl',scale=[0.3,0.3,0.3])

#enable physics and apply shapes
viz.phys.enable()
piazza.collideMesh()
crate1.collideBox()
crate2.collideBox()
crate3.collideBox()
arrow.collideBox()
arrow.disable( viz.DYNAMICS )
arrow.disable( viz.PHYSICS )

#Link arrow to mousetracker
viewTracker = viztracker.Keyboard6DOF()
viewlink = viz.link( viewTracker, viz.MainView )
viewlink.preTrans([0,1.5,0])
tracker = viztracker.MouseTracker()
trackerlink = viz.link( tracker, arrow )
trackerlink.postTrans([0,0,-5])
closest = None

def updateClosest():
global closest
list = viz.phys.intersectNode( arrow )

if list != []:

for object in list:
if object == piazza:
list.remove(piazza)

closestDistance = 999999

arrowPos = arrow.getPosition()
for object in list:
distance = vizmat.Distance(arrowPos,object.getPosition())
if distance < closestDistance:
closest = object
closestDistance = distance
else:
closest = None


vizact.onupdate(viz.PRIORITY_DEFAULT,updateClosest )

link = None
grabbedObject = None
def onMouseDown():
global link, grabbedObject
if closest is not None:
link = viz.grab( arrow, closest )
grabbedObject = closest

def onMouseUp():
global link, grabbedObject
if grabbedObject is not None:
link.remove()
grabbedObject = None

vizact.onmousedown( viz.MOUSEBUTTON_LEFT, onMouseDown )
vizact.onmouseup( viz.MOUSEBUTTON_LEFT, onMouseUp )

pwsnow
09-17-2012, 03:02 AM
Excellent, works like a charm.

Many thanks again!