multiselection rts

Hi!
like a Rts as supreme commander, I’d like get all object in the selection. The projection of my rectangular that i draw in the screen, is a trapezium on the map (if it a plane without mountains)
how can i get all object in pyramid that has as big base the trapezium on the map and has the little base the rectangular that i draw with the mouse?

I hope i explain my trouble!! :astonished:

[Drag Selecting multiple nodes)
might help you.

Thanks for your answer!

i see this example, but in this code there’re 4 plane and than traverse through render. if i have 1000 clickable unit, this code is not better solution i think… or do i wrong?

if i create 4 straight line dependent by parameter, i could create a polygon with 4 vertices. i add a task that slips the polygon updating the 4 vertices.
is this solution better than the previous?

I write this code to get the selected objects… is this solution better than the previous?

from math import pi, sin, cos
import random as rand
import sys
 
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core import Point3, Point2, CardMaker
from pandac.PandaModules import * 

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
 
        # Disable the camera trackball controls.
        self.disableMouse()

        cm = CardMaker("cardMaker")
        cm.setFrame(-50, 50, -50, 50)
        cm.setColor(1, 0, 0, 1)
        base.render.attachNewNode(cm.generate()).setP(270)
 
        
        self.queue = CollisionHandlerQueue()
        self.trav = CollisionTraverser()
        
        # Load and transform the panda actor.
        for i in range(100):
            smile = self.loader.loadModel("smiley")
            smile.reparentTo(self.render)
            smile.setPos(0+rand.randint(-40, 40), 0+rand.randint(-4, 4), 3)
            smile.setCollideMask(BitMask32.allOff())
            
            cnode = smile.attachNewNode(CollisionNode("smile-collision"))
            cnode.node().addSolid(CollisionSphere(0, 0, 0, 1))
            cnode.node().setFromCollideMask(BitMask32.bit(20))
            cnode.node().setIntoCollideMask(BitMask32.allOff())
            cnode.show()
            self.trav.addCollider(cnode, self.queue)
        
        
        self.accept("mouse1", self.beginSelection)
        self.accept("mouse1-up", self.endSelection)
        
        base.cam.setPos(0, -50, 30)
        base.cam.setHpr(35, -20, 0)
        base.cam.node().getLens().setNearFar(1, 100)
    
    def beginSelection(self):
        self.startPoint = base.mouseWatcherNode.getMouseX(), base.mouseWatcherNode.getMouseY()
    def endSelection(self):
        endPoint = base.mouseWatcherNode.getMouseX(), base.mouseWatcherNode.getMouseY()
        point1 = Point2(self.startPoint[0], self.startPoint[1])
        point2 = Point2(self.startPoint[0], endPoint[1])
        point3 = Point2(endPoint[0], self.startPoint[1])
        point4 = Point2(endPoint[0], endPoint[1])
        lines = []
        def getLine(n, f): return lambda t:  n+(f-n)*t
        for point in [point1, point2, point3, point4]:
            nPoint, fPoint = Point3(), Point3()
            base.cam.node().getLens().extrude(point, nPoint, fPoint)
            lines.append(getLine(base.render.getRelativePoint(base.cam,nPoint), base.render.getRelativePoint(base.cam,fPoint)))
        cnode = CollisionNode("selection-node")
        for i in range(101):
            cnode.addSolid(CollisionPolygon(lines[0](i/101.0), lines[1](i/101.0), lines[2](i/101.0)))
            cnode.addSolid(CollisionPolygon(lines[3](i/101.0), lines[2](i/101.0), lines[1](i/101.0)))
        cnode.setIntoCollideMask(BitMask32.bit(20))
        cnode.setFromCollideMask(BitMask32.allOff())
        node = base.render.attachNewNode(cnode)
        node.show()
        self.trav.traverse(base.render)
        found = set(entry.getFromNodePath().getParent() for entry in self.queue.getEntries())
        print found, len(found)
        
app = MyApp()
app.run()

thanks for all!