#===================== # shoot.py # # This script places a "hitspot" object where # a ray sensor hits a face, oriented along # the face normal, then it handles shooting. # # Randall Rickert # randall@blender.nl #===================== from math import sqrt #===================== # Functions # # These first 3 are standard vector math # (if used a lot, might be faster in C). #===================== 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]]] #===================== # Game logic #===================== controller = GameLogic.getCurrentController() raySensor = controller.getSensor("raySensor") hitspot = controller.getOwner() addFlash = controller.getActuator("addFlash") addMark = controller.getActuator("addMark") if hitspot.shoot == 1: if raySensor.isPositive(): position = raySensor.getHitPosition() hitspot.setPosition(position) normal = raySensor.getHitNormal() up = [0, 0, 1] orientation = vecToMat3(normal, up) hitspot.setOrientation(orientation) hitObject = raySensor.getHitObject() if hasattr(hitObject, "is_dynamic"): rayVector = raySensor.getRayDirection() force = mul(hitspot.k_gunForce, rayVector) hitObject.applyImpulse(position, force) else: GameLogic.addActiveActuator(addMark, 1) if hasattr(hitObject, "hits"): hitObject.hits = hitObject.hits + hitspot.k_gunDamage GameLogic.addActiveActuator(addFlash, 1) hitspot.shoot = 0