2012年11月11日日曜日

ボールを落としてバウンドさせながら 坂を転がす。


C:\myprg_main\python_my_prg\ode_prg\cylinder_geom_korokoro3.py

# coding: UTF-8
# 平面をy=4で固定して作成後 z軸で-10度回転
# ボールを落としてバウンドさせながら
# その坂を転がす。
# 以下坂の回転コマンド rotationMoj.pyを使用
# self.geom.setRotation(rotationMoj.metaRotater(0.0, 0.0, -10.0))


import random
import ode
from visual import *
import rotationMoj

boxList  = []
ballList = []
jointList= []
box_kosuu=1
ball_kosuu=5

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()
    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()
        print
        time.sleep(0.4)
        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))#z軸で回転
        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,4,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))

if __name__=='__main__':
    field = Field()
    metaball = MetaBall(field)
    metabox = MetaBox(field)

    while True:
        field.tick()




C:\myprg_main\python_my_prg\ode_prg\rotationMoj_test.py
# coding: UTF-8
# setRotation.pyのモジュール をテストする
# update関数はつかわず ただたんにbodyを回転させてみる

import ode
from visual import *
from math import *
import rotationMoj

boxList  = []
ballList = []
cylList  = []
box_kosuu=5
ball_kosuu=5

class Field:
    scene = display(autoscale=0, forward=norm((-2.0,-1.0,-1.0)))
   
    #物理世界を作成
    world=ode.World()
    world.setGravity((0, -9.81, 0))
    #world.setGravity((0, 0, 0))

    #地平面を作成?
    space=ode.Space()
    ode_floor=ode.GeomPlane(space,(0,1,0),0)
    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))

    #衝突関係
    jointgroup=ode.JointGroup()
    vball_x=sphere( pos=(0, 0, 0), radius=0.2, color=color.cyan)  #原点
    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=30
    #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)
            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()
        boxList[0].update()
        #cylList[0].update()
        print "tick"
        time.sleep(0.5)
        self.space.collide((),self.near_callback)
        self.world.step(self.dt)
        self.jointgroup.empty()
        return True

class Box:
    def __init__(
            self, field,
            m_density=1.01,
            #m_density=0.01,
            v_x=7, v_y=1, v_z=3,
            b_pos=vector(0,5,0),
            v_color=color.cyan
            ):
        #デフォルトで...(vpthonのパラメータだけですます)
        self.m_x = v_x
        self.m_y = v_y
        self.m_z = v_z
        self.g_x = v_x
        self.g_y = v_y
        self.g_z = v_z

        self.body=ode.Body(field.world)
        M=ode.Mass()
        M.setBox(m_density, self.m_z, self.m_y, self.m_x)#密度,z,y,x w,h,l
        self.body.setMass(M)
        self.body.setPosition(b_pos)
        self.geom = ode.GeomBox(
                space=field.space, lengths=(self.g_z, self.g_y, self.g_x)#w,h,l
                )
        self.geom.setCategoryBits(1)
        self.geom.setCollideBits(7)
        #ボール同士の衝突を避ける
        self.geom.setBody(self.body)

        #self.geom.setRotation([0.866,0,0.5, 0,1,0, -0.5,0,0.866])#y軸30°回転
        #self.geom.setRotation([1,0,0, 0,0.866,-0.5, 0,0.5,0.866]) #x軸30°回転
        #self.geom.setRotation([0.866,-0.5,0, 0.5,0.866,0, 0,0,1]) #z軸30°回転
        #self.geom.setRotation(kaiten_gyouretu(30.0, 0.0, 30.0)) #z軸30°回転
        #kaiten_gyouretu(30.0, 0.0, 0.0)
        #metaRotater(30.0, 0.0, 0.0)
        self.geom.setRotation(rotationMoj.metaRotater(0.0, 0.0, 30.0)) #x z軸30°回転

        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=v_x, height=v_y, width=v_z, color=v_color)

        #mat=self.geom.getRotation()
        #self.f.axis=(10,-10,0)
        #self.f.axis=(mat[0],mat[3],mat[6])
        #self.f.up=mat[1],mat[4],mat[7]
        #self.f.axis=(1, 1, 1)
        #self.vbox.up=mat[1],mat[4],mat[7]
        #setRotationとmatの表示が微妙にずれるのでうえのコードで
        #vpytonのオブジェクトをmatで表示してからまたvpythonの
        #回転こまんどで微調整をしよう
   
        #self.geom.setRotation([0.866,0,0.5, 0,1,0, -0.5,0,0.866])
        # opacity :透明度
        #BoxのMassの大きさ,geomの大きさ,
        #   vboxの大きさを同じにする
        #print m_x,m_y,m_z

    def update(self):
        print 'box_update'
        pos = self.geom.getPosition()
        #boxのジオメトリの位置を得る
        #self.vbox.pos = pos
        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]



if __name__=='__main__':
    field = Field()
    box = Box(field)
    boxList.append(box)
   
#    while True:
#        field.tick()



0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ページ

Featured Posts