def getObjectsUnderMouse(self): vp = base.viewportMgr.activeViewport if not vp: return [] entries = vp.click(self.Mask) if not entries or len(entries) == 0: return [] objects = [] key = self.Key for i in range(len(entries)): # Our entries have been sorted by distance, so use the first (closest) one. entry = entries[i] np = entry.getIntoNodePath().findNetPythonTag(key) if not np.isEmpty(): # Don't backface cull if there is a billboard effect on or above this node if entry.hasSurfaceNormal() and not LEUtils.hasNetBillboard( entry.getIntoNodePath()): surfNorm = entry.getSurfaceNormal(vp.cam).normalized() rayDir = entry.getFrom().getDirection().normalized() if surfNorm.dot(rayDir) >= 0: # Backface cull continue obj = np.getPythonTag(key) actual = self.getActualObject(obj, entry) objects.append((actual, entry)) return objects
def mouseDown(self): vp = base.viewportMgr.activeViewport if not vp: return if vp.is3D(): # If we clicked in the 3D viewport, try to intersect with an existing MapObject # and immediately place the entity at the intersection point. If we didn't click on any # MapObject, place the entity on the grid where we clicked. entries = vp.click(GeomNode.getDefaultCollideMask()) if entries and len(entries) > 0: for i in range(len(entries)): entry = entries[i] # Don't backface cull if there is a billboard effect on or above this node if not LEUtils.hasNetBillboard(entry.getIntoNodePath()): surfNorm = entry.getSurfaceNormal(vp.cam).normalized() rayDir = entry.getFrom().getDirection().normalized() if surfNorm.dot(rayDir) >= 0: # Backface cull continue # We clicked on an object, use the contact point as the # location of our new entity. self.pos = entry.getSurfacePoint(self.doc.render) self.hasPlaced = True # Create it! self.confirm() break else: # Didn't click on an object, intersect our mouse ray with the grid plane. plane = LPlane(0, 0, 1, 0) worldMouse = vp.viewportToWorld(vp.getMouse()) theCamera = vp.cam.getPos(render) # Ensure that the camera and mouse positions are on opposite # sides of the plane, or else the entity would place behind us. sign1 = plane.distToPlane(worldMouse) >= 0 sign2 = plane.distToPlane(theCamera) >= 0 if sign1 != sign2: pointOnPlane = Point3() ret = plane.intersectsLine(pointOnPlane, theCamera, worldMouse) if ret: # Our mouse intersected the grid plane. Place an entity at the plane intersection point. self.pos = pointOnPlane self.hasPlaced = True self.confirm() return # The user clicked in the 2D viewport, draw the visualization where they clicked. self.showVis() self.updatePosFromViewport(vp) self.mouseIsDown = True self.hasPlaced = True