I don't have time to pursue this. Maybe someone else can add the rigid bodies. I had some success with making objects out of cross-linked chains, but it got to be too many chains for even a simple cube.
The missing code is the part that adjusts the rotation of the object. I suggest building off of what i have, rather than doing a whole new routine.
Do not ask me for support.
Demo program:
Physics routines ("physics.bb"):
The missing code is the part that adjusts the rotation of the object. I suggest building off of what i have, rather than doing a whole new routine.
Do not ask me for support.
Demo program:
Include "physics.bb" Graphics3D 800,600,16,2 SetBuffer BackBuffer() Global cam=CreateCamera() MoveEntity cam,0,30,-45 TurnEntity cam,35,0,0 ;MoveEntity cam,0,0,-24 g=LoadMesh("start.b3d") ScaleMesh g,.10,.10,.10 MoveEntity g,0,-15,30 ;RotateEntity g,0,0,5 ;g=CreatePlane() EntityType g,2 ;MoveEntity g,0,-10,0 ;EntityColor g,100,100,100 ; For n=1 To 0 g=CreateCube() RotateEntity g,0,90+45,0 MoveEntity g,2*n+50,-10+n*2,-50 ScaleEntity g,1,1,100 EntityType g,2 EntityColor g,100,100,100 Next ;g=CreateCube() ;ScaleMesh g,20,20,20 ;MoveEntity g,0,0,20 ;FlipMesh g r#=1.5 m=CreateSphere() EntityShininess m,1 EntityType m,1 EntityRadius m,r ScaleMesh m,r,r,r HideEntity m l=CreateLight() RotateEntity l,25,45,0 EntityParent l,cam Collisions 1,2,2,2 Collisions 1,1,1,2 link=CreateSphere() EntityType link,1 EntityRadius link,1 HideEntity link For m=1 To 6 For n=1 To 6 link=CopyEntity(link) EntityColor link,Rand(255),Rand(255),Rand(255) If n=1 firstlink=link ;entitymass link,100000 PositionEntity link,Rnd(-32,33),20,Rnd(-32,32) EndIf If n=1 And m<>6 ScaleEntity link,2,2,2 EntityRadius link,2 enablephysics link,0 entitymass link,100000 Else PositionEntity link,EntityX(firstlink),20-5*n,EntityZ(firstlink) ScaleEntity link,r,r,r EntityRadius link,r enablephysics link,11 ;entityelasticity link,0.9 entityfriction link,0.01 EndIf If n=2 chain=createchain(link,lastlink,5) EndIf If n>2 chain=createchain(link,lastlink,5) EndIf lastlink=link Next ;If ll<>0 And m<>6 createchain ll,firstlink,5 ll=link Next entitymass link,20 rb.rigidbody=New rigidbody ball=CopyMesh(link) ScaleEntity ball,1,1,1 EntityType ball,0 rb\mesh=ball Include "CreateRigidCube.bb" ball=CopyMesh(link) ScaleEntity ball,2,2,2 EntityType ball,1 EntityRadius ball,2 MoveEntity ball,5,0,0 EntityColor ball,255,0,0 ph.physics=enablephysics(ball,11) ph\body=rb entityelasticity ball,0.9 entityfriction ball,0.01 ball=CopyMesh(link) ScaleEntity ball,2,2,2 EntityType ball,1 EntityRadius ball,2 MoveEntity ball,-5,0,0 EntityColor ball,255,0,0 ph.physics=enablephysics(ball,11) ph\body=rb entityelasticity ball,0.9 entityfriction ball,0.01 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) ;r=Rand(2)+1 r=3 ball=CopyMesh(link) ScaleEntity ball,r,r,r EntityRadius ball,r EntityType ball,1 PositionEntity ball,Rnd(-20,20),Rnd(20),Rnd(-20,20) enablephysics ball,11 entitymass ball,2;r^2 EntityElasticity ball,0.98 EntityColor ball,Rand(255),Rand(255),Rand(255) EntityFriction ball,0.01 MoveEntity ball,Rnd(-2,2),Rnd(-2,2),Rnd(-2,2) balls=balls+1 If lastball ;If Rand(2)=1 createchain lastball,ball,10 lastball=0 Else lastball=ball EndIf EndIf TranslateEntity link,0.05*(KeyDown(205)-KeyDown(203)),0.5*KeyDown(16),0.05*(KeyDown(200)-KeyDown(208)) UpdatePhysics 1 Next RenderWorld Text 0,0,fps() Text 0,20,"Press Q to lift chain." Text 0,40,"Arrow keys move chain" Text 0,60,"Press enter to add balls." Text 0,80,balls+" balls." Flip Wend 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
Physics routines ("physics.bb"):
Type bond Field mesh Field a.physics, b.physics Field length# Field nextlink.bond Field updated Field offsetA# Field offsetb# End Type Type rigidbody Field mesh Field points End Type Type physics Field mesh Field velocity#[5] Field elasticity# Field mass# Field flags Field friction#[1] Field position#[5] Field compression#[1] Field dvelocity#[5] Field offset#[2] Field body.rigidbody End Type Function CreateChain(a,b,length#) ph.physics=findphysics(a) If ph=Null RuntimeError "Entity does not have physics enabled." ph2.physics=findphysics(b) If ph2=Null RuntimeError "Entity does not have physics enabled." l.bond=New bond l\mesh=CreateCube() l\a=ph l\b=ph2 l\length=length loffseta=Rnd(-90,90) loffsetb=Rnd(-90,90) Return Handle(l) End Function Function AddLink(chain,link,length#) ph.physics=findphysics(link) If ph=Null RuntimeError "Entity does not have physics enabled." l2.bond=Object.bond(chain) l.bond=New bond l2\nextlink=l l\mesh=CreateCube() l\a=l2\b l\b=ph l\length=length/2 Return Handle(l) End Function Function UpdatePhysics(detail=2) For ph.physics=Each physics ;update velocity If 2^0 And ph\flags If 2^3 And ph\flags ph\velocity[0]=ph\velocity[0]+EntityX(ph\mesh,1)-ph\position[0] ph\velocity[1]=ph\velocity[1]+EntityY(ph\mesh,1)-ph\position[1] ph\velocity[2]=ph\velocity[2]+EntityZ(ph\mesh,1)-ph\position[2] EndIf EndIf ph\position[0]=EntityX(ph\mesh,1) ph\position[1]=EntityY(ph\mesh,1) ph\position[2]=EntityZ(ph\mesh,1) ;gravity If 2^1 And ph\flags ph\velocity[1]=ph\velocity[1]-0.05 EndIf ;execute translational velocity If 2^0 And ph\flags TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1 ;TranslateEntity ph\mesh,Rnd(-0.00001,0.00001),Rnd(-0.0001,0.0001),Rnd(-0.0001,0.0001),1 EndIf ;execute rotational velocity If 2^2 And ph\flags TurnEntity ph\mesh,ph\velocity[3],ph\velocity[4],ph\velocity[5],1 ph\position[3]=EntityX(ph\mesh,1) ph\position[4]=EntityY(ph\mesh,1) ph\position[5]=EntityZ(ph\mesh,1) Next UpdateWorld For ph.physics=Each physics ph\velocity[3]=ph\velocity[0] ph\velocity[4]=ph\velocity[1] ph\velocity[5]=ph\velocity[2] ph\velocity[0]=EntityX(ph\mesh,1)-ph\position[0] ph\velocity[1]=EntityY(ph\mesh,1)-ph\position[1] ph\velocity[2]=EntityZ(ph\mesh,1)-ph\position[2] Next ;transfer inertia For ph.physics=Each physics vx#=ph\velocity[3]-ph\velocity[0] vy#=ph\velocity[4]-ph\velocity[1] vz#=ph\velocity[5]-ph\velocity[2] For c=1 To CountCollisions(ph\mesh) collider=CollisionEntity(ph\mesh,c) x#=CollisionX(ph\mesh,c) y#=CollisionY(ph\mesh,c) z#=CollisionZ(ph\mesh,c) nx#=Abs(CollisionNX(ph\mesh,c)) ny#=Abs(CollisionNY(ph\mesh,c)) nz#=Abs(CollisionNZ(ph\mesh,c)) Select GetEntityType(collider) ; ;Spheres Case 1 k#=0.5 ph2.physics=findphysics(collider) If ph2<>Null ph2\velocity[0]=ph2\velocity[0]+vx*k*ph\mass/ph2\mass ph2\velocity[1]=ph2\velocity[1]+vy*k*ph\mass/ph2\mass ph2\velocity[2]=ph2\velocity[2]+vz*k*ph\mass/ph2\mass Exit EndIf ;Polygons with infinite mass Case 2 k#=0.8 If k*nx*Abs(ph\velocity[3])>Abs(ph\velocity[0]) ph\velocity[0]=ph\velocity[0]*(1.-k*nx)-ph\velocity[3]*nx*k If k*ny*Abs(ph\velocity[4])>Abs(ph\velocity[1]) ph\velocity[1]=ph\velocity[1]*(1.-k*ny)-ph\velocity[4]*ny*k If k*nz*Abs(ph\velocity[5])>Abs(ph\velocity[2]) ph\velocity[2]=ph\velocity[2]*(1.-k*nz)-ph\velocity[5]*nz*k 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]*ph\friction[0] ;static friction If Abs(ph\velocity[n])<ph\friction[1] ph\velocity[n]=0.0 Next EndIf Next ;save positions for automatic velocity updating For ph.physics=Each physics ph\position[0]=EntityX(ph\mesh,1) ph\position[1]=EntityY(ph\mesh,1) ph\position[2]=EntityZ(ph\mesh,1) Next ;handle chains For b.bond=Each bond ScaleEntity b\mesh,1,1,1 fma#=b\a\mass/(b\a\mass+b\b\mass) fmb#=b\b\mass/(b\a\mass+b\b\mass) PositionEntity b\mesh,EntityX(b\a\mesh,1)*fma+EntityX(b\b\mesh,1)*fmb,EntityY(b\a\mesh,1)*fma+EntityY(b\b\mesh,1)*fmb,EntityZ(b\a\mesh,1)*fma+EntityZ(b\b\mesh,1)*fmb 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 MoveEntity b\mesh,0,0,(0.5-fma)*b\length TFormPoint 0,0,b\length/2.0,b\mesh,0 PositionEntity b\a\mesh,TFormedX(),TFormedY(),TFormedZ(),1 TFormPoint 0,0,-b\length/2.0,b\mesh,0 PositionEntity b\b\mesh,TFormedX(),TFormedY(),TFormedZ(),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)) Next For rb.rigidbody=Each rigidbody x#=0.0 y#=0.0 z#=0.0 yaw#=0.0 n=0 For ph.physics=Each physics If ph\body=rb x=x+EntityX(ph\mesh,1) y=y+EntityY(ph\mesh,1) z=z+EntityZ(ph\mesh,1) TFormPoint ph\offset[0],ph\offset[1],ph\offset[2],rb\mesh,0 dx#=EntityX(ph\mesh,1)-EntityX(rb\mesh,1) dy#=EntityY(ph\mesh,1)-EntityY(rb\mesh,1) dz#=EntityZ(ph\mesh,1)-EntityZ(rb\mesh,1) Normalize dx,dy,dz If n=0 AlignToVector rb\mesh,dx,0,dz,1 Else AlignToVector rb\mesh,-dx,0,-dz,1 If EntityYaw(rb\mesh,1)<0.0 yu=360.0+EntityYaw(rb\mesh,1) Else yu=EntityYaw(rb\mesh,1) yaw=yaw+yu n=n+1 EndIf Next x=x/Float(n) y=y/Float(n) z=z/Float(n) yaw=yaw/Float(n) PositionEntity rb\mesh,x,y,z,1 RotateEntity rb\mesh,0,yaw,0,1 For ph.physics=Each physics If ph\body=rb TFormPoint ph\offset[0],ph\offset[1],ph\offset[2],rb\mesh,0 PositionEntity ph\mesh,TFormedX(),TFormedY(),TFormedZ() EndIf Next Next End Function Function MoveLinks(entity,x#,y#,z#) If KeyDown(57) For b.bond=Each bond If b\updated=False If b\a\mesh=entity TranslateEntity b\b\mesh,x,y,z,1 b\updated=True movelinks b\b\mesh,x,y,z ElseIf b\b\mesh=entity TranslateEntity b\a\mesh,x,y,z,1 b\updated=True movelinks b\a\mesh,x,y,z EndIf EndIf Next EndIf End Function Function CreateVerletCube() End Function Function EntityCompression(ease#,max#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\Compression[0]=ease ph\Compression[1]=max End Function Function PointDistance#( x1#,y1#,z1#,x2#,y2#,z2# ) Return Sqr#((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) End Function Function EntityFriction(e,sliding#,static#=0.0001) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\friction[0]=1.0-sliding ph\friction[1]=static End Function Function FindPhysics.physics(e) For ph.physics=Each physics If ph\mesh=e Return ph Next Return Null End Function Function EnablePhysics.physics(e,flags=9) ph.physics=findphysics(e) If ph=Null ph=New physics For n=0 To 5 ph\velocity[n]=0 Next ph\mesh=e ph\mass=1.0 ph\elasticity=0.0 ph\flags=flags ph\friction[0]=0.9 ph\friction[1]=0.001 ResetEntity e ph\position[0]=EntityX(e,1) ph\position[1]=EntityY(e,1) ph\position[2]=EntityZ(e,1) ph\compression[0]=0.8 ph\compression[1]=1.5 ph\offset[0]=EntityX(e) ph\offset[1]=EntityY(e) ph\offset[2]=EntityZ(e) Return ph End Function Function DisablePhysics(e) ph.physics=findphysics(e) If ph<>Null Delete ph End Function Function EntityElasticity(e,m#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\Elasticity=m End Function Function AccelerateEntity(e,x#,y#,z#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\velocity[0]=ph\velocity[0]+x ph\velocity[1]=ph\velocity[1]+y ph\velocity[2]=ph\velocity[2]+z End Function Function EntityVelocity(e,x#,y#,z#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\velocity[0]=x ph\velocity[1]=y ph\velocity[2]=z End Function Function EntityInertia(e,x#,y#,z#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\velocity[0]=x/ph\mass ph\velocity[1]=y/ph\mass ph\velocity[2]=z/ph\mass End Function Function EntityMass(e,m#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." ph\mass=m End Function Function GetEntityMass#(e,m#) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\mass End Function Function EntityInertiaX#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\mass*ph\velocity[0] End Function Function EntityInertiaY#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\mass*ph\velocity[1] End Function Function EntityInertiaZ#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\mass*ph\velocity[2] End Function Function EntityVelocityX#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\velocity[0] End Function Function EntityVelocityY#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\velocity[1] End Function Function EntityVelocityZ#(e) ph.physics=findphysics(e) If ph=Null RuntimeError "Entity does not have physics enabled." Return ph\velocity[2] End Function