Bugün Panda 3D nin fizik kütüphanesini anlatmaya çalışacağım. Aslında Panda 3Dnin iki adet fizik kütüphanesi var, ben bunlardan ODE yi yani Open Dynamics Engine yi uygun buldum.
Kutumuz yer çekimine karşı koyamıyor
Bu yazımda diğer yazılardan farklı olarak herşeyi tek bir örnekte herşeyi açıklamaya çalışacağım. Çünkü örnek biraz uzun ve bunu bölmek yazıyı gereksiz yere uzatacaktırBu örnekte göreceğimiz şeyler;1.Fiziksel dünya ve yerçekimi2.Uzay ve otomatik çarpışma kontrolü3.Ve dolayısıya bir fizik simülasyonuBunla neler yapabiliriz;-Her türlü oyun için yerçekimini öğrenebiliriz-Özellikle araba yarışı oyunları için önemli çarpışma kurallarının temelini öğrenebiliriz-Fiziksel simülasyonlar hazırlayabilirizfrom direct.directbase import DirectStartfrom pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroupfrom pandac.PandaModules import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeomfrom pandac.PandaModules import BitMask32, CardMaker, Vec4, Quatfrom random import randint, random#gerekli kütüphanerli içeri aktarıyoruz#fiziksel dünyamızı oluşturuyoruzdunya = OdeWorld()dunya.setGravity(0, 0, -9.81)#sadece z eksenine yer çekimi verdik#bu tablo “autoCollide” için gerekli. yani otomatik çarpışma konrolcüsüdunya.initSurfaceTable(1)dunya.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002)#bir uzay oluşturuyoruz,fiziksel cisimleri bunun içine koyacağızuzay = OdeSimpleSpace()uzay.setAutoCollideWorld(dunya) #dünyamızın çarpışma kontrolünü uzaya veriyoruzgrup = OdeJointGroup()#bir grup kuruyoruz, ki fiziksel cisimler bu grup üzerinden birbiriyle etkileşime girsinleruzay.setAutoCollideJointGroup(grup)#grubumuzu uzaya teslim ettikkutumodel = loader.loadModel(“box”)#kutu modelimizi içeri aktarıyoruz#bu model Panda3D nin beraberinde gelen modellerden biri,#kutunun kenralarıın hepsi 1 birimkutumodel.setPos(-.5, -.5, -.5)#kutumuzun orta noktasını geometrik olarak orta noktası seçiyoruz;#çünkü modelin orta noktası kutunun köşelerinde bir yerde#eğer modelinizi çizerken orta noktasını tam x-y-z eksenininin#ortasına getirirseniz buna gerek kalmazkutumodel.reparentTo(render)#kutumuzu render a aktardıkkutumodel.setPos(randint(-10, 10), randint(-10, 10), 10 + random())#kutumuza rasgele bir pozisyon ayarladıkkutumodel.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))#ve buradada kutumuza rasgele bir açı ayarladıkkutufizik = OdeBody(dunya)#yeni bir fiziksel obje oluşturdukM = OdeMass()#bir ağırlık oluşturuyoruzM.setBox(50, 1, 1, 1)#ağırlığımız;#bir kutu(setBox bir kutu oluşturur)#ilk argüment yoğunluğu#diğer argümenler x,y,z eksenlerindeki uzunluğu,#bizim kutumuzda 1,1,1 olduğu için 1,1,1 yaptıkkutufizik.setMass(M)#fiziksel objeye ağırlığını veriyoruzkutufizik.setPosition(kutumodel.getPos(render))kutufizik.setQuaternion(kutumodel.getQuat(render))#fiziksel objenin bir görüntüsü yok, oyüzden onu kutu modelimizle birleştiriyoruz;#bunu yapmak içinde açısını ve pozisyonunu aynen fiziksel objemize geçiriyoruz#şimdi burada kutu modelimize birde kutu geometrisi ekleyeceğiz. nedenmi?#çünkü biz cismimizin yerçekimine uymasını ve bir “plane” üzerine düşmesini istiyoruz.#”plane” fiziksel bir obje değil, çünkü yerçekimiyle bir alakası yok,#bizde kutu modelimizi farklı bir yoldan “plane” nin içinden geçmemesi için ayarlıyoruzkutugeo = OdeBoxGeom(uzay, 1, 1, 1)kutugeo.setCollideBits(BitMask32(0x00000002))kutugeo.setCategoryBits(BitMask32(0x00000001))kutugeo.setBody(kutufizik)#şimdi ise geldi “plane” yada yeryüzünü oluşturmayacm = CardMaker(“ground”)cm.setFrame(-20, 20, -20, 20)ground = render.attachNewNode(cm.generate())ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)#pozisyon ayarlagroundGeom = OdePlaneGeom(uzay, Vec4(0, 0, 1, 0))groundGeom.setCollideBits(BitMask32(0x00000001))groundGeom.setCategoryBits(BitMask32(0x00000002))base.disableMouse()base.camera.setPos(40, 40, 20)base.camera.lookAt(0, 0, 0)#kameramızı sabitledik ve fareyi devre dışı bıraktık#fizik simülasyonu döngümüzdef simulasyon(task):uzay.autoCollide()dunya.quickStep(globalClock.getDt())#cisimlerin bir sonraki pozisyonlarını ayarlakutumodel.setPosQuat(render, kutufizik.getPosition(), Quat(kutufizik.getQuaternion()))#kutu modelimizi yeni pozisyonuna göre konumlandırgrup.empty() #grubu temizlereturn task.cont #döngüyü başa al# döngümüzü burda başlatıyoruztaskMgr.doMethodLater(0.5, simulasyon, “Simulasyon”)run()