Animations - Creating a Curve2IPO wizard

Re: Animations - Creating a Curve2IPO wizard

Postby Aloys » Sat Aug 16, 2008 3:58 am

I am clueless at half of the technical details you write here but if your project will enventually allow us to have objects follow curves (and thus allow rides and better camera animation) then you have all my support! :) (becase that's really the only thing I can give you here :? )
User avatar
Aloys
 
Posts: 1968
Joined: Sun Oct 21, 2007 7:57 pm
Location: France (GMT +1)

Re: Animations - Creating a Curve2IPO wizard

Postby Trylon » Sat Aug 16, 2008 12:13 pm

Oh, there's nothing more easy (well, not exactly but still) than converting localspace to worldspace.
One day I ran through the cleft for the fiftieth time, and found that uru held no peace for me anymore.
User avatar
Trylon
 
Posts: 1446
Joined: Fri Sep 28, 2007 11:08 pm
Location: Gone from Uru

Re: Animations - Creating a Curve2IPO wizard

Postby Grogyan » Sat Aug 16, 2008 1:23 pm

He he, blame it on too much Sci Fi :lol:

Thanks guys for your support, this really is a tough project for me
Better to have loved and lost than never to have loved at all
User avatar
Grogyan
 
Posts: 1203
Joined: Thu Oct 11, 2007 1:27 am

Re: Animations - Creating a Curve2IPO wizard

Postby Grogyan » Sat Aug 16, 2008 1:29 pm

Trylon wrote:Oh, there's nothing more easy (well, not exactly but still) than converting localspace to worldspace.


Mmm, just thinking out loud here, but i'll wait to see what Lontahv can do with the delta curves in PyPrp
The thought I just had, would just make things too ugly, PyPrp will need to associate the animation with local space to the Curve object.
Better to have loved and lost than never to have loved at all
User avatar
Grogyan
 
Posts: 1203
Joined: Thu Oct 11, 2007 1:27 am

Re: Animations - Creating a Curve2IPO wizard

Postby Lontahv » Sat Aug 16, 2008 2:40 pm

Ok, I see the delta curves... I'm wondering if delta to world would just require the rest position of the object plus the delta. So it'd be:

Code: Select all
obj = Blender.Object.Get('objectname')
X = obj.loc[0]+deltaX
Y = obj.loc[1]+deltaY
Z = obj.loc[2]+deltaZ


I dunno, it's worth a try.

EDIT: Did some manual testing and it looks like Delta curves can be used as LOC curves as long as the object rest-point is 0. Just try saving into the LOC with that data instead of the Delta. Then see what happens. :)

EDIT: Got it.
Currently getting some ink on my hands over at the Guild Of Ink-Makers (PyPRP2).
User avatar
Lontahv
Councilor of Artistic Direction
 
Posts: 1331
Joined: Wed Oct 03, 2007 2:09 pm

Re: Animations - Creating a Curve2IPO wizard

Postby Grogyan » Sat Aug 16, 2008 3:08 pm

Ok, will give it a shot this afternoon sometime

I thought that may have been your idea, but i'm thinking that the ipo curves would look very strange, ie +/- the axis without delta.

If that happens then it is impossible to move the curve (not changing anything in that curve) with the ipo keeping the relative position in the world. You know when you are debugging your Age/level and you just want to move it just a bit, the ipo curves will still the same or run the script again
Better to have loved and lost than never to have loved at all
User avatar
Grogyan
 
Posts: 1203
Joined: Thu Oct 11, 2007 1:27 am

Re: Animations - Creating a Curve2IPO wizard

Postby Lontahv » Sat Aug 16, 2008 3:09 pm

Code: Select all
#!BPY

# A script to convert a curve to an IPO curve which can be used by an object to simulate the path it is flying

# Specifically designed to help with GoW_PyPrp plugin
"""
Name: 'Curve2IPO'
Blender: 246
Group: 'Wizards'
Tooltip: 'Make IPO curves from path'
"""
# ==============================================
#
#         ToDo
#
#   1) Move the else statement
#      to the end so that that section is skipped
#      when the condition isn't true
#      -> DONE
#
#   2) Put in a check object type in before the
#      first if statement, the else goes at the end
#      -> DONE
#
#   3) Put in a check for if its cyclic or not,
#      if it is true then save copy of the first
#      BezTriple and apply it after the for loop
#
#   4) Apply the BezTriple of locations to the IPO
#      window
#
#   5) Add to the IPO window the folowing blocks
#      dRotX, dRotY, dRotZ and Time where time is
#      the slow down or speed up at certain sections
#      though this is probably redundant and just
#      maintain a constand speed
#   
#   6) Work out an algorithm for the above
#      but don't for get that rotation is divided
#      by 10, eg 90 degres becomes 9 degrees
#      but test it out first.
#
#   7) Set the curves' datablock name as the
#      objects'
#      -> DONE
#
# ==============================================

import Blender
import math
from math import *

print"\n\n\n#################################################"
print"   Attempting to run script"
print"##############################################\n"

# Get the currently selected object
myCurve = Blender.Object.GetSelected()[0]
#get X,Y,Z of the curve
myCurveX = myCurve.loc[0]
myCurveY = myCurve.loc[1]
myCurveZ = myCurve.loc[2]

# Create variable and get the type of object   
myObjectType = myCurve.getType()

if myObjectType == 'Curve':
   print"   -> Object is a %s" % myObjectType
      
   myCurveData = Blender.Curve.Get()[0]
   myCurveFlag1 = myCurveData.getFlag()

   # Standard bit mask for bit 3
   if myCurveFlag1 and 0x08: #  Is "CurvePath" flag set
      print"   -> Curve flag bit 3 at 0x00001000 is set, value is: %x " % (myCurveFlag1 and 0x08)

      # Get the object name of the curve
      myCurveName = myCurve.getName()
      #myCurveBez = Blender.Object.Get(myCurve)   # Get data of curve
      
      # Initialize what will be the name of the IPO's
      myIPOCurveSet =  myCurve.getName()
      
      # Get the length of the curve in frames
      myPathLength = myCurveData.getPathLen()
      
      # Create variables myPathIter, myCurrentPathLen
      # and initialize them to a known value
      myPathIter = myCurrentPathLen = myPathLength
      
      #myIPOCurves = myIPOCurves.LOC[x]
      myIPOCurveSet = Blender.Ipo.New('Object', myCurveName) # Attmpting  to get the Curve name same as IPO curve set
      
      #####################################
      #handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
      #####################################
      
      # Get the name of the data block
      myCurveData = myCurve.data
      
      myCyclicTest = myCurveData.isCyclic()
      if myCyclicTest == True:
         print"   -> Curve is cyclic"
      else:
         print"   -> Curve is not cyclic"
      
      # Set the name of the data block as the
      # objects' name
      myCurveData.setName(myCurveName)
      
      # Create the variable and intialize it to 0
      myCurvePoints = 0
      # Old way -> myCurvePoints = myCurveData.__getitem__(myCurvePoints)
      myCurvePoints = myCurveData[myCurvePoints]    

      # can't be bothered how to figure out how
      # use get curve length function in the API
      # its just as easy to write a loop to calculate it
      myNumberOfPoints = 0
      for iNumberOfPoints in myCurvePoints:
         myNumberOfPoints = myNumberOfPoints + 1.0
      myPathIter = myPathLength / myNumberOfPoints
      
      myHandleIter = myPathIter / (myNumberOfPoints * 2.0)
      myHandleIter = ceil (myHandleIter)
         
      print "\n##############################################"
      print "Curve name: %s " % myCurveName
      print "Curve data: %s " % myCurveData
      print "Ipo curves: %s " % myIPOCurveSet
      print "Ipo length: %s " % myPathLength
      print "Path iteration constant: %s" % myPathIter
      print "##############################################\n"   

      # Create LocX, LocY, and LocZ Ipo curves in our new Curve Object
      # and store them so we can access them later
      myIPOCurveLoc_X = myIPOCurveSet.addCurve('LocX')
      myIPOCurveLoc_Y = myIPOCurveSet.addCurve('LocY')
      myIPOCurveLoc_Z = myIPOCurveSet.addCurve('LocZ')
      myIPOCurveRot_X = myIPOCurveSet.addCurve('RotX')
      myIPOCurveRot_Y = myIPOCurveSet.addCurve('RotY')
      myIPOCurveRot_Z = myIPOCurveSet.addCurve('RotZ')
      #myIPOCurveSpeed = myIPOCurveSet.addCurve('Time')
         
      myBezPointNumber = 1
      myCurrentPathLen = 1
      for nCurvePoints in myCurvePoints:
         
         # Copy the first set of co-ordinates
         # ready for a isCyclic condtion
         if myBezPointNumber == 0:
            myFirstCoods = nCurvePoints
         
         # Apparently  BezTriple outputs 9 floats for each handle/knot in 3D space
         # so print out each float value
         print"\n##############################################"
         print"Bezier point number: %s" % myBezPointNumber
         print"Out of a total: %s" % myNumberOfPoints
         print"Current iteration at frame: %s\n" %  myCurrentPathLen
         print"H1x: %s " % nCurvePoints.vec[0][0]
         print"H1y: %s " % nCurvePoints.vec[0][1]
         print"H1z: %s " % nCurvePoints.vec[0][2]
         print"\n"
         print"Px: %s " % nCurvePoints.vec[1][0]
         print"Py: %s " % nCurvePoints.vec[1][1]
         print"Pz: %s " % nCurvePoints.vec[1][2]
         print"\n"
         print"H2x: %s " % nCurvePoints.vec[2][0]
         print"H2y: %s " % nCurvePoints.vec[2][1]
         print"H2z: %s " % nCurvePoints.vec[2][2]
         print"##############################################\n"
   
         # Store all bezier points
         H1_X = nCurvePoints.vec[0][0]
         H1_Y = nCurvePoints.vec[0][1]
         H1_Z = nCurvePoints.vec[0][2]
         P_X = nCurvePoints.vec[1][0]
         P_Y = nCurvePoints.vec[1][1]
         P_Z = nCurvePoints.vec[1][2]
         H2_X = nCurvePoints.vec[2][0]
         H2_Y = nCurvePoints.vec[2][1]
         H2_Z = nCurvePoints.vec[2][2]
      
         # make 3 BezTriples, and mke sure their handles are FREE
         # pass eacch of these 3 new BezTriples for X, Y and Z
         # to their relevant IPO's
         myIPOCurveX = Blender.BezTriple.New(myCurrentPathLen - myHandleIter+myCurveX, H1_X, 0, myCurrentPathLen, P_X+myCurveX, 0, myCurrentPathLen + myHandleIter, H2_X+myCurveX, 0)
         myIPOCurveY = Blender.BezTriple.New(myCurrentPathLen - myHandleIter, H1_Y+myCurveY, 0, myCurrentPathLen, P_Y+myCurveY, 0, myCurrentPathLen + myHandleIter, H2_Y+myCurveY, 0)
         myIPOCurveZ = Blender.BezTriple.New(myCurrentPathLen - myHandleIter, H1_Z+myCurveZ, 0, myCurrentPathLen, P_Z+myCurveZ, 0, myCurrentPathLen + myHandleIter, H2_Z+myCurveZ, 0)
         
         myIPOCurveX.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         myIPOCurveY.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         myIPOCurveZ.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         
         myIPOCurveLoc_X.append(myIPOCurveX)
         myIPOCurveLoc_Y.append(myIPOCurveY)
         myIPOCurveLoc_Z.append(myIPOCurveZ)
         
         #myIPOCurveSpeed.append((myCurrentPathLen, 30))
         # Must be done last in the for loop
         myBezPointNumber = myBezPointNumber + 1
         myCurrentPathLen = myPathIter * myBezPointNumber
   
         
   
         myIPOCurveLoc_X.recalc()
         myIPOCurveLoc_Y.recalc()
         myIPOCurveLoc_Z.recalc()
   
   else:
      Blender.Draw.PupMenu("Curve is not a Path")
      print"   -> Curve flag bit 3 at 0x00001000 is NOT set, value is: %x " % (myCurveFlag1 and 0x08)       

else:
   Blender.Draw.PupMenu("Object is not a curve")
   print"   -> Object is a %s" % myObjectType


There, now all you need to do is set the IPO curves one by one to use linear interpolation (in the menus). Then you should be set. This spits out curves that can be used with PyPRP. :)


Edit: Linear interpolation is now automated:

Code: Select all
#!BPY

# A script to convert a curve to an IPO curve which can be used by an object to simulate the path it is flying

# Specifically designed to help with GoW_PyPrp plugin
"""
Name: 'Curve2IPO'
Blender: 246
Group: 'Wizards'
Tooltip: 'Make IPO curves from path'
"""
# ==============================================
#
#         ToDo
#
#   1) Move the else statement
#      to the end so that that section is skipped
#      when the condition isn't true
#      -> DONE
#
#   2) Put in a check object type in before the
#      first if statement, the else goes at the end
#      -> DONE
#
#   3) Put in a check for if its cyclic or not,
#      if it is true then save copy of the first
#      BezTriple and apply it after the for loop
#
#   4) Apply the BezTriple of locations to the IPO
#      window
#
#   5) Add to the IPO window the folowing blocks
#      dRotX, dRotY, dRotZ and Time where time is
#      the slow down or speed up at certain sections
#      though this is probably redundant and just
#      maintain a constand speed
#   
#   6) Work out an algorithm for the above
#      but don't for get that rotation is divided
#      by 10, eg 90 degres becomes 9 degrees
#      but test it out first.
#
#   7) Set the curves' datablock name as the
#      objects'
#      -> DONE
#
# ==============================================

import Blender
import math
from math import *

print"\n\n\n#################################################"
print"   Attempting to run script"
print"##############################################\n"

# Get the currently selected object
myCurve = Blender.Object.GetSelected()[0]
#get X,Y,Z of the curve
myCurveX = myCurve.loc[0]
myCurveY = myCurve.loc[1]
myCurveZ = myCurve.loc[2]

# Create variable and get the type of object   
myObjectType = myCurve.getType()

if myObjectType == 'Curve':
   print"   -> Object is a %s" % myObjectType
     
   myCurveData = Blender.Curve.Get()[0]
   myCurveFlag1 = myCurveData.getFlag()

   # Standard bit mask for bit 3
   if myCurveFlag1 and 0x08: #  Is "CurvePath" flag set
      print"   -> Curve flag bit 3 at 0x00001000 is set, value is: %x " % (myCurveFlag1 and 0x08)

      # Get the object name of the curve
      myCurveName = myCurve.getName()
      #myCurveBez = Blender.Object.Get(myCurve)   # Get data of curve
     
      # Initialize what will be the name of the IPO's
      myIPOCurveSet =  myCurve.getName()
     
      # Get the length of the curve in frames
      myPathLength = myCurveData.getPathLen()
     
      # Create variables myPathIter, myCurrentPathLen
      # and initialize them to a known value
      myPathIter = myCurrentPathLen = myPathLength
     
      #myIPOCurves = myIPOCurves.LOC[x]
      myIPOCurveSet = Blender.Ipo.New('Object', myCurveName) # Attmpting  to get the Curve name same as IPO curve set
     
      #####################################
      #handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
      #####################################
     
      # Get the name of the data block
      myCurveData = myCurve.data
     
      myCyclicTest = myCurveData.isCyclic()
      if myCyclicTest == True:
         print"   -> Curve is cyclic"
      else:
         print"   -> Curve is not cyclic"
     
      # Set the name of the data block as the
      # objects' name
      myCurveData.setName(myCurveName)
     
      # Create the variable and intialize it to 0
      myCurvePoints = 0
      # Old way -> myCurvePoints = myCurveData.__getitem__(myCurvePoints)
      myCurvePoints = myCurveData[myCurvePoints]   

      # can't be bothered how to figure out how
      # use get curve length function in the API
      # its just as easy to write a loop to calculate it
      myNumberOfPoints = 0
      for iNumberOfPoints in myCurvePoints:
         myNumberOfPoints = myNumberOfPoints + 1.0
      myPathIter = myPathLength / myNumberOfPoints
     
      myHandleIter = myPathIter / (myNumberOfPoints * 2.0)
      myHandleIter = ceil (myHandleIter)
         
      print "\n##############################################"
      print "Curve name: %s " % myCurveName
      print "Curve data: %s " % myCurveData
      print "Ipo curves: %s " % myIPOCurveSet
      print "Ipo length: %s " % myPathLength
      print "Path iteration constant: %s" % myPathIter
      print "##############################################\n"   

      # Create LocX, LocY, and LocZ Ipo curves in our new Curve Object
      # and store them so we can access them later
      myIPOCurveLoc_X = myIPOCurveSet.addCurve('LocX')
      myIPOCurveLoc_Y = myIPOCurveSet.addCurve('LocY')
      myIPOCurveLoc_Z = myIPOCurveSet.addCurve('LocZ')
      myIPOCurveRot_X = myIPOCurveSet.addCurve('RotX')
      myIPOCurveRot_Y = myIPOCurveSet.addCurve('RotY')
      myIPOCurveRot_Z = myIPOCurveSet.addCurve('RotZ')
      #myIPOCurveSpeed = myIPOCurveSet.addCurve('Time')
         
      myBezPointNumber = 1
      myCurrentPathLen = 1
      for nCurvePoints in myCurvePoints:
         
         # Copy the first set of co-ordinates
         # ready for a isCyclic condtion
         if myBezPointNumber == 0:
            myFirstCoods = nCurvePoints
         
         # Apparently  BezTriple outputs 9 floats for each handle/knot in 3D space
         # so print out each float value
         print"\n##############################################"
         print"Bezier point number: %s" % myBezPointNumber
         print"Out of a total: %s" % myNumberOfPoints
         print"Current iteration at frame: %s\n" %  myCurrentPathLen
         print"H1x: %s " % nCurvePoints.vec[0][0]
         print"H1y: %s " % nCurvePoints.vec[0][1]
         print"H1z: %s " % nCurvePoints.vec[0][2]
         print"\n"
         print"Px: %s " % nCurvePoints.vec[1][0]
         print"Py: %s " % nCurvePoints.vec[1][1]
         print"Pz: %s " % nCurvePoints.vec[1][2]
         print"\n"
         print"H2x: %s " % nCurvePoints.vec[2][0]
         print"H2y: %s " % nCurvePoints.vec[2][1]
         print"H2z: %s " % nCurvePoints.vec[2][2]
         print"##############################################\n"
   
         # Store all bezier points
         H1_X = nCurvePoints.vec[0][0]
         H1_Y = nCurvePoints.vec[0][1]
         H1_Z = nCurvePoints.vec[0][2]
         P_X = nCurvePoints.vec[1][0]
         P_Y = nCurvePoints.vec[1][1]
         P_Z = nCurvePoints.vec[1][2]
         H2_X = nCurvePoints.vec[2][0]
         H2_Y = nCurvePoints.vec[2][1]
         H2_Z = nCurvePoints.vec[2][2]
     
         # make 3 BezTriples, and mke sure their handles are FREE
         # pass eacch of these 3 new BezTriples for X, Y and Z
         # to their relevant IPO's
         myIPOCurveX = Blender.BezTriple.New(myCurrentPathLen - myHandleIter+myCurveX, H1_X, 0, myCurrentPathLen, P_X+myCurveX, 0, myCurrentPathLen + myHandleIter, H2_X+myCurveX, 0)
         myIPOCurveY = Blender.BezTriple.New(myCurrentPathLen - myHandleIter, H1_Y+myCurveY, 0, myCurrentPathLen, P_Y+myCurveY, 0, myCurrentPathLen + myHandleIter, H2_Y+myCurveY, 0)
         myIPOCurveZ = Blender.BezTriple.New(myCurrentPathLen - myHandleIter, H1_Z+myCurveZ, 0, myCurrentPathLen, P_Z+myCurveZ, 0, myCurrentPathLen + myHandleIter, H2_Z+myCurveZ, 0)
         
         myIPOCurveX.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         myIPOCurveY.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         myIPOCurveZ.handleTypes = (Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE)
         
         myIPOCurveLoc_X.append(myIPOCurveX)
         myIPOCurveLoc_Y.append(myIPOCurveY)
         myIPOCurveLoc_Z.append(myIPOCurveZ)
         
         #myIPOCurveSpeed.append((myCurrentPathLen, 30))
         # Must be done last in the for loop
         myBezPointNumber = myBezPointNumber + 1
         myCurrentPathLen = myPathIter * myBezPointNumber
   
         myIPOCurveLoc_X.recalc()
         myIPOCurveLoc_Y.recalc()
         myIPOCurveLoc_Z.recalc()

      lin = Blender.IpoCurve.InterpTypes.LINEAR
      myIPOCurveLoc_X.interpolation = lin
      myIPOCurveLoc_Y.interpolation = lin
      myIPOCurveLoc_Z.interpolation = lin
      myIPOCurveRot_X.interpolation = lin
      myIPOCurveRot_Y.interpolation = lin
      myIPOCurveRot_Z.interpolation = lin

   else:
      Blender.Draw.PupMenu("Curve is not a Path")
      print"   -> Curve flag bit 3 at 0x00001000 is NOT set, value is: %x " % (myCurveFlag1 and 0x08)       

else:
   Blender.Draw.PupMenu("Object is not a curve")
   print"   -> Object is a %s" % myObjectType



Edit: Hmm, I guess it can only use bezier paths... so it needs the bezier interpolation. The top one seems right. Give it a go. 8-)
Currently getting some ink on my hands over at the Guild Of Ink-Makers (PyPRP2).
User avatar
Lontahv
Councilor of Artistic Direction
 
Posts: 1331
Joined: Wed Oct 03, 2007 2:09 pm

Re: Animations - Creating a Curve2IPO wizard

Postby Grogyan » Sat Aug 16, 2008 5:04 pm

Yes, that in theory should work.

The interpolation needs to be Bezier so i'll give it a shot this afternoon

I'm watching Star Trek right now, and will come back to this soon.

I'm still uneasy though about keeping the curves in world space
Better to have loved and lost than never to have loved at all
User avatar
Grogyan
 
Posts: 1203
Joined: Thu Oct 11, 2007 1:27 am

Re: Animations - Creating a Curve2IPO wizard

Postby Lontahv » Sat Aug 16, 2008 5:19 pm

Hmm... well if we had PyPRP have to deal with deltas then your tool would only work with the latest version of it. Also, I think it'd be great to have the anims to converted from Path to something normal that we can tweek if need be. :) If you want I could add a delta-curve reader and transformer to PyPRP easily but I think this local stuff just makes it more confusing.
Currently getting some ink on my hands over at the Guild Of Ink-Makers (PyPRP2).
User avatar
Lontahv
Councilor of Artistic Direction
 
Posts: 1331
Joined: Wed Oct 03, 2007 2:09 pm

Re: Animations - Creating a Curve2IPO wizard

Postby Grogyan » Sat Aug 16, 2008 6:48 pm

If you could that would be grand

I'm going to put a poll up on in the general forum to see what builders would want, that should sort out the issue of local or global space
Better to have loved and lost than never to have loved at all
User avatar
Grogyan
 
Posts: 1203
Joined: Thu Oct 11, 2007 1:27 am

PreviousNext

Return to Grogyan's Journal

Who is online

Users browsing this forum: No registered users and 1 guest