Basic questions: How to... for beginners!

Hi all :smiley:

I’m trying to start with Panda 3D. I’ve already take a look at the Chessboard, Music-box and Roaming-Ralph examples but i try to start making some stuff and i get lost… I will put this by steps, if somenone can help me i would aprreciate a lot 8)

  1. I want to have a world like in Roaming-Ralph (I already have the example so it’s easy if i use it … but i would like to create an own world )

  2. I want to have some objects in that world so i can select them

  3. After selecting i would like to have acess to a menu of options

  4. After selecting an option i would like to load some information from a webserver, at a first phase it could be only text from a PHP file

Is that possible ? Someone can help me ? Where i can find step-by-step tutorials ? :confused:

Best Regards and Thanks :unamused:

panda3d.org/manual/index.php/Main_Page

Covers perty much everything you wanted. Now it doesn’t put all that in one, but does cover loading to networking connections. Check out F., all; C., all; L., all; U., all; and AA, all.

ATM, theres no demo/tut that covers all that at once.

To creat your own world, you’ll want to use a 3d modeling program. I would recommand deled. Its easy to learn and the community perty nice. It’s also going open source soon, so you should check it out.

Thanks :slight_smile:

I’m trying to do with the manual but i’m a bit lost… i dont know where to start…

I’m in step 1… i’ve loaded an object equal to ralph (i’m working with roaming-ralph) and i’m trying to make that object clickable but i’m getting the error: NameError: global name “objecto” is not defined.

Seems some problem with declaring variables, someone can help me ?

i have the code:

        objectoStartPos = self.environ.find("**/start_point").getPos()
        self.objecto = loader.loadModel("models/ralph")
        self.objecto.reparentTo(render)
        self.objecto.setScale(.8)
        self.objecto.setPos(objectoStartPos+(0,0,2))
        objecto.setTag('objecto', '1')
		
        #teste clicks
		
        pickerNode=CollisionNode('mouseRay')
        pickerNP=camera.attachNewNode(pickerNode)
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        pickerRay=CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser.addCollider(pickerNP, myHandler)
		
        def myFunction():
            mpos=base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            myTraverser.traverse(render)
   
            if myHandler.getNumEntries() > 0:
                myHandler.sortEntries()
                pickedObj=myHandler.getEntry(0).getIntoNodePath()
                pickedObj=pickedObj.findNetTag('objecto')
            if not pickedObj.isEmpty():
                handlePickedObject(pickedObj)
self.objecto.setPos(objectoStartPos+(0,0,2)) 
objecto.setTag('objecto', '1')

You’re missing “self.” in the second line here.

hehe thanks :slight_smile:

Now it’s another error of the same kind:

NameError: global name “myHandler” is not defined.

It’s sad to be noob :unamused:

solved, just added this:

        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue() 

But now i have this error:

:collide(error): Invalid attempt to detect collision from CollisionRay into Col
isionRay!

This means that a CollisionRay object attempted to test for an
intersection into a CollisionRay object. This intersection
test has not yet been defined; it is possible the CollisionRay
object is not intended to be collidable. Consider calling
set_into_collide_mask(0) on the CollisionRay object, or
set_from_collide_mask(0) on the CollisionRay object.

can someone help me ?
[/code]

Your ray is attempting to collide with itself. Do:

pickerNode.setIntoCollideMask(BitMask32(0))

David

Eheheh thanks David, it launches without errors :stuck_out_tongue:

But i click on the “objecto” and dont happen nothing, how i make to click in the “objecto” and appear a menu with options ? I’m really lost here … it’s suppossed to be myFunction right ? :astonished:

I see a tutorial developing here, right emekapa?
:slight_smile:

I am watching yo’all :wink:

I hope so, but it isnt easy… i cant get it working :frowning:

First get this to work and then I’ll help you with a pop-up menu. (Sorry would write some code for you, but really don’t have a lot of time, even thos it’s my b-day today ^^.)

First, look up something called task, and learn how they work:

panda3d.org/manual/index.php/L … anda_Model
panda3d.org/manual/index.php/Tasks

Then make sure you have this code listed below:

panda3d.org/manual/index.php/C … 3D_Objects

Now we then assian it to a key:

panda3d.org/manual/index.php/Keyboard_Support

Example on how this would look ish (so don’t use it lol):

    def Controls(self):
      #Defindes our keymap
      self.keyMap = {"menu":0, "left":0, "right":0, "forward":0, "back":0, "jump":0, "shoot":0}
      #Accept the control keys for movement
      self.accept("escape", self.setKey, ["menu",1])
      self.accept("a", self.setKey, ["left",1])
      self.accept("d", self.setKey, ["right",1])
      self.accept("w", self.setKey, ["forward",1])
      self.accept("s", self.setKey, ["back",1])
      self.accept("space", self.setKey, ["jump",1])
      self.accept("mouse1", self.setKey, ["shoot",1])

      self.accept("escape-up", self.setKey, ["menu",0])
      self.accept("a-up", self.setKey, ["left",0])
      self.accept("d-up", self.setKey, ["right",0])
      self.accept("w-up", self.setKey, ["forward",0])
      self.accept("s-up", self.setKey, ["back",0])
      self.accept("space-up", self.setKey, ["jump",0])
      self.accept("mouse1-up", self.setKey, ["shoot",0])

After we have everything this far. Lets put it all togather. After you make the example code above, add a task command to check for those keys. Usally people call this a “controls” task. As you learn and use the task command you’ll start to see the power behind them.

Example of this:

      #Controls for moving around.
      taskMgr.add(self.move,"moveTask")

After we set that up, we have to now setup a def name move and make it a task by definding that in the (). We can also add our if/check and to make life easy and since we all ready def the code to shoot, we just make a “hot link” to our predefinde code.:

    def move(self, task):
      if (self.keyMap["shoot"]!=0):
         self.myFunction()

or do it the long way:

    def move(self, task):
      if (self.keyMap["shoot"]!=0):
        mpos=base.mouseWatcherNode.getMouse()
        pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

        myTraverser.traverse(render)
       #assume for simplicity's sake that myHandler is a CollisionHandlerQueue
        if myHandler.getNumEntries() > 0:
          myHandler.sortEntries() #this is so we get the closest object
          pickedObj=myHandler.getEntry(0).getIntoNodePath()
          pickedObj=pickedObj.findNetTag('myObjectTag')
          if not pickedObj.isEmpty():
            handlePickedObject(pickedObj)

Heheh Happy Birthday!!! :smiley:

Thanks for the help, i’ll try it and i will say something in the next 30 hours i hope :stuck_out_tongue:

eheh Thanks for your tips :stuck_out_tongue:

I’ve made to configure the arrow_down to ralph walk backward and i have seen the tips you gave me! But it seems i still cant select the model! Now when i try to click in anything it shows me the error: Atribute Error: World instance has no attribute “select” (seems i’m using the select in th wrong place).

Let’s imagine i want to click in the model and appears printed “Hello World” (after that, will try to make the popup menu :stuck_out_tongue:)

I’ve made the changes:

#keymap

self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "backward":0, "select":0}

#Load the model:
        objectoStartPos = self.environ.find("**/start_point").getPos()
        self.objecto = loader.loadModel("models/ralph")
        self.objecto.reparentTo(render)
        self.objecto.setScale(.8)
        self.objecto.setPos(objectoStartPos+(0,0,2))
        self.objecto.setTag('objecto', '1')

#Code for clicking
        pickerNode=CollisionNode('mouseRay')
        pickerNP=camera.attachNewNode(pickerNode)
        pickerNode.setIntoCollideMask(BitMask32(0)) 
        pickerRay=CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue() 
        myTraverser.addCollider(pickerNP, myHandler)

#myFunction

        def select():
            mpos=base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            myTraverser.traverse(render)
   
            if myHandler.getNumEntries() > 0:
                myHandler.sortEntries()
                pickedObj=myHandler.getEntry(0).getIntoNodePath()
                pickedObj=pickedObj.findNetTag('objecto')
            if not pickedObj.isEmpty():
                handlePickedObject(pickedObj)

#Assign the keys:

        self.accept("mouse1", self.setKey, ["select",1])
        self.accept("mouse1-up", self.setKey, ["select",0])

#Key command:

        if (self.keyMap["select"]!=0):
            self.select
1 Like

Cause you’re asking for select as a gobal and you only have it as a local… aka add self.select()

Heres your code with “some” fixes:

#keymap:
self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "backward":0, "select":0} 

#Assign the keys: 
self.accept("mouse1", self.setKey, ["select",1]) 
self.accept("mouse1-up", self.setKey, ["select",0]) 

#Load the model: 
objectoStartPos = self.environ.find("**/start_point").getPos() 
self.objecto = loader.loadModel("models/ralph") 
self.objecto.reparentTo(render) 
self.objecto.setScale(.8) 
self.objecto.setPos(objectoStartPos+(0,0,2)) 
self.objecto.setTag('objecto', '1') 

#Code for clicking:
pickerNode=CollisionNode('mouseRay') 
pickerNP=camera.attachNewNode(pickerNode) 
pickerNode.setIntoCollideMask(BitMask32(0)) 
pickerRay=CollisionRay() 
pickerNode.addSolid(pickerRay) 
myTraverser = CollisionTraverser() 
myHandler = CollisionHandlerQueue() 
myTraverser.addCollider(pickerNP, myHandler) 

#myFunction:
def select(self):
  mpos=base.mouseWatcherNode.getMouse() 
  pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) 

  myTraverser.traverse(render) 

  if myHandler.getNumEntries() > 0: 
      myHandler.sortEntries() 
      pickedObj=myHandler.getEntry(0).getIntoNodePath() 
      pickedObj=pickedObj.findNetTag('objecto') 
  if not pickedObj.isEmpty(): 
      print pickedObj #Name of the object, or you can make it say, "BLAVASDA BLAASD! WORLD!".

#Key command: 
if (self.keyMap["select"]!=0): 
    self.select()

hmmm thanks for your help :stuck_out_tongue:

It’s at line 239 and there i already have the self.select()

        if (self.keyMap["select"]!=0):
            self.select()

I’ve seen foruns and that, do you think it could be because of the indent ?

Re-read the code I posted, I fix more than one bug in the example code.

Hi there, sorry for being a bit boring but i’ve tried and nothing… i think i have the self.select() in the wrong place because the world instance has no atribbute “select” :confused:

...

class World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "backward":0, "select":0} 
        base.win.setClearColor(Vec4(0,0,0,1))
....
        self.accept("mouse1", self.setKey, ["select",1])
        self.accept("mouse1-up", self.setKey, ["select",0])
		


        taskMgr.add(self.move,"moveTask")
		
        def move(self, task):
            if (self.keyMap["select"]!=0):
                self.select() 
		
        objectoStartPos = self.environ.find("**/start_point").getPos()
        self.objecto = loader.loadModel("models/ralph")
        self.objecto.reparentTo(render)
        self.objecto.setScale(.8)
        self.objecto.setPos(objectoStartPos+(0,0,2))
        self.objecto.setTag('objecto', '1')
		
		
        #teste clicks
		
        pickerNode=CollisionNode('mouseRay')
        pickerNP=camera.attachNewNode(pickerNode)
        pickerNode.setIntoCollideMask(BitMask32(0)) 
        pickerRay=CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue() 
        myTraverser.addCollider(pickerNP, myHandler)
			
        def select(self):
            mpos=base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) 

            myTraverser.traverse(render)
   
            if myHandler.getNumEntries() > 0:
                myHandler.sortEntries()
                pickedObj=myHandler.getEntry(0).getIntoNodePath()
                pickedObj=pickedObj.findNetTag('objecto')
            if not pickedObj.isEmpty():
                print "Teste"
...

        if (self.keyMap["left"]!=0):
            self.ralph.setH(self.ralph.getH() + elapsed*300)
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - elapsed*300)
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -(elapsed*25))
        if (self.keyMap["backward"]!=0):
            self.ralph.setY(self.ralph, (elapsed*25))
        if (self.keyMap["select"]!=0):
            self.select()
...
        return Task.cont

w = World()
run()

Make sure your def are where they need to be to. It’s np, I know how hard it was for me to learn panda 3d too. Make sure your learning from the mistakes tho :slight_smile: The error messages in the cmd prompt are big help in finding your errors, so learn them as fast as you can to.

class World(DirectObject): 
  def __init__(self):
    self.environ = loader.loadModel("models/world")      
    self.environ.reparentTo(render)
    self.environ.setPos(0,0,0)
    
    # Create the main character, Ralph
    self.ralphStartPos = self.environ.find("**/start_point").getPos()
    self.objecto = loader.loadModel("models/ralph") 
    self.objecto.reparentTo(render) 
    self.objecto.setScale(.8) 
    self.objecto.setPos(self.ralphStartPos) 
    self.objecto.setTag('objecto', '1')
    base.camera.setPos(self.ralphStartPos,+(0,-2,0))
   
   
    #teste clicks 
    self.pickerNode=CollisionNode('mouseRay') 
    self.pickerNP=camera.attachNewNode(self.pickerNode) 
    self.pickerNode.setIntoCollideMask(BitMask32(0)) 
    self.pickerRay=CollisionRay() 
    self.pickerNode.addSolid(self.pickerRay) 
    self.myTraverser = CollisionTraverser() 
    self.myHandler = CollisionHandlerQueue() 
    self.myTraverser.addCollider(self.pickerNP, self.myHandler)
    
    base.win.setClearColor(Vec4(0,0,0,1))

    self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "backward":0, "select":0} 

    self.accept("mouse1", self.setKey, ["select",1]) 
    self.accept("mouse1-up", self.setKey, ["select",0])

    taskMgr.add(self.move,"moveTask") 
      
  def select(self): 
    self.mpos=base.mouseWatcherNode.getMouse()
    self.pickerRay.setFromLens(base.camNode, self.mpos.getX(), self.mpos.getY()) 
    self.myTraverser.traverse(render) 
    if self.myHandler.getNumEntries() > 0: 
      self.myHandler.sortEntries() 
      self.pickedObj=self.myHandler.getEntry(0).getIntoNodePath()
    if not self.pickedObj.isEmpty(): 
      print self.pickedObj.getParent().getParent().getName()

  #Records the state of the arrow keys.
  def setKey(self, key, value):
    self.keyMap[key] = value

  def move(self, task): 
    if (self.keyMap["left"]!=0): 
        self.ralph.setH(self.ralph.getH() + elapsed*300) 
    if (self.keyMap["right"]!=0): 
        self.ralph.setH(self.ralph.getH() - elapsed*300) 
    if (self.keyMap["forward"]!=0): 
        self.ralph.setY(self.ralph, -(elapsed*25)) 
    if (self.keyMap["backward"]!=0): 
        self.ralph.setY(self.ralph, (elapsed*25)) 
    if (self.keyMap["select"]!=0): 
        self.select() 

    return Task.cont 


World() 
run() 

ermmm… i’m experienced PHP programmer, i thought it wasnt difficult but i guess i was wrong! The problem is that i see an error and dont know how to solve it ! Thanks for your kind motivation :slight_smile:

i’ve tried what you said and im getting the same error … i remade, it gives no errors but it also doesnt print what i want! I’m seeing it’s better i post my whole document here :astonished: I dont want to abuse but i’ve put the code in testes.comuf.com/testes.zip

the changes i made were:

        if (self.keyMap["select"]!=0):
            self.mpos=base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, self.mpos.getX(), self.mpos.getY())
            self.myTraverser.traverse(render)
            if self.myHandler.getNumEntries() > 0:
                self.myHandler.sortEntries()
                self.pickedObj=self.myHandler.getEntry(0).getIntoNodePath()
            if not self.pickedObj.isEmpty():
                print self.pickedObj.getParent().getParent().getName()

When I copy and pasted your entire class World code into notepad++, I noticed that according to the indents, your custom function definitions were inside the definition of the init function, which is not what you want. This may be a copy/paste error, I’m not sure, but I do know that by looking at the code in these little code windows its very hard to notice. Here is what I saw, simplified:

class World():
     def __init__(self):
          some stuff
          some stuff
          some stuff
          
          def myFunc(self):
               some stuff

What you want is this:

class World():
     def __init__(self):
          some stuff
          some stuff
          some stuff
          
     def myFunc(self):
          some stuff

So that your custom function definitions are outside the definition of the initialization function.