ด้วยวัตถุเพียง 30 ชิ้นเท่านั้นคุณไม่จำเป็นต้องปรับให้เหมาะสมมากนักนอกจากจะไม่ตรวจสอบสองคู่เดียวกันกับแต่ละอื่น ๆ มากกว่าหนึ่งครั้งต่อเฟรม ซึ่งตัวอย่างโค้ดด้านล่างจะครอบคลุม แต่ถ้าคุณสนใจการเพิ่มประสิทธิภาพที่แตกต่างกันซึ่งเครื่องยนต์ฟิสิกส์จะใช้แล้วอ่านต่อในส่วนที่เหลือของโพสต์นี้
สิ่งที่คุณจะต้องมีคือการใช้การแบ่งพาร์ติชันเชิงพื้นที่เช่นOctree (สำหรับเกม 3D) หรือQuadtree (สำหรับเกม 2D) แบ่งพาร์ติชันเหล่านี้โลกออกเป็นส่วนย่อยจากนั้นแต่ละส่วนย่อยจะแบ่งพาร์ติชันเพิ่มเติมในคฤหาสน์เดียวกันจนกว่าพวกเขาจะแบ่งย่อยให้มีขนาดต่ำสุด สิ่งนี้ช่วยให้คุณตรวจสอบวัตถุอื่น ๆ ที่อยู่ในภูมิภาคเดียวกันของโลกได้อย่างรวดเร็วเป็นอย่างมากซึ่งจะ จำกัด จำนวนการชนที่คุณต้องตรวจสอบ
นอกเหนือจากการแบ่งเชิงพื้นที่ฉันขอแนะนำให้สร้าง AABB ( กล่องจัดแนวแกน ) สำหรับวัตถุฟิสิกส์ของคุณ สิ่งนี้ช่วยให้คุณสามารถตรวจสอบ AABB ของวัตถุหนึ่งกับวัตถุอื่นซึ่งเร็วกว่าการตรวจสอบต่อโพลีระหว่างวัตถุอย่างละเอียดมาก
สิ่งนี้สามารถนำไปสู่ขั้นตอนต่อไปสำหรับวัตถุทางฟิสิกส์ที่มีความซับซ้อนหรือขนาดใหญ่ซึ่งคุณสามารถแบ่งการแบ่งย่อยของฟิสิกส์เองทำให้ AABB ของตัวเองย่อยแต่ละรูปร่างที่คุณสามารถตรวจสอบได้ต่อเมื่อ AABB ของวัตถุสองอันซ้อนกัน
เอ็นจิ้นฟิสิกส์ส่วนใหญ่จะปิดการใช้งานการจำลองทางฟิสิกส์แบบแอคทีฟบนร่างกายของฟิสิกส์เมื่อพวกเขาหยุดพัก เมื่อร่างกายฟิสิกส์ถูกปิดการใช้งานจะต้องตรวจสอบการชนกับ AABB ของแต่ละเฟรมเท่านั้นและหากมีสิ่งใดที่ขัดแย้งกับ AABB จากนั้นมันจะเปิดใช้งานอีกครั้งและทำการตรวจสอบการชนกันอย่างละเอียดยิ่งขึ้น สิ่งนี้จะช่วยให้เวลาในการจำลองลดลง
นอกจากนี้เอ็นจิ้นฟิสิกส์จำนวนมากยังใช้ 'จำลองเกาะ' ซึ่งเป็นที่ตั้งของกลุ่มฟิสิกส์ที่รวมตัวกันอยู่รวมกัน หากทุกสิ่งในเกาะจำลองเป็นที่พักผ่อนจากนั้นเกาะจำลองจะไม่ทำงาน ประโยชน์ของเกาะจำลองคือศพทั้งหมดในนั้นสามารถหยุดการตรวจสอบการชนได้เมื่อเกาะไม่ทำงานและสิ่งเดียวที่ตรวจสอบแต่ละเฟรมคือดูว่ามีบางสิ่งเข้าสู่ AABB ของเกาะหรือไม่ มีเพียงครั้งเดียวที่มีสิ่งใดเข้าสู่ AABB ของเกาะแต่ละศพในเกาะจะต้องตรวจสอบการชนกัน เกาะจำลองยังเปิดใช้งานหากร่างกายใด ๆ ในนั้นเริ่มเคลื่อนไหวอีกครั้งด้วยตนเอง หากร่างกายเคลื่อนที่ห่างจากศูนย์กลางของกลุ่มมากพอมันจะถูกลบออกจากเกาะ
ในที่สุดคุณก็เหลืออะไรแบบนี้ (ในรหัสหลอก):
// Go through each leaf node in the octree. This could be more efficient
// by keeping a list of leaf nodes with objects in it.
for ( node in octreeLeafNodes )
{
// We only need to check for collision if more than one object
// or island is in the bounds of this octree node.
if ( node.numAABBsInBounds > 1)
{
for ( int i = 0; i < AABBNodes.size(); ++i )
{
// Using i+1 here allows us to skip duplicate checks between AABBS
// e.g (If there are 5 bodies, and i = 0, we only check i against
// indexes 1,2,3,4. Once i = 1, we only check i against indexes
// 2,3,4)
for ( int j = i + 1; j < AABBNodes.size(); ++j )
{
if ( AABBOverlaps( AABBNodes[i], AABBNodes[j] ) )
{
// If the AABB we checked against was a simulation island
// then we now check against the nodes in the simulation island
// Once you find overlaps between two actual object AABBs
// you can now check sub-nodes with each object, if you went
// that far in optimizing physics meshes.
{
}
}
}
}
ฉันจะแนะนำไม่ให้มีลูปจำนวนมากภายในลูปเช่นนี้ตัวอย่างด้านบนเป็นเพียงเพื่อให้คุณมีความคิดฉันจะแบ่งมันออกเป็นฟังก์ชั่นหลายอย่างที่ทำให้คุณมีฟังก์ชั่นเช่นเดียวกับที่แสดงไว้
นอกจากนี้ตรวจสอบให้แน่ใจว่าไม่ได้แก้ไขคอนเทนเนอร์ AABBNode ขณะวนลูปผ่านเนื่องจากอาจหมายถึงการตรวจสอบการชนที่ไม่ได้รับ สิ่งนี้อาจฟังดูเป็นเรื่องสามัญ แต่คุณจะประหลาดใจว่าความง่ายในการตอบสนองต่อการชนทำให้เกิดการเปลี่ยนแปลงที่คุณไม่คาดคิด ตัวอย่างเช่นหากการชนกันทำให้เกิดการชนกันของวัตถุอย่างใดอย่างหนึ่งเพื่อเปลี่ยนตำแหน่งเพียงพอที่จะลบพวกเขาออกจาก AABB ของโหนด Octree ที่คุณกำลังตรวจสอบแล้วมันสามารถแก้ไขภาชนะที่ เพื่อแก้ปัญหานี้ฉันขอแนะนำให้เก็บรายการเหตุการณ์การชนกันทั้งหมดที่เกิดขึ้นระหว่างการตรวจสอบและหลังจากการตรวจสอบทั้งหมดเสร็จสิ้นแล้วให้เรียกใช้ผ่านรายการและส่งเหตุการณ์การชนกันทั้งหมด