Thursday, July 9, 2009

##### Bacteria War _ crowd systems
#### started 20:21 08.07.09


### import all possibly needed


### Super Plan
###Passive agents:
## BODY (obstacles__rigid body)
## BRAIN (finish area__rigid body)
##Active agents:
## BACTERIUM (agent type1)
## DRUG (agent type2)


#####################################TRANSLATING into script
####create "BODY" and Agent 3d(small - Bacterium, big - Drug)
#### have them on stage
### rename 3d objects
### run script

import maya.cmds as cmds
import maya.mel as mel
import random
import math

def hit(hit, agent):
### define what to do when it some collision is detected
#if it hit the body, ignore
if hit == "wall_rigid":
return
agentRole = cmds.getAttr(agent + ".role")
hitRole = cmds.getAttr(hit + ".role")
if hitRole == agentRole:
#check if both are Drugs
if hitRole == "Drug":
#then rotate
cmds.rotate(90,90,0)
else:
#if Bacteria, delete Bacteria
cmds.delete('agent')
elif hitRole != agentRole:
if hitRole == "Drug":
#means agent role is Bacteria
cmds.duplicate('agent')
cmds.move(0,0,0)
elif hitRole == "Bacteria":
#means agent was Drug
cmds.delete('agent')




class Agent:
def __init__(self, solver, role, position=(0,0,0), size=(3,3,3), color=(0,0,0), objType="agent", rigidType="active", bounciness=.6, collide=1):
#set agent atributes
self.bounciness = bounciness
self.collide = collide
self.rigidType = rigidType
self.solver=solver
self.role = role
self.initialScale = size
#create the agent and scale it
NameDubObj1 = []
myDubObj1 = cmds.duplicate( 'agent' )# creation ( dublication) of the elements (bacteria/drug)
self.object = myDubObj1
cmds.scale(size[0], size[1], size[2])

#create the rigid body
self.rigid = cmds.rigidBody(self.object,
name=self.object[0] + "_rigid",
p=position,
b=self.bounciness,
impulse=(0,0,0),
sio=objType, #stand in object
cc = 1, #contact count
cp = 1, #contact position
cn = 1, #contact name
solver=self.solver)

#add attribute to the rigid body to store the type of agent
cmds.select(self.rigid, r=1)
cmds.addAttr(ln="role", dt="string", keyable=1)
cmds.setAttr(self.rigid + ".role", "Bacteria", type="string")

if self.rigidType == "active":
cmds.setAttr(self.rigid + ".active", 1)
else:
cmds.setAttr(self.rigid + ".active", 0)

#apply the expression
self.applyExpression()

def applyExpression(self):
"Function to apply the expression to the agent"
#first disconnect the rotation attributes because we want to controll it via expressions
cmds.disconnectAttr (self.rigid + "ry.output", self.object[0] + ".rotateY")
cmds.disconnectAttr (self.rigid + "rx.output", self.object[0] + ".rotateX")
cmds.disconnectAttr (self.rigid + "rz.output", self.object[0] + ".rotateZ")
# Create expression for VehicleF with a random multiplier added to the expression.
randX = random.uniform(-1,1)
randY = random.uniform(1,-1)

#the first lines define how the agent will wander
expString = "// Set wander motion of vehicle and add random multipliers.\n"
expString += "%s.impulseX" % self.rigid
expString += " = sin(time * %f);\n" % randX
expString += "%s.impulseY" % self.rigid
expString += " = (noise(time) * %f);\n\n" % randY
#the second part, how it rotates according to the direction it is going (velocity vector)
expString += "// Set orientation of Vehicle according to the velocity direction.\n"
expString += "float $fVel[];\n"
expString += "$fVel = `getAttr %s.velocity`;\n\n" % (self.rigid)
expString += "%s.rotateX = 0;\n" % self.object[0]
expString += "%s.rotateZ = atan2d( $fVel[0], $fVel[1] );\n" % (self.object[0])
expString += "%s.rotateY = 0;\n\n" % self.object[0]
#the third part, checking bumps on other agents
expString += "//checking bumps on other agents\n"
expString += "string $lastHit;\n"
expString += "if (%s.contactCount > 0){\n" % self.rigid
expString += " int $contactCount = `getAttr %s.contactCount`;\n" % self.rigid
expString += " $lastHit = `getAttr %s.contactName[0]`;\n" %self.rigid
expString += ' string $rigid = "%s";\n' % self.rigid
expString += ' python("hit(\'"+$lastHit+"\', \'"+ $rigid +"\')");\n'
expString += "};//endif\n"

self.expString = expString
cmds.expression(s=expString)


##############################################
class Crowd:
def __init__(self, numAgents=4, minPosition=-20, maxPosition=20, walls=0):
#set the playback options to increase the time range
cmds.playbackOptions(min= 1, max=5000)
self.numAgents = numAgents
self.minPosition = minPosition
self.maxPosition = maxPosition
#get any selected objects
self.wallObjs = cmds.ls(sl=1)
#create the rigid solver
self.solver = self.createSolver()
#create the agents
self.createAgents()
#create the walls
if walls: self.makeWalls()

def createSolver(self):
solver = cmds.rigidSolver( create=1,
current=1,
name="crowdSolver",
velocityVectorScale=0.5,
displayVelocity=1,
sc=1, #showcollision
ctd=1 #contact data
)
cmds.setAttr(solver + ".allowDisconnection", 1)
return solver

def createAgents(self):
type1 = ["Bacteria", (1,1,1), (1,1,0)] #name, scale, color
type2 = ["Drug", (5,5,5), (.6,.6,.6)]
types = [type1, type2]
self.DrugAgents = []
self.BacteriaAgents = []
for i in range(self.numAgents):
#get the agent type randomly
at = random.choice(types)
#get random x and y
x = random.uniform(self.minPosition,self.maxPosition)
y = random.uniform(self.minPosition,self.maxPosition)
#create the agents
a = Agent(self.solver, at[0], color=at[2], size=at[1], position=(x,y,0))
if at[0] == "Bacteria":
self.BacteriaAgents.append(a)
else:
self.DrugAgents.append(a)

def makeWalls(self):
#get selected object,
#which should be already with its normals facing to the right directions,
#and convert it to passive rigid bodies
if len(self.wallObjs) == 0:
return "No wall objects were selected."
else:
for w in self.wallObjs:
self.wallRigid = cmds.rigidBody(w, passive=1, name= "wall_rigid", bounciness=.8)

########################################
c=Crowd(numAgents=4, walls=1)

3 comments:

  1. HI Daniel!
    I have some problems with the script:
    elements when collisions are detected - do not do what they are supposed to do (duplicate or delete)
    and have no idea what to do with the brain area yet...

    ReplyDelete
  2. Daniel, tomorrow I am going home (Russia), and it will take me 3 days to get there, so It will be impossible to finish my script(. I hope that stage of scripting will be enough to pass our Elective.
    Wish U all the best.
    Hope to see You next semester)

    ReplyDelete
  3. ok, I am checking it out.
    have a nice break...

    ReplyDelete