collision detection bug in iminib3d

BlitzMax Forums/MiniB3D Module/collision detection bug in iminib3d

jhocking(Posted 2010) [#1]
I've encountered a really subtle bug with collision detection involving certain b3d files. This isn't a critical bug to fix because I know how not to get it, but I figure you'll want to know.

Basically, b3d files exported from Blender behave correctly in the simulator but not on device. In the simulator they collide as expected, but on device they are mostly not responding to collisions except for randomly in empty space.

The same model exported from Ultimate Unwrap works great, so the problem is specific to b3d files exported from Blender. In the short run this is only a minor inconvenience, but in the long run I figure you might be curious why this is happening.

For your reference, here are the two models:
http://www.tofrutti.com/dev/working-proto_level.b3d
http://www.tofrutti.com/dev/broken-proto_level.b3d


simonh(Posted 2010) [#2]
Thanks, I'll look into it. Sounds like a strange one indeed. I'll look into the lighting issue as well when I get a chance.


jkrankie(Posted 2010) [#3]
I guess this is along similar lines to a problem i found. Basically, i use colour materials applied in Wings3D rather than textures to colour my enemies. If i export the mesh as b3d in Deled, the matierial applies it's colour to other meshes instead of itself. If i export to b3d from Milkshape there's no problem.

To be honest i just thought this was a bug with Deled's exporter, rather than any fault of MiniB3d, but you never know. It's not a show stopper or anything, and i've bought Milkshape now anyway.

Cheers
Charlie


jhocking(Posted 2010) [#4]
Well whether it's a bug in Deled or minib3d is just a matter of perspective. On the one hand, Deled is clearly exporting b3d files slightly differently from how Milkshape does it, so you could say there's a bug in Deled's exporter. However, whoever developed the Deled exporter probably tested it in Blitz3D and it worked fine, so from that perspective there's a bug in minib3d, because it doesn't exactly replicate the behavior of Blitz3D.

It's sort of like how a website can look different in different browsers: in theory different browsers can all display html files, but they have subtle differences in how they interpret the data. A good web developer will ensure their site works well in all browsers, so if a site doesn't work in certain browsers is that a problem with the browser or a problem with the developer?


jhocking(Posted 2010) [#5]
I've discovered some more bugs with collision detection. First off, CountCollisions doesn't report the correct number. It's sensitive to the order that I call Global::Collisions when setting up collisions; whatever is the last kind of collision set is the only collisions counted.


Second, the order of calling Collisions can result in some entities passing through each other. It's a little hard to explain, and I've not setup enough test cases to know for sure what are the boundaries of this bug, but when I first set the characters to collide with level and then with each other, they all collide normally. However when I first set the characters to collide with each other and then set them to collide with the level, the first character passes through the third character (I have three in the scene right now.)

Note that both characters collide with the level just fine, they both collide with the second character just fine, and in fact the third character collides with the first character! That is, when the third character moves toward the first character they collide, but the first character passes right through when he moves toward the third character.



ADDITION: I just realized that CountCollisions doesn't work for both entities involved in a collision. It's counting the collisions on characters when they collide with the level (subject to the bug described at the beginning of this post) but collisions aren't counted on the level.

I can't think of any workaround here either, I need to have my characters respond to the surface they are walking on.


simonh(Posted 2010) [#6]
CountCollisions only works for the source entity. Use EntityCollided to check if a dest entity has collided with a source entity.

What kind of collisions set up do you have for your level and three characters?


jhocking(Posted 2010) [#7]
hm this could be tricky then. Maybe that means I'll need to split the level up into separate parts for using EntityCollided with, because I can't think of any way to get a surface on the level from counting collisions on the character.

The collision setup is pretty straightforward, sphere->polygon collisions with the character spheres colliding with the level polygons.


ima747(Posted 2010) [#8]
This could possibly be related to the collision issue I reported a while ago for iminib3d (directly through email I believe, can dig it out of my back log if it will help), relating to child entities not colliding and not updating their positions properly with a global flag, and not properly responding to point entity.


jhocking(Posted 2010) [#9]
yay, splitting up the level into separate meshes works great, now I have characters sliding around when they step off normal ground onto the ice.

There's still the issue with characters not colliding with each other, but I think I can work around that problem using EntityDistance.


jhocking(Posted 2010) [#10]
CountCollisions doesn't report the correct number. It's sensitive to the order that I call Global::Collisions when setting up collisions; whatever is the last kind of collision set is the only collisions counted.


I have an additional tidbit to add to this bug report that I just noticed. By "the last kind of collision set," that doesn't mean the last call to Collisions in general, but rather the last collision set for that particular entity type. So in other words if I have the following code:
Global::Collisions(1, 4, 1, 2);	//player to enemy
Global::Collisions(1, 2, 2, 2);	//player to level
Global::Collisions(5, 4, 1, 1);	//shot to enemy
Global::Collisions(5, 2, 2, 1);	//shot to level

then collisions of player to level will be reported by CountCollisions, and collisions of shots to level will be reported, but the count won't show collisions with enemies.

This additional nugget of information makes me think iminib3d is counting all the collisions but the count is being overwritten for each collision set, rather than added. That's an easy bug for me to find and fix, but I'm gonna wait because I still haven't gotten around to upgrading to 0.4 (was planning to do it this weekend, ie. today) so for all I know this bug has already been fixed in the latest version of iminib3d.


ADDITION: Just upgraded the project to 0.4 and collisions still aren't counting correctly. There are a few other unrelated bugs I no longer have to work around (eg. problems with lighting,) but I guess this particular bug wasn't fixed. Fortunately this bug is easy for me to work around, but that's only because of the particular situation I'm needing it in.


jhocking(Posted 2010) [#11]
I couldn't keep working around the bug while working on AI characters, so I dug into iminib3d's source to figure it out. The problem is in collision2.mm

Comment out these lines near the top of UpdateStaticCollisions:
ent.no_collisions=0;
for(int ix=0;ix<ent.collision.size();ix++){
delete ent.collision[ix];
}
ent.collision.clear();


Then in UpdateCollisions uncomment ClearCollisions


Now I'm not sure what unintended negative consequences this will have, it just looks from a few minutes testing like collisions are being counted correctly now. From the comments in the code it looks like it used to be this way actually and you changed it for some reason.


EDIT: whoops now the count just keeps increasing forever without being reset every frame. Well anyway this is where to futz around in the code to fix this bug.


EDIT2: This isn't related, I just didn't want to start a new thread. I noticed a bug with EntityVisible. In pick.h set EntityVisible to static.


simonh(Posted 2010) [#12]
OK, thanks jhocking. Will fix in the next release.


jhocking(Posted 2010) [#13]
Noticed more bugs with EntityVisible. Long story short, it works great in the simulator but crashes on device. I'm not sure the problem isn't due to something I'm doing wrong, but I have isolated the crash to the line where I call EntityVisible. The first thing I'm gonna try to work around the bug is use LinePick instead.

EDIT: False alarm, it was a stupid little mistake on my part. Posting this message reminded me that I had made a small change to EntityVisible in the source code for iminib3d. I rebuilt the library for the simulator after changing that, but I forgot to rebuild the library for device.


jhocking(Posted 2010) [#14]
Tiny additional bug with EntityVisible:

The optional obscurer parameter doesn't seem to work. This bug is really easy to work around just by looping through objects to change their pick mode, and the parameter is kinda stupid to begin with anyway, but I figured I'd let you know.


jhocking(Posted 2010) [#15]
I decided to take another stab at fixing the bug with CountCollisions. I started with simply doing exactly what I wrote a couple posts ago, and now it works great. Which is weird, since in that post I said my proposed fix had a problem.

Maybe I had commented out those other lines but accidentally didn't uncomment the ClearCollisions? If you don't uncomment that then the count keeps increasing without being reset. I'm not sure how I accidentally didn't do that, since my post explained to do that, but I'm at a loss to understand why it's working now when it didn't work before.


JoeRetro(Posted 2010) [#16]
Hey Joe, I followed your instructions above and it works great!


jhocking(Posted 2010) [#17]
Thanks for the confirmation. I suppose I should have asked for that explicitly: because I'm not 100% sure my proposed fix is the right way to go, it would be great if other people could test it out and tell us if there are any problems that come up.


JoeRetro(Posted 2010) [#18]
I concur...One thing is certain though whether it was the correct fix or not I was able to move on my list of other items to tackle.