Improved NES physics

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Improved NES physics

Post by slembcke »

Now that NESDev 2018 is done, I've started to poke around on my NES physics project again. Basically it implemented circle to circle, and circle to line collisions. Currently it's just particle physics, but I want to allow some objects to enable full rigid body collisions (balls, wheels). I guess I'll have to see how much that actually costs. The original project was all in C and used full 8.8 fixed point for everything. It was slow, but it let me figure out how little precision I needed and still have nice movement.

Since I now know how many bits of precision I needed for the intermediate values, I went back and rewrote it in assembly with some unrolled 2 8x4 bit multiplications, and 4 16x3 bit multiplications. Worst case scenario is ~1000 cycles per collision, and that only happens a small portion of the time so I think I have time to process more collisions per frame than I have sprites to draw now. :D

I threw a quick demo up on my webpage of a circle moving around a tilemap. My plan is to make something with a 2 wheeled vehicle or maybe a 1 wheeled robot. It should hopefully get more interesting once I re-implement circle to line collisions so I can have slopes and such.
http://files.slembcke.net/temp/nes-embe ... ysics.html
User avatar
dougeff
Posts: 2875
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Improved NES physics

Post by dougeff »

circle to circle
Wouldn't that be adding 2 radii, and seeing if the distance between center points is less than that?

If you had fixed sized circles, you could speed this up with a look up table of precalculated values, and would only need to do a bit of addition.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Improved NES physics

Post by slembcke »

Yes, that's the easy part, and uses a lookup table.

The hard part is resolving the collision. How far in x and y does it need to be pushed to resolve the overlap, and how do you resolve the velocity constraint caused by the contact between the two surfaces.

Off the top of my head, it works like this:

Code: Select all

delta.x = pos0.x - pos1.x
delta.y = pos0.y - pos1.y
dist_sq = delta.x*delta.x + delta.y*delta.y
if(dist_sq < radius_sq){
	// Fix distance with projection.
	projection_coef = radius/math.sqrt(dist_sq) - 1
	pos0.x += delta * projection_coef
	pos0.y += delta * projection_coef
	
	// Fix velocity constraint
	n.x = delta.x/sqrt(dist_sq);
	n.y = delta.y/sqrt(dist_sq);
	vn = max(0, vel.x*n.x + vel.y*n.y);
	vel.x -= n.x*vn;
	vel.y -= n.y*vn;
}
The squares are calculated with tables. The projection coef is looked up from a table. 'delta' only has 4 bits, so those multiplies are unrolled and shortened. 'n', the collision normal, isn't really ever calculated. It's assumed to be close to delta/8, and so the last 4 multiplies are optimized 16x3 bit multiplies.
Post Reply