Entitypickmode affects childs entities?

Blitz3D Forums/Blitz3D Programming/Entitypickmode affects childs entities?

Pinete(Posted 2006) [#1]
Hi all,

Could someone please solve this little question?
I'm trying to setup a enemy as a 'pickable' entity.

The entity is a .B3D animated model with a scene root and some chidrens depending of it (arms, body, legs, etc...)

When I create the enemy I use the next...

...
enemy\entity = loadanimmesh("enemy.b3d")
enemy\root = finchild(entity,"SceneRoot")
...
...

then I have doubts about how to do the picking setup:

a) entitypickmode enemy\entity,2
or
b) entitypickmode enemy\root,2

What option should be the correct one?

...or maybe we need to make all the childs pickables?

Now it seems to work properly just when I point to some
polygons, but really doesn't works as it should, with the
whole model.

Thanks in advance!


octothorpe(Posted 2006) [#2]
function EntityPickModeRecursive(entity, value)
	If EntityClass$(entity)="Mesh" then entitypickmode entity, value
	for i = 1 to countchildren(entity)
		EntityPickModeRecursive(getchild(entity, i), value)
	next
end function


EDIT: "If EntityClass$(m)="Mesh"", thanks jfk


jfk EO-11110(Posted 2006) [#3]
you need to make the children pickabe too, use a recursive function to set the pickmode to all MESH children (see here: http://www.blitzbasic.com/codearcs/codearcs.php?code=1170 )

Now I guess you want to have one entityhandle only, to control if you eg. shot the enemy, or see the enemy etc.

Personally I solved this with a socalled orphan structure. Every main root handle of an enemy animesh will get its list of child entities (a simple nonhierarchical list). Now when linepick returns a child handle, you need to search the orphan lists to see what root parent was shot.

It may look slow, but in fact it's pretty fast because it's only comparing some ints, so checking several thousand children won't consume siginficant amounts of time.

It's up to you to use:

banks, eg:
int root entity handle
int number of orphans
int oprhan 1
int orphan 2
...

arrays:
dynamicly redim the arrays as required, using a second array to save the content before you resize the main array. Con: waste of space when the number of children differs a lot between the various meshes. Pro: easy access.

types:
create a new type instance for each enemy and a subtype instance for every child. Elegant code, but some overhead compared to banks IMHO.

Alternatively you can do it the easy way, use the Command GetParent. You need to use this recursively to find the root entity. Recursive function calls may be slower than the orphans structure I described before.


octothorpe(Posted 2006) [#4]
There's a third option: indexing, which would be a faster (and cleaner IMHO) approach.

You can store a string in an entity's EntityName and use this to either (a) index an object for the child entity which contains a pointer to the parent object (i.e. enemy) or (b) index the parent object directly.

The string can work as an index either by being a Handle() to the object or - if you keep all your objects in global arrays like Frank Taylor - the array index to find the object (aka its "ID".)

I think the simplest solution is to set the EntityName of all the entities belonging to an enemy to the Handle() of that enemy object; you only need to call Object() on the EntityName of the picked entity to get the correct enemy.


jfk EO-11110(Posted 2006) [#5]
That's indeed a clean solution. Storing the top root handle in the EntityName of every child. Although you still need to extract the handle from a string it may be the fastest way.

Probably you need to use an individual part for every entityname, not sure if you can name them with the same name, and I would not recommend to do so. But you may name it something like this:
(handle)+"_"+oldname$

So the value of the handle can be converted to int simply by automatic type casting, eg:
value%=entityname$(picked_child)


Pinete(Posted 2006) [#6]
Thanks a lot, thanks a lot to all!!!!
really grateful!
:)


octothorpe(Posted 2006) [#7]
Probably you need to use an individual part for every entityname, not sure if you can name them with the same name, and I would not recommend to do so.


It's perfectly safe to do so.

I like your automatic type-casting trick though. I often prefix EntityNames with the type of object the Handle() points to - I think I'll start postfixing instead. :)