2012年10月11日木曜日
シリンダーの geom vpytonCylinder
# coding: UTF-8
# どうやってもボールがすり抜けるやつがある
# C:\myprg_main\python_my_prg\ode_prg\cylinder_geom.py
import random
import ode
from visual import *
global Flg
Flg = True
#Flg = False
boxList = []
ballList = []
box_kosuu=5
ball_kosuu=50
class Field:
scene = display(autoscale=0, forward=norm((-2.0,-1.0,-1.0)))
#物理世界を作成
world=ode.World()
world.setGravity((0, -9.81, 0))
#自由落下させたいなら worldのコメントアウトのほうを生かし
# 最後の方の ball.body.addForce((0,-1000,0)) を殺す
#world.setGravity((0, 0, 0))
#地平面を作成?
space=ode.Space()
#衝突関係
jointgroup=ode.JointGroup()
ode_floor=ode.GeomPlane(space,(0,1,0),0.2)
#0.2の引数を与えないとなぜかシリンダーが地面に少しめり込む
#()なかの引数 上の例ではy軸方向に重力が発生
#多分 spaceの最後の引数が y軸の座標を示す
#ode_floor.setCategoryBits(1)
#ode_floor.setCollideBits(3)
ode_floor.viz=box(
pos=(0,-0.03,0),
width=20,length=20,height=0.06,color=(0.5,0.5,1.0))
vball_x=sphere( pos=(5, 0, 0), radius=0.2, color=color.red) #x軸
vball_y=sphere( pos=(0, 5, 0), radius=0.2, color=color.white)#y軸
vball_z=sphere( pos=(0, 0, 5), radius=0.2, color=color.yellow) #z軸
target_fps=50
#target_fps=30だから1秒間に30回の処理をする
dt=1.0/target_fps
def near_callback(self,args,geom1,geom2):
#isBall = ((ground == o1) || (ground == o2));
#if (isGround)//地面だけと衝突判定
print geom1
for c in ode.collide(geom1,geom2):
c.setBounce(1.0)
c.setMu(5)#摩擦
c.setMu2(5)
c.setSoftERP(0.8)
c.setSoftCFM(0)
c.setBounceVel(0)
c.setMotion1(0)
#random.seed(1)
j=ode.ContactJoint(self.world,self.jointgroup,c)
j.attach(geom1.getBody(),geom2.getBody())
def tick(self):
for i in range(ball_kosuu):
ballList[i].update()
cyld.update()
time.sleep(0.5)
self.space.collide((),self.near_callback)
self.world.step(self.dt)
self.jointgroup.empty()
return True
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.cyan
):
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(0)
#ボール同士の衝突を避ける
#上は Boxのジオメトリを作成
self.geom.setBody(self.body)
# 剛体にジオメトリをセット
self.frame = frame()
self.vball=sphere(
frame=self.frame, radius=v_radius,
color=v_color
)
def update(self):
pos_tup = self.body.getPosition()
#boxのジオメトリの位置を得る
self.frame.pos = pos_tup
mat = self.body.getRotation()
self.frame.axis = mat[0], mat[3], mat[6]
self.frame.up = mat[1], mat[4], mat[7]
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(-4,4)
pos.y=random.randint(10,10)
pos.z=random.randint(-4,4)
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:
#多分pyodeとvpythonの座標系は一緒だったな
def __init__(self, field, r, h, pos):
self.body = ode.Body(field.world)
M = ode.Mass()
M.setCylinder(1, 1, r, h)#密度,方向1はx軸の向き,半径,長さ
#方向のパラメータは役にたっていない
self.body.setMass(M)
self.body.setPosition(pos)
#とりあえずbodyのシリンダーの位置はboxのように物体の重心にあるものとして設定
#vpythonとpyodeのposが合うか?
self.geom = ode.GeomCylinder(space=field.space, radius=r, length=h)#vpythonの座標でx,y,z
self.geom.setBody(self.body)
#self.geom.setCategoryBits(1)
#self.geom.setCollideBits(1)
self.frame = frame()
#self.vbox = box(
# frame=self.frame, width= 1, height= 2, length= 5)
self.vcyld = cylinder(
frame=self.frame, pos=(0,0,-h/2),
axis=(0, 0, h), radius=r) #vpythonの座標系でx,y,zの順
#self.vbox.pos = (0, 1, 0)
#方向w:z h:y l:x
#self.visual.rotate(angle=visual.pi/2.0, axis=(0,1,0))
def update(self):
#self.body.setPosition((0, 1.5, 0))
pos_tup = self.body.getPosition()
self.frame.pos = pos_tup
#v1 = vector(pos_tup[0], pos_tup[1], pos_tup[2])
#pos_tup = tuple(v1)
#self.frame.pos = pos_tup
#self.frame.pos.x = pos_tup[0]
#self.frame.pos.y = pos_tup[1] - self.vcyld.axis.x/2
#self.frame.pos.z = pos_tup[2]
#self.vcyld.pos = pos
mat = self.body.getRotation()
#self.vbox.pos = pos
#self.frame.pos = pos
self.frame.axis = mat[0], mat[3], mat[6]
self.frame.up = mat[1], mat[4], mat[7]
if __name__=='__main__':
field = Field()
metaball = MetaBall(field)
#metabox = MetaBox(field)
cyld=Cylinder(field, 1.5, 5, (0,1.5,0))
#box.body.setPosition((0,1.5,0))
#while True:
while Flg:
field.tick()
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿