Hi everybody!

I wanna start a project with you together. It's about the nice physics engine, 3d GameStudio has, and about the fact of a deficit in examples and tutorials in this category.

So let's make and collect some nice gimmicks.

Code:
/*
A project started by Clemens Möckel (23.1.2011)

with the aim of a nice, big collection of 3dGS PhysX gimmicks...

Start now and create/add yours. Here's the How-to:

1) Program a function which creates your physics gimmick (simulation)... like the function create_chain_ball()
	-try to keep it as simple as possible
	-document and comment your source code and insert "[help]" at each places, you have trouble with
2) Implement a hotkey to your function in the main function.
3) You need to have a while loop
	-which includes the user control (if there is one) (I)
	-a draw_text command giving a short description of your gimmick (II)
	-and very important: a "if (key_delete)" block, which removes your gimmick (III)
4) Add a "gimmick_is_running=1;" before the while loop and a "gimmick_is_running=0;" after that loop
5) Share it in the 3dGs forum at: [url]
   -don't forget a download with the models/prefabs
   -post a screenshot of your gimmick
*/

///////////////////////////////
#include <acknex.h>
#include <default.c>
#include <ackphysx.h>
///////////////////////////////

BOOL gimmick_is_running;

////////////////////////
// chain_ball v0.3 by Clemens

function create_chain_ball() {
	// Create the chains, and the ball at the bottom
	ENTITY* Ring1 = ent_create("chain_ring.mdl", vector(0,0,0), NULL);
	ENTITY* Ring2 = ent_create("chain_ring.mdl", vector(0,0,-10), NULL);
	Ring2.pan=90;
	ENTITY* Ring3 = ent_create("chain_ring.mdl", vector(0,0,-20), NULL);
	ENTITY* Ring4 = ent_create("chain_ring.mdl", vector(0,0,-30), NULL);
	Ring4.pan=90;
	ENTITY* Ring5 = ent_create("chain_ring.mdl", vector(0,0,-40), NULL);
	ENTITY* Ring6 = ent_create("chain_ring.mdl", vector(0,0,-50), NULL);
	Ring6.pan=90;
	ENTITY* Ball = ent_create("sphere.mdl", vector(0,0,-64), NULL);
	
	// Just for the look
	// material
	set(Ring1,LIGHT|CAST);set(Ring2,LIGHT|CAST);set(Ring3,LIGHT|CAST);set(Ring4,LIGHT|CAST);set(Ring5,LIGHT|CAST);set(Ring6,LIGHT|CAST);set(Ball,LIGHT|CAST);
	Ring1.material=mat_metal;Ring2.material=mat_metal;Ring3.material=mat_metal;Ring4.material=mat_metal;Ring5.material=mat_metal;Ring6.material=mat_metal;Ball.material=mat_metal;
	// colors
	//[variante1] vec_set(Ring1.blue,vector(200,0,0));vec_set(Ring2.blue,vector(0,100,0));vec_set(Ring3.blue,vector(200,0,0));vec_set(Ring4.blue,vector(0,200,0));vec_set(Ring5.blue,vector(200,0,0));vec_set(Ring6.blue,vector(0,200,0));vec_set(Ball.blue,vector(0,0,200));
	vec_set(Ring1.blue,vector(200,0,0));vec_set(Ring2.blue,vector(160,40,0));vec_set(Ring3.blue,vector(120,80,0));vec_set(Ring4.blue,vector(80,120,0));vec_set(Ring5.blue,vector(40,160,0));vec_set(Ring6.blue,vector(0,200,0));vec_set(Ball.blue,vector(0,100,100));
	// casting shadows
	set(Ring1,SHADOW); set(Ring2,SHADOW); set(Ring3,SHADOW); set(Ring4,SHADOW); set(Ring5,SHADOW); set(Ring6,SHADOW); set(Ball,SHADOW);


	// Make them physical by define their types
	pXent_settype(Ring1,PH_RIGID,PH_CONVEX);
	pXent_settype(Ring2,PH_RIGID,PH_CONVEX);
	pXent_settype(Ring3,PH_RIGID,PH_CONVEX);
	pXent_settype(Ring4,PH_RIGID,PH_CONVEX);
	pXent_settype(Ring5,PH_RIGID,PH_CONVEX);
	pXent_settype(Ring6,PH_RIGID,PH_CONVEX);
	pXent_settype(Ball,PH_RIGID,PH_BALL);
	
	// group the rings so they dont affect each other related to their collision (getting important if they losing their constraints)
	pXent_setgroup(Ring1,3); pXent_setgroup(Ring2,3); pXent_setgroup(Ring3,3); pXent_setgroup(Ring4,3);pXent_setgroup (Ring5,3);pXent_setgroup (Ring6,3);
	 //pXent_setgroup(Ball,3);
	
	// Connect the objects!
	pXcon_add ( PH_BALL, Ring1, NULL, 0 );		// PH_BALL makes it more movable...
 	pXcon_add ( PH_HINGE, Ring2, Ring1, 0 );
 	pXcon_add ( PH_HINGE, Ring3, Ring2, 0 );
 	pXcon_add ( PH_HINGE, Ring4, Ring3, 0 );
 	pXcon_add ( PH_HINGE, Ring5, Ring4, 0 );
 	pXcon_add ( PH_HINGE, Ring6, Ring5, 0 );
 	pXcon_add ( PH_HINGE, Ball, Ring6, 0 );
	
	pXcon_setparams1(Ring1, vector(0,0,5), NULL, NULL);	// anchor point at the top, like attached on the ceiling
	// change the axis - otherwise the chains wouldn't keep their 90° pan relation ... (1,0,0), (0,1,0), (1,1,0) seems to make no difference (?)
	pXcon_setparams1(Ring2, NULL, vector(0,1,0), NULL);
	pXcon_setparams1(Ring3, NULL, vector(0,1,0), NULL);
	pXcon_setparams1(Ring4, NULL, vector(0,1,0), NULL);
	pXcon_setparams1(Ring5, NULL, vector(0,1,0), NULL);
	pXcon_setparams1(Ring6, NULL, vector(0,1,0), NULL);

	pXent_setmass(Ball, 0.01);		// if the ball is to heavy it results in physical chaos
			// reducing pXent_setmaxspeed can help to protect chaos, too - but then the sixth ring becomes stiff... why? [help]
			//pXent_setmaxspeed(Ball, 0.1);
			// second way would probably be to change parameter3 --> let it break before
	pXent_setdamping (Ball, 50, 50 ); // the ball gets forced, so it as well has to be damped - otherwise doesn't stop moving

	gimmick_is_running=1;
	while(1) {
		// (I) user control
		if (key_cul) pXent_addforcecentral(Ball, vector(-0.01, 0, 0));
		if (key_cur) pXent_addforcecentral(Ball, vector(0.01, 0, 0));
		if (key_cuu) pXent_addforcecentral(Ball, vector(0, 0.01, 0));
		if (key_cud)pXent_addforcecentral(Ball, vector(0, -0.01, 0));
		// (II) info text
		draw_text("chain_ball v0.3 by Clemens \n arrow keys: give the ball a force in that direction \n del key: destroy it", 10,10,vector(255,255,255));			
		// (III) remove gimmick... (only a part) 
		if (key_del) {
			pXcon_remove(Ball);	// backwards order important
			pXcon_remove(Ring6);
			pXcon_remove(Ring5);
			pXcon_remove(Ring4);
			pXcon_remove(Ring3);
			pXcon_remove(Ring2);
			pXcon_remove(Ring1);			
			break;
		}
		pX_pick();
		wait(1);	
	}
	gimmick_is_running=0;
	wait(-5);
	// placed the real remove routine here, because it's a nice effect, having it destroyed and lying on the door for five seconds
	ent_remove(Ball);
	/* "Error E1513: Script crash in physX_ent_remove: SYS" when deleting the rings -> don't know why [help]
	ent_remove(Ring6);
	ent_remove(Ring5);
	ent_remove(Ring4);
	ent_remove(Ring3);
	ent_remove(Ring2);
	ent_remove(Ring1);
	*/
}


////////////////
// main function

function main() {
	sun_angle.pan -= 80;
	sun_angle.tilt = 50;
	shadow_stencil = 3;
	d3d_antialias = 4;
	
	physX_open();
	level_load(""); // load empty level
	vec_set(camera.x,vector(0,-180,-50));
	camera.pan=90;

	// create ground plate (copied from physXtest.c by jcl)
	ENTITY* ground = ent_create(CUBE_MDL,vector(0,0,-100),NULL);
	vec_set(ground.scale_x,vector(20,20,1));
	pXent_settype(ground,PH_STATIC,PH_BOX); 
	pXent_setfriction(ground,10);

	
	while (1) {
		if (gimmick_is_running==0) {
			if (key_a) {
				create_chain_ball();
				wait(-1);
			}
			// Here you have to insert your function-hotkey
			// ...
		}
		wait(1);
	}
}



Don't forget to upload the needed models/prefabs etc.

Here's the whole "starter" package: Download

Including my first gimmick chain_ball v0.3:


Feel free to correct spelling mistakes and to edit any script (but document it!) for making new better versions!

Interested to join work, but no ideas? What about one of these...
-rope
-seesaw
-weighing machine
-trampoline
-carousel
-Newton's cradle
-piece of furniture
-elevator
-skid
-snake
-breakable glass
-crane
-chart house
-"jenga" tower
-gearwheel
-trap (for mouse/bear/saw^^)

Best regards,
Clemens

Last edited by Clemens; 02/01/11 20:01.