เทคนิคการตรวจจับการชนของเครื่องยนต์ฟิสิกส์อย่างต่อเนื่อง


10

ฉันกำลังทำงานกับเอนจินฟิสิกส์แบบต่อเนื่องล้วนๆและฉันต้องเลือกอัลกอริทึมสำหรับการตรวจจับการชนกันของเฟสกว้างและแคบ "ต่อเนื่องอย่างหมดจด" หมายถึงฉันไม่เคยทำการทดสอบทางแยก แต่ต้องการหาวิธีที่จะจับการชนกันทุกครั้งก่อนที่มันจะเกิดขึ้นและวางลงในสแต็ก "การชนกันตามแผน" ที่จัดทำโดย TOI

ช่วงกว้าง วิธีเดียวในช่วงกว้างอย่างต่อเนื่องที่ฉันสามารถนึกได้คือการห่อหุ้มร่างกายแต่ละดวงในวงกลมและทดสอบว่าแต่ละวงกลมจะทับซ้อนกันหรือไม่ อย่างไรก็ตามเรื่องนี้ดูเหมือนว่าจะไม่มีประสิทธิภาพอย่างน่ากลัวและขาดการคัดเลือกใด ๆ

ฉันไม่มีความคิดว่า analogs แบบต่อเนื่องอาจมีอยู่สำหรับวิธีการคัดแยกการชนกันของวันนี้เช่นต้นไม้สี่ต้นอย่างใดอย่างหนึ่ง ฉันจะป้องกันการทดสอบในวงกว้างที่ไม่เหมาะสมและไม่มีจุดหมายได้อย่างไรเช่นเครื่องยนต์ไม่ต่อเนื่องทำอย่างไร ฉันต้องการเห็นการชนกันมากกว่า 1 เฟรมก่อนหน้า

Narrow Phase
ฉันพยายามปรับ SAT แคบ ๆ ให้เป็นการตรวจสอบอย่างต่อเนื่องมากกว่าที่จะแยก แต่ฉันแน่ใจว่ามีอัลกอริธึมอื่นที่ดีกว่าในเอกสารหรือเว็บไซต์ที่คุณอาจเจอ
คุณแนะนำให้ฉันใช้อัลกอริทึมแบบเร็วและแม่นยำแบบใดและข้อได้เปรียบ / ข้อเสียของแต่ละข้อคืออะไร?

หมายเหตุสุดท้าย:
ฉันพูดถึงเทคนิคและไม่ใช่อัลกอริธึมเพราะฉันยังไม่ได้ตัดสินใจว่าฉันจะเก็บรูปหลายเหลี่ยมหลายรูปแบบได้อย่างไรซึ่งอาจเป็นเว้านูนกลมหรือมีรู ฉันวางแผนที่จะตัดสินใจบนพื้นฐานของสิ่งที่อัลกอริทึมต้องการ (เช่นถ้าฉันเลือกอัลกอริทึมที่แบ่งรูปหลายเหลี่ยมออกเป็นรูปสามเหลี่ยมหรือรูปทรงนูนฉันจะเก็บข้อมูลรูปหลายเหลี่ยมในรูปแบบนี้)


ผมขอแนะนำให้คุณตรวจสอบหนังสือเหล่านี้ amazon.com/Real-Time-Collision-Detection-Interactive-Technology/... amazon.com/...
concept3d

ฉันขอโทษที่จะเพิ่ม แต่ทำไมไม่ใช้ Box2D มันได้รับการแจ้งความถึงเกือบทุกภาษา หากคุณไม่ได้วางแผนที่จะใช้ทำไมไม่ลองดูที่มาของมันเพื่อที่คุณจะได้เห็นว่ามันจัดการการคอรัปชั่นได้อย่างไร
ดีเร็ก

คำตอบ:


2

ฉันแค่โยนความคิดรอบ ๆ ที่นี่ สมมติว่าคุณมีcurrentตำแหน่งและnextตำแหน่ง(อย่างน้อยที่สุด) สำหรับแต่ละเฟรม

คุณจะต้องแยกเป็นสองเฟสกว้าง ๆ ตามด้วยช่วงแคบ ๆ ของคุณ:

  • หนึ่งที่คิดออกว่าจะเกิดการชนกัน
  • หนึ่งในตัวเลขที่ประมาณการชนที่เกิดขึ้นจริง (เช่นระยะกว้าง / SAT ไม่ถูกต้อง)
  • ในที่สุดระยะแคบของคุณจะปรับปรุงผลลัพธ์ของระยะกว้างสอง

ช่วงกว้างเริ่มต้น

คุณสามารถตรวจสอบพื้นที่ hashing (ใช้nextตำแหน่งไม่current) สำหรับระยะกว้างเริ่มต้น นี่จะแบ่งพื้นที่ปัญหาของคุณออกเป็นกลุ่มผู้สมัครการชน

ช่วงกว้างที่สอง

ทำหลายตัวอย่างไบนารีโดยใช้วิธีการตัดวงกลมที่คุณอธิบาย ในคำอื่น ๆ :

left = current
right = next
midpoint = (left + right) / 2
loop a desired amount of times tweaked to the accuracy you want:
  is a collision occuring at midpoint?
    right = midpoint
  else?
    left = midpoint
  midpoint = (left + right) / 2
pointOfCollision = midpoint

การปรับแต่งความแม่นยำนั้นอาจคำนึงถึงระยะทางด้วย - ฉันคิดว่าการใช้ 'ความยาวกำลังสอง' ของnext - currentจะได้รับผลพิกเซลที่สมบูรณ์แบบ

เฟสที่แคบ

ทำไบนารีหลายตัวอย่างโดยใช้บางอย่างเช่นPMask - ตรรกะจะเหมือนกันทุกประการ เพียงใช้รูทีนการชนที่แตกต่างกัน

ในที่สุด

คุณจะสามารถที่จะทำงานออกเวลาของการแยกจากpointOfCollision, currentและปัจจุบันของคุณspeedและacceleration(สมมติว่าคุณมีบูรณาการที่เหมาะสม)


ดังนั้นสำหรับการตรวจจับระยะกว้างระยะที่สองคุณแนะนำให้ฉันหาจุดกึ่งกลางของเส้นทางการเดินทางของวงกลมและทดสอบว่ามันอยู่ในวงกลมที่กำลังถูกทดสอบหรือไม่? ฉันคิดว่าฉันสามารถสร้างสมการที่ให้ระยะทางวงกลมสองวงจากกันเมื่อเวลาผ่านไปและดูว่าตลอดเวลาระยะทางเท่ากับ 0 หรือไม่
กริฟฟิน

Pmask ทำอะไรกันแน่? เว็บไซต์ไม่ได้อธิบาย = /
Griffin

@Griffin ความคิดเห็นแรกของคุณอาจใช้ได้ - ดูว่าคุณสามารถคิดออกได้ไหม โดยทั่วไปฉันกำลังทำการค้นหาแบบทวิภาคบนพื้นที่ชน ... PMask ค่อนข้างฉลาด ดู 64-int ที่ไม่ได้ลงนามเป็นตาราง 8x8 พิกเซล (เปิด / ปิด) - และ AND (ไบนารี) แบบง่ายจะกำหนดว่ามีการชนกันหรือไม่ (ไม่ใช่ศูนย์); คุณต้องทำการยกระดับบิตที่ชาญฉลาดก่อน แต่นั่นเป็นความคิด อ่านแหล่งข้อมูลเพิ่มเติม มันยากที่จะอธิบายที่นี่ (หรือมากกว่านั้นคำอธิบายของฉันจะดูด) - คุณต้องอ้างถึงแหล่งที่มา
Jonathan Dickinson

1

เอาล่ะฉันเห็นว่าคุณได้อัปเดตคำถามของคุณแล้วเพื่อให้เฉพาะเจาะจงมากขึ้น ฉันจะลองและช่วยคุณเพิ่มเติม

สำหรับการตรวจสอบในวงกว้างเฟสแรกของคุณ, ฉันจะขอแนะนำคร่ำเครียดเชิงพื้นที่

โดยพื้นฐานแล้วคุณแบ่งหน้าจอเป็นกริดขนาดเท่ากัน จากนั้นหากวัตถุอยู่ในกริดคุณสามารถเพิ่มลงใน "bucket" ในตารางแฮช 1D

นั่นคือการตรวจสอบครั้งแรกของคุณทำ หากวัตถุไม่อยู่ในที่เก็บข้อมูลเดียวกันมันจะเป็นไปไม่ได้ที่วัตถุจะตัดกัน

ต่อจากนั้นตอนนี้คุณมีรายการของถังที่มีวัตถุ (อาจ) ในพวกเขา คุณสามารถตรวจสอบระยะกว้างอื่นได้ที่นี่โดย:

A. ) การแบ่งที่ฝากข้อมูลนี้ออกเป็น 4 ที่เก็บข้อมูลอื่นและตรวจสอบตารางแฮช 1D ที่เกิดขึ้น หากไม่อยู่ในที่เก็บข้อมูลเดียวกันจะไม่มีการชนกัน

หรือ:

B. ) ทำการตรวจสอบระยะทางอย่างง่ายและรักษาความกว้างและ / หรือความสูงของวัตถุในใจเพื่อให้แน่ใจว่าถูกต้อง

แต่ถ้าคุณชนกันล่ะ

แล้วฉันจะแนะนำสิ่งที่ตามสายของนี้ มันเป็นการผสมผสานระหว่างการชนกันของรูปหลายเหลี่ยม (สำหรับรูปร่างที่ซับซ้อน) หรือสี่เหลี่ยมผืนผ้า / วงกลมสำหรับรูปร่างที่ซับซ้อนน้อยกว่า

นอกจากนี้หากคุณต้องการ "ตรวจสอบการชนก่อนที่จะเกิดขึ้นและเก็บไว้" คุณสามารถทำสิ่งนี้ได้เสมอ:

หากวัตถุสองชิ้นอยู่ในที่ฝากข้อมูลเดียวกันวัตถุเหล่านั้นอาจชนกัน

นอกจากนี้วัตถุอยู่ใกล้เพียงพอที่จะชนกันเร็ว ๆ นี้หรือไม่? (คำนึงถึงความเร็วขนาดวัตถุและระยะทาง)

หากคำตอบของทั้งคู่คือใช่ให้ไปข้างหน้าและเก็บไว้เพื่อทำการทดสอบทางแยกในภายหลัง


" คำตอบเก่า

โชคไม่ดีที่ฉันได้ติดตามคู่มือ "ประเภทการชนทั้งหมดและสิ่งที่ใช้สำหรับ" คู่มือของฉัน :)

อย่างไรก็ตามถึงแม้ว่านี่จะเป็นภารกิจที่กว้างมากแต่ฉันจะให้คุณเริ่ม

มีดี (ตอบ) คำถามเกี่ยวกับบางสิ่งบางอย่างเช่นนี้เป็นที่นี่

เช่นเดียวกับบทความโดยคนที่ทำ N และ N + มากกว่าที่นี่

ไม่ต้องพูดถึงคุณมีcollision per-pixel collision ต่อพิกเซลที่ดี

ฉันสงสัยอย่างจริงใจว่าทุกคนจะมีรายการที่เป็นประโยชน์สำหรับการปะทะกันทุกประเภท แต่สิ่งนี้จะช่วยให้คุณเริ่มต้นได้

อย่างไรก็ตามฉันควรระบุว่าประเภทของการชนที่คุณต้องการ (และจะสิ้นสุดการใช้งาน) ส่วนใหญ่ขึ้นอยู่กับประเภทของเกมที่คุณกำลังสร้าง นั่นเป็นเหตุผลที่คุณพบบทเรียน - คนส่วนใหญ่คิดว่าคุณมีความคิดในสิ่งที่คุณต้องการดังนั้นพวกเขาจึงช่วยคุณในเรื่องนั้น ฉันรู้ว่าลิงก์ส่วนใหญ่ของฉันเป็นแบบฝึกหัดในหัวข้อเฉพาะ แต่ฉันคิดว่าการสอนจะช่วยคุณได้มากขึ้น รายการเป็นสิ่งหนึ่ง แต่ถ้าคุณอ่านเกี่ยวกับแต่ละหัวข้อด้วยตัวคุณเองคุณสามารถตัดสินใจที่มีการศึกษามากขึ้นซึ่งจะเหมาะสมกับความต้องการของคุณโดยเฉพาะ


ลืมที่จะเพิ่มวิธีการที่ฉันใช้การชนกันของฉัน (ต่อพิกเซลโดยใช้การออกแบบฮัลล์) ยกโทษให้เก็บถาวรเว็บไซต์เดิมได้ไปสวรรค์ของเว็บไซต์ web.archive.org/web/20090126230334/http://www.ziggyware.com/…
electroflame
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.