model to voxel converter

How it works: Makes a cube of collision solids, throws the model in the middle of it, removes any collision solids that arent colliding with the model, then spits out the coordinates of the remaining collision solids. Simple and easier than any other way i could figure to do this.

Why i cant get it to work: i THINK i got collisions with visible geometry to work. now my problem is sifting through the collisionQue entries and removing any collision solids that arent colliding with the model.

My Code:

from direct.showbase.ShowBase import ShowBase
from direct.interval.IntervalGlobal import Sequence, Func, Wait
from pandac.PandaModules import CollisionTraverser, CollisionHandlerQueue
from pandac.PandaModules import CollisionNode, CollisionSphere
from pandac.PandaModules import VBase4
from pandac.PandaModules import Point3
from panda3d.core import BitMask32

class Voxelize(ShowBase):
    
    def __init__(self):
        ShowBase.__init__(self)
        
        self.CubeSize = 5
        
        base.cTrav = CollisionTraverser()
        self.collHandEvent = CollisionHandlerQueue()
        
        self.createVoxelField(self.CubeSize, .5)
        self.loadModel('models/ship.egg')
        
        base.cTrav.traverse(render)
        for i in range(self.collHandEvent.getNumEntries()):
            entry = self.collHandEvent.getEntry(i)
            if entry.hasInto() == True and entry.getIntoNodePath() != "render/ship.egg":
                this = entry.getFromNodePath()
                this.hide()
                print(this)
        
    def createVoxelField(self, CubeSize, VoxelSize):
        for i in range(CubeSize):
            for k in range(CubeSize):
                for j in range(CubeSize):
                    self.makeVoxel(i,k,j,VoxelSize)
                    
    def loadModel(self, modelPath):
        model = loader.loadModel(str(modelPath))
        model.reparentTo(render)
        model.setPos(self.CubeSize/2, self.CubeSize/2, self.CubeSize/2)
        geomnode = model.find('**/-GeomNode').node() 
        geomnode.setIntoCollideMask(BitMask32.bit(1))
        print(model)
        
    def makeVoxel(self, x, y, z, size):
        center = Point3(0,0,0)
        Cnode = CollisionNode('VoxelCollisionNode')
        node = render.attachNewNode(Cnode)
        sphere = CollisionSphere(center,size)
        Cnode.addSolid(sphere)
        node.setPos(x,y,z)
        node.show()
        base.cTrav.addCollider(node, self.collHandEvent)
        
    def collide(self, collEntry):
        print(collEntry)
        
        
app = Voxelize()
app.run()

the code i need help on:

base.cTrav.traverse(render)
        for i in range(self.collHandEvent.getNumEntries()):
            entry = self.collHandEvent.getEntry(i)
            if entry.hasInto() == True and entry.getIntoNodePath() != "render/ship.egg":
                this = entry.getFromNodePath()
                this.hide()
                print(this)

the code i think i have correct but could use some feedback on:

def loadModel(self, modelPath):
        model = loader.loadModel(str(modelPath))
        model.reparentTo(render)
        model.setPos(self.CubeSize/2, self.CubeSize/2, self.CubeSize/2)
        geomnode = model.find('**/-GeomNode').node() 
        geomnode.setIntoCollideMask(BitMask32.bit(1))
        print(model)

what happens in my current code: all my collision solids end up hidden, not completey sure why.

bump

have you made any headway with this? this is an interesting method

Hi

in the line

if entry.hasInto() == True and entry.getIntoNodePath() != "render/ship.egg":

looks like you are comparing a NodePath with text, I think you need:

if entry.hasInto() == True and entry.getIntoNodePath().getName() != "render/ship.egg":

also make sure the name in your model for the node that will be “hit” is “render/ship.egg”

ooooh, ill give that a shot :smiley: thanks for replying! lol been waiting for a while on this XD

mmmm the same thing happens. I think i know why. All of the collision solids and collision nodes are named the same thing - cnode and sphere so wheni call this.hide() is hides all of them since thenames are all the same. I dont know how to fix this tho