collision velocity workaround

Hi! First of all, sorry for weak English. I don’t have descent practice.

For some time I was trying to get object velocity upon collision with another object with no success. The problem was (or is?) that function getLinearVelocity() usually returns [0,0,0] when objects collide. So… Maybe we need to know velocity just before the collision?
My workaround is to create an array (or list) of 4-5 elements*, that stores object velocity on each logic tic - and when collision occurs we can get velocity from previous tics.

* - we don’t need to store data for each tic, but for 4-5 last tics. First we store data to element 0, then 1, 2, 3 and 0 again. And etc… 0,1,2,3,0,1,2,3,0,1,2…

download example blend - velo.blend (493 KB)
controls: space - push cube, R - restart scene

In this example we need to set up 2 scripts and 2 properties for moving object.

1) Add integer or float property “coll.speed” and timer “speedtimer”.

2) Set up 1st script “set timelist”. This script runs at game start and creates “timelist” property for object. Create Always sensor with Tap enabled and connect it to Python controller with following script:

import bge

def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner

    own["timelist"] = [0,0,0,0]

main()

3) Set up 2nd script “check speed”. Add Always sensor with TRUE level triggering and 0 delay, add Collision sensor with Tap enabled. Don’t forget to set collision property/material. Connect them to Python controller with following script:

import bge
import math
# we need math module to calculate velocity

def main():
    cont = bge.logic.getCurrentController()
    own = cont.owner
    speed = own.getLinearVelocity()
    tic = 0.017
    totaltics = 4
    # tic = 1/FPS = 1/60 = 0.016666667 by default settings. It shows duration of one logic tic in seconds.
    # totaltics - number of tics for wich we will store data. With 4 tics we'll be able to travel 0.68 secs back in time! Won't we?..

    if own["speedtimer"] > tic*totaltics:
         own["speedtimer"] = 0.0
    # we don't need to count all time, just time for 4 tics
     
    time = own["speedtimer"]//tic
    velocity = abs(math.sqrt(pow(speed[0],2)+pow(speed[1],2)+pow(speed[2],2)))
    # time shows how much tics of total tics passed
    # velocity - actual velocity value
    
    if time == 0:
        own["timelist"][0] = velocity
        if cont.sensors["Collision"].positive: own["coll.speed"] = own["timelist"][3]
    elif time == 1:
        own["timelist"][1] = velocity
        if cont.sensors["Collision"].positive: own["coll.speed"] = own["timelist"][0]
    elif time == 2:
        own["timelist"][2] = velocity
        if cont.sensors["Collision"].positive: own["coll.speed"] = own["timelist"][1]    
    elif time == 3:
        own["timelist"][3] = velocity
        if cont.sensors["Collision"].positive: own["coll.speed"] = own["timelist"][2]
     
main()

That’s it. Now we have collision velocity stored in “coll.speed” :wink:
P.S. I’m newbe in python scripting, so this scripts may be simplier.