from direct.showbase.DirectObject import DirectObject
from direct.task.Task import Task
from pandac.PandaModules import Vec4, CollisionTraverser, CollisionRay, CollisionHandlerQueue, CollisionNode, GeomNode, TextureStage
from direct.interval.IntervalGlobal import *
class Picker(DirectObject):
def __init__(self, world):
self.world = world
self.hoveredObject = render.attachNewNode("dummy node")
self.tex = loader.loadTexture('green.png')
self.ts = TextureStage('ts')
self.ts.setSort(1)
self.ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSPrevious, TextureStage.COSrcColor, TextureStage.CSConstant, TextureStage.COSrcColor, TextureStage.CSConstant, TextureStage.COSrcAlpha)
self.fromAlpha = 0.5
self.toAlpha = 0.1
self.animateColorForward = LerpFunc(self.paintColor, fromData = self.fromAlpha, toData = self.toAlpha, duration = 1.0, blendType = 'easeInOut', extraArgs = [], name = "AnimateColorForward")
self.animateColorBackward = LerpFunc(self.paintColor, fromData = self.toAlpha, toData = self.fromAlpha, duration = 1.0, blendType = 'easeInOut', extraArgs = [], name = "AnimateColorBackward")
self.animateColor = Sequence(self.animateColorForward, self.animateColorBackward)
self.animateColor.loop()
self.animateColor.pause()
self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
self.collTrav = CollisionTraverser() #the collision traverser. we need this to perform collide in the end
#self.collTrav.showCollisions(render) #just to visualize the collisions
self.queue = CollisionHandlerQueue()
self.pickerNode = CollisionNode('mouseRay') #Node which will contain collision ray
self.pickerNP = camera.attachNewNode(self.pickerNode) #NodePath to pickerNode, notice that pickerNode is now getting attached to camera NodePath
self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.pickerRay = CollisionRay()
self.pickerNode.addSolid(self.pickerRay)
self.collTrav.addCollider(self.pickerNP, self.queue)
def mouseTask(self, task):
if base.mouseWatcherNode.hasMouse():
mpos = base.mouseWatcherNode.getMouse()
self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
self.collTrav.traverse(render)
if self.queue.getNumEntries() > 0: #if there are collision detected
self.queue.sortEntries() #sort collision, ones which are closer to source of ray go first
entry = self.queue.getEntry(0) #we need only first entry (one nearest to camera)
if self.hoveredObject != entry.getIntoNodePath(): #if hovered object is changed
self.hoveredObject.clearTexture()
self.hoveredObject = entry.getIntoNodePath()
self.animateColor.resume()
self.hoveredObject.setTexture(self.ts, self.tex)
elif self.animateColor.isPlaying() != True: #if object is not changed and it is not animating
self.animateColor.resume() #so we dont start interval on each frame while mouse is hovering
self.hoveredObject.setTexture(self.ts, self.tex)
else:
self.hoveredObject.clearTexture()
self.animateColor.pause()
return Task.cont
def paintColor(self, t):
self.ts.setColor(Vec4(0.3, 0.8, 0, t))