Here’s a quick video of my result.
The first part of my code is taken from the excellent FPS template here at blender art forums. They used it to orient the bulet hole textures.
Can anyone suggest a better way of orienting the footprints to the direction of the character? I know my way is very awkward…
from math import sin, cos, sqrt
import Mathutils
# vector functions
def VEC_length(x):
return sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
def VEC_normalize(x):
length = VEC_length(x)
return [x[0]/length,x[1]/length,x[2]/length]
def VEC_cross(x, y):
return [x[1]*y[2] - x[2]*y[1],
x[2]*y[0] - x[0]*y[2],
x[0]*y[1] - x[1]*y[0]]
def VEC_min(x, y):
return [x[0] - y[0], x[1] - y[1], x[2] - y[2]]
def MAT_trackvector(fw, y):
if abs(abs(fw[2]) - abs(y[2])) < .001: #prevent gimbol lock
y.append(y[0])
del y[0]
right = VEC_normalize(VEC_cross(y, fw))
up = VEC_cross(fw, right)
return [[right[0], up[0], fw[0]],
[right[1], up[1], fw[1]],
[right[2], up[2], fw[2]]]
#owners
cont = GameLogic.getCurrentController()
own = cont.owner
#sensors and actuators
walker = cont.actuators['walker']
default = cont.actuators['default']
right_leg = cont.actuators['right_leg']
left_leg = cont.actuators['left_leg']
leg_tilt = cont.actuators['leg_tilt']
step = cont.actuators['step']
engine = cont.actuators['engine']
#get_scenelist
scn = GameLogic.getCurrentScene()
ob_list = scn.objects
w_speed = own['speed'] /2.5
#set walkspeed
own['walk'] = own['walk'] + w_speed
if own['walk'] >= 120:
own['walk'] = 0
if own['walk'] <= -120:
own['walk'] = 0
#walk/run
if w_speed <= 8:
walker.action = "walk"
if w_speed >= 9:
walker.action = "run"
if w_speed>= 0.2:
cont.activate(walker)
cont.deactivate(default)
else:
cont.activate(default)
cont.deactivate(walker)
#engine noise
engine.pitch = ((w_speed +2) /4) + 1
cont.activate(engine)
#leg_height setup
left_hip = ob_list['OBl_hip']
pl = left_hip.worldPosition
pl_end = pl[2] -12
l_ender= [pl[0],pl[1],pl_end]
right_hip = ob_list['OBr_hip']
pr = right_hip.worldPosition
pr_end = pr[2] -12
r_ender= [pr[0],pr[1],pr_end]
front_hip = ob_list['OBfront_hip']
pf = front_hip.worldPosition
pf_end = pf[2] -12
f_ender= [pf[0],pf[1],pf_end]
<b>#player get_ori convert to euler
player = ob_list['OBplayer']
p_ori = player.worldOrientation
p_ori_m = Mathutils.Matrix(p_ori[0],p_ori[1],p_ori[2])
p_ori_e = p_ori_m.toEuler() </b>
#l_legray
l_ob, l_pt, l_n = own.rayCast(l_ender, pl, 10.0, "floor", 1, 1, 0)
if l_ob:
l_leg_length = ((pl[2] - l_pt[2]) - 6.5) *10
own['l_height']= float(l_leg_length)
cont.activate(left_leg)
#r_legray
r_ob, r_pt, r_n = own.rayCast(r_ender, pr, 10.0, "floor", 1, 1, 0)
if r_ob:
r_leg_length = ((pr[2] - r_pt[2]) - 6.5) *10
own['r_height']= float(r_leg_length)
cont.activate(right_leg)
#front_legray
f_ob, f_pt, f_n = own.rayCast(f_ender, pf, 0.0, "floor", 1, 1, 0)
if f_ob:
f_leg_length = ((pf[2] - f_pt[2]) - 5) *10
own['tilt']= float(f_leg_length)
cont.activate(leg_tilt)
#footsteps
st= own['walk']
if st >= 0 and st <=9:
own['ini']= 0
if st >=10 and st <=25 and own['ini']==0:
own['ini']= 1
if st >=26 and st <=74:
own['ini']= 0
if st >=75 and st <=80 and own['ini']==0:
own['ini']= 2
if st >=81:
own['ini']= 0
leg = 1
own['step_set'] =0
make_r = f_ob and own['ini']== 1
if make_r:
cont.activate(step)
own['ini']= 3
leg = 2
own['step_set'] =1
make_l = f_ob and own['ini']== 2
if make_l:
cont.activate(step)
own['ini']= 3
leg = 1
own['step_set'] =1
footstep_obj = step.objectLastCreated
#footstep_ori to euler
<b>def re_oreint():
f_ori = MAT_trackvector(hit_norm, [0.0,0.0,1.0])
f_ori_m = Mathutils.Matrix(f_ori[0],f_ori[1],f_ori[2])
f_ori_e = f_ori_m.toEuler()
re_ori = (f_ori_e[0],f_ori_e[1],p_ori_e[2])
re_ori_e = Mathutils.Euler(f_ori_e[0],f_ori_e[1],p_ori_e[2])
re_ori_m = re_ori_e.toMatrix()
return re_ori_m</b>
#left_foot place footprint
if l_ob and leg == 2 and own['step_set'] ==1:
hit_pos = l_pt
hit_norm = l_n
<b>re_matrix = re_oreint()</b>
footstep_obj.localOrientation = re_matrix
footstep_obj.localPosition = hit_pos
own['step_set'] =0
#right_foot place footprint
if r_ob and leg == 1 and own['step_set'] ==1:
hit_pos = r_pt
hit_norm = r_n
<b>re_matrix = re_oreint()</b>
footstep_obj.localOrientation = re_matrix
footstep_obj.localPosition = hit_pos
own['step_set'] =0