2D Rope Physics Example

Programming examples for the Psy-Q SDK
Post Reply
User avatar
mzxtuelkl
Curious PSXDEV User
Curious PSXDEV User
Posts: 11
Joined: Jul 26, 2021
PlayStation Model: SCPH-5501
Location: United States
Contact:

2D Rope Physics Example

Post by mzxtuelkl » August 19th, 2021, 3:04 am


2D Rope Physics Example

Username: mzxtuelkl
Project Title: 2D Rope Physics Example
Time to Complete: 2 weeks
SDK: Psy-Q
Genre: Example
Latest Release: Version 1.0
In Development: No
Initial Release Date: 18-AUGUST-2021
Last Date Updated: 31-AUGUST-2021
Controller: Digital
Players: 1
Memory Card: -
Languages: Eng
Region: -
Burn and Play: -
Executable Included: Yes
Source Included: Yes

Last month I was following NeHe's tutorial on how to do rope physics and it worked! In a nutshell, the rope is composed of 24 masses (the tutorial uses 80). Each pair of masses is connected via a spring, and we use Hooke's Law (F = -k * (x-d)) to determine the forces upon each spring. Note that we've written Hooke's Law in a way that only works in one dimension, so to expand into two dimensions we multiply the formula with a unit vector like so: (F = u * (-k * (x-d))).

We obtain the unit vector by first finding the difference of the two masses' positions connected to the spring. Store that into a VECTOR struct called "v". Next, find the length of "v" and store the result into an int called "r". Finally, divide each component of "v" by the length (r) and store it into the final unit vector called "u". More information can be found here. Here's some code:

Code: Select all

/* 
 * modified code snippet of spring_solve() from physics.c.
 * Note how 2^6 (and not 4096) == 1.0 here
 */
 
/* determine unit vector */
setVector(&u, 0, 0, 0);
setVector(&f, 0, 0, 0);

setVector(&v,	p_spring->p_mass1->pos.vx - p_spring->p_mass2->pos.vx,
		p_spring->p_mass1->pos.vy - p_spring->p_mass2->pos.vy,
		0);

r = psqrt(	((v.vx*v.vx)>>6) +
		((v.vy*v.vy)>>6) );

if( r != 0 )
{
	if( r>>6 != 0 )
	{
		setVector(&u,	v.vx / (r>>6),
				v.vy / (r>>6),
				0);
	}
}
From there just apply all the other forces you want: gravitational force, friction force, forces from other objects, etc..

I've made it so that all physics calculations use 2^6 format (64 == 1.0) instead of 2^12 (4096 == 1.0), which allows a far greater range when doing certain operations (such as squaring numbers). This also means that I had to write a few custom math routines to accommodate 2^6 format in pfixed.c. If you decide to play around with the rope values, there's a chance that the rope may go haywire since my iffy handling of fixed-point arithmetic in the physics functions can sometimes fail to produce fractional values under certain conditions.. at least that's what I think is happening. I've had to do some dumb stuff like doubling the amount of gravity to get the rope to fall faster but ehhhh...

Image

EXE and Source Code: https://www.mediafire.com/file/ei8y4l0w ... pe.7z/file

Last edited by mzxtuelkl on April 2nd, 2022, 10:15 am, edited 3 times in total.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2562
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » August 26th, 2021, 5:26 pm

That is extremely impressive. Very nice job :)
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest