Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Thing v3.1
- from pymel.core import *
- import maya.cmds as mc
- import maya.api.OpenMaya as om
- import maya.OpenMaya as omm
- import time
- import math
- import random as r
- start = time.clock()
- def grpr(name):
- g = ls(name)
- if g:
- delete(g)
- g = group(n=name,em=1)
- return g
- def makeBoid(name):
- boidGrpr = grpr("boidGrp")
- pc = polyCube(w=1.36, n = name, ch=0)[0]
- pf = select(pc.f[5])
- setToolTo('Move')
- piv = manipMoveContext('Move', q=True, p=True,m=2)
- scale(pf, .13,.13,.13, p = piv)
- select(cl=1)
- pcT = polyCube(w=.36,h=.36,d=.36, n = name+"_tail", ch=0)[0]
- move(pcT, .86,0,0)
- xform(pcT, sp=[-.18,0,0],rp=[-.18,0,0], r=1)
- parent(pcT, pc)
- boid = pc
- parent(pc,boidGrpr)
- return boid
- def lookAt(base, target, up=[0,1,0]):
- x = omm.MVector(target[0]-base[0], target[1]-base[1], target[2]-base[2])
- x.normalize()
- z = x ^ omm.MVector(-up[0], -up[1], -up[2])
- z.normalize()
- y = x ^ z
- y.normalize()
- m = omm.MMatrix()
- 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]
- omm.MScriptUtil.createMatrixFromList(l, m)
- r = omm.MTransformationMatrix(m).eulerRotation() * 57.2958
- return r[0], r[1], r[2]
- def getDist(p1,p2):
- dist = math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 + (p1[2] - p2[2])**2)
- return dist
- def rVec(randAmnt):
- rV = om.MVector(r.uniform(-randAmnt,randAmnt),r.uniform(-randAmnt,randAmnt),r.uniform(-randAmnt,randAmnt))
- return rV
- def vectorLimit(value,max):
- newMax = []
- for v in value:
- if v > max:
- v = v + max /2
- newMax.append(v)
- newMax = om.MVector(newMax)
- om.MVector.normalize(newMax)
- value *= max
- return value
- class defAttr:#################### Default Attributes ######################################
- amnt = 200
- maxSpeed = 3
- timeStepAmnt = 5
- randoScale = [.4,1]
- spread = 1
- boundsMaxDis = 20
- boundsForce = 2# how strong the boids will try to stay in the bounds
- wanderForce = 3
- wanderDist = 5
- wanderRadius = 20
- rando = 1
- #wanderForce = 0
- rTargetRDamp = 1
- targetForce = 0
- rAvoidRDamp = 1
- avoidForce = 0
- runSeek = 1
- # Seperate Force
- rSMulti = 3 # radius scale multiplier, - seperate search based on boid radius
- rSeperateF = .3# radius seperate force
- # Align Force
- alignSwarm = .1
- rAlignR = 10 # align radius multiplier
- rAlignF = 40
- # align force
- # Grouping Force
- rCosRDamp = 1
- rCosR = 40
- rCosF = 1# cohesion force
- trail = 1
- tailLegnth = 3
- progress = 1
- """
- boundWidth = amnt*.1#30
- boundHeight = amnt*.1
- boundDepth = amnt*.1
- """
- boundsCheck = ls("bounds_obj")
- if boundsCheck:
- bounds = (xform(boundsCheck[0], bbi=1, q=1))
- #boundLocation = om.MVector(boundsCheck[0].getTranslation())
- #boundsScale = boundsCheck[0].getScale()
- #boundWidth = boundsScale[0]
- #boundHeight = boundsScale[1]
- #boundDepth = boundsScale[2]
- else:
- boundLocation = om.MVector(0,0,0)
- boundWidth = 100
- boundHeight = 30
- boundDepth = 10
- bounds = [-boundWidth, -boundHeight, -boundDepth,boundWidth, boundHeight, boundDepth]
- #bounds = om.MVector(boundWidth + boundLocation[0], boundHeight + boundLocation[1], boundDepth + boundLocation[2])
- #bounds = boundLocation + om.MVector(boundWidth*.5, boundHeight*.5, boundDepth*.5)
- #boundsMin = boundLocation + om.MVector(boundWidth*.5, boundHeight*.5, boundDepth*.5)
- #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]))
- #[-100, 30, 10, 100, -30, -10]
- #[-44.40203590730266, -0.35115264794782775, -57.09075662231567, 44.40203590730266, 113.83036059668352, 57.09075662231567]
- #duper = "livingScale_0_fish"
- #duper = "spaceShipGrp"
- #duper = "boid_obj"
- boid = makeBoid("boid_")
- allThings = []
- allItterations = 0
- tStart = int(playbackOptions(q=1,ast=1))
- tEnd = int(playbackOptions(q=1,aet=1))+1
- class thing():
- def __init__(self, thingObject):
- self.thingObj = thingObject[0]
- self.thingObjTail = listRelatives(thingObject[0],c=1)[1]
- self.dirObj = []
- self.pos = rVec(defAttr.spread)
- self.lastPos = rVec(defAttr.rando)
- self.dir = om.MVector.normalize(self.pos + rVec(defAttr.rando))
- self.lastDir = self.dir
- self.radius = om.MVector(thingObject[0].getScale())
- self.maxSpeed = 1
- self.maxForce = 1
- self.toCrv = []
- def swarm(self):
- countS = -1
- countA = -1
- countC = -1
- countCD = 0
- sumS = om.MVector(0,0,0)
- sumA = om.MVector(0,0,0)
- sumC = om.MVector(0,0,0)
- sumT = om.MVector(0,0,0)
- sumAll = om.MVector(0,0,0)
- closestThing = []
- record = 1000
- for thing in defAttr.allThings:
- sumAll += thing.pos
- dist = getDist(self.pos, thing.pos)
- if dist < record:
- closestThing = thing
- record = dist
- if dist >= 0:
- pass
- if dist < defAttr.rSMulti * self.radius[0]:
- diff = self.pos - thing.pos # attract towards target
- diff *= dist
- om.MVector.normalize(diff)
- sumS += diff
- countS += 1
- if dist < defAttr.rCosR*self.radius[0]:
- sumC += thing.pos
- #countCD += dist
- countC += 1
- if dist < defAttr.rAlignR:#*self.radius[0]:#self.radius[0]+1*defAttr.rAlignR:
- #diff = thing.dir # attract towards target
- #om.MVector.normalize(diff)
- sumA += thing.dir #*dist
- sumA *= dist
- countA += 1
- if countS > 0:
- sumS += sumS / countS
- om.MVector.normalize(sumS)
- else:
- sumS = om.MVector(0,0,0)
- if countC > 0:
- """
- sumC /= countC
- om.MVector.normalize(sumC)
- sumC *= defAttr.rCosF
- sumT -= sumC
- """
- sumC /= -countC
- #om.MVector.normalize(sumC)
- sumC += self.pos
- om.MVector.normalize(sumC)
- #sumC *= defAttr.maxSpeed
- #sumC -= self.dir
- #sumC += sumC / countC
- #om.MVector.normalize(sumC)
- else:
- #sumC = om.MVector(0,0,0)
- #sumC = self.pos + sumAll
- sumC = self.pos + sumAll / -len(defAttr.allThings)#closestThing.pos
- sumC -= self.dir
- om.MVector.normalize(sumC)
- d = getDist(self.pos, sumC)
- sumC *= d
- #print "HERE", sumC
- if countA > 0:
- sumA += sumA / countA
- #sumA /= countA
- ##d = getDist(self.pos, sumA)
- om.MVector.normalize(sumA)
- #sumA *= d
- else:
- #sumA = om.MVector(0,0,0)
- sumA = sumAll/-len(defAttr.allThings)+self.pos#closestThing.pos
- #sumA += self.dir
- #d = getDist(self.pos, sumA)
- #sumA *= d
- om.MVector.normalize(sumA)
- sumA *= -defAttr.alignSwarm
- #print "HERE", sumA
- return sumS ,sumA , sumC
- def avoid(self):
- avoid = om.MVector(0,0,0)
- avoidR = om.MVector(1,1,1)
- stearing = om.MVector(0,0,0)
- if defAttr.avoidForce > 0 :
- avoidCheck = ls("avoid_lctr")
- if avoidCheck:
- avoid = om.MVector(ls("avoid_lctr")[0].getTranslation())
- avoidR = om.MVector(ls("avoid_lctr")[0].getScale())
- desire = avoid - self.pos# * avoidR[1]
- d = getDist(self.pos, avoid)
- if d < avoidR[1]:
- desire *= d/avoidR[1]# * defAttr.rAvoidRDamp
- else:
- desire = om.MVector(0,0,0)#*defAttr.maxSpeed # set mag to max speed
- stearing = self.dir + -desire
- om.MVector.normalize(stearing)
- return stearing
- def target(self):
- target = om.MVector(0,0,0)
- targetR = om.MVector(1,1,1)
- stearing = om.MVector(0,0,0)
- if defAttr.targetForce > 0 :
- targetCheck = ls("target_lctr")
- if targetCheck:
- target = om.MVector(ls("target_lctr")[0].getTranslation())
- targetR = om.MVector(ls("target_lctr")[0].getScale())
- desire = target - self.pos
- d = getDist(self.pos, target)
- if d < targetR[1]:
- desire *= d/targetR[1] * defAttr.rTargetRDamp
- else:
- desire = om.MVector(0,0,0)#*defAttr.maxSpeed # set mag to max speed
- stearing = desire + self.dir
- om.MVector.normalize(stearing)
- return stearing
- def wander(self):
- #wander = om.MVector(0,0,0)
- #wander = self.pos + self.dir
- #wanderDesire = getDist(self.pos, self.dir)
- #wander = self.dir * (wanderDesire*defAttr.rando)#*defAttr.speedDecay # add noise
- growDirection = self.dir*defAttr.wanderDist
- radius = self.radius[0]*defAttr.wanderRadius
- 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]))
- #wander = om.MVector(r.uniform(-radius,radius),r.uniform(-radius,radius),r.uniform(-radius,radius))
- om.MVector.normalize(wander)
- #wander * -defAttr.wanderForce
- #wander += self.dir*defAttr.wanderForce
- #om.MVector.normalize(wander)
- #om.MVector.normalize(growDirection)
- #growDirection *= defAttr.wanderDist
- #om.MVector.normalize(growDirection)
- #om.MVector.normalize(wander)
- #wander *= defAttr.wanderSpeed
- #wander = om.MVector(0,0,0)
- return wander
- def bounds(self):
- forceB = om.MVector(0,0,0)
- boundsCheck = ls("bounds_obj")
- outOfBounds = 0
- if boundsCheck:
- defAttr.bounds = (xform(boundsCheck[0], bbi=1, q=1))
- boundDis = self.pos
- if boundDis[0] < defAttr.bounds[0]:
- forceB[0] = defAttr.bounds[0] - self.pos[0]# - self.lastDir[0]
- if boundDis[1] < defAttr.bounds[1]:
- forceB[1] = defAttr.bounds[1] - self.pos[1]# - self.lastDir[1]
- if boundDis[2] < defAttr.bounds[2]:
- forceB[2] = defAttr.bounds[2] - self.pos[2]# - self.lastDir[2]
- if boundDis[0] > defAttr.bounds[3]:
- forceB[0] = defAttr.bounds[0] - self.pos[0]# - self.lastDir[0]
- if boundDis[1] > defAttr.bounds[4]:
- forceB[1] = defAttr.bounds[1] - self.pos[1]# - self.lastDir[1]
- if boundDis[2] > defAttr.bounds[5]:
- forceB[2] = defAttr.bounds[2] - self.pos[2]# - self.lastDir[2]
- om.MVector.normalize(forceB)
- return forceB
- def applyForce(self, forceT, forceS, forceW, forceB, forceA):
- #newDir = om.MVector(0,0,0)
- self.dir = om.MVector(0,0,0)
- self.dir += om.MVector(forceT * defAttr.targetForce) # add attract force
- self.dir += om.MVector(forceA * defAttr.avoidForce) # add attract force
- #print "B", self.dir
- #self.dir -= forceS[0] # add swarm
- self.dir += om.MVector(forceW) * defAttr.wanderForce
- self.dir += om.MVector(forceB * defAttr.boundsForce)
- self.dir += om.MVector(forceS[0] * defAttr.rSeperateF) # add push away force
- self.dir += om.MVector(forceS[1] * defAttr.rAlignF) # add swarm align
- self.dir -= om.MVector(forceS[2] * defAttr.rCosF) # add cohesien
- #self.dir += self.lastDir
- #self.dir += rVec(defAttr.rando)
- om.MVector.normalize(self.dir)
- self.dir *= defAttr.maxSpeed# * (self.radius[0]*.5) # limit speed
- self.pos += self.dir
- self.lastPos = self.pos
- self.lastDir = self.dir
- #defAttr.allItterations += 1
- def doGrow(newThings):
- print "Starting growing"
- #toParentG = []
- if defAttr.progress:
- progWin2 = progressWindow(isInterruptable=1, t= "Please wait", min = defAttr.tStart, max = defAttr.tEnd)
- timeStep = defAttr.timeStepAmnt
- for i in range(defAttr.tStart,defAttr.tEnd):
- if defAttr.progress:
- progressWindow(progWin2, edit=True, pr = i+1)
- if progressWindow(progWin2, query=1, isCancelled=1 ):
- print "killed at", i+1
- break
- currentTime(i, u=1)
- #tracker = 0
- lastAim = om.MVector(0,0,0)
- for thing in newThings:
- forceW = om.MVector(0,0,0)
- forceT = om.MVector(0,0,0)
- forceS = om.MVector(0,0,0),om.MVector(0,0,0),om.MVector(0,0,0)
- forceB = om.MVector(0,0,0)
- forceA = om.MVector(0,0,0)
- forceB = thing.bounds()
- forceW = thing.wander()
- if defAttr.runSeek:
- forceT = thing.target()
- forceS = thing.swarm()
- forceA = thing.avoid()
- thing.applyForce(forceT, forceS, forceW, forceB, forceA)
- if timeStep == defAttr.timeStepAmnt:
- move(thing.thingObj, thing.pos)
- tailScale = getDist(thing.pos, thing.pos + thing.dir*defAttr.tailLegnth)
- scale(thing.thingObjTail, tailScale,1,1)
- toCrvAdd = thing.pos[0],thing.pos[1],thing.pos[2]
- thing.toCrv.append(toCrvAdd)
- newV = thing.pos - thing.dir
- aimToRotate = lookAt(thing.pos, newV)
- rotate(thing.thingObj, aimToRotate)
- setKeyframe(thing.thingObj.rotate)
- setKeyframe(thing.thingObj.translate)
- #setKeyframe(thing.thingObjTail.translate)
- setKeyframe(thing.thingObjTail.scale)
- i += 1
- if timeStep == defAttr.timeStepAmnt:
- timeStep = 0
- timeStep += 1
- if defAttr.progress:
- progWin2 = progressWindow(isInterruptable=1, t= "Creating boids", min = 0, max = defAttr.amnt)
- newThingsGrp = grpr("ThingGrp")
- newThings = []
- toParentT = []
- for i in range(defAttr.amnt):
- if defAttr.progress:
- progressWindow(progWin2, edit=True, pr = i)
- if progressWindow(progWin2, query=1, isCancelled=1 ):
- print "killed at", i+1
- break
- thingObj = duplicate(defAttr.boid, ic=1, rc=1)
- #thingObj = instance(defAttr.boid)
- randR = r.uniform(defAttr.randoScale[0],defAttr.randoScale[1])
- #randR = 1
- scale(thingObj[0], randR,randR,randR)
- toParentT.append(thingObj[0])
- #toParentT.append(thingObj[1])
- #toParentT.append(thingObj[2])
- newThing = thing(thingObj)###
- newThings.append(newThing)
- defAttr.allThings.append(newThing)
- parent(toParentT, newThingsGrp)
- select(cl=1)
- setAttr(defAttr.boid.visibility, 0 )
- if defAttr.progress:
- progressWindow(progWin2, endProgress=1)
- doGrow(newThings)
- newCrvs = []
- toFilter = []
- for thing in newThings:
- add = str(thing.thingObj+"_rotateX "),str(thing.thingObj+"_rotateY "),str(thing.thingObj+"_rotateZ ")
- toFilter.append(add)
- if defAttr.trail:
- c = curve(p =thing.toCrv, d = 3)
- newCrvs.append(c)
- filterCurve(toFilter, e = defAttr.tEnd, s = defAttr.tStart)
- parent(newCrvs, "ThingGrp")
- if defAttr.progress:
- progressWindow(progWin2, edit=True, pr = 0)
- progressWindow(progWin2, endProgress=1)
- select(cl=1)
- #print "total itterations ", defAttr.allItterations
- elapsedChunk = (time.clock() - start)
- print "done, took:", elapsedChunk
Advertisement
Add Comment
Please, Sign In to add comment