Try this one. If anyone can get the bonds to keep the balls the right distance from each other, please do:
Graphics3D 800,600,16,2 SetBuffer BackBuffer() cam=CreateCamera() MoveEntity cam,0,15,-20 TurnEntity cam,35,0,0 g=CreateCube() ScaleMesh g,10,10,10 FlipMesh g EntityType g,2 EntityColor g,100,100,100 r=1 m=CreateSphere() EntityShininess m,1 EntityType m,1 EntityRadius m,r ScaleEntity m,r,r,r Collisions 1,2,2,2 Collisions 1,1,1,2 Collisions 1,3,2,2 Collisions 3,2,2,2 ;Collisions 3,1,1,2 ;Collisions 3,3,1,2 ;cubes=5 ;For n=1 To cubes ; cube=CreateCube() ; EntityRadius cube,r ; ScaleEntity cube,r,r,r ; cubeph.physics=New physics ; cubeph\mesh=cube ; cubeph\elasticity=0.2 ; ScaleEntity cube,3,1,1 ; EntityType cube,3 ; EntityColor cube,255,0,0 ; MoveEntity cube,Rnd(-8,8),-8,Rnd(-8,8) ; Next RotateEntity CreateLight(),25,45,0 Global gravity=True Type bond Field mesh Field a.physics, b.physics End Type Type physics Field mesh Field velocity#[5] Field elasticity# Field mass# End Type balls=5 e#=0.9 b.bond=New bond b\mesh=CreateCube() For n=1 To balls ph.physics=New physics If n=1 b\a=ph If n=2 b\b=ph ph\mesh=CopyEntity(m) ph\velocity[0]=Rnd(-.5,.5) ph\velocity[1]=Rnd(-1,1) ph\velocity[2]=Rnd(-.5,.5) PositionEntity ph\mesh,Rnd(-8,8),-8,Rnd(-8,8) ResetEntity ph\mesh ph\elasticity#=e# EntityColor ph\mesh,Rand(255),Rand(255),Rand(255) Next HideEntity m period=1000/60 time=MilliSecs()-period While Not KeyHit(1) Repeat elapsed=MilliSecs()-time Until elapsed ticks=elapsed/period tween#=Float(elapsed Mod period)/Float(period) For k=1 To ticks time=time+period If KeyDown(28) ph.physics=New physics ph\mesh=CopyEntity(m) ph\velocity[0]=Rnd(-.5,.5) ph\velocity[1]=Rnd(-1,1) ph\velocity[2]=Rnd(-.5,.5) ScaleEntity ph\mesh,r,r,r EntityRadius ph\mesh,r ResetEntity ph\mesh ph\elasticity#=e EntityColor ph\mesh,Rand(255),Rand(255),Rand(255) balls=balls+1 EndIf If KeyHit(57) For ph.physics=Each physics ph\velocity[0]=Rnd(-.5,.5) ph\velocity[1]=Rnd(-2,2) ph\velocity[2]=Rnd(-.5,.5) ph\velocity[4]=0 Next EndIf If KeyHit(34) gravity=1-gravity UpdatePhysics Next RenderWorld Text 0,0,fps() Text 0,20,"Press space to reset balls." Text 0,40,"Press enter to add more balls." Text 0,60,"Press g to toggle gravity." Text 0,80,balls+" balls exist." Flip Wend Function UpdatePhysics() friction#=1;0.99;sliding friction staticfriction#=0.0000;static friction = minimum velocity before an objects starts sticking For ph.physics=Each physics ;gravity If gravity ph\velocity[1]=ph\velocity[1]-0.03 ;ph\velocity[1]=0 ;execute translational velocity TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1 ;execute rotational velocity TurnEntity ph\mesh,ph\velocity[3],ph\velocity[4],ph\velocity[5],1 Next UpdateWorld ;transfer inertia For ph.physics=Each physics vx#=ph\velocity[0] vy#=ph\velocity[1] vz#=ph\velocity[2] For c=1 To CountCollisions(ph\mesh) collider=CollisionEntity(ph\mesh,c) dx#=ph\velocity[0]*Abs(CollisionNX(ph\mesh,c)) dy#=ph\velocity[1]*Abs(CollisionNY(ph\mesh,c)) dz#=ph\velocity[2]*Abs(CollisionNZ(ph\mesh,c)) Select GetEntityType(collider) ;Spheres Case 1 ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c))) ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c))) ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c))) ph\velocity[0]=ph\velocity[0];-dx*.5 ph\velocity[1]=ph\velocity[1];-dy*.5 ph\velocity[2]=ph\velocity[2];-dz*.5 ph2.physics=findphysics(collider) ph2\velocity[0]=ph2\velocity[0]+dx;*.5 ph2\velocity[1]=ph2\velocity[1]+dy;*.5 ph2\velocity[2]=ph2\velocity[2]+dz;*.5 ;Polygons with infinite mass Case 2 ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))-dx*ph\elasticity ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))-dy*ph\elasticity ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))-dz*ph\elasticity ;Polygons ;Case 3 ; ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c))) ; ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c))) ; ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c))) ; ph2.physics=findphysics(collider) ; temp=CreatePivot() ; PositionEntity temp,CollisionX(ph\mesh,c),CollisionY(ph\mesh,c),CollisionZ(ph\mesh,c);PickedX(),PickedY(),PickedZ() ; AlignToVector temp,-CollisionNX(ph\mesh,c),-CollisionNY(ph\mesh,c),-CollisionNZ(ph\mesh,c),3 ; TFormPoint EntityX(ph2\mesh,1),EntityY(ph2\mesh,1),EntityZ(ph2\mesh,1),0,temp ; ph2\velocity[4]=ph2\velocity[4]-TFormedX()*Sqr(dx^2.0+dz^2.0) ; TFormPoint 0,0,TFormedZ(),temp,0 ; ph2\velocity[0]=ph2\velocity[0]-dx*CollisionNX(ph\mesh,c) ; ph2\velocity[1]=ph2\velocity[1]-dy*CollisionNY(ph\mesh,c) ; ph2\velocity[2]=ph2\velocity[2]-dz*CollisionNZ(ph\mesh,c) ; FreeEntity temp End Select Next Next ;add friction For ph.physics=Each physics If EntityCollided(ph\mesh,2) For n=0 To 5 ;sliding friction ph\velocity[n]=ph\velocity[n]*friction ;static friction If Abs(ph\velocity[n])<staticfriction# ph\velocity[n]=0.0 Next EndIf Next For b.bond=Each bond PositionEntity b\mesh,(EntityX(b\a\mesh,1)+EntityX(b\b\mesh,1))/2.0,(EntityY(b\a\mesh,1)+EntityY(b\b\mesh,1))/2.0,(EntityZ(b\a\mesh,1)+EntityZ(b\b\mesh,1))/2.0 AlignToVector b\mesh,EntityX(b\a\mesh,1)-EntityX(b\b\mesh,1),EntityY(b\a\mesh,1)-EntityY(b\b\mesh,1),EntityZ(b\a\mesh,1)-EntityZ(b\b\mesh,1),3 RotateEntity b\mesh,EntityPitch(b\mesh,1),EntityYaw(b\mesh,1),0,1 ScaleEntity b\mesh,.25,.25,0.5*pointdistance(EntityX(b\b\mesh,1),EntityY(b\b\mesh,1),EntityZ(b\b\mesh,1),EntityX(b\a\mesh,1),EntityY(b\a\mesh,1),EntityZ(b\a\mesh,1)) ax#=b\a\velocity[0] ay#=b\a\velocity[1] az#=b\a\velocity[2] bx#=b\b\velocity[0] by#=b\b\velocity[1] bz#=b\b\velocity[2] ;TFormPoint EntityX(b\a\mesh),EntityY(b\a\mesh),EntityZ(b\a\mesh),0,b\mesh ;TFormPoint 0,0,TFormedZ()+2,b\mesh,0 ;b\a\velocity[0]=b\a\velocity[0]+TFormedX() ;b\a\velocity[1]=b\a\velocity[1]+TFormedY() ;b\a\velocity[2]=b\a\velocity[2]+TFormedZ() ;TFormPoint EntityX(b\b\mesh),EntityY(b\b\mesh),EntityZ(b\b\mesh),0,b\mesh ;TFormPoint 0,0,TFormedZ()-2,b\mesh,0 ;b\b\velocity[0]=b\b\velocity[0]+TFormedX() ;b\b\velocity[1]=b\b\velocity[1]+TFormedY() ;b\b\velocity[2]=b\b\velocity[2]+TFormedZ() ;b\a\velocity[0]=-bx;(EntityX(b\a\mesh)-TFormedX()) ;b\a\velocity[1]=-by;(EntityY(b\a\mesh)-TFormedY()) ;b\a\velocity[2]=-bz;(EntityZ(b\a\mesh)-TFormedZ()) ;PositionEntity b\a\mesh,TFormedX(),TFormedY(),TFormedZ(),1 ;TranslateEntity b\a\mesh,bx,by,bz,1 ;TFormPoint 0,0,2,b\mesh,0 ;b\b\velocity[0]=-ax;(EntityX(b\b\mesh)-TFormedX()) ;b\b\velocity[1]=-ay;(EntityY(b\b\mesh)-TFormedY()) ;b\b\velocity[2]=-az;(EntityZ(b\b\mesh)-TFormedZ()) ;TranslateEntity b\b\mesh,ax,ay,az,1;TFormedX(),TFormedY(),TFormedZ(),1 Next End Function Function FindPhysics.physics(e) For ph.physics=Each physics If ph\mesh=e Return ph Next Return Null End Function Function PointDistance#( x1#,y1#,z1#,x2#,y2#,z2# ) Return Sqr#((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) End Function Global FPS_fpstime Function FPS() oldtime=FPS_fpstime FPS_fpstime=MilliSecs() elapsed=FPS_fpstime-oldtime If Not elapsed elapsed=1 FPS_fps=1000/elapsed Return FPS_FPS End Function