info about pendulum clocks:
http://electronics.howstuffworks.com/ga ... /printable
http://static.howstuffworks.com/flash/c ... pement.swf
in short there are main gear powered by either a spring or a falling weight, it has tilted teeth, normaly it will rotate very speedy and in 3 seconds the spring will lost all its energy, but the existence of swinging pendulum with its 2 pieces LeftStop and RighStop prevent the gear from rotating speedily, also the gear gives the pendulum itself small push.
i have some problems with the tik tok sound, look the code, may someone elaborate it. the tik tok works the best in windows xp/32 and works the worst in my windows 7/x64
keys:
1-mouse and arrows to move and rotate camera so you can inspect the clock closely
2- D : display worldDebug info
3- S : toggle sound (tik tok) on/of
4- if gears stuck press Z or/and space
5- X: toggle stop/run the main gear
you need this sound file: save it to the same folder as the code
http://s000.tinyupload.com/index.php?fi ... 3582948230
PB 5.50 beta 2, tested in windows xp/32 win7/x64 ubuntu 14.x x/64
Note: the LeftStop and RightStop pieces are passed as concave geometry (#PB_Entity_StaticBody) for exact touch to the Escapement gear teeth
needs PB 5.50 beta 2 + http://s000.tinyupload.com/index.php?fi ... 3582948230
Code: Select all
;
;
; ------------------------------------------------------------
;
; PureBasic - CompoundBody
;
;
; (c) Fantaisie Software
;
; ------------------------------------------------------------
;
Structure pendulum
pendulum.l
escapeRod.l
RightStop.l
LeftStop.l
Rod.l
sphere.l
EndStructure
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
#CameraSpeed = 0.1
Define.f KeyX, KeyY, MouseX, MouseY
Declare Gear_Make()
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If InitSound() = 0
MessageRequester("Error", "Can't open DirectX 7 Or Sound Card is not present", 0)
End
EndIf
LoadSound(0, "tik.wav")
If Screen3DRequester()
Add3DArchive("." , #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/" , #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures" , #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models" , #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts" , #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI" , #PB_3DArchive_FileSystem)
Parse3DScripts()
;WorldDebug(#PB_World_DebugBody)
;-------------------------------
CreateLight(0, RGB(255,255,255), 10, 0, 10)
CreateLight(1, RGB(255,255,255), -10, 5, -10)
CreateLight(2, RGB(255,255,255), 10, -1, 0)
; create material
GetScriptMaterial(5, "Color/Green")
SetMaterialColor(5, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
GetScriptMaterial(6, "Color/Yellow")
SetMaterialColor(6, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
GetScriptMaterial(7, "Color/Red")
SetMaterialColor(7, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
CreateMaterial(1, LoadTexture(1, "Wood.jpg"))
SetMaterialColor(1, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
;
CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
SetMaterialColor(2, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
CreateMaterial(3, LoadTexture(3, "MRAMOR6X6.jpg"))
SetMaterialColor(3, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
CreateMaterial(4, LoadTexture(4, "ground_diffuse.png"))
CreateMaterial(8, LoadTexture(8, "Tire_Shi.png"))
AddMaterialLayer(8, TextureID(1) , #PB_Material_Modulate )
;-------------------------------
;construction of a gear with 18 teeth
ang=40 ; the angle wanted for every tooth of the gear
CreateCylinder(50, 1, 0.3)
CreateEntity(50, MeshID(50),MaterialID(1), 0, 0, 0)
RotateEntity(50, 90,0, 0, #PB_Absolute)
CreateCube(1, 1)
Global EscapeGear = CreateEntity(#PB_Any,0,0)
For i=1 To 18
angle.f+20
x.f = Cos(Radian(angle)) * 1: z.f = Sin(Radian(angle)) * 1
CreateEntity(i, MeshID(1),MaterialID(1), x, z, 0)
ScaleEntity(i, 0.5, 0.05, 0.2)
ang+20
RotateEntity(i, 0,0, ang, #PB_Absolute)
AddSubEntity(EscapeGear, i, #PB_Entity_BoxBody)
Next
AddSubEntity(EscapeGear, 50, #PB_Entity_CylinderBody)
;Gear1
; the component of the smaller yellow gear which will be attached later to the main woody gear (EscapeGear)
;Global Gear1 = CreateCylinder(#PB_Any, 3, 1 , 3, 1, 1)
Global Gear1 = CreateCube(#PB_Any, 1)
For i=81 To 84
CreateEntity(i, MeshID(Gear1),MaterialID(6), 0, 0, -1)
RotateEntity(i, 0,0,rot, #PB_Absolute)
ScaleEntity(i, 0.7,0.7,0.3)
rot + 30
If i = 101
SetEntityMaterial(101, MaterialID(8))
MoveEntity(101, 0,0, 0.01)
EndIf
AddSubEntity(EscapeGear, i, #PB_Entity_BoxBody)
Next
; a useless axis, just a shape to fill the gap between the EscapeGear and the small tellow gear
axis = CreateEntity(#PB_Any, MeshID(50),MaterialID(1), 0, 0, -0.5)
RotateEntity(axis, 90,0, 0, #PB_Absolute)
ScaleEntity(axis, 0.1,3,0.1)
AddSubEntity(EscapeGear, axis, #PB_Entity_ConvexHullBody)
CreateEntityBody(EscapeGear, #PB_Entity_CompoundBody, 10, 0.0, 0.2)
SetEntityAttribute(EscapeGear, #PB_Entity_DisableContactResponse, 1) ;disable collision
Global Gear2 = CreateEntity(#PB_Any,0,0)
Gear_Make() ; call proc to make the big green gear
CreateEntityBody(Gear2, #PB_Entity_CompoundBody, 1, 0.0, 0.5)
SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 1) ;disable collision
;-----------------------------------------
pendulum.pendulum
pendulum\pendulum= CreateEntity(#PB_Any,0,0)
;the rod above the gear teeth
pendulum\escapeRod = CreateEntity(#PB_Any, MeshID(1),MaterialID(3), 0, 0, 0)
ScaleEntity(pendulum\escapeRod, 1.5, 0.05, 0.2)
;the right small piece attached to the rod
CreateCylinder(200, 0.7, 1 , 3, 1, 1)
pendulum\RightStop = CreateEntity(#PB_Any, MeshID(200),MaterialID(2), 0.5, -0.1, 0)
ScaleEntity(pendulum\RightStop, 0.1, 0.1, 0.3)
;RotateEntity(RightStop , 90,30,0, #PB_Absolute)
RotateEntity(pendulum\RightStop , 90,0,0, #PB_Absolute)
AddSubEntity(pendulum\pendulum, pendulum\escapeRod, #PB_Entity_BoxBody)
AddSubEntity(pendulum\pendulum, pendulum\RightStop, #PB_Entity_StaticBody) ;HasContactResponse
;the left small piece attached To the rod
pendulum\LeftStop = CreateEntity(#PB_Any, MeshID(1),MaterialID(2), -0.6, -0.1, 0)
ScaleEntity(pendulum\LeftStop, 0.5,0.05,0.2)
RotateEntity(pendulum\LeftStop , 0 , 0, -90, #PB_Absolute)
AddSubEntity(pendulum\pendulum, pendulum\LeftStop, #PB_Entity_StaticBody)
; pendulum
pendulum\Rod = CreateEntity(#PB_Any, MeshID(1),MaterialID(2), 0, -1.3, 0.3)
ScaleEntity(pendulum\Rod, 0.05,2.5,0.05)
AddSubEntity(pendulum\pendulum, pendulum\Rod, #PB_Entity_BoxBody)
pendulum\sphere = CreateSphere(#PB_Any,0.5)
TransformMesh(pendulum\sphere, 0,0,0,1,1,0.2,0,0,0) ; make thin sphere
pendulum\sphere = CreateEntity(#PB_Any, MeshID(pendulum\sphere), MaterialID(7) ,0, -2.3, 0.5)
MoveEntity(pendulum\sphere, 0,-0.7, 0)
AddSubEntity(pendulum\pendulum, pendulum\sphere, #PB_Entity_ConvexHullBody)
CreateEntityBody(pendulum\pendulum, #PB_Entity_CompoundBody, 30, 0, 1); 0.2
SetEntityAttribute(pendulum\pendulum, #PB_Entity_DisableContactResponse, 1) ;disable collision
MoveEntity(pendulum\pendulum, 0,0.1,1,#PB_Absolute)
;Ground
Ground = CreateEntity(#PB_Any, MeshID(1), MaterialID(4), 0, -7, 0)
ScaleEntity(Ground, 40, 0.4, 40)
CreateEntityBody(Ground, #PB_Entity_StaticBody)
GenericJoint(4,EntityID(Ground), 0, 4, 0,EntityID(EscapeGear), 0, 0, 0)
SetJointAttribute(4, #PB_Joint_EnableSpring, #True, 5)
SetJointAttribute(4, #PB_Joint_Stiffness, 5, 5)
SetJointAttribute(4, #PB_Joint_Damping, 0.0, 5)
GenericJoint(5,EntityID(Ground), 2.52, 4, -1,EntityID(Gear2), 0, 0, 0)
;SetJointAttribute(5, #PB_Joint_NoLimit , 0, 5)
SetJointAttribute(5, #PB_Joint_EnableSpring, #True, 5)
SetJointAttribute(5, #PB_Joint_Stiffness, 5, 5)
SetJointAttribute(5, #PB_Joint_Damping, 0.0, 5)
GenericJoint(6,EntityID(Ground), 0, 5.1, 0.0,EntityID(pendulum\pendulum), 0, -0.3, 0)
SetJointAttribute(6, #PB_Joint_EnableSpring, #True, 5)
SetJointAttribute(6, #PB_Joint_Stiffness, 1000, 5)
SetJointAttribute(6, #PB_Joint_Damping, 0.5, 5);
; camera
CreateCamera(0, 0, 0, 100, 100, #True)
MoveCamera(0,1,-2,10, #PB_Absolute)
CameraLookAt(0, 1,-3.2,0)
CameraBackColor(0, RGB(231,232,240))
; GUI
OpenWindow3D(0, 0, 0, 50 , 10 , "")
HideWindow3D(0,1)
ShowGUI(128, 0) ; Display the GUI, semi-transparent and display the mouse cursor
;SetWindowTitle(0, "PureBasic-3D Demos .... Press 'Space' to apply initial push to the pendulum")
tm.f = ElapsedMilliseconds(); we need to wait 1 second for the whole gears construction to fit together before enabling the collison again
Repeat
Screen3DEvents()
If ExamineMouse()
MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
InputEvent3D(MouseX(), MouseY(),0)
BodyPick(CameraID(0), MouseButton(#PB_MouseButton_Left), MouseX(), MouseY(), 1)
EndIf
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Space) ; in case gears teeth stuck
ApplyEntityImpulse(pendulum\pendulum, -0.2, 0, 0, 0, 10,0)
EndIf
If KeyboardPushed(#PB_Key_Z) ; if gear2 stuck push it
ApplyEntityImpulse(Gear2, -10, 0, 0, 0, 10,0)
EndIf
If KeyboardReleased(#PB_Key_S)
soundOn ! 1
EndIf
If KeyboardReleased(#PB_Key_X)
torque ! 1 ; stop or initiate torque on the EscapeGear
EndIf
If KeyboardReleased(#PB_Key_D)
debugWire ! 1
If debugWire
WorldDebug(#PB_World_DebugBody)
Else
WorldDebug(#PB_World_DebugNone )
EndIf
EndIf
If KeyboardPushed(#PB_Key_Left)
KeyX = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Right)
KeyX = #CameraSpeed
Else
KeyX = 0
EndIf
If KeyboardPushed(#PB_Key_Up)
KeyY = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Down)
KeyY = #CameraSpeed
Else
KeyY = 0
EndIf
EndIf
If torque=0
ApplyEntityTorque(EscapeGear, 0, 0, 100)
;ApplyEntityTorque(EscapeGear, 0, 0, 50)
EndIf
MoveCamera (0, KeyX, 0, KeyY)
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
;If EntityCollide(EscapeGear, pendulum\pendulum) ; does not work
;Debug "ok"
;PlaySound(0, 0, 100)
;EndIf
If soundOn
If ExamineWorldCollisions(#True) ; get also contacts
While NextWorldCollision()
If FirstWorldCollisionEntity() = EscapeGear And SecondWorldCollisionEntity() = pendulum\pendulum
If chaosTime2.f >= 600
PlaySound(0, 0, 100)
chaosTime.f = ElapsedMilliseconds()
EndIf
chaosTime2.f = ElapsedMilliseconds() - chaosTime
EndIf
Wend
EndIf
EndIf
RenderWorld()
;Screen3DStats()
FlipBuffers()
If oneSecond = 0
tm2.f = ElapsedMilliseconds()
If (tm2-tm) >= 300 ; after 1 second enable the collison
;enable the collision for the green big gear
SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 0)
SetEntityAttribute(pendulum\pendulum, #PB_Entity_DisableContactResponse, 0)
SetEntityAttribute(EscapeGear, #PB_Entity_DisableContactResponse, 0)
oneSecond =1
EndIf
EndIf
If soundOn:StopSound(0,#PB_All):EndIf
;Delay(1)
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure Gear_Make()
;the big gear made from 60 teeth
CreateCube(101, 1)
For i=101 To 115
CreateEntity(i, MeshID(1),MaterialID(5), 0, 0, 0)
RotateEntity(i, 0,0,rot, #PB_Absolute)
ScaleEntity(i, 3,3,0.5)
rot + 6
If i = 101
SetEntityMaterial(101, MaterialID(8))
MoveEntity(101, 0,0, 0.01)
EndIf
AddSubEntity(Gear2, i, #PB_Entity_BoxBody)
Next
;RotateEntity(Gear2, 90,0,0)
EndProcedure
