2012年11月12日月曜日
坂をシリンダーを転がす
# coding: UTF-8
# 平面をy=4で固定して作成後 z軸で-10度回転
# ボールを落としてバウンドさせながら
# その坂を転がす。
# 以下坂の回転コマンド rotationMoj.pyを使用
# self.geom.setRotation(rotationMoj.metaRotater(0.0, 0.0, -10.0))
#今度はcylinderを落としてみる
# yodeのposの設定をそのままvpythonのposにするとだめ
# x座標とz座標をいれかえる
# http://blogs.yahoo.co.jp/hhhappyyyymoto/44369740.html
import random
import ode
from visual import *
import rotationMoj
boxList = []
ballList = []
cylList = []
jointList= []
box_kosuu= 1
ball_kosuu= 5
cyl_kosuu = 1
class Field:
#scene = display(forward=norm((-0.05,-0.07,-1.0)),
# autoscale = 0
# )
scene = display(autoscale=0, forward=norm((-1.0,-0.5,-2.0)))
#scene = display(autoscale=0, forward=norm((-2.0, 4, 0)))
world=ode.World()
space=ode.Space()
#ode_floor=ode.GeomPlane(space,(0,1,0),-10)
#ode_floor.viz=box(
# pos=(0,-4.01,0),
# width=10,length=10,height=0.02,color=(0.5,0.5,1.0))
jointgroup=ode.JointGroup()
world.setGravity((0,-9.81,0))
vball_x=sphere( pos=(5, 4, 0), radius=0.2, color=color.red) #x軸
vball_y=sphere( pos=(0, 9, 0), radius=0.2, color=color.white)#y軸
vball_z=sphere( pos=(0, 4, 5), radius=0.2, color=color.yellow) #z軸
vball_z=sphere( pos=(0, 4, 0), radius=0.2, color=color.black) #z軸
target_fps=30
#target_fps=30だから1秒間に30回の処理をする
dt=1.0/target_fps
def near_callback(self,args,geom1,geom2):
for c in ode.collide(geom1,geom2):
c.setBounce(0.9)
c.setMu(50)
c.setMu2(50)
j=ode.ContactJoint(self.world,self.jointgroup,c)
j.attach(geom1.getBody(),geom2.getBody())
def tick(self):
for i in range(box_kosuu):
boxList[i].update()
#for i in range(ball_kosuu):
# ballList[i].update()
for i in range(cyl_kosuu):
cylList[i].update()
time.sleep(0.1)
self.space.collide((),self.near_callback)
self.world.step(self.dt)
self.jointgroup.empty()
return True
class Box:
#def __init__(self):
def __init__(self,field,b_pos,m_x,m_y,m_z,b_color,w_opacity=1):
self.body=ode.Body(field.world)
M=ode.Mass()
M.setBox(1, m_x,m_y,m_z)
#上の引数の1を10000などとするとFixedJointで固定しても、ある程度動く
self.body.setMass(M)
self.body.setPosition(b_pos)#このコードいらないね
self.geom=ode.GeomBox(
space=field.space,
lengths=(m_x,m_y,m_z)
)
self.geom.setCategoryBits(1)
self.geom.setCollideBits(3)
self.geom.setBody(self.body)
self.geom.setRotation(rotationMoj.metaRotater(0.0, 0.0, -10.0))#x軸で回転
mat=self.geom.getRotation()
self.f = frame()
self.f.pos = b_pos
self.f.axis=(mat[0],mat[3],mat[6])
self.f.up=(mat[1],mat[4],mat[7])
self.vbox = box(frame=self.f,
length=m_x, height=m_y, width=m_z, color=b_color)
self.joint = ode.FixedJoint(field.world)
self.joint.attach(self.body, ode.environment)
self.joint.setFixed()
def update(self):
pos=self.geom.getPosition()
self.f.pos=pos
mat=self.geom.getRotation()
self.f.axis=(mat[0],mat[3],mat[6])
self.f.up=(mat[1],mat[4],mat[7])
print pos
class MetaBox:
def __init__(self, field):
boxList.append(Box(field,(0,3.995,0),20,0.01,20,color.cyan))
class Ball:
def __init__(
self,field,
m_density=1,
m_radius=0.3,
g_radius=0.3,
v_radius=0.3,
b_pos=vector(-4,1,0),
b_sp =vector(10,0,0),
v_color=color.blue
):
self.body=ode.Body(field.world)
M=ode.Mass()
M.setSphere(m_density, m_radius)
#(密度,半径)
self.body.setMass(M)
self.body.setPosition(b_pos)
#self.body.addForce(b_sp)
self.geom=ode.GeomSphere(
space=field.space,
radius=g_radius
)
#このradiusが実際のバウンドを決める
#多分 sphereの座標が0で radiusが0.3だから
#posが0.3ぐらいのバウンド点になる
self.geom.setCategoryBits(1)
self.geom.setCollideBits(3)
#上は Boxのジオメトリを作成
self.geom.setBody(self.body)
# 剛体にジオメトリをセット
self.vball=sphere(
radius=v_radius,
color=v_color
)
def update(self):
pos=self.geom.getPosition()
#boxのジオメトリの位置を得る
self.vball.pos=pos
#print pos,
class MetaBall:
def __init__(self, field):
posList= []
for i in range(ball_kosuu):
#posをランダムに発生
while True:
pos=vector(0,0,0)
pos.x=random.randint(-3,3)
pos.y=random.randint(5,5)
pos.z=random.randint(-3,3)
if pos not in posList:
posList.append(pos)
only_pos=pos
break
#posのx,y,zの座標を()の中の範囲でランダムに発生
#if文の中で同じposがsetPositionされないようにしている
#posがないなら posを集合型の要素として 加える
#else:
# #print '個数が多すぎる'
#print posList
#初速度をランダムに
sp=vector(0,0,0)
sp.x=random.randint(-50,50)
sp.y=random.randint(-50,50)
sp.z=random.randint(-50,50)
ballList.append(Ball(field,b_pos=only_pos,b_sp=sp))
class Cylinder:
def __init__(self, field, b_pos, r, h, v_color):
self.body = ode.Body(field.world)
M = ode.Mass()
M.setCappedCylinder(0.01, 3, r, h)#密度,方向1はx軸の向き,半径,長さ #方向のパラメータは役にたっていない
self.body.setMass(M)
self.body.setPosition(b_pos)
#self.geom = ode.GeomCylinder(space=field.space, radius=r, length=h)
self.geom = ode.GeomCapsule(space=field.space, radius=r, length=h)
self.geom.setCategoryBits(1)
self.geom.setCollideBits(3)
self.geom.setBody(self.body)
self.f = frame()
self.f.pos = b_pos
self.vobj = cylinder(
frame=self.f, pos=(0,0,-h/2),
axis=(0, 0, h), radius=r, color=v_color
)
def update(self):
pos=self.geom.getPosition()
self.f.pos=pos
mat = self.geom.getRotation()
self.f.axis = (mat[0], mat[3], mat[6])
self.f.up = (mat[1], mat[4], mat[7])
class MetaCylinder:
def __init__(self, field):
cylList.append(Cylinder(field,(0,4.3,0),0.3,2.6,color.blue))
if __name__=='__main__':
field = Field()
#metaball = MetaBall(field)
metabox = MetaBox(field)
metacyl = MetaCylinder(field)
while True:
field.tick()
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿