Patterns for the CollisionHandler dont seem to work right or i dont understand them right

def furniture(self):
    self.furniture = []
    for i in range(5):  # Create 5 pieces of furniture
        box = loader.loadModel("grass-block.glb")  # Assuming you have a box model
        box.reparentTo(render)
        box.setScale(0.5)  # Adjust the size as needed
        box.setPos(i*2 - 4, i*2 - 4, 0.5)  # Position them in the room
        
        dragNode = CollisionNode('drag')
        cBox = CollisionBox(Point3(-1, -1, -1), Point3(1, 1, 1))
        dragNode.addSolid(cBox)
        dragNode.setIntoCollideMask(BitMask32.bit(1))
        dragNode.set_from_collide_mask(0)
        dragNodePath = box.attachNewNode(dragNode)
        self.picker.addCollider(dragNodePath, self.pq)
        
        # Collision for furniture collision detection
        cNode = CollisionNode('furniture')
        cNode.addSolid(cBox)
        cNode.setFromCollideMask(BitMask32.bit(2))
        cNodePath = box.attachNewNode(cNode)
        self.picker.addCollider(cNodePath, self.furnitureCollisionHandler)

        proximityNode = CollisionNode('proximity')
        proximityBox = CollisionBox(Point3(-2, -2, -1), Point3(2, 2, 1))
        proximityNode.addSolid(proximityBox)
        proximityNode.setIntoCollideMask(BitMask32.bit(3))
        #proximityNode.set_from_collide_mask(0)
        proximityNodePath = box.attachNewNode(proximityNode)
        self.picker.addCollider(proximityNodePath, self.furnitureCollisionHandler)

def collition_setup(self):
    self.picker = CollisionTraverser()
    self.pq = CollisionHandlerQueue()
    self.furnitureCollisionHandler = CollisionHandlerEvent()

    self.furnitureCollisionHandler.setInPattern('furniture-into-furniture')

    self.pickerNode = CollisionNode('mouseRay')
    self.pickerNP = camera.attachNewNode(self.pickerNode)
    self.pickerNode.setFromCollideMask(BitMask32.bit(1))
    self.pickerRay = CollisionRay()
    self.pickerNode.addSolid(self.pickerRay)
    self.picker.addCollider(self.pickerNP, self.pq)

def handleCollision(self, entry):
    movObject = entry.getFromNodePath().getParent()
    if entry.getIntoNodePath().getName() == 'furniture':
        movObject.setPos(entry.getSurfaceNormal(render) + movObject.getPos())

    if entry.getIntoNodePath().getName() == 'proximity'
        print(entry)

How come i always get into the function even with proximity collision even though i set the pattern to furniture-into-furniture

Indeed, that’s not quite how the patterns work.

In short, the “pattern” system involves two steps:

  • First, the definition of a pattern
  • And second, the setting of at least one event that matches that pattern

Importantly, those patterns aren’t specific: they define a broad form for an event; they define how you want to have that collision-event be structured.

For example, a pattern might take the form of “<from-node> <into-node>”–that is, that the structure is: the name of the node that is the “from”-object in the collision, followed by a space, followed by the name of the node that is the “into”-object in the collision.

This would be specified in code as follows:
self.handler.setInPattern("%fn %in")

Note that the code above doesn’t specify the names of the objects involved–just the broad pattern of how those names would be placed in an event.

(You can also include some text in the pattern–but it’s just text, and always copied into the event exactly as specified. This is what’s happening in your case: you have just text, with no “pattern” to it.)

From these patterns events are generated: the pattern above would generate events that start with the name of the “from”-object, followed by a space, followed by the name of the “into”-object.

It’s then in the second step that specifics are used. Here one “accepts” events that one is interested in, based on the patterns that one has set.

So, continuing the example above, let’s say that we wanted to get events for cats colliding into mice. This might be done something like this:

# Assuming that the class is derived from ShowBase--adjust as called
# for if not.
self.accept("cat mouse", self.eventMethod)

~

All that sad, I am a little mystified that you get into the “handleCollision” method at all, if I understand you correctly: nothing in the code that you posted seems to reference it…

Is it perhaps referenced elsewhere in your code…?

2 Likes

Hey Thaumaturge,
Thanks for the reply and very good explained answer. I do understand how the patterns work now and i just didnt include the accept function by accident. I do have another question though if you have the time for that too. I am putting these proximity collision boxes in a different collidemask because i dont want it to collide with anything else than themselves but still on every startup of the app it is colliding with other colliding box. It is my first project in pandas3d so im not sure if i understood the collidemask correctly but as i looked up i thought only objects in the same mask can collide with each other

Oh as i just checked again they are also colliding with my ray as well even if my mouse is not pointing at them

It’s my pleasure! And I’m glad that you understand the pattern-system better now! :slight_smile:

Aah, fair enough–that makes sense now, then! Thank you for clarifying! :slight_smile:

Looking over your code, I think that this may be that they’re close enough to be touching.

And since you don’t seem to be setting the “into”-mask for your “cNode” collision-objects, those presumably still have the default mask, which I imagine includes bit 2.

As a result, I think that “cNode” colliders are able to collide with other “cNode” colliders, and hence the collisions that you’re seeing.

Well, I don’t see any code that would move your ray with the mouse…

~

Something that I do notice, by the way, is that you’re applying a scale to your model, and then attaching your collision-objects to that model. This means that the collision-objects are also being scaled–and it’s generally unwise to do that, I fear: scaling can interfere with the collision system.

I’d suggest instead incorporating an additional node into your objects that serves as a common parent for both the model and the collision-objects, with only the model then being scaled. (And the collision-objects being created with the appropriate size to match, by adjusting the points used to define the boxes.)

I already tried to also set the into mask and i modified the box so they are for sure not touching.
proximityNode.setIntoCollideMask(BitMask32.bit(3))
proximityNode.setFromCollideMask(BitMask32.bit(3))
but that does not help
and also with removing the scale the issue remains

Well, no, you’re there setting the masks to have the same value, meaning that those colliders will collide with each other.

To prevent them from colliding with each other, set their into- and from- masks to be different.

(Specifically, unless you do want things to collide into those “cNode” colliders, I’d suggest that you try setting their “into” mask to 0, so that they don’t act as “into” colliders at all, only “from” colliders.)

Oh, the comment on scaling is more a general note: whether or not it affects this specific issue, it may yet cause problems later.

1 Like

Ok nice even though the objects still collide at the beginning i dont really care about that the rest works fine now thank you

One last question: Is it also possible to jsut detect the collision without acually colliding? as like a invisible detector for objects around the subject

Sure! CollisionSolids have a method called “setTangible” that allows you to set whether or not the solid in question has a “physical presence” for collisions.

1 Like

Hey that doesnt seem to work for me i tried to simplify it as much as possible

        proximityNode = CollisionNode('proximity')
        proximityBox = CollisionBox(Point3(-2, -2, -1), Point3(2, 2, 1))
        proximityBox.setTangible(False)
        proximityNode.addSolid(proximityBox)
        #proximityNode.setIntoCollideMask(0)
        #proximityNodePath = box.attachNewNode(proximityNode)
        #self.picker.addCollider(proximityNodePath, self.furColHandler)
        
        self.furniture.append(box)

I tried to put it on the CollisionNode first but it seems that doesnt exist and like this it doesnt work

Yup: as per the manual page to which I linked earlier, it’s a method of CollisionSolid. (And thus, in this case, CollisionBox.)

Well, what’s happening? Are the boxes being pushed apart?

Nothing happened, now i changed the program completly so it doesnt matter anymore but thanks

1 Like