Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / DBC Collision Oddities

Author
Message
TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 30th Apr 2008 00:58 Edited at: 30th Apr 2008 01:02
I am in the process of writing a new tutorial covering advanced collision using DBC's native collision commands - in particular, covering the navigation of ramps and stairs loaded as .X files.

The basic aim was to use another object in front of the main character object to test for collision - ie steps or ramps. In order to do this, you need to somehow attach these 'detector' objects to the main character object so they move around with the character.

As it's something I've not done myself before, I expected it to be not all that straight forward, but I wasn't expecting to find the odd behaviour I did find. Let's say that it's no surprise that people say that DBC's native collision commands are not good for doing this kind of thing.

But, not one to give up easily, I decided to persevere...

Anyway, I've discovered the following things about DBC and collision (some of which I knew already and some I have just discovered). Hopefully this list will be a guide for any of you having collision problems.

Here's the list:

1. If you create an object for collision and scale it up or down, the automatically created collision bounding box will not be scaled with it. It will remain the size of the originally created object.

Example:



Notice that even though the collision detection is with Object 1 (the red cube), it doesn't register when the red cube bumps into the blue walls - only when the white cube hits the walls. (The white cube merely shows the size of the red cube before it was scaled up and even has collision turned off).

The same happens when scaling down too. Try setting CubeSize to 2 and ScaleFactor to 30 and running the example again. Remember, the collision test is on the red object - not the white one!


2. Glue Object To Limb Problem

If you use Glue Object To Limb it disables collision on the object being attached. For example, if you want to attach secondary objects around the red main player cube (but not touching it) and have the objects remain in position when the main player cube is moved, you can use the following method (example only uses 1 secondary cube)...

Example:



If however you want to rotate the main cube, you need to use Glue Object. Swap the Rems on the two lines marked Line A and Line B in the above example and run it again.

This time, as the white cube has been glued to object 1, it no longer has any collision.


3. Hide Object Another Object Is Glued To Problem

This was the next step to try and get around problem 2 above...

Create a red cube (1). Next, create a second white cube (2), glue it to the first one, then offset the limb it's attached via.

Note: The intention is to have white cubes on all four sides, so the limbs of the four cubes are offset - not the red cube's limb - as this would only allow positioning on one side. The example below demonstrates this with one white cube for brevity.

As the collision doesn't work with the second cube due to problem 2 above, you turn off it's collision and use this cube's X/Y/Z position (using the Limb Position function) with a third cube - which you can use for collision testing. This works perfectly as you can see from the following example:

Example:



However, you don't want to be able to see the second white cube (or the third one eventually), so you use Hide Object 2.

The problem is that if you do use Hide Object 2 then the Limb Position command simply stops working! Try simply removing the Rem from the start of the Hide Object 2 line in the MakeObjects procedure.


How many of these 'problems' are still present in DBPro, I don't know.

Also, if anyone has any work-arounds that will make the above examples work, please post them here and I'll credit you in the finished tutorial - if it ever gets finished!

I also concede that I may be going about this in completely the wrong way, so if you know of a better way to do the same thing, please feel free to chip in...

TDK_Man

Latch
19
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 30th Apr 2008 02:51
For the first scenario, after the object has been scaled reinstate the method of collision:



For scenario 3, you don't have to offset the limbs the objects are glued to. You can use POSTION OBJECT <glued object> and it will offset according to the coordinates you give it.

I have to be brief at the moment. I'll take a look another time at the examples.

Enjoy your day.
TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 30th Apr 2008 03:19
Quote: "reinstate the method of collision"


Doh! I tried that already and it didn't work. I try it again after you suggest it and it works! Go figure *sigh*...

Anyway - thanks for just suggesting it as that was all that seemed to be required to do the trick.

Quote: "For scenario 3, you don't have to offset the limbs the objects are glued to."


I modified the third example to do as you suggest, but the result is the same because it's the Hide Object command which is causing the problem.



As before the above snippet works how it should. The green cube returns collision data when it hits the blue wall. But hide object 2 (by removing the Rem) and the green cube no longer moves with the white cube (which is in turn glued to the red cube).

TDK_Man

Latch
19
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 30th Apr 2008 04:54
Oh, Ok, it's not the method of positioning it's the hide object command. I hadn't really thought that through before posting.

Don't use HIDE OBJECT 2. Instead use hide limb 2,0 to hide the main mesh. Then hide limb for any remaining limbs. Should do the trick.

Also, glue object won't really help. Better to just create limbs, offset the limbs to the final positions you want the collision detectors to be and set your detection objects to the limb positions. You can then hide the "skeleton" objects limbs one at a time starting with limb zero. All that should remain are your collision detection objects.

Here's an example. A little sloppy but shows the idea. The cubes are the skeleton object and the limb. The sphere (object 2) is positioned at the offset of limb 1. As the main skeleton rotates, the sphere is automatically repositioned at limb 1's coordinates. The cylinder is there to detect collision bewteen it (object 3) and the sphere. Press SPACE to toggle the skeleton from being hidden or shown.



Enjoy your day.
TDK
Retired Moderator
23
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 30th Apr 2008 05:28
OK - thanks for that.

If I didn't explain myself clearly before, here's the thinking behind what I'm doing...

I've looked extensively for info on negotiating both ramps and stairs/steps in DBC using native commands - without any success. Found lots of 'how do you' posts though.

Have you seen it done anywhere purely in DBC code?

My idea was to have a 'detector' object in front of the main character object and when the player object bumps into something, the detector does a quick vertical scan to see if the object bumped into ends before a certain height in relation to the player object's height.

That way, for example, you couldn't climb up a step which was higher than the character's foot could be realistically lifted.

If it is a step, you know the height of it so you can raise the player object by that amount and move it forward a little - repeating the process for the next step if it's stairs.

Sounds fairly painless when you put it like that, but the above issues have complicated things a little.

As I said, I've not seen a solution to this anywhere - apart from using an external DLL or only using DB primitives, so being able to do it with a loaded .X file using pure DBC is a challenge to me at the moment.

TDK_Man

Latch
19
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 30th Apr 2008 07:12 Edited at: 2nd May 2008 12:31
Quote: "I've looked extensively for info on negotiating both ramps and stairs/steps in DBC using native commands - without any success. Found lots of 'how do you' posts though.

Have you seen it done anywhere purely in DBC code?"


I believe a user named roddman put together a pretty good example. The only other example I can think of is by you.

I think your approach with the limb thing will probably work. Even hiding the detection object that is being positioned with the limb coordinates will still give back the collision info.

I just got an idea I'm gonna try out... it's for a terrain specifically. I'll let you know how it goes.

[EDIT]
Ok, the idea is possible but maybe a bit clumsy. My goal was to implement height detection without collision testing during game time and without using memblocks. All the collision testing for the terrain occurs before hand during setup. Anyway, once a terrain object is loaded, the coder has to figure these things out:

* the x size of the terrain
* the y size of the terrain
* the z size of the terrain
all easy with object size x() y() and z()

* how many points to test in the x and z directions
this will determine the size of an array that will be used to store the y heights.

* create a box object that is maybe 1 x 2*ysize x 1
* using collision detection between the box and the terrain, starting at the terrains position, moving the box in the x and z directions until the lowest/highest x and lowest/highest z are found (the pivot point of the terrain can be anywhere so we have to find the relative offsets of where to start our data storage coordinates. Depending on the program used to create the terrain, we also have no idea of what the order of the vertices is. Vertex 1 could be in the middle, upper left, lower left, anywhere - so we create our own order based on world coordinates.)

* once the x and z extremes are found, using the x and z sizes, set up a for next loop(s) using the steps based on the array size you chose earlier. (dim array#(100,100)or whatever values for x and z. The larger the array, the more accurate the info also the more memory)

Using a plane object xrotated 90 degrees maybe 1x1 in size, goto each x and z coordinate based on the steps and the size of the terrain and move the plain up or down within the y size of the terrain, testing for collision until you get a y height for that position. Record that in the array at position x,z.

When finished with the whole terrain, delete the plain. Now whenever there is height to be determined over the terrain, just reference the array at the current or closest position. One could even average the closest neighboring points - or set up a percentage of height between neighbors so there is actually a gradual height shift based on position. The initial setup for all of this may take a minute, but once the array is done, getting the ground height would be very fast - but only as accurate as the resolution of the array grid that was set up.

Enjoy your day.

Login to post a reply

Server time is: 2026-07-06 11:07:23
Your offset time is: 2026-07-06 11:07:23