MMOC - Minimal Mogre Collision

smiley80

13-11-2008 21:19:15

Hi,

I've ported the MOC toolkit to C#.

Differences:
- Raycast methods return a class with the results (position, entity, distance) instead of a bool
- Changed the MouseEvent param in RaycastFromCamera to Vector2 (mouse position)

Download link:
http://code.google.com/p/minimal-ogre-c ... n-toolkit/

GenericJoe

12-12-2008 12:13:28

Excellant, thanks for sharing smiley80 - simple physics collision detection straight out of Ogre is extremely useful.

Will definately check this out later!

Chulein

12-12-2008 12:23:46

Nice work smiley80!

thanks for sharing

Nauk

12-12-2008 13:26:34

Awesome work, I'll put it up on sourceforge :)

Nauk

16-01-2009 13:00:25

Took a while but there it is, :) :
Edit: We moved to google because it is so much easier to maintain:
http://code.google.com/p/minimal-ogre-c ... n-toolkit/

raygeee

13-04-2009 13:47:08

Great work you both did, Nauk and Smiley80. Runs absolutely wonderful.
Thanks! (and a bump for this thread)

I've had one issue with MMOC while using it with Hydrax, posted here: http://www.ogre3d.org/forums/viewtopic.php?f=11&t=45267&p=336605#p336605
If it's not happening in the original MOC it should be because of the port (or my code...)

smiley80

13-04-2009 21:34:24

Hmm,

looks like the value of indices, indices or indices is larger than Int.MaxValue.

Could you please check if that's the case? My current PC is too slow for Hydrax, so I can't test it myself.

raygeee

14-04-2009 18:36:49

Good catch. Yes, some are. Sometimes one or two of them, sometimes all of them.
indices is an array of ulong and vertices is an array of Vector3, so the used index of vertices is greater than the biggest possible Int.

I tried patching it by setting vertex_count to ulong instead of uint (in Raycast and in GetMeshInformation) but it didn't help.
Isn't it possible to create an array with long or ulong indices? I searched a little and didn't find out how. I simply triedVector3[] vertices = new Vector3[ulong.MaxValue - 1L]which resulted in the same OverflowException.

edit: Ok, just found out that array indices in .NET are always implicitly Int32. But then why does it work in C++? Is this possible in unmanaged code?

smiley80

14-04-2009 19:49:47

Okay three possibilities:
a) HardwareIndexBufferSharedPtr.Lock returns wrong and way too high values (but I don't know why it would do that)
b) the values are correct, because Hydrax creates so many vertices (but that should throw a OutOfMemoryException earlier)
c) there's a bug in GetMeshInformation (the code is (nearly) the same as the code in the wiki)

What are the values of vertex_count and index_count?

raygeee

14-04-2009 21:31:15

Ok, here's an example:
I set a breakpoint on line 225 with the following condition:indices[i] > Int32.MaxValue || indices[i+1] > Int32.MaxValue || indices[i+2] > Int32.MaxValue
In my test terrain with Hydrax enabled the debugger always stopped at the breakpoint with the following values:i 0 int
vertex_count 6400 uint
index_count 37446 uint
Already the first run in the for-loop triggered it! I looked into the indices array and it has got big values all over the place. Well, it's an array of unsigned long... So with the current code there's always the possibility of a value bigger than a signed Int32.

By the way: There's a boolean flag "use32bitindexes" in GetMeshInformation, is it useful?

P.S.: Now, that's what I call "remote debugging" :D

smiley80

14-04-2009 22:25:35

Let's see what happens when you change ulong* in this line:
ulong* plong = (ulong*)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
to uint*/int* or ushort*/short*.


By the way: There's a boolean flag "use32bitindexes" in GetMeshInformation, is it useful?

Well, it's always false for me, so it should use 16 bit indexers.
You can also try to remove the if-conditional and only use the first for-loop.


P.S.: Now, that's what I call "remote debugging" :D

:lol:

raygeee

15-04-2009 17:11:13

Let's see what happens when you change ulong* in this line:
ulong* plong = (ulong*)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
to uint*/int* or ushort*/short*.

I set it to int* and it worked - No more OverflowExceptions with Hydrax! But I've got the feeling that I'm "cutting" some values... :(
If you look at the code it's still not safe to say that I won't have any index values greater than Int32.MaxValue.
Shouldn't we modify the type of indices[] too - from ulong[] to int[]? Also the variable offset is an uint...

How can I be sure that collision detection stills works fine? Collision detection with camera works fine as far as I can tell. But about collision detection between objects I'm not so sure. It didn't work all the time before, so I can't tell if something changed now.
Example: I've got a Robot entity walking over the terrain which uses CollidesWithEntity every step it takes. Now if there is a Tudorhouse entity standing in the way sometimes it doesn't walk at all, sometimes it just walks through. The same happens if I put a Ninja entity in the way of the Robot.

This leads me to a general question: Is MOC designed to handle collision detection between (moving) objects? I'm not very sure since they wouldn't need it at vertex level, only the camera does.

@smiley80: So oder so, danke jedenfalls schon mal für die Hilfe! ;-)

smiley80

15-04-2009 18:54:06

But I've got the feeling that I'm "cutting" some values... :(
The high values are probably the result of the type mismatch. (Stupid pointer bs, I hate this crap.)

If you look at the code it's still not safe to say that I won't have any index values greater than Int32.MaxValue.
Shouldn't we modify the type of indices[] too - from ulong[] to int[]? Also the variable offset is an uint...

I'll add a check for that in a future version, which will throw an exception if the values are higher than they should be.


Is MOC designed to handle collision detection between (moving) objects?

The problem is, that if the 'fromPoint' is inside the entity it will collide with the mesh of the entity.
So you can either specify a point that is outside the mesh or add a filter for that entity in Raycast.

Bekas

15-04-2009 19:17:49

Hey, good job smiley80!

About the indices thing..

IMO the choice of "unsigned long" from the original C++ author is an unfortunate one. Indices for the GPU are either 2 bytes (use32bitindexes == false) or 4 bytes (use32bitindexes == true). "unsigned long" in C++ is 4 bytes for 32bit platforms and all is good, but AFAIK "unsigned long" is 8 bytes for 64bit platforms, so the code would not work for 64bit.
Instead of "unsigned long" he should have picked an explicitly 4-byte type like Ogre::uint32 (and I think 'int' is 4 bytes on both 32 and 64 platforms but I'm not sure).

The above is for C++, what about .NET ?
ulong is 8 bytes there so that's why the indices are off. You should use Int32 for the indices array. (and if use32bitindexes == false, get the indices from a Int16* pointer, and convert them to Int32.) Note that 'int' is the same as Int32 in C#, but it's probably better to be explicit about the size of the type when referring to indices.

Bekas

15-04-2009 19:27:10

Ok, correction, in the above post replace Int32/Int16 with UInt32/UInt16.

raygeee

15-04-2009 22:00:04

Thank you both for explaining! This makes it much clearer.
I'm familiar with Integer being the unit which is the "natural unit" of the operating system/cpu, so on a 32bit system Int is 4bytes and on a 64bit system Int is 8 bytes. One thing I didn't know was that indices for the GPU are either 2 or 4 bytes, which leads me to the conclusion that I can safely change the indices[] to Int32. :)

The problem is, that if the 'fromPoint' is inside the entity it will collide with the mesh of the entity.
So you can either specify a point that is outside the mesh or add a filter for that entity in Raycast.
Good catch! That's a very good explanation why my entities didn't start walking in the first place! I'm going to try that, but I think I have to adjust the MMOC code for that. A simple filter would require to be able to filter only one single mesh (out of maybe lots of entities with the same mesh and QueryFlag).

hedphelym

06-10-2009 19:28:36

Is there someone of you who could take the time
to explain how to use this one? :)

Kohedlo

30-05-2010 22:12:12

Very usefull thought - add to MMOC Pack - simple demo(100 lines as mogre demos) showing using all methods in CollisionTools.cs

{Entity + entity = collision or camera + entity = collision}

Thanks!

xerios

31-05-2010 15:15:06

Those functions do what they're supposed to do according to their name, and they aren't made for complex scene collisions and stuff ( mesh against mesh, etc... ).

If you want a good collision library, use one of the physic engines ( bullet , physx or any other kind of physic library )

Beauty

04-06-2010 12:09:05

It would be nice if someone update the wiki page MOC - Minimal Mogre Collision (or create a new page for the Mogre version).

Beauty

11-11-2014 09:38:32

Just for information:

User SuperNess improved the MOC code (C++ original).
Based on the MOC original lib, but with focus on efficiency and with some bonus features.

The advantage of this snippet over the original MOC is performances, especially when doing lots of collision checks per frame. note that terrain collision is currently not supported in this snippet.


The C++ code is only about 500 lines (including comments).
So if somebody has a need, it should be quickly done to port the code to C#.

All related links you find on the wiki page of New Minimal Ogre Collision.