Rapier, bộ máy vật lý 2D·3D được viết bằng Rust
(rapier.rs)- Rapier là bộ máy vật lý dựa trên Rust, nhắm đến các ứng dụng cần vật lý thời gian thực như game, hoạt hình và robot
- Hướng tới mục tiêu chạy nhanh và ổn định, đồng thời có thể hỗ trợ tính quyết định đa nền tảng theo tùy chọn khi cần
- Cung cấp các tính năng cần thiết cho mô phỏng vật lý như va chạm và lực của vật thể cứng, ràng buộc khớp nối, sự kiện tiếp xúc·cảm biến, ảnh chụp trạng thái
- Cung cấp JavaScript binding để có thể sử dụng Rapier ngoài môi trường Rust
- Đây là phần mềm mã nguồn mở miễn phí theo giấy phép Apache 2.0, do Dimforge phát triển và nhận tài trợ qua GitHub Sponsor
Các trường hợp sử dụng mà Rapier hướng đến
- Rapier là bộ máy vật lý 2D và 3D được viết bằng Rust
- Đối tượng chính là các ứng dụng cần xử lý vật lý thời gian thực
- Trò chơi điện tử
- Hoạt hình
- Robot
- Mục tiêu thiết kế là hoạt động nhanh và ổn định, đồng thời hỗ trợ tính quyết định đa nền tảng theo tùy chọn
Tính năng cung cấp và cách phát hành
- Bao gồm các tính năng chính cho mô phỏng vật lý
- Va chạm vật thể cứng và lực
- Ràng buộc khớp nối
- Sự kiện tiếp xúc và cảm biến
- Ảnh chụp trạng thái
- Tính quyết định đa nền tảng theo tùy chọn
- JavaScript binding
- Rapier là mã nguồn mở miễn phí và được phát hành theo giấy phép Apache 2.0
- Đơn vị phát triển là công ty mã nguồn mở Dimforge
- Có thể tài trợ qua GitHub Sponsor
1 bình luận
Các ý kiến trên Hacker News
Đã làm một trò chơi multiplayer online bằng chế độ quyết định luận của Rapier
Cách chơi là người chơi lần lượt cho các con bọ húc về phía đội đối phương và chiếm ngọn đồi
Hiện chưa có chế độ chơi đơn, và việc viết AI khó hơn so với các game kiểu cờ trước đây tôi từng làm
Có thể xem game tại https://evrimzone.itch.io/crittershowdown, còn mã nguồn logic vật lý/game ở https://github.com/evrimoztamur/crittershowdown/blob/e4d9a19...
Sau này tôi định viết bài về cách đã ghép mọi thứ lại với nhau và những gì đã học được; nhìn chung đây là một thư viện rất vững chắc, và nhờ thiết kế API đúng chất Rust nên tôi có thể triển khai mọi thứ mình cần
Không rõ là biên dịch sang WebAssembly, hay host toàn bộ logic trên một server local
Vài tháng trước tôi bị cuốn vào đại số hình học (Geometric Algebra), và thấy nó có vẻ là một cách ngắn gọn, trực quan đến đáng ngạc nhiên để xử lý rất nhiều loại hình học khác nhau như 2D, 3D, 4D trở lên, phi Euclid, v.v.
Vì vậy tôi tự hỏi liệu đại số hình học có thể trở thành một nền tảng tốt cho physics engine hay không
Có vài thư viện Rust trông thú vị [1][2], nhưng dường như chưa có cái nào được chú ý nhiều
Không biết có ai đã tìm hiểu hướng này chưa
[1]: https://crates.io/keywords/geometric-algebra
[2]: https://github.com/Lichtso/geometric_algebra
Nếu muốn bắt đầu, “Why can't you multiply vectors?” của Freya Holmér có thể là một điểm vào tốt: https://www.youtube.com/watch?v=htYh-Tq7ZBI và https://bivector.net/index.html
Đại số hình học đẳng cấu với đại số vector Heaviside “cổ điển”, còn những vấn đề khó nằm ở các phần như xử lý va chạm, bảo toàn năng lượng và tính ổn định
Vì vậy tôi đã tạo một thư viện có thể sinh đại số hình học tùy ý và thực hiện nhiều phép toán thú vị, cũng có thể dùng làm nền tảng cho physics engine
Nếu quan tâm thì ở đây: https://cljdoc.org/d/net.clojars.jordibc/geometric-algebra/
Tôi đã viết hướng dẫn về plugin Bevy Rapier cho Rust: https://taintedcoders.com/bevy/rapier/
Bên Bevy cũng có một lựa chọn thay thế thú vị là Bevy XPBD, tôi cũng đã tổng hợp thành bài viết: https://taintedcoders.com/bevy/xpbd/
“Sleeping” được mô tả là kỹ thuật tăng hiệu năng bằng cách giảm chi phí mô phỏng cho các vật thể không chuyển động, và có thể điều chỉnh bằng tài nguyên
SleepingThresholdVí dụ giá trị mặc định có
linear: 0.1,angular: 0.2Cho tới nay chỉ có một vấn đề là vài va chạm biến mất trong một frame, nhưng những thứ như vậy có thể dễ dàng workaround, hoặc tốt hơn là báo lỗi để được sửa
Hiện chỉ có phần xoay là chưa làm được đúng, còn lại thì cảm giác như độ phức tạp tan chảy hết
Đại số tuyến tính? Không cần. Chỉ là
Vec3thôi. Ma trận? Solver? Cứ như quay lại năm 1998, chỉ cần lặp để thỏa mãn mọi ràng buộcBiên độ dự phòng va chạm? Vấn đề kỹ năng thôi. Broad phase? GJK? Đừng nghĩ quá nhiều, cứ giao cho CPU hiện đại xử lý
Sau khi tối ưu
collect_pairsrồi nhận ra nút thắt thực sự làmallocvà sửa nó, khoảng 100 object thì xử lý ngon lành. Không cần BulletBước hiệu chỉnh vận tốc lúc đầu cũng khó hiểu, nhưng sau khi prototype bằng AABB, có vẻ cũng có thể chuyển lại sang các hình tổng quát
Ban đầu tôi bỏ qua bước này nên mọi va chạm đều hoạt động hơi giống đàn hồi
Dimforge đang làm những việc thật sự ấn tượng
Nếu nalgebra + Rust có thể thay thế Eigen + C++ trong các lĩnh vực như định vị và lập bản đồ trong robotics thì rất đáng kỳ vọng
Trong Rust có rất nhiều thứ cứ thế là chạy. Chỉ tiếc là vẫn có thế hệ cũ nhất quyết không chịu đầu tư vào Rust
Thành thật mà nói, quanh code robotics C++ có cả một ngành công nghiệp khổng lồ, nên tôi cũng hiểu lý do
Hiện tôi tò mò liệu trong Rust có framework robotics nào dùng được không
Tôi có nghe nói ROS2 đang dần đưa Rust vào [1], nhưng không rõ tiến triển ra sao
Vì phần tích hợp/trừu tượng hóa phần cứng đã được làm bằng C++, ROS có thể là cửa ngõ tốt để đi vào hợp nhất cảm biến, lập bản đồ và định vị
Tôi cũng tò mò liệu các công ty có đang dùng thứ này không
[1] https://github.com/ros2-rust/ros2_rust
Theo ký ức của tôi khi làm engine vật lý vật thể cứng vài chục năm trước, xếp chồng (stacking) là một vấn đề rất khó
Khi đó, giải pháp tốt nhất để tránh việc vật thể lún xuống sàn là tạo một đồ thị có hướng không chu trình, bắt đầu từ sàn và đẩy vật thể ra ngoài
Phải lặp lại nhiều lần mới hội tụ, và cảm giác khá hacky
Tôi tự hỏi ngày nay vấn đề này đã được giải quyết chưa. Tôi không tìm thấy đề cập nào về xếp chồng trong dự án này
Video của tác giả được liên kết ở cuối bài cho thấy từng solver xử lý nhiều bài toán xếp chồng khó như thế nào: https://youtu.be/sKHf_o_UCzI
Không cần đồ thị không chu trình; chỉ cần tăng đủ số lần lặp của solver là sẽ hội tụ
Xét đến số lượng ràng buộc tiếp xúc và ma sát, việc lặp nhiều lần là tự nhiên; nếu theo dõi phần dư tối đa thì có thể chạy cho đến khi gần như về 0
Phần hơi hỏng là va chạm và solver chỉ chạy ở tốc độ cập nhật hữu hạn
Nếu ngay từ đầu đã bắt đầu ở trạng thái xuyên vào nhau thì phải giải quyết điều đó, nhưng vật thể ngoài đời không xuyên như vậy, nên đây phần nào là xử lý “giả” và có thể tạo thêm chuyển động, làm giảm độ ổn định của chồng vật thể
Dù vậy vẫn có nhiều cách để lách vấn đề này, và các engine vật lý phổ biến đều có lời giải theo cách này hay cách khác
Rust dường như tiếp tục chứng minh định kiến
Tôi nhớ đến câu đùa rằng có 50 game engine viết bằng Rust, nhưng chỉ có 5 game viết bằng Rust
Rapier không đáp ứng chính xác nhu cầu cần thiết, mà lại không có lựa chọn thay thế tốt
Vì vậy, với các game 2D nhỏ không cần dùng nhiều code engine thì có vẻ khả thi
Game này hầu như xử lý bằng SDL
Tôi cũng từng làm một demo web nhỏ bằng Rapier: https://github.com/iErcann/NotRoblox
Tôi không dùng Rust
Điểm tôi thích là tài liệu tốt hơn AmmoJS. Với AmmoJS thì tôi phải đọc pybullet
Nó tương đối mới, và có thể chạy ở cả phía server (Node) lẫn client (trình duyệt)
Ở đây tôi chạy phía server, nhưng cũng có thể chạy ở cả hai phía và triển khai dự đoán cùng hiệu chỉnh phía client
Bundle cũng nhỏ. Tôi nhớ AmmoJS khoảng 2MB
May là nó bị neo ở phiên bản cũ nên cũng không quá tệ
Khả năng tương tác với JavaScript cũng rất tốt: https://www.rapier.rs/docs/user_guides/javascript/getting_st...
https://threlte.xyz/docs/reference/rapier/getting-started
Dimforge trước đây có một engine vật lý tên là nphysics, hỗ trợ soft body và multibody
Giờ nó đã bị loại bỏ để nhường chỗ cho Rapier, nhưng Rapier không hỗ trợ nổi một nửa những thứ đó hay các tính năng khác mà nphysics từng có
Kết quả là nphysics đã quá cũ nên khó dùng trong hệ sinh thái hiện đại, còn Rapier thì quá mới nên thiếu chức năng hơn rất nhiều
Trước đây cũng từng có chuyện tương tự. Một thư viện mô phỏng chất lưu tên Salva từng hỗ trợ ghép nối hai chiều với nphysics và chạy trên mọi GPU/CPU, nhưng nay đã bị loại bỏ để nhường chỗ cho Sparkl
Thế nhưng Sparkl không có những tính năng đó và chỉ hỗ trợ CUDA. Vì vậy Salva thì cũ kỹ như nphysics, còn Sparkl thì quá mới, ít tính năng hơn nhiều và cũng không hỗ trợ đa nền tảng
Thậm chí có vẻ như là cố ý. Kiểu như “viết lại để làm cho code này kém đa nền tảng hơn”
Hy vọng một ngày nào đó việc liên tục viết lại sẽ dừng lại, và họ sẽ ổn định ở một thứ thật sự hỗ trợ tất cả các tính năng cần thiết
Nhưng nếu mỗi lần viết lại đều mất tính năng, tôi không chắc hệ sinh thái Dimforge có phù hợp với mình không
Làm sao biết được liệu một ngày nào đó Rapier cũng sẽ bị loại bỏ để nhường chỗ cho thứ mới hơn, và engine mới đó lại không hỗ trợ nổi một nửa tính năng của Rapier
Tôi hiểu rằng vì là dự án mới nên nó không thể hỗ trợ tất cả tính năng của nphysics đã trưởng thành
Nhưng vấn đề là chính nphysics trưởng thành đó lại bị loại bỏ hoàn toàn và không được bảo trì
Nếu Dimforge chưa từng có tiền lệ như vậy thì đây sẽ là nỗi lo thiếu thực tế, nhưng họ đã có lịch sử
Có thể một ngày nào đó Rapier sẽ đạt đến mức tính năng mà nphysics đã có từ 5 năm trước, nhưng với nhà phát triển muốn xây dựng thứ gì đó trên các tính năng hiện đang thiếu, chuyện này giống như một bước thụt lùi 5 năm tùy tiện