adding to the conversation, the brick's PROPERTIES (solid, cloud, passable etc.) are also an obstacle, but it's easier to resolve in a theoretical point.
I think the most practical solution would be to be able to change it directly in-game, the same way that we do to change what layer the brick is in.
as you mentioned, collisions in OpenSurge are implemented with polygons,
Collisions in Open Surge are implemented using collision masks. Bricks can be thought of as polygons, specially in the old days of 0.1.4 (as we didn't have collision masks back then).
I want to make the brick system easier. Easy to use, easy to put together, easy to create. It is easy (conceptually): you just place the bricks in your level and you're all set. What makes it hard is the "angle" property. Can we ditch it?
What I am proposing is to make something better than polygons: a collision mask combined with a normal map. Easier to use, easier to compute, and great physics! Why is it better? Because it has the accuracy of a collision mask, with no extra work required. It's also better than tile-based collision.
let the user put whatever bricks they want and then create collision polygons
You can just place your bricks on the level, and that's it. You don't need to worry about anything anymore. No angles, no polygons, nothing! It's all done for you.
How is this achieved? This is what this brainstorming is all about. You use something magical called a normal map. A normal map offers geometric properties of the brick and can be computed by a program.
I see that some points look to be dotted or dithered. What should be a soft slope has parts where the game would treat it as a rapid succession of different angles or solid types until it settles for one.
The visual part isn't as important as what is being conveyed. When the ramp goes up, the angle goes up. When the ramp stays roughly on the same level, the angle doesn't go up. We can, of course, smooth the image further.
In any case, an improvement in this direction would be a huge step for the game, in my opinion. Really looking forward to it.
As far as I know, this proposed method has not been implemented anywhere else for a purpose like ours. I find it very exciting. It's innovative and very user-friendly.
]]>I see that some points look to be dotted or dithered. What should be a soft slope has parts where the game would treat it as a rapid succession of different angles or solid types until it settles for one.
here we must set a standard: what is the minimum size for a normal patch? I'd say 16*16 is a good unit of measure, that leaves space for many different angles while keeping the physics precise
edit:
it just struck me: polygons, yes. grid, yes. but the grid has a twist: it snaps either in 4*1 or 1*4 steps, along with 4*4, meaning you can use a 16*16 block to produce multiple angles. You could even store these possible angles in a table, like you did with bricks, making it that much more efficient and probably even cross reference that into the brickset system, like making these possible angles into actual images hard coded into the game. we would call that the brickset and leave only one of it.
actual "bricksets" as we know it, would then rather be a collection of images to build and decorate the level layout. we could call this level blocks, or simply blocks.
]]>Taking also in account that, as you mentioned, collisions in OpenSurge are implemented with polygons, another idea would be to let the user put whatever bricks they want and then create collision polygons. From this, computing normals is even easier.
In any case, an improvement in this direction would be a huge step for the game, in my opinion. Really looking forward to it.
]]>so for sprite angles would be nice to have some soft rotation to interpolate better and giving off a better feedback of what's truly happening.
I agree this is a good idea.
I did some experimenting today. Here's what I came up with. In this example, I'm storing the surface normals in what I'll call a normal map.
Here's a brick:
Its bitmask:
Compute the derivative in the x-axis and in the y-axis using Sobel with a large kernel:
Now take the arc tangent of the images and get the angles of the normal vectors:
ta-da!
The surface normals are codified in the colors. The angles at each point are displayed. This is a normal map of the brick.
With this method, perhaps we can leave the "angle" property in the past?
]]>Remember that the floor angle only affects the sprite angle and the physics, so for sprite angles would be nice to have some soft rotation to interpolate better and giving off a better feedback of what's truly happening.
]]>edit
yes, but at least we know what part of this brick is solid and what part isn't. Isn't that enough to compute the normals?
]]>wait, how about this, add two feet sensors, and compute the angle between them.
Think about it: can this angle be uniquely defined, or does the equation have multiple solutions?
edit
"add two feet sensors": this reasoning is very good. The trouble is: we don't know what "feet" mean. The character won't walk on the brick before this is specified (currently by the angle).
However, if we state what "feet" mean (what is the direction of the floor?), then we can indeed compute the angles by taking the derivative (it's like using two sensors).
A brick syntax could become something like this:
// compute angle automatically
brick 0
{
type obstacle
behavior default
angle auto floor-bottom
sprite
{
...
}
}
For each pixel of the surface, we can tell its normal vector if we know what "floor" is (up, down, left, right).
]]>Not to mention these can only trigger when the player is standing on ground.
I wrote
while defining a character one could then choose between legacy angles(brickset based) or computed angles (sensor based).
but deleted it. after thinking it through, it would only lead to more unnecessary coding.
I think it is best to mix both and use precomputed where angle = 0. that way we get the pixel perfect collision and correct behavior of player's actor and sprite without changing things around too much.
]]>Here's another observation: the main limitation of the current system is not the collision per-se, but rather, it is the brick angle. In a solid brick, a collision is defined by two things:
- A collision mask
- A brick angle
A collision mask can be implicitly defined by the brick image (whatever is not transparent is solid) - or it can be defined by the user (for custom masks). A brick angle is a single number that defines the normal vector of that brick, to be used by the physics engine. That is fine for small bricks, but what about something like this?
Clearly, the normal vector of the surface varies according to the position. Even though the collision mask can be perfectly defined for that curvy surface, the angle can't, because it changes. Therefore, the problem isn't the collision, but just the angle.
What if a single brick could have multiple angles? All the user would have to do is define a normal vector for each part of the brick (perhaps visually), and the angles would be computer automatically.
In practice, currently we end up breaking the brick into smaller bricks, setting their angles and putting them together again in the level editor. While it works, it is painful for the user. We should just be able to put the whole thing in the level as a single brick and it see that it just works.
]]>I have difficulties when I want to create an uneven road. I use the simplest solution is creating individual brick for each uneven road
What if you could approximate your uneven road with some sort of polyline?
sometimes physics were ok, others just wonky.
How did you set the angles?
]]>I tried that with scripts but the result was inconsistent. sometimes physics were ok, others just wonky.
]]>I have difficulties when I want to create an uneven road. I use the simplest solution is creating individual brick for each uneven road:
The collision map would create solid bricks, or each object would act as a brick?
Each collision object represents a brick. Once the level is started, they become solid bricks.
Rather than defining collisions in a brick script, you define them visually by creating a collision map.
A brick script defines visually coherent pieces of your level as non-solid bricks.
]]>