Loading the same model multiple times.

Hello there.
I have a fence model but I want the same models load like 10 times, but I don’t want to write fence1, 2,3,4 and say every island detachNode().
So I want 10 models of the same one and I want to give them all a new location, that’s not the problem.
Does anyone know such a code

Hi,

If I understand you correctly, you want to load the same model 10 times and keep on being able to re position those 10 models independent from each other?

If so:

You can load the models by using instanceTo as described here: https://www.panda3d.org/manual/index.php/Instancing

Then instance the model in python in a list and use a loop to re position them

If you run into performance problems because you have to many Geoms if you use way more than 10 models for example, you can use the rigid body combiner:
https://www.panda3d.org/manual/index.php/The_Rigid_Body_Combiner

If you only position them once and don’t intend to position them again, I would reparent the instance to one node and call node.flattenStrong() on the parent node instead of using the rigid body combiner.

Hope this helps

Models are cached so calling load_model repeatedly is no big problem, so you can do:

models=[loader.load_model('models/fence.egg') for _ in range(10)]
positions=[Point3(random.random(), random.random(), random.random()) for _ in range(10)]#some random pos
for model, pos  in zip(models, positions):
    model.reparent_to(render)
    model.set_pos(pos)

or if you don’t care to have a handle on each model:

model=loader.load_model('path_to_model')
root=render.attach_new_node('my_model_root')
positions=[]#fill list with positions...
for pos in positions:
    node=model.copy_to(root)
    node.set_pos(pos)
root.clear_model_nodes()
root.flatten_strong()

I used copy_to not instance_to, because as far as I know it’s more or less the same thing for static models.

1 Like

than you, make sense.
How does the position looks like?
I want to give the position on my own, so I quess I take the second one.
What do I need to fill in #Postions, I wanna use X, Y, Z and H postions.
I know how to set it, but not on this way, so could you give a example, from 1. 2 and than 10(Positions may be random)

For position in Panda3D you should be using Point3, it’s a kind of a container that keeps x,y,z coordinates and have some other handy functions. But in every place that you can use a Point3, you can also use a tuple (or list I think) and in many places just x,y,z components, so this are a few ways to write the same:

node.set_pos(1,2,3)
node.set_pos(Point3(1,2,3)
node.set_pos((1,2,3))
node.set_pos(x=1, y=2, z=3)
pos=[1,2,3]
node.set_pos(*pos)#unpacking args 

If I had a list of 10 positions for some model, I’d just put them in a list :smiley:

positions=[(0,0,0), (1,0,0), (2,0,0)]

If you also want to set H (heading) you can make another list with just the headings or put it all in one list.

model=loader.load_model('path_to_model')
root=render.attach_new_node('my_model_root')
pos_headings=[(0,0,0,15), (1,0,0,30), (2,0,0,45)]
for x,y,z,h in pos_headings:
    node=model.copy_to(root)
    node.set_pos(x,y,z)
    node.set_h(h)
root.clear_model_nodes()
root.flatten_strong()

Ok so what combination of codes do you prefer?(one that I can say how many and with the H pos)
And what is(My_Model_Root)?

The last snippet I posted looks ‘pythonic’ to me, I’d used that :mrgreen: You can add as many positions/headings to the list as you like (within sane limits, adding 5 million and more is not recommended).

About the model root…

root=render.attach_new_node('my_model_root')

This creates a new node named ‘my_model_root’ (you can name it as you like) just under the render node. Latter I attach all the copies of the model to this node, so that I can reduce it to just one node with flatten_strong(), because GPUs can render 1 node with a million triangles very fast and a million nodes with one triangle very, very slow

Hey man,
I tried this, I didn’t test it yet. is this possible:
Fence1 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),
Fence2 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),
Fence3 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),
Fence4 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),
Fence5 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),
Fence6 = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam),

Fence = [Fence1, Fence2, Fence3, Fence4, Fence5, Fence6

    for i in range(0,6):
	Fence[i].reparentTo(render)
Fence1.setY(656.31)
Fence1.setX(-281.65)
Fence1.setZ(67.98)
Fence1.setH(630.4)
Fence2.setY(656.31)
Fence2.setX(-291.65)
Fence2.setZ(67.98)
Fence2.setH(630.4)
Fence3.setY(646.31)
Fence3.setX(-281.65)
Fence3.setZ(67.98)
Fence3.setH(630.4)
Fence4.setY(646.31)
Fence4.setX(-291.65)
Fence4.setZ(67.98)
Fence4.setH(630.4)
Fence5.setY(636.31)
Fence5.setX(-281.65)
Fence5.setZ(67.98)
Fence5.setH(630.4)
Fence6.setY(636.31)
Fence6.setX(-291.65)
Fence6.setZ(67.98)
Fence6.setH(630.4)

Coords are made up

and when I wanna render it I do:
for i in range(0, 6):
Fence[i].reparentTo()

and when not
for i in range(0, 6):
Fence[i].detachNode()

if you know something better pls tell me and give the codes, cuz idk of this takes a lot of performance

I assume ‘Model()’ is some kind of towntown wrapper for loading models

#load the model
fence_model = Model(phase3/models/props/pir_m_prp_fnc_wood20.bam)
#root node
fence_node=render.attach_new_node('fence_node')
#make a list of all the positions and heading 
transforms=[(656.31,-281.65,67.98,630.4), # (x,y,z,h)
                (656.31,-291.65,67.98,630.4),
                (646.31,-281.65,67.98,630.4),
                (646.31,-291.65,67.98,630.4),
                (636.31,-281.65,67.98,630.4),
                (636.31,-291.65,67.98,630.4) ]
#apply the transform, reparent to root
for x,y,z,h in transforms:
    node=fence_model.copy_to(fence_node)
    node.set_pos(x,y,z)
    node.set_h(h)
#collapse to one node
fence_node.clear_model_nodes()
fence_node.flatten_strong()

#code to hide:
fence_node.hide()

#code to show:
fence_node.show()

If you want to get better at Python read this: amazon.com/Python-Cookbook- … 1449340377
and/or watch this:
youtube.com/results?search_ … +hettinger

I get a error:
fence_model = loader.loadModel(“phase_3/models/props/pir_m_prp_fnc_wood20.bam”)

transforms=[(656.31,-281.65,67.98,630.4),
(656.31,-291.65,67.98,630.4),
(646.31,-281.65,67.98,630.4),
(646.31,-291.65,67.98,630.4),
(636.31,-281.65,67.98,630.4),
(636.31,-291.65,67.98,630.4) ]

for x,y,z,h in transforms:
node=fence_model.copy_to(fence_node)
node.set_pos(x,y,z)
node.set_h(h)

fence_node.clear_model_nodes()
fence_node.flatten_strong()

error: NameError: name ‘fence_node’ is not defined

I think you skipped “fence_node=render.attach_new_node(‘fence_node’)”