Yeah, here it is. Well, in a minute, my computer is having a tummy ache

```
#=====================
# shadow.py
#
# This script locates a shadow mesh
# on the floor.
#
# The object casting the shadow should have
# a "Python" controller linked to this script.
#
# The shadow object should have a sensor
# linked to the controller (I use "always"
# with the pulse turned off, so the script
# doesn't run unnecessarily).
#
# The object casting the shadow should have
# a vertex-child located on its underside
# which has a "ray" sensor linked to the
# controller, with pulse mode on and f:0.
#
# Randall Rickert
# [email protected]
#=====================
from math import sqrt
#=====================
# Functions
#
# These are standard vector math.
#=====================
def normalize(x):
length = sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
return [x[0]/length,x[1]/length,x[2]/length]
def 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 dot(x,y):
return x[0]*y[0] + x[1]*y[1]+x[2]*y[2]
def mul(s,x):
return [s*x[0],s*x[1],s*x[2]]
#=====================
# Given any two vectors, vecToMat3 will return
# a 3x3 matrix having z aligned to the first
# vector and y tracking as near as possible
# to the second.
#=====================
def vecToMat3(vec, track):
z = normalize(vec)
dotprod = dot(z, normalize(track))
if abs(dotprod) == 1: #prevent gimbol lock
track.append(track[0])
del track[0]
x = normalize(cross(track, vec))
y = cross(z, x)
return [
[-x[0],-y[0],-z[0]],
[x[1],y[1],z[1]],
[x[2],y[2],z[2]]]
# Get handlers for logic bricks and their owners
controller = GameLogic.getCurrentController()
shadowray = controller.getSensor("shadowray")
if shadowray.isPositive():
shadowsensor = controller.getSensor("shadowsensor")
shadowcaster = controller.getOwner()
shadow = shadowsensor.getOwner()
# Read orientation for orienting the shadow
orientation = shadowcaster.getOrientation()
forward = orientation[0]
# Get the position and normal where the ray hit
shadowpos = shadowray.getHitPosition()
faceNormal = shadowray.getHitNormal()
# Build orientation matrix for shadow
shadowori = vecToMat3(faceNormal, forward)
# Set the shadow's position and orientation
shadow.setPosition(shadowpos)
shadow.setOrientation(shadowori)
```

Yes! So they have all that nifty math in there already. You can pretty much just copy those defines into your program it looks like, and change the bit at the end to match your objects. Thanks NaN!

I can finally do stuff I always was afraid of trying.