cwisbg

boids-maya python

Nov 10th, 2016
423
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.23 KB | None | 0 0
  1. # Thing v3.1
  2. from pymel.core import *
  3. import maya.cmds as mc
  4. import maya.api.OpenMaya as om
  5. import maya.OpenMaya as omm
  6. import time
  7. import math
  8. import random as r
  9.  
  10. start = time.clock()
  11.  
  12. def grpr(name):
  13.     g = ls(name)
  14.     if g:
  15.         delete(g)
  16.     g = group(n=name,em=1)
  17.     return g
  18. def makeBoid(name):
  19.     boidGrpr = grpr("boidGrp")
  20.     pc = polyCube(w=1.36, n = name, ch=0)[0]
  21.     pf = select(pc.f[5])
  22.     setToolTo('Move')
  23.     piv = manipMoveContext('Move', q=True, p=True,m=2)
  24.     scale(pf, .13,.13,.13, p = piv)
  25.     select(cl=1)
  26.     pcT = polyCube(w=.36,h=.36,d=.36, n = name+"_tail", ch=0)[0]
  27.     move(pcT, .86,0,0)
  28.     xform(pcT, sp=[-.18,0,0],rp=[-.18,0,0], r=1)
  29.     parent(pcT, pc)
  30.     boid = pc
  31.     parent(pc,boidGrpr)
  32.     return boid
  33.  
  34.  
  35. def lookAt(base, target, up=[0,1,0]):
  36.     x = omm.MVector(target[0]-base[0], target[1]-base[1], target[2]-base[2])
  37.     x.normalize()
  38.     z = x ^ omm.MVector(-up[0], -up[1], -up[2])
  39.     z.normalize()
  40.     y = x ^ z
  41.     y.normalize()
  42.     m = omm.MMatrix()
  43.     l = [x.x, x.y, x.z, 0, y.x, y.y, y.z, 0, z.x, z.y, z.z, 0, 0, 0, 0, 1]
  44.     omm.MScriptUtil.createMatrixFromList(l, m)
  45.     r = omm.MTransformationMatrix(m).eulerRotation() * 57.2958
  46.     return r[0], r[1], r[2]
  47. def getDist(p1,p2):
  48.     dist = math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 + (p1[2] - p2[2])**2)
  49.     return dist  
  50. def rVec(randAmnt):
  51.     rV = om.MVector(r.uniform(-randAmnt,randAmnt),r.uniform(-randAmnt,randAmnt),r.uniform(-randAmnt,randAmnt))
  52.     return rV
  53. def vectorLimit(value,max):
  54.     newMax = []
  55.     for v in value:
  56.         if v > max:
  57.             v = v + max /2
  58.         newMax.append(v)
  59.     newMax = om.MVector(newMax)  
  60.     om.MVector.normalize(newMax)
  61.     value *= max
  62.     return value
  63. class defAttr:####################  Default Attributes  ######################################
  64.  
  65.     amnt = 200
  66.     maxSpeed = 3
  67.     timeStepAmnt = 5
  68.  
  69.     randoScale = [.4,1]
  70.    
  71.     spread = 1
  72.     boundsMaxDis = 20
  73.     boundsForce = 2# how strong the boids will try to stay in the bounds
  74.    
  75.    
  76.     wanderForce = 3
  77.     wanderDist = 5
  78.     wanderRadius = 20
  79.     rando = 1
  80.    
  81.    
  82.     #wanderForce = 0
  83.     rTargetRDamp = 1
  84.     targetForce = 0
  85.     rAvoidRDamp = 1
  86.     avoidForce = 0
  87.    
  88.  
  89.        
  90.     runSeek = 1
  91.     # Seperate Force
  92.     rSMulti = 3 # radius scale multiplier, - seperate search based on boid radius
  93.     rSeperateF = .3# radius seperate force
  94.     # Align Force
  95.     alignSwarm = .1
  96.     rAlignR = 10 # align radius multiplier
  97.     rAlignF = 40
  98.     # align force
  99.     # Grouping Force
  100.     rCosRDamp = 1
  101.     rCosR = 40
  102.     rCosF = 1# cohesion force
  103.    
  104.     trail = 1
  105.    
  106.     tailLegnth = 3
  107.     progress = 1
  108.    
  109.    
  110.     """
  111.    boundWidth = amnt*.1#30
  112.    boundHeight = amnt*.1
  113.    boundDepth = amnt*.1
  114.    """
  115.     boundsCheck = ls("bounds_obj")
  116.     if boundsCheck:
  117.         bounds = (xform(boundsCheck[0], bbi=1, q=1))
  118.         #boundLocation = om.MVector(boundsCheck[0].getTranslation())
  119.         #boundsScale = boundsCheck[0].getScale()
  120.         #boundWidth = boundsScale[0]
  121.         #boundHeight = boundsScale[1]
  122.         #boundDepth = boundsScale[2]
  123.     else:
  124.         boundLocation = om.MVector(0,0,0)
  125.         boundWidth = 100
  126.         boundHeight = 30
  127.         boundDepth = 10
  128.         bounds = [-boundWidth, -boundHeight, -boundDepth,boundWidth, boundHeight, boundDepth]
  129.     #bounds = om.MVector(boundWidth + boundLocation[0], boundHeight + boundLocation[1], boundDepth + boundLocation[2])
  130.     #bounds = boundLocation + om.MVector(boundWidth*.5, boundHeight*.5, boundDepth*.5)
  131.     #boundsMin = boundLocation + om.MVector(boundWidth*.5, boundHeight*.5, boundDepth*.5)
  132.     #self.pos = om.MVector(r.uniform(-width+treeCenter[0],+width+treeCenter[0]),r.uniform(-height+treeCenter[1],+height+treeCenter[1]),r.uniform(-width+treeCenter[2],+width+treeCenter[2]))
  133.  
  134.     #[-100, 30, 10, 100, -30, -10]
  135.     #[-44.40203590730266, -0.35115264794782775, -57.09075662231567, 44.40203590730266, 113.83036059668352, 57.09075662231567]
  136.    
  137.     #duper = "livingScale_0_fish"
  138.     #duper = "spaceShipGrp"
  139.     #duper = "boid_obj"
  140.     boid = makeBoid("boid_")
  141.    
  142.     allThings = []
  143.     allItterations = 0
  144.     tStart = int(playbackOptions(q=1,ast=1))
  145.     tEnd = int(playbackOptions(q=1,aet=1))+1  
  146.    
  147.    
  148.  
  149. class thing():
  150.     def __init__(self, thingObject):
  151.         self.thingObj = thingObject[0]
  152.         self.thingObjTail = listRelatives(thingObject[0],c=1)[1]
  153.         self.dirObj = []
  154.         self.pos = rVec(defAttr.spread)
  155.         self.lastPos = rVec(defAttr.rando)
  156.         self.dir = om.MVector.normalize(self.pos + rVec(defAttr.rando))
  157.         self.lastDir = self.dir
  158.         self.radius = om.MVector(thingObject[0].getScale())
  159.         self.maxSpeed = 1
  160.         self.maxForce = 1
  161.         self.toCrv = []
  162.        
  163.     def swarm(self):
  164.         countS = -1
  165.         countA = -1
  166.         countC = -1
  167.         countCD = 0
  168.         sumS = om.MVector(0,0,0)
  169.         sumA = om.MVector(0,0,0)
  170.         sumC = om.MVector(0,0,0)
  171.         sumT = om.MVector(0,0,0)
  172.         sumAll = om.MVector(0,0,0)
  173.         closestThing = []
  174.         record = 1000
  175.         for thing in defAttr.allThings:
  176.              sumAll += thing.pos
  177.              dist = getDist(self.pos, thing.pos)
  178.              if dist < record:
  179.                  closestThing = thing
  180.                  record = dist
  181.              if dist >= 0:
  182.                  pass
  183.              if dist < defAttr.rSMulti * self.radius[0]:
  184.                  diff = self.pos - thing.pos # attract towards target
  185.                  diff *= dist
  186.                  om.MVector.normalize(diff)
  187.                  sumS += diff
  188.                  countS += 1  
  189.              if dist < defAttr.rCosR*self.radius[0]:
  190.                  sumC += thing.pos
  191.                  #countCD += dist
  192.                  countC += 1
  193.              if dist < defAttr.rAlignR:#*self.radius[0]:#self.radius[0]+1*defAttr.rAlignR:
  194.                  #diff = thing.dir # attract towards target
  195.                  
  196.                  #om.MVector.normalize(diff)
  197.                  sumA +=  thing.dir #*dist
  198.                  sumA *= dist
  199.                  countA += 1
  200.              
  201.         if countS > 0:
  202.             sumS += sumS  / countS
  203.             om.MVector.normalize(sumS)
  204.         else:
  205.             sumS = om.MVector(0,0,0)    
  206.         if countC > 0:
  207.             """
  208.            sumC /= countC
  209.            om.MVector.normalize(sumC)
  210.            sumC *= defAttr.rCosF
  211.            sumT -= sumC
  212.            """
  213.             sumC /= -countC
  214.             #om.MVector.normalize(sumC)
  215.             sumC += self.pos  
  216.             om.MVector.normalize(sumC)
  217.            
  218.             #sumC *= defAttr.maxSpeed
  219.             #sumC -= self.dir
  220.             #sumC += sumC / countC
  221.             #om.MVector.normalize(sumC)
  222.         else:
  223.             #sumC = om.MVector(0,0,0)
  224.             #sumC = self.pos + sumAll
  225.             sumC = self.pos + sumAll / -len(defAttr.allThings)#closestThing.pos
  226.             sumC -= self.dir
  227.             om.MVector.normalize(sumC)
  228.             d = getDist(self.pos, sumC)
  229.             sumC *= d
  230.             #print "HERE", sumC
  231.            
  232.         if countA > 0:
  233.             sumA += sumA  / countA
  234.             #sumA /= countA
  235.             ##d = getDist(self.pos, sumA)
  236.             om.MVector.normalize(sumA)
  237.             #sumA *= d
  238.         else:
  239.             #sumA = om.MVector(0,0,0)
  240.             sumA = sumAll/-len(defAttr.allThings)+self.pos#closestThing.pos
  241.             #sumA += self.dir
  242.             #d = getDist(self.pos, sumA)
  243.             #sumA  *= d
  244.             om.MVector.normalize(sumA)
  245.             sumA *= -defAttr.alignSwarm
  246.             #print "HERE", sumA
  247.         return sumS ,sumA , sumC
  248.     def avoid(self):
  249.         avoid = om.MVector(0,0,0)
  250.         avoidR = om.MVector(1,1,1)
  251.         stearing = om.MVector(0,0,0)
  252.         if defAttr.avoidForce > 0 :
  253.             avoidCheck = ls("avoid_lctr")
  254.             if avoidCheck:
  255.                 avoid = om.MVector(ls("avoid_lctr")[0].getTranslation())
  256.                 avoidR = om.MVector(ls("avoid_lctr")[0].getScale())
  257.             desire = avoid - self.pos# * avoidR[1]
  258.             d = getDist(self.pos, avoid)
  259.             if d < avoidR[1]:
  260.                 desire *= d/avoidR[1]# * defAttr.rAvoidRDamp
  261.             else:
  262.                 desire = om.MVector(0,0,0)#*defAttr.maxSpeed # set mag to max speed  
  263.            
  264.             stearing = self.dir + -desire
  265.         om.MVector.normalize(stearing)
  266.         return stearing
  267.     def target(self):
  268.         target = om.MVector(0,0,0)
  269.         targetR = om.MVector(1,1,1)
  270.         stearing = om.MVector(0,0,0)
  271.         if defAttr.targetForce > 0 :
  272.             targetCheck = ls("target_lctr")
  273.             if targetCheck:
  274.                 target = om.MVector(ls("target_lctr")[0].getTranslation())
  275.                 targetR = om.MVector(ls("target_lctr")[0].getScale())
  276.  
  277.             desire = target - self.pos
  278.             d = getDist(self.pos, target)
  279.             if d < targetR[1]:
  280.                 desire *= d/targetR[1] * defAttr.rTargetRDamp
  281.             else:
  282.                 desire = om.MVector(0,0,0)#*defAttr.maxSpeed # set mag to max speed  
  283.             stearing = desire + self.dir
  284.         om.MVector.normalize(stearing)
  285.         return stearing
  286.     def wander(self):
  287.         #wander = om.MVector(0,0,0)
  288.         #wander = self.pos + self.dir
  289.         #wanderDesire = getDist(self.pos, self.dir)
  290.         #wander = self.dir * (wanderDesire*defAttr.rando)#*defAttr.speedDecay  # add noise
  291.         growDirection = self.dir*defAttr.wanderDist
  292.         radius = self.radius[0]*defAttr.wanderRadius
  293.         wander = om.MVector(r.uniform(-radius+growDirection[0],radius+growDirection[0]),r.uniform(-radius+growDirection[1],radius+growDirection[1]),r.uniform(-radius+growDirection[2],radius+growDirection[2]))
  294.         #wander = om.MVector(r.uniform(-radius,radius),r.uniform(-radius,radius),r.uniform(-radius,radius))
  295.         om.MVector.normalize(wander)
  296.         #wander * -defAttr.wanderForce
  297.         #wander += self.dir*defAttr.wanderForce
  298.         #om.MVector.normalize(wander)
  299.         #om.MVector.normalize(growDirection)
  300.         #growDirection *= defAttr.wanderDist
  301.         #om.MVector.normalize(growDirection)
  302.  
  303.         #om.MVector.normalize(wander)
  304.         #wander *= defAttr.wanderSpeed
  305.         #wander = om.MVector(0,0,0)
  306.         return wander
  307.  
  308.     def bounds(self):
  309.         forceB = om.MVector(0,0,0)
  310.         boundsCheck = ls("bounds_obj")
  311.         outOfBounds = 0
  312.         if boundsCheck:
  313.             defAttr.bounds = (xform(boundsCheck[0], bbi=1, q=1))
  314.            
  315.         boundDis = self.pos
  316.         if boundDis[0] < defAttr.bounds[0]:
  317.             forceB[0] = defAttr.bounds[0] - self.pos[0]# - self.lastDir[0]
  318.         if boundDis[1] < defAttr.bounds[1]:
  319.             forceB[1] = defAttr.bounds[1] - self.pos[1]# - self.lastDir[1]
  320.         if boundDis[2] < defAttr.bounds[2]:
  321.             forceB[2] = defAttr.bounds[2] - self.pos[2]# - self.lastDir[2]
  322.  
  323.         if boundDis[0] > defAttr.bounds[3]:
  324.             forceB[0] = defAttr.bounds[0] - self.pos[0]# - self.lastDir[0]
  325.         if boundDis[1] > defAttr.bounds[4]:
  326.             forceB[1] = defAttr.bounds[1] - self.pos[1]# - self.lastDir[1]
  327.         if boundDis[2] > defAttr.bounds[5]:
  328.             forceB[2] = defAttr.bounds[2] - self.pos[2]# - self.lastDir[2]
  329.  
  330.            
  331.         om.MVector.normalize(forceB)
  332.         return forceB
  333.        
  334.        
  335.        
  336.        
  337.        
  338.     def applyForce(self, forceT, forceS, forceW, forceB, forceA):
  339.  
  340.         #newDir = om.MVector(0,0,0)
  341.         self.dir = om.MVector(0,0,0)
  342.         self.dir += om.MVector(forceT * defAttr.targetForce) # add attract force
  343.         self.dir += om.MVector(forceA * defAttr.avoidForce) # add attract force
  344.         #print "B", self.dir
  345.         #self.dir -= forceS[0]  # add swarm
  346.         self.dir += om.MVector(forceW) * defAttr.wanderForce
  347.         self.dir += om.MVector(forceB * defAttr.boundsForce)
  348.         self.dir += om.MVector(forceS[0] * defAttr.rSeperateF) # add push away force
  349.         self.dir += om.MVector(forceS[1] * defAttr.rAlignF) # add swarm align
  350.         self.dir -= om.MVector(forceS[2] * defAttr.rCosF)   # add cohesien
  351.        
  352.        
  353.         #self.dir += self.lastDir
  354.         #self.dir += rVec(defAttr.rando)
  355.         om.MVector.normalize(self.dir)
  356.         self.dir *= defAttr.maxSpeed# * (self.radius[0]*.5) # limit speed
  357.        
  358.         self.pos += self.dir
  359.         self.lastPos = self.pos
  360.         self.lastDir = self.dir
  361.         #defAttr.allItterations += 1
  362.  
  363. def doGrow(newThings):
  364.     print "Starting growing"
  365.     #toParentG = []
  366.  
  367.     if defAttr.progress:
  368.         progWin2 = progressWindow(isInterruptable=1, t= "Please wait", min = defAttr.tStart, max = defAttr.tEnd)
  369.     timeStep = defAttr.timeStepAmnt
  370.     for i in range(defAttr.tStart,defAttr.tEnd):
  371.         if defAttr.progress:  
  372.             progressWindow(progWin2, edit=True, pr = i+1)
  373.             if progressWindow(progWin2, query=1, isCancelled=1 ):
  374.                 print "killed at", i+1
  375.                 break    
  376.         currentTime(i, u=1)
  377.         #tracker = 0
  378.         lastAim = om.MVector(0,0,0)
  379.         for thing in newThings:
  380.  
  381.                
  382.             forceW = om.MVector(0,0,0)  
  383.             forceT = om.MVector(0,0,0)
  384.             forceS = om.MVector(0,0,0),om.MVector(0,0,0),om.MVector(0,0,0)
  385.             forceB = om.MVector(0,0,0)
  386.             forceA = om.MVector(0,0,0)
  387.            
  388.             forceB = thing.bounds()
  389.             forceW = thing.wander()
  390.             if defAttr.runSeek:
  391.                 forceT = thing.target()
  392.                 forceS = thing.swarm()
  393.                
  394.                 forceA = thing.avoid()
  395.             thing.applyForce(forceT, forceS, forceW, forceB, forceA)
  396.             if timeStep == defAttr.timeStepAmnt:
  397.                 move(thing.thingObj, thing.pos)
  398.                 tailScale = getDist(thing.pos, thing.pos + thing.dir*defAttr.tailLegnth)
  399.                 scale(thing.thingObjTail, tailScale,1,1)
  400.                 toCrvAdd = thing.pos[0],thing.pos[1],thing.pos[2]
  401.                 thing.toCrv.append(toCrvAdd)
  402.                
  403.                 newV = thing.pos - thing.dir
  404.                 aimToRotate =  lookAt(thing.pos, newV)
  405.                 rotate(thing.thingObj, aimToRotate)
  406.                 setKeyframe(thing.thingObj.rotate)  
  407.                 setKeyframe(thing.thingObj.translate)
  408.                 #setKeyframe(thing.thingObjTail.translate)
  409.                 setKeyframe(thing.thingObjTail.scale)
  410.             i += 1
  411.         if timeStep == defAttr.timeStepAmnt:
  412.             timeStep = 0
  413.         timeStep += 1
  414.        
  415. if defAttr.progress:  
  416.     progWin2 = progressWindow(isInterruptable=1, t= "Creating boids", min = 0, max = defAttr.amnt)
  417.                    
  418. newThingsGrp = grpr("ThingGrp")
  419. newThings = []
  420. toParentT = []
  421. for i in range(defAttr.amnt):
  422.     if defAttr.progress:  
  423.         progressWindow(progWin2, edit=True, pr = i)
  424.         if progressWindow(progWin2, query=1, isCancelled=1 ):
  425.             print "killed at", i+1
  426.             break
  427.     thingObj = duplicate(defAttr.boid, ic=1, rc=1)
  428.     #thingObj = instance(defAttr.boid)
  429.     randR = r.uniform(defAttr.randoScale[0],defAttr.randoScale[1])
  430.     #randR = 1
  431.     scale(thingObj[0], randR,randR,randR)
  432.     toParentT.append(thingObj[0])
  433.     #toParentT.append(thingObj[1])
  434.     #toParentT.append(thingObj[2])
  435.     newThing = thing(thingObj)###
  436.     newThings.append(newThing)
  437.     defAttr.allThings.append(newThing)
  438.  
  439.  
  440. parent(toParentT, newThingsGrp)
  441. select(cl=1)
  442.  
  443.  
  444. setAttr(defAttr.boid.visibility, 0 )
  445.  
  446.  
  447.  
  448. if defAttr.progress:  
  449.     progressWindow(progWin2, endProgress=1)
  450.  
  451. doGrow(newThings)
  452.  
  453. newCrvs = []
  454. toFilter = []
  455. for thing in newThings:
  456.     add =  str(thing.thingObj+"_rotateX "),str(thing.thingObj+"_rotateY "),str(thing.thingObj+"_rotateZ ")
  457.     toFilter.append(add)
  458.     if defAttr.trail:
  459.         c = curve(p =thing.toCrv, d = 3)
  460.         newCrvs.append(c)
  461.  
  462. filterCurve(toFilter, e = defAttr.tEnd, s = defAttr.tStart)
  463. parent(newCrvs, "ThingGrp")
  464.  
  465.  
  466. if defAttr.progress:
  467.     progressWindow(progWin2, edit=True, pr = 0)  
  468.     progressWindow(progWin2, endProgress=1)
  469.    
  470. select(cl=1)
  471. #print "total itterations ", defAttr.allItterations
  472. elapsedChunk = (time.clock() - start)
  473. print "done, took:", elapsedChunk
Advertisement
Add Comment
Please, Sign In to add comment