; ################################################################################################### ; # JV-ODE - Pyramid Destruction IV Demo # ; # Jim Williams (VIP3R) and Wayne Gray # ; ################################################################################################### AppTitle "JV-ODE - Pyramid Destruction IV" Include "JV-ODE.bb" Graphics3D 800,600,32,2 HidePointer Global ElapsedTime Global LastTime Global FrameCount Global Frames Global Time Global cflag Global Proj Global Projbody Global snd1 Global snd2 Global piv1 Global Planet$ Global gx Global Wide=10 ; Number of blocks wide at the base, default 10 Global Gap#=8 ; Gap spacing, default 8 Global RBW#=5 ; Real block width, default 5 piv1=CreatePivot() Type ODEGeom Field body Field geom Field mesh End Type ; create a blank image gfxBlank=CreateImage (256,256) ; ################################################################################################### ; ### Setup ODE Global World=dWorldCreate() Global Space=dHashSpaceCreate(0) Global ContactGroup=dJointGroupCreate(0) dWorldSetAutoDisableFlag(World,1) dWorldSetGravity(World,0,-1.0,0) Planet="Earth" gx=1 dWorldSetERP(World,0.4) dContactSetMode(dContactBounce) dContactSetBounce(0.0) dContactSetMu(80) ; High Performance Settings ; Causes objects to settle down and sleep faster dWorldSetAutoDisableLinearThreshold (World, .1) dWorldSetAutoDisableAngularThreshold (World, .1) dWorldSetAutoDisableSteps (World,10) dContactSetMaxContacts(16) dWorldSetQuickStepNumIterations (World,20) ; default 20 ; ### Create light Global Light=CreateLight() RotateEntity Light,45,-90,0 LightColor Light,255,255,255 AmbientLight 130,130,130 ; ### Create camera Global Camera=CreateCamera() CameraClsColor Camera,0,0,0 CameraRange Camera,1,1000 PositionEntity Camera,30,25,-100 RotateEntity Camera,15,0,0 ; Create first camera Global cam1=CreateCamera() ; Set the first camera's viewport so that it fills the top half of the camera CameraViewport cam1,GraphicsWidth()-256,0,256,256 ; ### Load sounds snd1=Load3DSound("media\Impact.wav") snd2=LoadSound("media\whizz.wav") SoundVolume snd2,.2 mic1=CreateListener(camera,.3,1,1) ; Create listener, make it child of camera ; ### Create plane dCreatePlane(Space,0,1,0,0) Plane=CreatePlane() EntityAlpha Plane,0.8 PlaneTexture=CreateTexture(128,128,9) ClsColor 0,200,80 Cls Color 255,255,255 Rect 0,0,64,64,1 Rect 64,64,64,64,1 CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture) ScaleTexture PlaneTexture,20,20 EntityTexture Plane,PlaneTexture,0,0 Mirror=CreateMirror() ; Construct pyramid For j#=wide To 1 Step -1 For k#=1 To j AddObject(k#*Gap+(wide-j#)*Gap/2,RBW/2 + (wide-j#)*RBW) bcount=bcount+1 Next Next addProjectile(EntityX(camera),EntityY(camera),EntityZ(camera)) ; ################################################################################################### While Not KeyHit(1) UpdateControls() ; Calculate Time If T=0 Then T=MilliSecs() T=MilliSecs() ; Mouse Look code ; Poll Mouse Movement every 25ms ( 40/sec ) If T > Time2 + 25 Then Time2=T mxs#=mxs#+(MouseXSpeed()-mxs#)/3 mys#=mys#+(MouseYSpeed()-mys#)/3 If MouseDown(2) Then MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 p1#=p1#-mys# y1#=y1#-mxs# RotateEntity camera,-p1#,y1#,0 EndIf EndIf ; Run Physics every 15ms ( 66/sec ) If T > Time3 + 15 Then Time3=T PTime=MilliSecs() UpdateGeoms() dSpaceCollide(Space,World,ContactGroup) UpdateSounds() dWorldQuickStep(World,.2) dJointGroupEmpty(ContactGroup) PhysicsTime#=MilliSecs()-PTime End If ; Update missle cam image buffer every 66ms ( 15/sec ) If T > Time4 + 66 Then Time4=T cam1_flag=True Else cam1_flag=False End If SetBuffer BackBuffer() If cam1_flag=False Then ;Cls WireFrame False ShowEntity camera HideEntity cam1 RenderWorld CopyRect 0,0,256,256,GraphicsWidth()-256,0,ImageBuffer(gfxBlank),BackBuffer() Else ;save block cam image WireFrame False ; true to make wirefram missle cam HideEntity camera ShowEntity cam1 RenderWorld CopyRect GraphicsWidth()-256,0,256,256,0,0,BackBuffer(),ImageBuffer(gfxBlank) Cls ShowEntity camera HideEntity cam1 WireFrame False RenderWorld CopyRect 0,0,256,256,GraphicsWidth()-256,0,ImageBuffer(gfxBlank),BackBuffer() EndIf Rect GraphicsWidth()-256,0,256,256,0 Color 255,255,255 Text 0,0,"JV-ODE Version "+dGetVersion() Text 0,15,"Physics Time:"+PhysicsTime Text 0,30,"FPS:"+Fps() Color 255,0,0 Text 0,60,"P - Planet="+Planet Color 255,255,255 Text 0,75,"LM - Pushes Object" Text 0,90, "RM - Mouse Look" Text 0,105, "R - Reconstruct Pyramid" Text 0,120, "WSAD - Movement" Text 0,135, "K - Missle Cam" Text 0,150, "Space - Shoots" Text GraphicsWidth()/2-1,GraphicsHeight()/2,"[ ]" Flip Wend dJointGroupDestroy(ContactGroup) dSpaceDestroy(Space) dWorldDestroy(World) dCloseODE() End ; ################################################################################################### Function AddObject(x#,height#) ode.ODEGeom=New ODEGeom ode\body=dBodyCreate(World) dBodySetRotation(ode\body,0,0,0) dBodySetPosition(ode\body,x,Height,0) dBodySetAutoDisableFlag(ode\body,1) mass=dMassCreate() dMassSetBox(mass,1,5,5,5) dMassSetBoxTotal(mass,20,5,5,5) dBodySetMass(ode\body,mass) dMassDestroy(mass) ode\geom=dCreateBox(Space,5,5,5) dGeomContactSetMode(ode\geom,dContactBounce) dGeomContactSetBounce(ode\geom,0.0) dGeomContactSetSoftERP(ode\geom,0.1) dGeomSetBody(ode\geom,ode\body) ode\mesh=CreateCube() ScaleMesh ode\mesh,2.5,2.5,2.5 EntityColor ode\mesh,Rand(255),Rand(255),Rand(255) EntityAlpha ode\mesh,1 EntityShininess ode\mesh,0.7 EntityPickMode ode\mesh,2 ; Make pickable End Function ; ################################################################################################### Function PosObject(x#,height#, body) dBodyDisable(body) dBodySetRotation(body,0,0,0) dBodySetPosition(body,x,Height,0) dBodySetLinearVel (body, 0,0,0) dBodySetAngularVel (body, 0,0,0) dBodyEnable(body) End Function ; ################################################################################################### Function AddProjectile(X#,Y#,Z#) ode.ODEGeom=New ODEGeom ode\body=dBodyCreate(World) dBodySetRotation(ode\body,0,0,0) dBodySetPosition(ode\body,x#,Y#,Z#) dBodySetAutoDisableFlag(ode\body,1) mass=dMassCreate() dMassSetBox(mass,1,5,5,5) dMassSetBoxTotal(mass,20,5,5,5) dBodySetMass(ode\body,mass) dMassDestroy(mass) ode\geom=dCreateBox(Space,5,5,5) dGeomContactSetMode(ode\geom,dContactBounce) dGeomContactSetBounce(ode\geom,0.0) dGeomContactSetSoftERP(ode\geom,0.1) dGeomSetBody(ode\geom,ode\body) ode\mesh=CreateCube() ScaleMesh ode\mesh,2.5,2.5,2.5 EntityColor ode\mesh,Rand(255),Rand(255),Rand(255) EntityAlpha ode\mesh,1 EntityShininess ode\mesh,0.7 proj=ode\mesh ; ENTITY projbody=ode\body End Function ; ################################################################################################### Function UpdateGeoms() For ode.ODEGeom=Each ODEGeom If dBodyIsEnabled(ode\body) RotateEntity ode\mesh,dGeomGetPitch#(ode\geom),dGeomGetYaw#(ode\geom),dGeomGetRoll#(ode\geom) PositionEntity ode\mesh,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom) End If Next End Function ; ################################################################################################### Function Fps() Time=MilliSecs() ElapsedTime=ElapsedTime+Time-LastTime LastTime=Time FrameCount=FrameCount+1 If ElapsedTime>1000 ElapsedTime=0 Frames=FrameCount FrameCount=0 EndIf Return Frames End Function ; ################################################################################################### Function UpdateControls() If MouseDown(1)=1 CameraPick(Camera,MouseX(),MouseY()) If PickedEntity() For ode.ODEGeom=Each ODEGeom If ode\mesh=PickedEntity() dBodyEnable(ode\body) dBodyAddForce ode\body,-300*PickedNX#(),-300*PickedNY#(),-300*PickedNZ#() End If Next End If End If ; Spacebar - Fire If KeyHit(57) Then dBodyDisable(Projbody) ; Set projectile to match camera orientation dBodySetRotation(Projbody,EntityPitch(camera),EntityYaw(camera),EntityRoll(camera)) dBodySetPosition(Projbody,EntityX(camera),EntityY(camera),EntityZ(camera)) ; Set projectile velocity and spin to zero dBodySetLinearVel (Projbody, 0,0,0) dBodySetAngularVel (Projbody, 0,0,0) dBodyEnable(Projbody) dBodyAddRelForce(Projbody,0,0,2500) PlaySound snd2 EndIf ; Reconstruct pyramid If KeyDown(19) Then ode.ODEGeom=First ODEGeom ; Construct pyramid For j#=wide To 1 Step -1 For k#=1 To j PosObject(k#*Gap+(wide-j#)*Gap/2,RBW/2 + (wide-j#)*RBW,ode\body) ode = After ode Next Next End If ; (K)amera If KeyHit(37) Then PositionEntity cam1,EntityX(proj),EntityY(proj),EntityZ(proj) RotateEntity cam1,EntityPitch(proj), EntityYaw(proj), EntityRoll(proj) EntityParent cam1,proj EndIf ; WSAD - Movement ; W- Forward If KeyDown(17) Or KeyDown(200) Then MoveEntity camera,0,0,1 EndIf ; S- Reverse If KeyDown(31) Or KeyDown(208) Then MoveEntity camera,0,0,-1 EndIf ; A- Left If KeyDown(30) Or KeyDown(203) Then MoveEntity camera,-1,0,0 EndIf ; D- Right If KeyDown(32) Or KeyDown(205) Then MoveEntity camera,1,0,0 EndIf ; G - Gravity If KeyHit(25) Then gx=gx+1 If gx>4 Then gx=1 Select gx Case 1 Planet="Earth " dWorldSetGravity(World,0,-1.0,0) Case 2 Planet="Mars" dWorldSetGravity(World,0,-.33333,0) Case 3 Planet="Moon" dWorldSetGravity(World,0,-.16666,0) Case 4 Planet="Space" dWorldSetGravity(World,0,0,0) End Select EndIf End Function ; ################################################################################################### Function UpdateSounds() For ode.ODEGeom=Each ODEGeom If dGeomIsEnabled(ode\geom) numjoints=dBodyGetNumJoints(ode\body) If numjoints>0 For joints=0 To numjoints-1 joint=dBodyGetJoint(ode\body,joints) If dJointGetType(joint)=dJointTypeContact ; Get linear velocity vector ax#=dBodyGetLinearVelX#(ode\body) ay#=dBodyGetLinearVelY#(ode\body) az#=dBodyGetLinearVelZ#(ode\body) ; Get Angular velocity vector bx#=dBodyGetAngularVelX#(ode\body) by#=dBodyGetAngularVelY#(ode\body) bz#=dBodyGetAngularVelZ#(ode\body) ; Calculate magnitudes ForceA#=Sqr(ax*ax+ay*ay+az*az) ForceB#=Sqr(bx*bx+by*by+bz*bz) ;If ForceA>.01 ; LinearDamp(ode\body,.04) ;End If If ForceA>1.5 PositionEntity piv1,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom) EmitSound(snd1,piv1) End If ;If ForceB>.01 ; AngularDamp(ode\body,.06) ;End If End If Next End If End If Next End Function