A 3D weeble demo.
The controls use the virtual pointer so this'll work with a mouse or touch screen.
`3D wobbly weeble demo
`By 29 games
`03 Oct 2013
`written in AGK V1 10819
`instructions will be on screen (or see end of main loop)
`++++++++++++++++++++++
`++++++++++++++++++++++
`weeble properties
`(cog = center of gravity (relative to geometric center), moi = moment of inertia, dc = damping coefficient)
weeble_radius# = 10.0
weeble_cog# = weeble_radius#*0.5
weeble_weight# = 1.0
weeble_moi# = 15.0
weeble_dc# = 0.04
`weeble is made from two sphere for the body (lower sphere) and head (upper sphere)
body_obj = createObjectSphere(weeble_radius#*2,12,12)
head_obj = createObjectSphere(weeble_radius#*1.5,12,12)
`weeble starting linear positions
weeble_xpos# = 0.0
weeble_ypos# = weeble_radius#
weeble_zpos# = 0.0
`weeble starting angular positions
weeble_xang# = 180.0
weeble_yang# = 0.0
weeble_zang# = 180.0
`weeble starting angular velocities
weeble_xang_vel# = 0.0
weeble_yang_vel# = 0.0
weeble_zang_vel# = 0.0
`weeble starting angular accelerations
weeble_xang_acc# = 0.0
weeble_yang_acc# = 0.0
weeble_zang_acc# = 0.0
`create a ground (a green square)
for x = -2 to 2
for z = -2 to 2
ground_obj = createObjectBox(weeble_radius#,2,weeble_radius#)
setObjectColor(ground_obj,0,random(200,255),50,random(200,255))
setObjectPosition(ground_obj,weeble_radius#*x,-1,weeble_radius#*z)
next z
next x
`position and point camera and create a direction light
setCameraPosition(1,0,weeble_radius#*5,weeble_radius#*-10)
setCameraLookAt(1,0,weeble_radius#*2,0,0)
createLightDirectional(1,1,-0.5,0.5,255,255,0)
`main loop
do
`press space to quit
if getButtonState(1) = 1
end
endif
if getPointerState() = 1
if grab = 0
`the initial grab
grab = 1
`initial pointer coordinates
initial_grab_x = getPointerX()
initial_grab_y = getPointerY()
`save old anglular positions
old_weeble_zang# = weeble_zang#
old_weeble_xang# = weeble_xang#
`set angular velocities and accelerations to zero
weeble_zang_vel# = 0.0
weeble_xang_vel# = 0.0
weeble_zang_acc# = 0.0
weeble_xang_acc# = 0.0
else
`drag weeble
`drag about x axis
weeble_xang# = old_weeble_xang# + 2*(getPointerY()-initial_grab_y)
if weeble_xang# < 100 then weeble_xang# = 100
if weeble_xang# > 260 then weeble_xang# = 260
`drag about z axis
weeble_zang# = old_weeble_zang# + 2*(initial_grab_x - getPointerX())
if weeble_zang# < 100 then weeble_zang# = 100
if weeble_zang# > 260 then weeble_zang# = 260
endif
else
`wobble code
`the weeble is dealt with like a pendulum pivoting about the gemetric center of its body (the lower sphere)
grab = 0
`calculate horizontal distance between the center of gravity and center of rotation (ie geometric center)
horizontal_xdis# = weeble_cog#*sin(weeble_zang#)
horizontal_zdis# = weeble_cog#*sin(weeble_xang#)
`calculate angular acceleration, based on: (sum of angular forces) = (momenet of inertia) * (angular acceleration)
`the forces acting on the weeble are its own weight and friction/drag which is being simulated as a torsional damper
`(ie the resisting force is linearaly proportional to the angular velocity)
weeble_zang_acc# = (weeble_weight#*horizontal_xdis# - weeble_dc#*weeble_zang_vel#) / (weeble_moi#)
weeble_xang_acc# = (weeble_weight#*horizontal_zdis# - weeble_dc#*weeble_xang_vel#) / (weeble_moi#)
`calculate angular velocities
weeble_zang_vel# = weeble_zang_vel# + weeble_zang_acc#
weeble_xang_vel# = weeble_xang_vel# + weeble_xang_acc#
`calculate angular positions
weeble_zang# = weeble_zang# + weeble_zang_vel#
weeble_xang# = weeble_xang# + weeble_xang_vel#
endif
`calculate linear positions to simulate rolling (if you rem these two line out the weeble oscilates like a pendulum)
weeble_xpos# = weeble_radius#*sin(weeble_zang#)
weeble_zpos# = weeble_radius#*sin(weeble_xang#)
`position and orientate body
setObjectPosition(body_obj,weeble_xpos#,weeble_ypos#,weeble_zpos#)
setObjectRotation(body_obj,0,0,0)
rotateObjectGlobalX(body_obj,weeble_xang#)
rotateObjectGlobalZ(body_obj,weeble_zang#)
`position and orientate head relaltive to body
setobjectPosition(head_obj,weeble_xpos#,weeble_ypos#,weeble_zpos#)
setObjectRotation(head_obj,getObjectAngleX(body_obj),getObjectAngleY(body_obj),getObjectAngleZ(body_obj))
moveObjectLocalY(head_obj,weeble_radius#*1.2)
`instructions
print("press and hold left mouse button or touch screen")
print("drag left, right, up, down")
print("release mouse button or screen")
print("press space or button to quit")
sync()
loop
This was something I originally did as part of the DBC challenges (it's buried on the DBC challenge thread somewhere) but could only get the weeble to wobble on a single axis. In this version the weeble rolls around both the x and z axis so is more of a proper 3D effect, although I'm not entirely sure how true a simulation this is. I'm still happy with it though.
one of these days I'll come up with a better signature