車の実装

2010/6/8

Blender2.49

PhysicsConstraints モジュールの Vehicle Constraint というのを使うと、簡単にリアルな挙動の車ができる。

Documentation for the PhysicsConstraints module
http://blenderecia.orgfree.com/blender/tmp/PhysicsConstraints-module.html

設定しておくプロパティ
cid ・・・ (Int) Constraint ID を格納。 force ・・・ (Float) 推進力
steer ・・・ (Float) ハンドル

インポート

import GameLogic
import PhysicsConstraints

cont = GameLogic.getCurrentController()
own = cont.owner

ownerは車本体。

初期設定

最初の一回だけ行う。

Vehicle Constraint作成

physicsid = own.getPhysicsId()
vehicle = PhysicsConstraints.createConstraint(physicsid,0,11)
body["cid"] = vehicle.getConstraintId()
vehicle = PhysicsConstraints.getVehicleConstraint(body["cid"])


車輪の設定

vehicle.addWheel(wheelObject,wheelAttachPosLocal,wheelAttachDirLocal,
                 wheelAxleLocal,suspensionRestLength,wheelRadius,hasSteering)
  • wheelObject     ・・・ 車輪に使うオブジェクト
  • wheelAttachPosLocal ・・・ 車輪の位置(本体からの相対座標)。[x,y,z]
  • wheelAttachDirLocal ・・・ 車輪の軸方向。[x,y,z]。通常z軸下向きで、[0,0,-1]
  • wheelAxleLocal    ・・・ 車輪の初期の傾き。[x,y,z]。通常[-1,0,0]
  • suspensionRestLength ・・・ サスペンションの動作幅。0でなし。
  • wheelRadius     ・・・ 車輪の半径。
  • hasSteering     ・・・ 方向変換するか否か。0か1。(True,False)

挙動設定

各フレームで繰り返し行う。

取得
vehicle = physics.getVehicleConstraint(own["cid"])

推進力の設定
vehicle.applyEngineForce(force,wheel_id)
各車輪に設定する。wheel_idは数字でaddWheelで入れた順。つまり通常0~3。

ステアリングの設定
vehicle.setSteeringValue(steer,wheel_id)
最低、この推進力とステアリングだけで動く。

アクティブにしとく
own.applyImpulse([0.,0.,0.],[0.,0.,0.])
keep the vehicle active, otherwise simulation stops:らしいよ。ようわからんけど

遠心力?の影響
vehicle.setRollInfluence(influence,wheel_id)
influence=0なら転倒しない

サスペンションの硬さ
vehicle.setSuspensionStiffness(stiffness,wheel_id)

サスペンションの遅れ?
vehicle.setSuspensionDamping(damping,wheel_id)

サスペンションの圧縮度
vehicle.setSuspensionCompression(compression,wheel_id)

摩擦の設定
vehicle.setTyreFriction(friction,wheel_id)

import GameLogic as game
import PhysicsConstraints as physics

cont = game.getCurrentController()
own = cont.owner

own.applyImpulse([0,0,0],[0,0,0])
#physics.setDebugMode(1)

if not own["init"]:
    own["init"] = True
    physicsid = own.getPhysicsId()
    vehicle = physics.createConstraint(physicsid,0,11)
    own["cid"] = vehicle.getConstraintId()

    vehicle = physics.getVehicleConstraint(own["cid"])

    suspension = 0.2
    radius = 0.3
    dir = [0,0,-1]
    axle = [-1,0,0]

    scene = game.getCurrentScene()

    hasSteer = 1   
    radius = 0.236

    wheelFL = scene.objects["OBWheelFL"]
    z = wheelFL.position[2] - own.position[2]
    y = wheelFL.position[1] - own.position[1]
    x = wheelFL.position[0] - own.position[0]
    pos = [x, y, z]
    vehicle.addWheel(wheelFL,pos,dir,axle,suspension,radius,hasSteer)

    wheelFR = scene.objects["OBWheelFR"]
    z = wheelFR.position[2] - own.position[2]
    y = wheelFR.position[1] - own.position[1]
    x = wheelFR.position[0] - own.position[0]
    pos = [x, y, z]
    vehicle.addWheel(wheelFR,pos,dir,axle,suspension,radius,hasSteer)

    hasSteer = 0
    radius = 0.257

    wheelRL = scene.objects["OBWheelRL"]
    z = wheelRL.position[2] - own.position[2]
    y = wheelRL.position[1] - own.position[1]
    x = wheelRL.position[0] - own.position[0]
    pos = [x, y, z]
    vehicle.addWheel(wheelRL,pos,dir,axle,suspension,radius,hasSteer)   

    wheelRR = scene.objects["OBWheelRR"]
    z = wheelRR.position[2] - own.position[2]
    y = wheelRR.position[1] - own.position[1]
    x = wheelRR.position[0] - own.position[0]
    pos = [x, y, z]
    vehicle.addWheel(wheelRR,pos,dir,axle,suspension,radius,hasSteer)

else:

    power  = 400
    bpower = -1000
    turn  = 0.02
    rturn = 0.02

    steer = own["steer"]
    force = own["force"]

    if cont.sensors["RightArrow"].positive:
        steer -= turn + rturn
    if cont.sensors["LeftArrow"].positive:
        steer += turn + rturn
    if cont.sensors["UpArrow"].positive:
        force = -power
    if cont.sensors["UpArrowInv"].positive:
        force = 0
    if cont.sensors["DownArrow"].positive:
        force = -bpower

    if -rturn < steer and steer < rturn:
        steer = 0
    elif -1 < steer and steer < 0:
        steer += rturn
    elif 0 < steer and steer < 1:
        steer -= rturn
    elif steer < -1:
        steer = -0.99
    elif 1 < steer:
        steer = 0.99

    #behavior
    vehicle = physics.getVehicleConstraint(own["cid"])
    vehicle.setSteeringValue(steer,0)
    vehicle.setSteeringValue(steer,1)
    vehicle.applyEngineForce(force,0)
    vehicle.applyEngineForce(force,1)
    vehicle.applyEngineForce(force*0.5,2)
    vehicle.applyEngineForce(force*0.5,3)

    influence = -0.4
    vehicle.setRollInfluence(influence, 0)
    vehicle.setRollInfluence(influence, 1)
    vehicle.setRollInfluence(influence, 2)
    vehicle.setRollInfluence(influence, 3)

    stiffness = 15.0
    vehicle.setSuspensionStiffness(stiffness,0)
    vehicle.setSuspensionStiffness(stiffness,1)
    vehicle.setSuspensionStiffness(stiffness,2)
    vehicle.setSuspensionStiffness(stiffness,3)

    damping = 1.3
    vehicle.setSuspensionDamping(damping,0)
    vehicle.setSuspensionDamping(damping,1)
    vehicle.setSuspensionDamping(damping,2)
    vehicle.setSuspensionDamping(damping,3)

    compression = 2.4
    vehicle.setSuspensionCompression(compression,0)
    vehicle.setSuspensionCompression(compression,1)
    vehicle.setSuspensionCompression(compression,2)
    vehicle.setSuspensionCompression(compression,3)

    friction = 100.0
    vehicle.setTyreFriction(friction,0)
    vehicle.setTyreFriction(friction,1)
    vehicle.setTyreFriction(friction,2)
    vehicle.setTyreFriction(friction,3)

    own["steer"] = steer
    own["force"] = force


参考
Blender 3D Club :: Vehicle Physics - Basics
http://www.blender3dclub.com/index.php?name=News&file=article&sid=42&theme=Printer

Blender vehicle physics tutorial // mike's digital anthology
http://blog.mikepan.com/blender-vehicle-physics-tutorial/