Bullet教程: Hello World 實(shí)例
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括陸良網(wǎng)站建設(shè)、陸良網(wǎng)站制作、陸良網(wǎng)頁(yè)制作以及陸良網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,陸良網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到陸良省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
更多信息請(qǐng)關(guān)注 物理引擎中文社區(qū)
歡迎加qq群 52821727 討論更多關(guān)于Bullet的東西
這篇文章里我們將盡可能簡(jiǎn)單的向你展示怎么使用Bullet, 怎樣初始化Bullet, 設(shè)置一個(gè)動(dòng)力學(xué)世界, 還有一個(gè)球落向地表 這個(gè)對(duì)鑒別你的build是否成功非常有用并且也能夠讓你快速的學(xué)習(xí)到Bullet的API. 首先,我們假設(shè)你的Bullet已經(jīng)正確安裝并且正確設(shè)置了Bullet的include路徑(例如. /usr/local/include/bullet) 確保能連接到正確的lib. 否則請(qǐng)參閱Installation安裝. 如果你用的是gcc來(lái)編譯,請(qǐng)確保你的靜態(tài)庫(kù)反序,就是說(shuō). dynamics, collision, math.
初始化程序
以一個(gè)標(biāo)準(zhǔn)的hello world程序開(kāi)始:
[cpp] view plaincopy
#include iostream
int main ()
{
std::cout "Hello World!" std::endl;
return 0;
}
創(chuàng)建世界
現(xiàn)在我們要添加一個(gè)子彈(Bullet)模擬. 首先寫(xiě)入以下語(yǔ)句:
#include btBulletDynamicsCommon.h
我們想把btDiscreteDynamicsWorld 實(shí)例化但是在做此之前我們還需要解決一些其他事情. 對(duì)于一個(gè)“hello world”例子來(lái)說(shuō)它太復(fù)雜我們并不需要. 但是,為了能更符合我們自己的工程, 他們可以用來(lái)微調(diào)(fine-tuning)模擬環(huán)境.
我們需要指出使用什么樣的 Broadphase algorithm(寬相算法). 選擇什么樣的泛型算法很總要,如果有許多剛體在繪制場(chǎng)景里, since it has to somehow check every pair which when implemented naively(天真) is an O(n^2) problem.
寬相(broadphase)使用 傳統(tǒng)的近似物體形狀并且被稱之為代理.我們需要提前告訴子彈最大的代理數(shù), 所以才能很好的分配內(nèi)存避免浪費(fèi). 下面就是世界里任何時(shí)候的最大剛體數(shù).
int maxProxies = 1024;
一些 broadphases 使用特殊的結(jié)構(gòu)要求世界的尺度提前被告知, 就像我們現(xiàn)在遇到的情況一樣. 該broadphase可能開(kāi)始嚴(yán)重故障,如果離開(kāi)這個(gè)物體體積. 因?yàn)?the AxisSweep broadphase quantizes 空間基于我們使用的整個(gè)空間的大小, 您想這差不多等于你的世界.
使它小于你的世界將導(dǎo)致重大問(wèn)題, 使它大于你的世界將導(dǎo)致低劣的性能.這是你程序調(diào)整的一個(gè)簡(jiǎn)單部分, 所以為了確保數(shù)字的正確多花點(diǎn)時(shí)間也不防.
在這個(gè)例子中,世界從起點(diǎn)開(kāi)始延伸10公里遠(yuǎn)。
[cpp] view plaincopy
btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000);
這個(gè)broadphase是我們將要使用的, 這個(gè)執(zhí)行的是掃描和裁剪, 這里可以看到更多解釋Broadphase .
[cpp] view plaincopy
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
該broadphase是一個(gè)極好的空間以消除不應(yīng)碰撞的成隊(duì)物體. 這是為了提高運(yùn)行效率.
您可以使用碰撞調(diào)度注冊(cè)一個(gè)回調(diào),過(guò)濾器重置broadphase代理,使碰撞系統(tǒng)不處理系統(tǒng)的其它無(wú)用部分
. 更多信息請(qǐng)看 Collision Things.
碰撞配置可以讓你微調(diào)算法用于全部(而不是不是broadphase )碰撞檢測(cè)。這個(gè)方面現(xiàn)在還屬于研究階段
[cpp] view plaincopy
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
我們還需要一個(gè)"solver". 這是什么原因?qū)е挛矬w進(jìn)行互動(dòng)得當(dāng),考慮到重力,游戲邏輯等的影響,碰撞,會(huì)被制約。
它工作的很好,只要你不把它推向極端,對(duì)于在任何高性能仿真都有瓶頸有一些相似的可以線程模型:
[cpp] view plaincopy
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
終于我們可以初始化了世界了:
[cpp] view plaincopy
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
很明顯我們把重力方向設(shè)置成了Y軸的負(fù)方向,即Y軸是像上的
[cpp] view plaincopy
dynamicsWorld-setGravity(btVector3(0,-10,0));
子彈的政策是“誰(shuí)分配,也刪除” 記住,必須符合這樣的結(jié)果
在main()后記的刪除.
我們提供了一個(gè)通用的結(jié)果. 代碼如下:
[cpp] view plaincopy
#include btBulletDynamicsCommon.h
#include iostream
int main () {
std::cout "Hello World!" std::endl;
// Build the broadphase
int maxProxies = 1024;
btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000);
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
// 設(shè)置好碰撞屬性 和調(diào)度
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
// 實(shí)際上的物理模擬器
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
// 世界.
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
// 這里做一些你想做的事
// 作為一個(gè)好的編程習(xí)慣 做好刪除工作
delete dynamicsWorld;
delete solver;
delete dispatcher;
delete collisionConfiguration;
delete broadphase;
return 0;
}
碰撞包圍體
我們將創(chuàng)造一個(gè)接地平面[靜態(tài)剛體] ,和一個(gè)球體,將屬于在地上[動(dòng)態(tài)剛體] 。每個(gè)剛體需要參考碰撞包圍體. 碰撞包圍體只解決碰撞檢測(cè)問(wèn)題, 因此沒(méi)有質(zhì)量,慣性,恢復(fù)原狀等概念. 如果您有許多代理,使用相同的碰撞形狀[例如每飛船模擬是一個(gè)5單元半徑范圍]。這是個(gè)好做法,只有一個(gè)子彈形狀的碰撞,并分享它在所有這些代理. 但是我們這里的兩個(gè)剛體形狀都不一樣,所以他們需要各自的shape.
地面通常是向上的并且里原始點(diǎn)1米的樣子. 地面會(huì)和遠(yuǎn)點(diǎn)交叉,但子彈不允許這樣做,
因此,我們將抵消它的1米和用來(lái)彌補(bǔ),當(dāng)我們把剛體設(shè)置好以后。
[cpp] view plaincopy
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);
我們將讓它從天上掉下來(lái),它是一個(gè)球體,半徑為1米.
[cpp] view plaincopy
btCollisionShape* fallShape = new btSphereShape(1);
這里需要做碰撞形狀的清理工作.
剛體
在,我們可以添加形狀的碰撞到我們的現(xiàn)場(chǎng),并將它們定位.
讓我們先初始化地面. 它的方向是特定的, 子彈的四元數(shù)形式 x,y,z,w . 位置在地面下一米, 將要補(bǔ)充一米我們不得不做的. 運(yùn)動(dòng)狀態(tài)在這里可以得到詳細(xì)的說(shuō)明:MotionStates
[cpp] view plaincopy
btDefaultMotionState* groundMotionState =
new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
在第一個(gè)和最后一個(gè)參數(shù),在下面的構(gòu)造函數(shù)中是質(zhì)量和地表的慣性. 由于地面是靜止的所以我們把它設(shè)置成0. 固定不動(dòng)的物體,質(zhì)量為0 -他是固定的.
[cpp] view plaincopy
btRigidBody::btRigidBodyConstructionInfo
groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
最后我們把地面加到世界中:
[cpp] view plaincopy
dynamicsWorld-addRigidBody(groundRigidBody);
新增下跌領(lǐng)域非常相似。我們將其置于50米以上的地面.
[cpp] view plaincopy
btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
由于它是動(dòng)態(tài)剛體,我們將給予質(zhì)量1公斤。我不記得如何計(jì)算一個(gè)球體的慣性,但是,這并不重要,因?yàn)樽訌椞峁┧膶?shí)現(xiàn)
[cpp] view plaincopy
btScalar mass = 1;
btVector3 fallInertia(0,0,0);
fallShape-calculateLocalInertia(mass,fallInertia);
現(xiàn)在,我們可以建造剛體只是像以前一樣,并把它加到世界中:
[cpp] view plaincopy
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld-addRigidBody(fallRigidBody);
一個(gè)快速的解釋btRigidBody::btRigidBodyConstructionInfo是為了; 物體的構(gòu)建是通過(guò)某些參數(shù)的. 這是通過(guò)一個(gè)特殊的結(jié)構(gòu)實(shí)現(xiàn)的。 該部分的btRigidBodyConstructionInfo被復(fù)制到物體當(dāng)你建造的時(shí)候,并只用于在初始化的時(shí)候. 如果你想創(chuàng)建幾千個(gè)屬性一樣的物體, 你只需要建立一個(gè)btRigidBodyConstructionInfo, 并通過(guò)它創(chuàng)建所有的.
開(kāi)始模擬
這就是有趣的開(kāi)始。我們會(huì)加強(qiáng)模擬200倍,間隔60赫茲. 這使它有足夠的時(shí)間降落的地面上. 每一步, 我們都會(huì)打印出它離地面的高度.
這stepSimulation 在做你所期待, 不過(guò)他的接口確實(shí)很復(fù)雜. 讀Stepping The World 以獲得更多消息.
進(jìn)后,我們審查的狀態(tài)下降領(lǐng)域.位置和方向都封裝在btTranform對(duì)象,我們摘錄下降領(lǐng)域的運(yùn)動(dòng)狀態(tài). 我們只關(guān)心位置,我們退出變換getOrigin ( ) 。然后,我們打印y組成部分的立場(chǎng)載體.
[cpp] view plaincopy
for (int i=0 ; i300 ; i++) {
dynamicsWorld-stepSimulation(1/60.f,10);
btTransform trans;
fallRigidBody-getMotionState()-getWorldTransform(trans);
std::cout "sphere height: " trans.getOrigin().getY() std::endl;
}
這應(yīng)該產(chǎn)生一個(gè)輸出看起來(lái)像這樣的東西:
sphere height: 49.9917
sphere height: 49.9833
sphere height: 49.9722
sphere height: 49.9583
sphere height: 49.9417
sphere height: 49.9222
sphere height: 49.9
...
sphere height: 1
sphere height: 1
sphere height: 1
sphere height: 1
sphere height: 1
看起來(lái)不錯(cuò)迄今。如果你圖這對(duì)輸出迭代次數(shù),你就會(huì)得到這個(gè):
這個(gè)球體開(kāi)始于地表的一米處. 這是因?yàn)槿〉氖菐缀沃行牟⑶宜陌霃綖?米. 這個(gè)球剛開(kāi)始會(huì)有一個(gè)大的反彈然后漸漸的減緩彈起高度.
這是可以預(yù)料的實(shí)時(shí)物理引擎,但它可以盡量減少,增加頻率的模擬步驟
. 試試再說(shuō)!
現(xiàn)在你可以把這個(gè)動(dòng)態(tài)世界代入你的程序 實(shí)時(shí)繪制出這個(gè)球體. 也可以看看其他的 Collision Shapes . 試試一堆盒子 或者圓柱體然后用一個(gè)球去扔向他們.
完整代碼
[cpp] view plaincopy
#include iostream
#include btBulletDynamicsCommon.h
int main (void)
{
btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000);
int maxProxies = 1024;
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld-setGravity(btVector3(0,-10,0));
btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);
btCollisionShape* fallShape = new btSphereShape(1);
btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
btRigidBody::btRigidBodyConstructionInfo
groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld-addRigidBody(groundRigidBody);
btDefaultMotionState* fallMotionState =
new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
btScalar mass = 1;
btVector3 fallInertia(0,0,0);
fallShape-calculateLocalInertia(mass,fallInertia);
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld-addRigidBody(fallRigidBody);
for (int i=0 ; i300 ; i++) {
dynamicsWorld-stepSimulation(1/60.f,10);
btTransform trans;
fallRigidBody-getMotionState()-getWorldTransform(trans);
std::cout "sphere height: " trans.getOrigin().getY() std::endl;
}
dynamicsWorld-removeRigidBody(fallRigidBody);
delete fallRigidBody-getMotionState();
delete fallRigidBody;
dynamicsWorld-removeRigidBody(groundRigidBody);
delete groundRigidBody-getMotionState();
delete groundRigidBody;
delete fallShape;
delete groundShape;
delete dynamicsWorld;
delete solver;
delete collisionConfiguration;
delete dispatcher;
delete broadphase;
return 0;
}
路虎車上出來(lái)adaptivedynamicsfault的意思是:自適應(yīng)動(dòng)態(tài)故障
固定搭配:
1、adaptivefilter?自適應(yīng)濾波器
2、adaptivesystem?[計(jì)]自適應(yīng)系統(tǒng)
3、adaptivecapacity?適應(yīng)能力,適應(yīng)潛能
4、adaptivecontrolsystem?自適應(yīng)控制系統(tǒng);適應(yīng)式控制系統(tǒng)
adaptive讀法英[??d?pt?v]??美[??d?pt?v]
adj.適應(yīng)的;有適應(yīng)能力的
擴(kuò)展資料
adaptive的同根詞:adapt
詞語(yǔ)用法:
1、adapt的基本意思是通過(guò)必要的改動(dòng)以適應(yīng)新的條件或適于某事物。用作及物動(dòng)詞時(shí)意思是“使適應(yīng),使適合”,接sb/sth作賓語(yǔ),“適應(yīng)”的客體??捎媒樵~to引出。
2、adapt常接oneself作賓語(yǔ),意思是“使自己適應(yīng)?”,oneself有時(shí)略去不用,這時(shí)adapt則用作不及物動(dòng)詞。
3、adapt還可特指“改編”“改寫(xiě)”,這時(shí)其客體須由介詞for或from引出。adapt??捎糜谙当斫Y(jié)構(gòu),意為“是適應(yīng)?的”或“是改編的”。
詞義辨析:
adapt,accommodate,adjust這三者的共同意思是“使適合,使適應(yīng)”。
accommodate用于使之相適應(yīng)的兩事物之間懸殊極大的事物,帶有一方暫時(shí)必須屈從另一方的意味;adapt用于使之適應(yīng)的兩事物之間差別較小的事物,將某一方稍加改變便可適應(yīng)于另一方,帶有一定的靈活性和適應(yīng)性;adjust則著重于結(jié)果,即達(dá)到盡可能的符合或和諧。
Dynamics CRM用戶并不少,因?yàn)槭菢I(yè)務(wù)系統(tǒng)外人不得而知罷了。雖然dynamics 365在全球排名老二,但相對(duì)于排名第一的salesforce來(lái)說(shuō),Saas授權(quán)費(fèi)用要更便宜,而且還有本地部署的選項(xiàng),就是買斷的(這個(gè)費(fèi)用好像比saas還便宜,也可以實(shí)現(xiàn)云端體驗(yàn)),而且和office結(jié)合更緊密,畢竟都是他們自己家的產(chǎn)品啊。從功能上來(lái)說(shuō),它和salesforce之間的差距有多大呢?應(yīng)該是黃山和喜馬拉雅山的高度之差吧??赡苡腥瞬幻靼?,這個(gè)差距是很懸殊,還是很接近?我用這個(gè)比喻的意思是,如果你不是職業(yè)登山家,對(duì)你來(lái)說(shuō),都非常之高。如果你是耐克,星巴克,空中客車,你會(huì)在這兩者間有所傾向(但未必都會(huì)選第一,比如星巴克就選了Dynamics),如果你是一家中國(guó)民營(yíng)企業(yè)500強(qiáng),多數(shù)還是希望本地部署吧(在自己機(jī)房或者在阿里云上)。發(fā)展前景應(yīng)該非常不錯(cuò),它主要市場(chǎng)是歐美,今年剛剛落地中國(guó),非常確定的說(shuō),在國(guó)內(nèi)它沒(méi)有對(duì)手,各行各業(yè)都需要客戶管理啊,項(xiàng)目管理啊,銷售管理啊,現(xiàn)場(chǎng)服務(wù)啊,渠道管理啊,等等。很多人一開(kāi)始在乙方,就是微軟合作伙伴那里做,起薪6-8,做個(gè)幾年就能到12-15.如果給大客戶做大項(xiàng)目,很大可能就留在甲方了(20-25k). 產(chǎn)品詳細(xì)介紹看它的官網(wǎng):
其實(shí)單單財(cái)務(wù)沒(méi)有區(qū)別,最多在成本核算方面的差異,現(xiàn)在SAP做的比較專。