3D Gallery | Blender Tutorials | Dance Workshops | Essays | Letters | Quantum Entanglement | Technobabble | Contact

Blender Tutorial

by Dave Jarvis
Last Updated: (none)
Blender Version: 2.47

Game Physics and Paths

This is a complex, advanced tutorial showing how to create an animation using Blender's Game Physics Engine and Paths. A Sphere will be dropped onto a Plane, moved along a Path, and then dropped onto a Box.

Blender has the ability to record physics-based actions to an object's IPO. This functionality allows a recorded physics sequence to be rendered as an animation. Since Paths control objects independently of physics, Path motion is not recorded without special intervention. Let us now intervene.

Setup

Environment

  1. Press CTRL-x for a new file.
  2. Click OK to confirm.
  3. Click SR:2-Model and change it to SR:1-Animation:

    Layout Menu

  4. Split the right-hand side of the 3D view window into two new windows.
  5. Set the upper window to the IPO Curve Editor.
  6. Set the lower window to the Text Editor.
  7. Remove the Outliner window to increase the 3D view space, resulting in:

    Blender Layout

Objects

  1. Add » Mesh » UVSphere
  2. Click OK to accept the default options.
  3. Press s, .25 then Enter to shrink the Sphere.
  4. Press g, x, 2 then Enter to move the Sphere right.
  5. Press g, y, 2 then Enter to move the Sphere back.
  6. Press g, z, 4 then Enter to move the Sphere up.
  7. Add » Mesh » Plane
  8. Press s, 5, then Enter to scale the Plane.
  9. Press NUM-1 for a side view:

    Sphere, Box, and Plane

  10. Add » Curve » Path
  11. Press g, y, 2 then Enter to move the Path back.
  12. Press g, z, .25 then Enter to move the Path up.
    This will align the Path's first vertex with the Sphere's centre. After it falls, the Sphere will move along the Path. There are other ways to align vertices that don't rely on premeditated positioning, like step 18.
  13. Transform » Mirror » X Local
  14. Press NUM-7 for a top view.
  15. Press Tab to edit the Path.
  16. Press a to deselect all vertices.
  17. Click RMB to select the last vertex (left-most).
  18. Press SHIFT-S then click Selection -> Cursor.
  19. Press g, z, 1.5 then Enter to move the last vertex up.
  20. Click RMB to select the second-last vertex.
  21. Press g, x, 1 then Enter to align the second-last vertex with the last.
  22. Press g, z, 2 then Enter to move the second-last vertex up.
  23. Press SHIFT-S then click Cursor -> Selection.

Rotating the scene should show a view similar to:

Properly Positioned Path

Materials

  1. Press Tab to stop editing the Path.
  2. Press F5 for the Materials buttons.
  3. Click SHIFT-RMB on the Cube.
  4. Rename Material to Cube.
  5. Click SHIFT-RMB on the Plane.
  6. Click Add New.
  7. Rename Material to Plane.

Record Path IPO

  1. Press NUM-7 for a top view.
  2. Add » Empty
  3. Press NUM-7 for a top view.
  4. Click SHIFT-RMB on the Path.
    The Empty and Path should both be selected.
  5. Press CTRL-p for the parenting menu.
  6. Click Follow Path to parent the Empty to the Path.
  7. Copy and paste the following code into the Text window:
    #
    # This script is used to map the IPO curve of an object as it travels
    # through frames of an animation. The algorithm follows:
    #
    # 1. Calculate number of steps needed to animate at given framerate.
    # 2. Get the selected object.
    # 3. Duplicate the selected object (which will hold the generated IPO).
    # 4. Reset the duplicate object.
    # 5. Loop over the number of frames at the calculated framerate.
    # 6. Set the active frame.
    # 7. Position the duplicate object to the same place as the selected one.
    # 8. Copy the selected object's location and rotation into the duplicate's IPO.
    #
    # Usage:
    # (1) Select the object that follows a curve.
    # (2) Load this script in Blender's Text window.
    # (3) Move the mouse to the Text window.
    # (4) Press Alt-p.
    #
    import Blender
    from Blender import Object, Scene
    
    framesPerSecond = Scene.GetCurrent().getRenderingContext().fps
    firstFrame      = 0
    lastFrame       = 100
    stepsPerFrame   = (lastFrame - firstFrame) / framesPerSecond
    
    selected = Object.GetSelected()[0]
    
    Object.Duplicate()
    duplicate = Object.GetSelected()[0]
    duplicate.clrParent()
    duplicate.clearIpo()
    
    for frame in range( firstFrame, lastFrame, stepsPerFrame ):
      Blender.Set( 'curframe', frame )
      duplicate.setMatrix( selected.getMatrix() )
      duplicate.insertIpoKey( Object.LOC )
      duplicate.insertIpoKey( Object.ROT )
    
  8. Change the name of the script to copy-path.py.
  9. Save the script as copy-path.py.
  10. Click RMB to select the Empty.
  11. Move the mouse to the Text window.
  12. Press Alt-p to execute the script.
    While executing, the script instructs Blender to scrub through frames at 25 frames per second (default). With 100 frames, only every fourth frame is used. Each frame that is used causes the duplicate object to have its location and rotation recorded as an IPO key (i.e., a vertex in that object's IPO curve).
  13. Move the mouse to the 3D window.
  14. Press DEL then Enter to delete Empty.001.
  15. Click RMB to select the Empty.
  16. Press Alt-p.
  17. Click Clear Parent to remove the Path as the Empty's parent.
  18. Reset the IPO to frame 0.
    If the Empty moves in unexpected ways, it is likely this step was missed.
  19. In the IPO window, set the Empty to use the newly created IPO data block.

    Empty's New IPO

  20. Click RMB to select the Path.
  21. Press m, 2, then Enter to move the Path to another layer.
  22. Press F7 for the Object buttons.
  23. Click RMB to select the Empty.
  24. Set TimeOffset to 180.
    This is the number of frames the Sphere takes to hit the Plane.

Game Engine Actors

  1. Press F4 for the Logic buttons.
  2. Click RMB to select the Sphere.
  3. Click Actor.
  4. Click Dynamic.
  5. Click Bounds.
  6. Set Radius to 0.75.
  7. Change Box to Sphere (as the bounds type).
  8. Click RMB to select the Plane.
  9. Click Actor.
  10. Click Bounds.

Game Engine Logic

When the Sphere collides with the Plane the following must happen:

Logic Blocks - Empty

  1. Click RMB to select the Empty.
  2. Click Add Property.
  3. Set the name to collision.
  4. Change the type to Bool.
    This will record the Sphere colliding with the Plane. Upon collision, the Sphere must follow the Empty (which has an IPO that was derived from the Path that was banished to layer two).
  5. Click Add, below Sensors.
  6. Set the name of the sensor to s.copy.
    This sensor will help continually copy the value of the Sphere's collision property.
  7. Click Add, below Sensors.
  8. Change the sensor type from Always to Property.
  9. Set the name of the sensor to s.ipo.
  10. Set the value of Prop: to collision.
  11. Set the value of Value: to True.
  12. Click Add, below Controllers.
  13. Set the name of the controller to c.copy.
  14. Click Add, below Controllers.
  15. Set the name of the controller to c.ipo.
  16. Click Add, below Actuators.
  17. Set the name of the actuator to a.copy.
  18. Change the actuator type from Motion to Property.
  19. Change the type from Assign to Copy.
  20. Set the value of Prop: to collision.
  21. Set the value of OB: to Sphere.
  22. Set the value of Prop: to collision.
  23. Click Add, below Actuators.
  24. Change the type from Motion to Ipo.
  25. Set the name of the actuator to a.ipo.
  26. Set the value of End to 100.
  27. Link Sensor copy to Controller copy to Actuator copy.
  28. Link Sensor ipo to Controller ipo to Actuator ipo.

The logic should look similar to:

Logic Blocks for the Empty

The logic block instructs Blender to continually copy the Sphere's collision property into the Empty's property of the same name. Once the collision property is set to True, the Empty is instructed to replay its IPO. All that remains is to set the Sphere's parent to the Empty, remove the parent relationship when appropriate, and record the Sphere's complete IPO curve.

Logic Blocks - Sphere - Sensors

  1. Click Add Property.
  2. Set the name to collision.
  3. Change the type to Bool.
  4. Click Add Property.
  5. Set the name to time.
  6. Change the type to Timer.
    A timer will be used to remove the Sphere's parent (the Empty). It is also used to calculate the current frame.
  7. Click Add, below Sensors.
  8. Set the name to s.plane.
  9. Change the sensor type to Collision.
  10. Toggle M/P on.
  11. Set the value of M/P to Plane.
  12. Click Add, below Sensors.
  13. Set the name to s.time.
  14. Change the sensor type to Property.
  15. Toggle Activate TRUE level triggering on.
  16. Change the type to Interval.
  17. Set the value of Prop: to time.
  18. Set the value of Min: to 4.0.
  19. Set the value of Max: to 4.1.
  20. Click Add, below Sensors.
  21. Set the name to s.start.
  22. Toggle Activate TRUE level triggering off.
  23. Click Add, below Sensors.
  24. Set the name to s.record.
  25. Set the value of f: to 2.
  26. Toggle Activate TRUE level triggering on.
  27. Click Add, below Sensors.
  28. Set the name to s.stop.
  29. Change the sensor type to Collision.
  30. Toggle M/P on.
  31. Set the value of M/P to Cube.

Logic Blocks - Sphere - Controllers

  1. Click Add, below Sensors, five times.
  2. Set the name of the sensors, from top to bottom as:
    1. c.plane
    2. c.time
    3. c.start
    4. c.record
    5. c.stop
  3. Change the controller type to Python for c.start and c.record.
  4. Create new text in the Text window.
  5. Copy and paste the following code into the Text window:
    #
    # This script is used to record the IPO curve of an object as it is
    # assaulted by the Game Physics engine. It should be executed automatically
    # via Logic Blocks. The algorithm follows:
    #
    # 1. Get the object being controlled by physics.
    # 2. Create a new IPO for recording the motion of that object.
    # 3. Store the IPO curves for use by the frame recorder.
    #
    import Blender
    
    # Get the name of the object being controlled by physics.
    #
    gameObject = GameLogic.getCurrentController().getOwner()
    objectName = gameObject.getName()[2:]
    
    # Create an IPO of type Object named 'Recorded IPO'.
    #
    blenderObject = Blender.Object.Get( objectName )
    ipo = Blender.Ipo.New( 'Object', 'Recorded IPO' )
    blenderObject.setIpo( ipo )
    
    # Get the position of gameObject as IPO curves.
    #
    locx = ipo.addCurve( 'LocX' )
    locy = ipo.addCurve( 'LocY' )
    locz = ipo.addCurve( 'LocZ' )
    
    # Keep a reference to the curves in a global variable. The variable
    # (GameLogic.rec) is used by a script that records the position of the
    # game Object per frame.
    #
    GameLogic.rec = [gameObject, locx, locy, locz]
    
  6. Change the name of the script to record-ipo.py.
  7. Save the script as record-ipo.py.
  8. Create new text in the Text window.
  9. Copy and paste the following code into the Text window:
    #
    # This script is used to record the position of an object as it travels
    # through each frame, independent of the Game Physics. If Blender is set
    # to record Game Physics to IPO, toggle that menu item OFF. This is a
    # replacement. The algorithm follows:
    #
    # 1. Get the object being controlled by physics.
    # 2. Get the object's position (for a given frame).
    # 3. Update the recorded curves (stored in the global variable GameLogic.rec).
    #
    import Blender
    from Blender import Scene
    
    gameObject = GameLogic.getCurrentController().getOwner()
    
    position = gameObject.getPosition()
    frame = gameObject.time * Scene.GetCurrent().getRenderingContext().fps
    
    # Only try to update the curves if the variable has been initialised.
    #
    if hasattr( GameLogic, 'rec' ):
      # Set the curves for the X, Y, and Z axis.
      #
      GameLogic.rec[1].addBezier( (frame, position[0]) )
      GameLogic.rec[1].update()
      GameLogic.rec[2].addBezier( (frame, position[1]) )
      GameLogic.rec[2].update()
      GameLogic.rec[3].addBezier( (frame, position[2]) )
      GameLogic.rec[3].update()
    
  10. Set the value of Script: for c.start to record-ipo.py.
  11. Set the value of Script: for c.record to record-frame.py.
  12. Click Add, below Actuators, five times.
  13. Change the type of actuators, from top to bottom as:
    1. Property
    2. Parent
    3. Property
    4. Parent
    5. Game
  14. Set the name of the actuators, from top to bottom as:
    1. a.start.parent
    2. a.parent.empty
    3. a.stop.parent
    4. a.parent.none
    5. a.stop
  15. From top to bottom:
    1. Set the value of Prop: to collision.
    2. Set the value of Value: to True.
    3. Set the value of OB: to Empty.
    4. Set the value of Prop: to collision.
    5. Set the value of Value: to False.
    6. Change Set Parent to Remove Parent.
    7. Change Start new game to Quit this game.
  16. Link Sensors to Controllers to Actuators:

    Logic Blocks for the Sphere

Render Animation

  1. Move the mouse cursor over to the 3D window.
  2. Press p to invoke the wrath of the Game Physics.
  3. Press ALT-a to play the animation using IPO curves.
    The Sphere should fall from gravity to the Plane, follow the Path, then fall from gravity to the Box.
  4. Render » Render Animation

Play Rendered Animation

THE END - Download


3D Gallery | Blender Tutorials | Dance Workshops | Essays | Quantum Entanglement

Copyright © 2007-2008 by Dave Jarvis