feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy + release v0.32.0 (#909)
* feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy * chore: update changelog * Fix warnings and tests * Release v0.32.0
This commit is contained in:
4
.cargo/config.toml
Normal file
4
.cargo/config.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[target.wasm32-unknown-unknown]
|
||||||
|
runner = "wasm-server-runner"
|
||||||
|
# Needed for getrandom/uuid: https://github.com/uuid-rs/uuid/issues/792
|
||||||
|
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
|
||||||
41
CHANGELOG.md
41
CHANGELOG.md
@@ -1,3 +1,44 @@
|
|||||||
|
## v0.31.0 (09 Jan. 2026)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- **Breaking:** Migrate math types from nalgebra to glam (via parry). The main type aliases are now:
|
||||||
|
- `Isometry<Real>` → `Pose` (glamx `Pose2/3`)
|
||||||
|
- `Point<Real>` → `Vector` for world-space positions (parry no longer distinguishes Point from Vector)
|
||||||
|
- `Rotation<Real>` → `Rotation` (glamx `Rot2` or `Quat`)
|
||||||
|
- `Translation<Real>` → removed, use `Pose::from_translation()`
|
||||||
|
- nalgebra is still used internally for SIMD code and multibody Jacobians (via `SimdVector<N>`, `SimdPose<N>`, `DVector`, `DMatrix`).
|
||||||
|
- **Breaking:** Several getters now return by value instead of by reference:
|
||||||
|
- `RigidBody::linvel()` returns `Vector` instead of `&Vector<Real>`
|
||||||
|
- `RigidBody::angvel()` returns `AngVector` instead of `&Vector<Real>` (3D) or `Real` (2D)
|
||||||
|
- `RigidBody::center_of_mass()` returns `Vector` instead of `&Point<Real>`
|
||||||
|
- `RigidBody::local_center_of_mass()` returns `Vector` instead of `&Point<Real>`
|
||||||
|
- `Collider::translation()` returns `Vector` instead of `&Vector<Real>`
|
||||||
|
- `Collider::rotation()` returns `Rotation` instead of `&Rotation<Real>`
|
||||||
|
- **Breaking:** `DebugRenderBackend::draw_line` signature changed: takes `Vector` instead of `Point<Real>` for line endpoints.
|
||||||
|
- **Breaking:** `DebugRenderBackend::draw_polyline` and `draw_line_strip` now take `&Pose` and `Vector` instead of `&Isometry<Real>` and `&Vector<Real>`.
|
||||||
|
- Testbed migrated from Bevy to kiss3d for lighter dependencies and simpler maintenance.
|
||||||
|
- Removed `benchmarks2d` and `benchmarks3d` crates (merged with `examples2d` and `examples3d`).
|
||||||
|
|
||||||
|
### Migration guide
|
||||||
|
|
||||||
|
If your codebase currently relies on `nalgebra`, note that `nalgebra` and `glamx` provide type conversion. Enable the
|
||||||
|
corresponding features:
|
||||||
|
- `nalgebra = { version = "0.34", features = [ "convert-glam030" ] }`
|
||||||
|
- `glamx = { version = "0.1", features = ["nalgebra"] }`
|
||||||
|
then you can convert between `glam` and `nalgebra` types using `.into()`.
|
||||||
|
|
||||||
|
1. **Type changes:** Replace `Isometry<Real>` with `Pose`, and `Point<Real>` with `Vector` for positions.
|
||||||
|
2. **Pose construction:**
|
||||||
|
- `Isometry::identity()` → `Pose::IDENTITY`
|
||||||
|
- `Isometry::translation(x, y, z)` → `Pose::from_translation(Vector::new(x, y, z))`
|
||||||
|
- `Isometry::rotation(axis_angle)` → `Pose::from_rotation(Rotation::from_scaled_axis(axis_angle))`
|
||||||
|
- `isometry.translation.vector` → `pose.translation`
|
||||||
|
- `isometry.rotation.scaled_axis()` → `pose.rotation.to_scaled_axis()`
|
||||||
|
3. **Getter usage:** Remove `&` or `.clone()` when using `linvel()`, `angvel()`, `center_of_mass()`, `translation()`, `rotation()` since they now return by value.
|
||||||
|
4. **Debug renderer:** Update `DebugRenderBackend` implementations to use `Vector` instead of `Point<Real>`.
|
||||||
|
5. **glam access:** The `glamx` crate is re-exported as `rapier::glamx` for direct glam type access if needed.
|
||||||
|
|
||||||
## v0.31.0 (21 Nov. 2025)
|
## v0.31.0 (21 Nov. 2025)
|
||||||
|
|
||||||
- `InteractionGroups` struct now contains `InteractionTestMode`.
|
- `InteractionGroups` struct now contains `InteractionTestMode`.
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ members = [
|
|||||||
"crates/rapier_testbed2d",
|
"crates/rapier_testbed2d",
|
||||||
"crates/rapier_testbed2d-f64",
|
"crates/rapier_testbed2d-f64",
|
||||||
"examples2d",
|
"examples2d",
|
||||||
"benchmarks2d",
|
|
||||||
"crates/rapier3d",
|
"crates/rapier3d",
|
||||||
"crates/rapier3d-f64",
|
"crates/rapier3d-f64",
|
||||||
"crates/rapier_testbed3d",
|
"crates/rapier_testbed3d",
|
||||||
"crates/rapier_testbed3d-f64",
|
"crates/rapier_testbed3d-f64",
|
||||||
"examples3d",
|
"examples3d",
|
||||||
"examples3d-f64",
|
"examples3d-f64",
|
||||||
"benchmarks3d",
|
|
||||||
"crates/rapier3d-urdf",
|
"crates/rapier3d-urdf",
|
||||||
"crates/rapier3d-meshloader",
|
"crates/rapier3d-meshloader",
|
||||||
]
|
]
|
||||||
@@ -34,6 +32,7 @@ needless_lifetimes = "allow"
|
|||||||
#nalgebra = { path = "../nalgebra" }
|
#nalgebra = { path = "../nalgebra" }
|
||||||
#simba = { path = "../simba" }
|
#simba = { path = "../simba" }
|
||||||
#wide = { path = "../wide" }
|
#wide = { path = "../wide" }
|
||||||
|
#glamx = { path = "../glamx" }
|
||||||
|
|
||||||
#kiss3d = { git = "https://github.com/sebcrozet/kiss3d" }
|
#kiss3d = { git = "https://github.com/sebcrozet/kiss3d" }
|
||||||
#nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" }
|
#nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" }
|
||||||
|
|||||||
902
Claude.md
902
Claude.md
@@ -1,902 +0,0 @@
|
|||||||
# Rapier Physics Engine - Complete Codebase Guide
|
|
||||||
|
|
||||||
## What is Rapier?
|
|
||||||
|
|
||||||
Rapier is a high-performance 2D and 3D physics engine written in Rust by Dimforge. It's designed for games, animation, and robotics applications, offering deterministic simulations, snapshot/restore capabilities, and cross-platform support (including WASM).
|
|
||||||
|
|
||||||
**License:** Apache 2.0 (free and open-source)
|
|
||||||
**Repository:** https://github.com/dimforge/rapier
|
|
||||||
**Documentation:** https://rapier.rs/docs/
|
|
||||||
**Crate:** https://crates.io/crates/rapier3d
|
|
||||||
|
|
||||||
## Key Features
|
|
||||||
|
|
||||||
- **Dual-dimensional support**: Both 2D (`rapier2d`) and 3D (`rapier3d`) with f32 and f64 precision variants
|
|
||||||
- **Deterministic simulation**: Identical results across different machines (IEEE 754-2008 compliant)
|
|
||||||
- **Snapshot & restore**: Complete physics state serialization
|
|
||||||
- **Cross-platform**: Desktop, mobile, web (WASM), consoles
|
|
||||||
- **Performance-focused**: SIMD optimizations, optional multi-threading, sleeping system
|
|
||||||
- **Flexible**: Can be used for full physics or just collision detection
|
|
||||||
|
|
||||||
## Repository Architecture
|
|
||||||
|
|
||||||
The repository uses an unusual structure to share code between 2D/3D versions:
|
|
||||||
|
|
||||||
```
|
|
||||||
rapier/
|
|
||||||
├── src/ # Shared source code (2D/3D agnostic)
|
|
||||||
├── crates/ # Concrete 2D/3D crate definitions
|
|
||||||
│ ├── rapier2d/ # 2D f32
|
|
||||||
│ ├── rapier3d/ # 3D f32
|
|
||||||
│ ├── rapier2d-f64/ # 2D f64
|
|
||||||
│ ├── rapier3d-f64/ # 3D f64
|
|
||||||
│ ├── rapier_testbed2d/ # 2D visual debugger
|
|
||||||
│ ├── rapier_testbed3d/ # 3D visual debugger
|
|
||||||
│ └── rapier3d-urdf/ # Robot model loader
|
|
||||||
├── examples2d/ # 2D demos
|
|
||||||
├── examples3d/ # 3D demos
|
|
||||||
├── benchmarks2d/ # 2D performance tests
|
|
||||||
├── benchmarks3d/ # 3D performance tests
|
|
||||||
└── src_testbed/ # Testbed source
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core Modules Deep Dive
|
|
||||||
|
|
||||||
### 1. `src/dynamics/` - Physics Simulation
|
|
||||||
|
|
||||||
Handles movement, forces, and constraints.
|
|
||||||
|
|
||||||
#### RigidBody System
|
|
||||||
|
|
||||||
**`RigidBody`** (`rigid_body.rs`) - The fundamental physics object
|
|
||||||
- **Three body types:**
|
|
||||||
- `Dynamic`: Fully simulated - responds to forces, gravity, collisions
|
|
||||||
- `Fixed`: Never moves - infinite mass (walls, floors, terrain)
|
|
||||||
- `Kinematic`: User-controlled movement - pushes but isn't pushed (platforms, doors)
|
|
||||||
|
|
||||||
**Key properties:**
|
|
||||||
- Position/rotation: `translation()`, `rotation()`, `position()`
|
|
||||||
- Velocity: `linvel()`, `angvel()`, `set_linvel()`, `set_angvel()`
|
|
||||||
- Mass: `mass()`, `center_of_mass()`, computed from attached colliders
|
|
||||||
- Forces: `add_force()`, `add_torque()`, `add_force_at_point()` (continuous, cleared each step)
|
|
||||||
- Impulses: `apply_impulse()`, `apply_torque_impulse()`, `apply_impulse_at_point()` (instant)
|
|
||||||
- Damping: `linear_damping()`, `angular_damping()` (air resistance, drag)
|
|
||||||
- Sleeping: `sleep()`, `wake_up()`, `is_sleeping()` (performance optimization)
|
|
||||||
- CCD: `enable_ccd()`, prevents fast objects tunneling through walls
|
|
||||||
- Locking: `lock_rotations()`, `lock_translations()`, `set_locked_axes()` (constrain movement)
|
|
||||||
- Gravity: `gravity_scale()`, `set_gravity_scale()` (0.0 = zero-g, 1.0 = normal, 2.0 = heavy)
|
|
||||||
- Energy: `kinetic_energy()`, `gravitational_potential_energy()`
|
|
||||||
- Prediction: `predict_position_using_velocity()`, `predict_position_using_velocity_and_forces()`
|
|
||||||
|
|
||||||
**`RigidBodySet`** (`rigid_body_set.rs`) - Collection of all bodies
|
|
||||||
- Handle-based storage (generational indices prevent use-after-free)
|
|
||||||
- Methods: `insert()`, `remove()`, `get()`, `get_mut()`, `iter()`, `contains()`
|
|
||||||
- `propagate_modified_body_positions_to_colliders()` for manual position sync
|
|
||||||
|
|
||||||
**`RigidBodyBuilder`** - Builder pattern for creating bodies
|
|
||||||
- Type constructors: `dynamic()`, `fixed()`, `kinematic_velocity_based()`, `kinematic_position_based()`
|
|
||||||
- Configuration: `translation()`, `rotation()`, `linvel()`, `angvel()`
|
|
||||||
- Settings: `gravity_scale()`, `can_sleep()`, `ccd_enabled()`, `linear_damping()`, `angular_damping()`
|
|
||||||
- Constraints: `locked_axes()`, `lock_rotations()`, `lock_translations()`, `enabled_rotations()`
|
|
||||||
- Advanced: `dominance_group()`, `additional_mass()`, `enable_gyroscopic_forces()`
|
|
||||||
|
|
||||||
#### Joint System
|
|
||||||
|
|
||||||
**Joint Types** (all in `src/dynamics/joint/`):
|
|
||||||
|
|
||||||
1. **`FixedJoint`**: Welds two bodies rigidly together
|
|
||||||
2. **`RevoluteJoint`**: Hinge - rotation around one axis (doors, wheels)
|
|
||||||
3. **`PrismaticJoint`**: Slider - translation along one axis (pistons, elevators)
|
|
||||||
4. **`SphericalJoint`**: Ball-and-socket - free rotation, fixed position (shoulders, gimbals)
|
|
||||||
5. **`RopeJoint`**: Maximum distance constraint (ropes, cables, tethers)
|
|
||||||
6. **`SpringJoint`**: Elastic connection with stiffness/damping (suspension, soft constraints)
|
|
||||||
|
|
||||||
**Joint Features:**
|
|
||||||
- **Motors**: Powered actuation with `set_motor_velocity()`, `set_motor_position()`
|
|
||||||
- Velocity control: constant speed rotation/sliding
|
|
||||||
- Position control: spring-like movement toward target
|
|
||||||
- Max force limits: `set_motor_max_force()`
|
|
||||||
- Motor models: `AccelerationBased` (mass-independent) vs `ForceBased` (mass-dependent)
|
|
||||||
- **Limits**: Restrict range with `set_limits([min, max])`
|
|
||||||
- **Anchors**: Connection points in each body's local space
|
|
||||||
|
|
||||||
**`ImpulseJointSet`** - Collection of all joints
|
|
||||||
- Methods: `insert()`, `remove()`, `get()`, `get_mut()`, `iter()`
|
|
||||||
- Queries: `joints_between()`, `attached_joints()`, `attached_enabled_joints()`
|
|
||||||
|
|
||||||
#### Integration & Solving
|
|
||||||
|
|
||||||
**`IntegrationParameters`** - Controls simulation behavior
|
|
||||||
- `dt`: Timestep (1/60 for 60 FPS, 1/120 for 120 FPS)
|
|
||||||
- `num_solver_iterations`: Accuracy vs speed (4 = default, 8-12 = high quality, 1-2 = fast)
|
|
||||||
- `length_unit`: Scale factor if not using meters (100.0 for pixel-based 2D)
|
|
||||||
- `contact_natural_frequency`, `contact_damping_ratio`: Contact compliance
|
|
||||||
- `joint_natural_frequency`, `joint_damping_ratio`: Joint compliance
|
|
||||||
- Advanced: warmstarting, prediction distance, stabilization iterations
|
|
||||||
|
|
||||||
**`IslandManager`** - Sleeping/waking optimization
|
|
||||||
- Groups connected bodies into "islands" for parallel solving
|
|
||||||
- Automatically sleeps bodies at rest (huge performance gain)
|
|
||||||
- Wakes bodies when disturbed by collisions/joints
|
|
||||||
- Sleep thresholds configurable via `RigidBodyActivation`
|
|
||||||
|
|
||||||
**`CCDSolver`** - Prevents tunneling
|
|
||||||
- Detects fast-moving bodies that might pass through geometry
|
|
||||||
- Predicts time-of-impact and clamps motion
|
|
||||||
- Enable per-body with `ccd_enabled(true)`
|
|
||||||
- Soft-CCD: cheaper predictive variant with `set_soft_ccd_prediction()`
|
|
||||||
|
|
||||||
### 2. `src/geometry/` - Collision Detection
|
|
||||||
|
|
||||||
#### Collider System
|
|
||||||
|
|
||||||
**`Collider`** - Collision shape ("hitbox") attached to bodies
|
|
||||||
- **Shapes**: Ball, Cuboid, Capsule, Cylinder, Cone, Triangle, Segment, HeightField, TriMesh, Compound, ConvexHull
|
|
||||||
- **Material properties:**
|
|
||||||
- Friction: 0.0 = ice, 0.5 = wood, 1.0 = rubber
|
|
||||||
- Restitution: 0.0 = clay (no bounce), 1.0 = perfect elastic, >1.0 = super bouncy
|
|
||||||
- Combine rules: Average, Min, Max, Multiply (how to combine when two colliders touch)
|
|
||||||
- **Mass:** Set via `density()` (kg/m³) or `mass()` (kg directly)
|
|
||||||
- **Sensors:** `set_sensor(true)` for trigger zones (detect overlaps without physical collision)
|
|
||||||
- **Position:** `position()`, `translation()`, `rotation()`, `position_wrt_parent()`
|
|
||||||
- **Groups:** `collision_groups()`, `solver_groups()` for layer-based filtering
|
|
||||||
- **Events:** `active_events()`, `contact_force_event_threshold()` for collision notifications
|
|
||||||
- **Shape queries:** `compute_aabb()`, `compute_swept_aabb()`, `volume()`, `mass_properties()`
|
|
||||||
- **Enabled:** `set_enabled()` to temporarily disable without removal
|
|
||||||
|
|
||||||
**`ColliderSet`** - Collection of all colliders
|
|
||||||
- Methods: `insert()`, `insert_with_parent()`, `remove()`, `set_parent()`
|
|
||||||
- Access: `get()`, `get_mut()`, `iter()`, `iter_enabled()`
|
|
||||||
- Invalid handle: `ColliderSet::invalid_handle()`
|
|
||||||
|
|
||||||
**`ColliderBuilder`** - Creates colliders with builder pattern
|
|
||||||
- **Primitive shapes:**
|
|
||||||
- `ball(radius)` - Sphere/circle
|
|
||||||
- `cuboid(hx, hy, hz)` - Box (half-extents)
|
|
||||||
- `capsule_y(half_height, radius)` - Pill shape (best for characters!)
|
|
||||||
- `cylinder(half_height, radius)`, `cone(half_height, radius)` (3D only)
|
|
||||||
- **Complex shapes:**
|
|
||||||
- `trimesh(vertices, indices)` - Triangle mesh (slow but accurate)
|
|
||||||
- `heightfield(heights, scale)` - Terrain from height grid
|
|
||||||
- `convex_hull(points)` - Smallest convex shape containing points
|
|
||||||
- `convex_decomposition(vertices, indices)` - Breaks concave mesh into convex pieces
|
|
||||||
- `segment(a, b)`, `triangle(a, b, c)` - Simple primitives
|
|
||||||
- **Configuration:**
|
|
||||||
- Material: `friction()`, `restitution()`, `density()`, `mass()`
|
|
||||||
- Filtering: `collision_groups()`, `sensor()`
|
|
||||||
- Events: `active_events()`, `contact_force_event_threshold()`
|
|
||||||
- Position: `translation()`, `rotation()`, `position()`
|
|
||||||
- Advanced: `active_hooks()`, `active_collision_types()`, `contact_skin()`
|
|
||||||
|
|
||||||
#### Collision Detection Pipeline
|
|
||||||
|
|
||||||
**`BroadPhaseBvh`** - First pass: quickly find nearby pairs
|
|
||||||
- Uses hierarchical BVH tree for spatial indexing
|
|
||||||
- Filters out distant objects before expensive narrow-phase
|
|
||||||
- Incrementally updated as objects move
|
|
||||||
- Optimization strategies: `SubtreeOptimizer` (default) vs `None`
|
|
||||||
|
|
||||||
**`NarrowPhase`** - Second pass: compute exact contacts
|
|
||||||
- Calculates precise contact points, normals, penetration depths
|
|
||||||
- Builds contact manifolds (groups of contacts sharing properties)
|
|
||||||
- Managed automatically by PhysicsPipeline
|
|
||||||
- Access via `contact_graph()` for querying contact pairs
|
|
||||||
|
|
||||||
**`ContactPair`** - Detailed collision information
|
|
||||||
- Methods: `total_impulse()`, `total_impulse_magnitude()`, `max_impulse()`, `find_deepest_contact()`
|
|
||||||
- Contains multiple `ContactManifold` structures
|
|
||||||
- Each manifold has contact points with normals, distances, solver data
|
|
||||||
|
|
||||||
#### Collision Filtering
|
|
||||||
|
|
||||||
**`InteractionGroups`** - Layer-based collision control
|
|
||||||
- Two components: `memberships` (what groups I'm in) and `filter` (what groups I collide with)
|
|
||||||
- 32 groups available: `Group::GROUP_1` through `Group::GROUP_32`
|
|
||||||
- Bidirectional check: A and B collide only if A's memberships overlap B's filter AND vice versa
|
|
||||||
- Example: Player bullets (group 1) only hit enemies (group 2)
|
|
||||||
|
|
||||||
**`ActiveCollisionTypes`** - Filter by body type
|
|
||||||
- Controls which body type pairs can collide
|
|
||||||
- Defaults: Dynamic↔Dynamic ✓, Dynamic↔Fixed ✓, Dynamic↔Kinematic ✓, Fixed↔Fixed ✗
|
|
||||||
- Rarely changed - defaults are correct for most games
|
|
||||||
|
|
||||||
**`QueryFilter`** - Filter spatial queries
|
|
||||||
- Flags: `EXCLUDE_FIXED`, `EXCLUDE_DYNAMIC`, `EXCLUDE_SENSORS`, `ONLY_DYNAMIC`, etc.
|
|
||||||
- Groups: Filter by collision groups
|
|
||||||
- Exclusions: `exclude_collider`, `exclude_rigid_body`
|
|
||||||
- Custom: `predicate` closure for arbitrary filtering
|
|
||||||
|
|
||||||
### 3. `src/pipeline/` - Simulation Orchestration
|
|
||||||
|
|
||||||
**`PhysicsPipeline`** - The main simulation loop
|
|
||||||
- **`step()`**: Advances physics by one timestep
|
|
||||||
1. Handles user changes (moved bodies, added/removed colliders)
|
|
||||||
2. Runs collision detection (broad-phase → narrow-phase)
|
|
||||||
3. Builds islands and solves constraints (contacts + joints)
|
|
||||||
4. Integrates velocities to update positions
|
|
||||||
5. Runs CCD if needed
|
|
||||||
6. Generates events
|
|
||||||
- Reuse same instance for performance (caches data between frames)
|
|
||||||
|
|
||||||
**`CollisionPipeline`** - Collision detection without dynamics
|
|
||||||
- Use when you only need collision detection, not physics simulation
|
|
||||||
- Lighter weight than PhysicsPipeline
|
|
||||||
|
|
||||||
**`QueryPipeline`** - Spatial queries (created from BroadPhase)
|
|
||||||
- **Raycasting:**
|
|
||||||
- `cast_ray()` - First hit along ray
|
|
||||||
- `cast_ray_and_get_normal()` - Hit with surface normal
|
|
||||||
- `intersect_ray()` - ALL hits along ray
|
|
||||||
- **Shape casting:**
|
|
||||||
- `cast_shape()` - Sweep shape through space (thick raycast)
|
|
||||||
- `cast_shape_nonlinear()` - Non-linear motion sweep
|
|
||||||
- **Point queries:**
|
|
||||||
- `project_point()` - Find closest point on any collider
|
|
||||||
- `intersect_point()` - Find all colliders containing point
|
|
||||||
- **AABB queries:**
|
|
||||||
- `intersect_aabb_conservative()` - Find colliders in bounding box
|
|
||||||
- Filtering via `QueryFilter`
|
|
||||||
|
|
||||||
**`EventHandler`** trait - Receive physics events
|
|
||||||
- `handle_collision_event()` - When colliders start/stop touching
|
|
||||||
- `handle_contact_force_event()` - When contact forces exceed threshold
|
|
||||||
- Built-in: `ChannelEventCollector` sends events to mpsc channels
|
|
||||||
- Enable per-collider with `ActiveEvents` flags
|
|
||||||
|
|
||||||
**`PhysicsHooks`** trait - Custom collision behavior
|
|
||||||
- `filter_contact_pair()` - Decide if two colliders should collide
|
|
||||||
- `filter_intersection_pair()` - Filter sensor intersections
|
|
||||||
- `modify_solver_contacts()` - Modify contact properties before solving
|
|
||||||
- Enable per-collider with `ActiveHooks` flags
|
|
||||||
- Advanced feature - most users should use `InteractionGroups` instead
|
|
||||||
|
|
||||||
**`CollisionEvent`** - Collision state changes
|
|
||||||
- `Started(h1, h2, flags)` - Colliders began touching
|
|
||||||
- `Stopped(h1, h2, flags)` - Colliders stopped touching
|
|
||||||
- Methods: `started()`, `stopped()`, `collider1()`, `collider2()`, `sensor()`
|
|
||||||
|
|
||||||
### 4. `src/control/` - High-Level Controllers
|
|
||||||
|
|
||||||
**`KinematicCharacterController`** - Player/NPC movement
|
|
||||||
- Handles walking, slopes, stairs, wall sliding, ground snapping
|
|
||||||
- NOT physics-based - you control movement directly
|
|
||||||
- Features:
|
|
||||||
- `slide`: Slide along walls instead of stopping
|
|
||||||
- `autostep`: Automatically climb stairs/small obstacles
|
|
||||||
- `max_slope_climb_angle`: Max climbable slope (radians)
|
|
||||||
- `min_slope_slide_angle`: When to slide down slopes
|
|
||||||
- `snap_to_ground`: Keep grounded on uneven terrain
|
|
||||||
- Returns `EffectiveCharacterMovement` with `translation` and `grounded` status
|
|
||||||
|
|
||||||
**`DynamicRayCastVehicleController`** - Arcade vehicle physics
|
|
||||||
- Raycast-based suspension (simpler than constraint-based)
|
|
||||||
- Add wheels with suspension, steering, engine force
|
|
||||||
- Automatically handles wheel contacts and forces
|
|
||||||
|
|
||||||
### 5. `src/data/` - Core Data Structures
|
|
||||||
|
|
||||||
**`Arena<T>`** - Handle-based storage
|
|
||||||
- Generational indices: (index, generation) pair
|
|
||||||
- Prevents use-after-free: old handles become invalid when slots reused
|
|
||||||
- Used for: `RigidBodySet`, `ColliderSet`, `ImpulseJointSet`
|
|
||||||
- Methods: `insert()`, `remove()`, `get()`, `get_mut()`, `iter()`
|
|
||||||
- Advanced: `get_unknown_gen()` bypasses generation check (unsafe)
|
|
||||||
|
|
||||||
**`Graph<N, E>`** - Generic graph structure
|
|
||||||
- Nodes and edges with associated data
|
|
||||||
- Used for: interaction graph (bodies/colliders), joint graph
|
|
||||||
- Enables: "find all joints attached to this body"
|
|
||||||
|
|
||||||
**`ModifiedObjects`** - Change tracking
|
|
||||||
- Flags objects that changed since last frame
|
|
||||||
- Enables incremental updates (only process changed objects)
|
|
||||||
- Critical for performance
|
|
||||||
|
|
||||||
### 6. `src/counters/` - Profiling
|
|
||||||
|
|
||||||
**`Counters`** - Performance measurements
|
|
||||||
- Tracks time in: collision detection, solver, CCD, island construction
|
|
||||||
- Subdivided: broad-phase time, narrow-phase time, velocity resolution, etc.
|
|
||||||
- Access via `physics_pipeline.counters`
|
|
||||||
|
|
||||||
## Complete API Reference
|
|
||||||
|
|
||||||
### Body Types
|
|
||||||
|
|
||||||
```rust
|
|
||||||
RigidBodyType::Dynamic // Fully simulated
|
|
||||||
RigidBodyType::Fixed // Never moves
|
|
||||||
RigidBodyType::KinematicVelocityBased // Velocity control
|
|
||||||
RigidBodyType::KinematicPositionBased // Position control
|
|
||||||
```
|
|
||||||
|
|
||||||
### Joint Types
|
|
||||||
|
|
||||||
```rust
|
|
||||||
FixedJoint::new() // Weld
|
|
||||||
RevoluteJoint::new(axis) // Hinge
|
|
||||||
PrismaticJoint::new(axis) // Slider
|
|
||||||
SphericalJoint::new() // Ball-and-socket (3D only)
|
|
||||||
RopeJoint::new(max_dist) // Distance limit
|
|
||||||
SpringJoint::new(rest, stiff, damp) // Elastic
|
|
||||||
```
|
|
||||||
|
|
||||||
### Collision Shapes
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Primitives (fast)
|
|
||||||
ColliderBuilder::ball(radius)
|
|
||||||
ColliderBuilder::cuboid(hx, hy, hz) // Half-extents
|
|
||||||
ColliderBuilder::capsule_y(half_h, r) // Best for characters!
|
|
||||||
ColliderBuilder::cylinder(half_h, r) // 3D only
|
|
||||||
ColliderBuilder::cone(half_h, r) // 3D only
|
|
||||||
|
|
||||||
// Complex (slower)
|
|
||||||
ColliderBuilder::trimesh(verts, indices) // Arbitrary mesh
|
|
||||||
ColliderBuilder::heightfield(heights, scale) // Terrain
|
|
||||||
ColliderBuilder::convex_hull(points) // Convex wrap
|
|
||||||
ColliderBuilder::convex_decomposition(v, i) // Auto-split concave
|
|
||||||
```
|
|
||||||
|
|
||||||
### Events & Hooks
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Event flags
|
|
||||||
ActiveEvents::COLLISION_EVENTS // Start/stop touching
|
|
||||||
ActiveEvents::CONTACT_FORCE_EVENTS // Force threshold exceeded
|
|
||||||
|
|
||||||
// Hook flags
|
|
||||||
ActiveHooks::FILTER_CONTACT_PAIRS // Custom collision filtering
|
|
||||||
ActiveHooks::FILTER_INTERSECTION_PAIR // Custom sensor filtering
|
|
||||||
ActiveHooks::MODIFY_SOLVER_CONTACTS // Modify contact properties
|
|
||||||
```
|
|
||||||
|
|
||||||
### Filtering
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Collision groups (layer system)
|
|
||||||
let groups = InteractionGroups::new(
|
|
||||||
Group::GROUP_1, // I'm in group 1
|
|
||||||
Group::GROUP_2 | Group::GROUP_3 // I collide with 2 and 3
|
|
||||||
);
|
|
||||||
|
|
||||||
// Query filters
|
|
||||||
QueryFilter::default()
|
|
||||||
QueryFilter::only_dynamic() // Ignore static geometry
|
|
||||||
QueryFilter::exclude_sensors() // Only solid shapes
|
|
||||||
```
|
|
||||||
|
|
||||||
### Locked Axes
|
|
||||||
|
|
||||||
```rust
|
|
||||||
LockedAxes::ROTATION_LOCKED // Can't rotate at all
|
|
||||||
LockedAxes::TRANSLATION_LOCKED // Can't translate at all
|
|
||||||
LockedAxes::TRANSLATION_LOCKED_Z // Lock one axis (2D in 3D)
|
|
||||||
LockedAxes::ROTATION_LOCKED_X | LockedAxes::ROTATION_LOCKED_Y // Combine
|
|
||||||
```
|
|
||||||
|
|
||||||
## Advanced Concepts
|
|
||||||
|
|
||||||
### Sleeping System
|
|
||||||
|
|
||||||
Bodies automatically sleep when at rest (velocities below threshold for 2 seconds). Sleeping bodies:
|
|
||||||
- Skipped in collision detection and simulation
|
|
||||||
- Auto-wake when hit or joint-connected to moving body
|
|
||||||
- Configured via `RigidBodyActivation`:
|
|
||||||
- `normalized_linear_threshold`: Linear velocity threshold (default 0.4)
|
|
||||||
- `angular_threshold`: Angular velocity threshold (default 0.5)
|
|
||||||
- `time_until_sleep`: How long to be still before sleeping (default 2.0s)
|
|
||||||
- Disable with `can_sleep(false)` or `RigidBodyActivation::cannot_sleep()`
|
|
||||||
|
|
||||||
### CCD (Continuous Collision Detection)
|
|
||||||
|
|
||||||
Prevents "tunneling" where fast objects pass through thin walls:
|
|
||||||
- **Hard CCD**: Shape-casting with substeps (expensive but accurate)
|
|
||||||
- **Soft CCD**: Predictive contacts (cheaper, good for medium-speed objects)
|
|
||||||
- Enable: `RigidBodyBuilder::ccd_enabled(true)` or `body.enable_ccd(true)`
|
|
||||||
- Soft: `set_soft_ccd_prediction(distance)`
|
|
||||||
- Active when velocity exceeds auto-computed threshold
|
|
||||||
|
|
||||||
### Mass Properties
|
|
||||||
|
|
||||||
Total mass = collider masses + additional mass:
|
|
||||||
- Collider mass: `density × volume` or set directly
|
|
||||||
- Additional mass: `set_additional_mass()` adds to total
|
|
||||||
- Auto-computed: mass, center of mass, angular inertia tensor
|
|
||||||
- Manual recompute: `recompute_mass_properties_from_colliders()`
|
|
||||||
|
|
||||||
### Dominance Groups
|
|
||||||
|
|
||||||
Bodies with higher dominance push lower ones but not vice versa:
|
|
||||||
- Range: `i8::MIN` to `i8::MAX`
|
|
||||||
- Default: 0 (all equal)
|
|
||||||
- Rarely needed - use for "heavy objects should always win" scenarios
|
|
||||||
|
|
||||||
### Contact Skin
|
|
||||||
|
|
||||||
Small margin around colliders (keeps objects slightly apart):
|
|
||||||
- Improves performance and stability
|
|
||||||
- Might create small visual gaps
|
|
||||||
- Set via `ColliderBuilder::contact_skin(thickness)`
|
|
||||||
|
|
||||||
### Motor Models
|
|
||||||
|
|
||||||
How motor spring constants scale with mass:
|
|
||||||
- **`MotorModel::AccelerationBased`** (default): Auto-scales with mass, easier to tune
|
|
||||||
- **`MotorModel::ForceBased`**: Absolute forces, mass-dependent behavior
|
|
||||||
|
|
||||||
## Common Usage Patterns
|
|
||||||
|
|
||||||
### Creating a Dynamic Object
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let body = RigidBodyBuilder::dynamic()
|
|
||||||
.translation(vector![0.0, 10.0, 0.0])
|
|
||||||
.linvel(vector![1.0, 0.0, 0.0])
|
|
||||||
.build();
|
|
||||||
let body_handle = bodies.insert(body);
|
|
||||||
|
|
||||||
let collider = ColliderBuilder::ball(0.5)
|
|
||||||
.density(2700.0) // Aluminum
|
|
||||||
.friction(0.7)
|
|
||||||
.restitution(0.3)
|
|
||||||
.build();
|
|
||||||
colliders.insert_with_parent(collider, body_handle, &mut bodies);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Raycasting
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let query_pipeline = broad_phase.as_query_pipeline(
|
|
||||||
&QueryDispatcher,
|
|
||||||
&bodies,
|
|
||||||
&colliders,
|
|
||||||
QueryFilter::default()
|
|
||||||
);
|
|
||||||
|
|
||||||
let ray = Ray::new(point![0.0, 10.0, 0.0], vector![0.0, -1.0, 0.0]);
|
|
||||||
if let Some((handle, toi)) = query_pipeline.cast_ray(&ray, Real::MAX, true) {
|
|
||||||
let hit_point = ray.origin + ray.dir * toi;
|
|
||||||
println!("Hit {:?} at {:?}, distance = {}", handle, hit_point, toi);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Applying Forces vs Impulses
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// IMPULSE: Instant change (jumping, explosions)
|
|
||||||
body.apply_impulse(vector![0.0, 500.0, 0.0], true); // Jump!
|
|
||||||
|
|
||||||
// FORCE: Continuous (thrust, wind) - call every frame
|
|
||||||
body.add_force(vector![0.0, 100.0, 0.0], true); // Rocket thrust
|
|
||||||
```
|
|
||||||
|
|
||||||
### Creating a Joint
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let joint = RevoluteJointBuilder::new()
|
|
||||||
.local_anchor1(point![1.0, 0.0, 0.0])
|
|
||||||
.local_anchor2(point![-1.0, 0.0, 0.0])
|
|
||||||
.limits([0.0, std::f32::consts::PI / 2.0]) // 0-90° rotation
|
|
||||||
.build();
|
|
||||||
let joint_handle = joints.insert(body1, body2, joint, true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Character Controller
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let controller = KinematicCharacterController {
|
|
||||||
slide: true,
|
|
||||||
autostep: Some(CharacterAutostep::default()),
|
|
||||||
max_slope_climb_angle: 45.0_f32.to_radians(),
|
|
||||||
snap_to_ground: Some(CharacterLength::Relative(0.2)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let desired_movement = vector![input_x, 0.0, input_z] * speed * dt;
|
|
||||||
let movement = controller.move_shape(
|
|
||||||
dt, &bodies, &colliders, &query_pipeline,
|
|
||||||
character_shape, &character_pos, desired_movement,
|
|
||||||
QueryFilter::default(), |_| {}
|
|
||||||
);
|
|
||||||
character_pos.translation.vector += movement.translation;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Collision Events
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use std::sync::mpsc::channel;
|
|
||||||
|
|
||||||
let (collision_send, collision_recv) = channel();
|
|
||||||
let (force_send, force_recv) = channel();
|
|
||||||
let event_handler = ChannelEventCollector::new(collision_send, force_send);
|
|
||||||
|
|
||||||
// In physics step
|
|
||||||
physics_pipeline.step(..., &event_handler);
|
|
||||||
|
|
||||||
// After physics
|
|
||||||
while let Ok(event) = collision_recv.try_recv() {
|
|
||||||
match event {
|
|
||||||
CollisionEvent::Started(h1, h2, _) => println!("Collision!"),
|
|
||||||
CollisionEvent::Stopped(h1, h2, _) => println!("Separated"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Performance Optimization Tips
|
|
||||||
|
|
||||||
1. **Sleeping**: Let objects at rest sleep (default behavior)
|
|
||||||
2. **Shape choice**: Ball/Cuboid/Capsule >> Convex Hull >> TriMesh
|
|
||||||
3. **Solver iterations**: Lower `num_solver_iterations` if accuracy isn't critical
|
|
||||||
4. **Parallel**: Enable `parallel` feature for multi-core
|
|
||||||
5. **Broadphase**: Keep objects reasonably distributed (not all in one spot)
|
|
||||||
6. **CCD**: Only enable for fast objects that need it
|
|
||||||
7. **Event generation**: Only enable events on colliders that need them
|
|
||||||
8. **Collision groups**: Filter unnecessary collision checks
|
|
||||||
9. **Fixed timestep**: Use fixed `dt`, accumulate remainder for smooth rendering
|
|
||||||
|
|
||||||
## Common Patterns & Best Practices
|
|
||||||
|
|
||||||
### Handle Storage
|
|
||||||
```rust
|
|
||||||
// Store handles, not references
|
|
||||||
struct Player {
|
|
||||||
body_handle: RigidBodyHandle,
|
|
||||||
collider_handle: ColliderHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access when needed
|
|
||||||
let player_body = &mut bodies[player.body_handle];
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2D Game in 3D Engine
|
|
||||||
```rust
|
|
||||||
let body = RigidBodyBuilder::dynamic()
|
|
||||||
.locked_axes(
|
|
||||||
LockedAxes::TRANSLATION_LOCKED_Z |
|
|
||||||
LockedAxes::ROTATION_LOCKED_X |
|
|
||||||
LockedAxes::ROTATION_LOCKED_Y
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-Way Platforms (via hooks)
|
|
||||||
```rust
|
|
||||||
struct OneWayPlatform;
|
|
||||||
impl PhysicsHooks for OneWayPlatform {
|
|
||||||
fn filter_contact_pair(&self, context: &PairFilterContext) -> Option<SolverFlags> {
|
|
||||||
// Allow contact only if player is above platform
|
|
||||||
if player_above_platform(context) {
|
|
||||||
Some(SolverFlags::COMPUTE_IMPULSES)
|
|
||||||
} else {
|
|
||||||
None // No collision
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compound Shapes
|
|
||||||
```rust
|
|
||||||
// Multiple colliders on one body
|
|
||||||
let body_handle = bodies.insert(RigidBodyBuilder::dynamic().build());
|
|
||||||
|
|
||||||
colliders.insert_with_parent(
|
|
||||||
ColliderBuilder::cuboid(1.0, 1.0, 1.0).translation(vector![0.0, 1.0, 0.0]).build(),
|
|
||||||
body_handle, &mut bodies
|
|
||||||
);
|
|
||||||
colliders.insert_with_parent(
|
|
||||||
ColliderBuilder::ball(0.5).translation(vector![0.0, 3.0, 0.0]).build(),
|
|
||||||
body_handle, &mut bodies
|
|
||||||
);
|
|
||||||
// Now the body has a box + ball shape
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Objects Tunneling Through Walls
|
|
||||||
- Enable CCD: `body.enable_ccd(true)`
|
|
||||||
- Increase wall thickness
|
|
||||||
- Reduce timestep (`dt`)
|
|
||||||
- Increase `num_solver_iterations`
|
|
||||||
|
|
||||||
### Unstable Simulation (Jittering, Explosions)
|
|
||||||
- Reduce mass ratios (avoid 1kg vs 1000kg objects)
|
|
||||||
- Increase `num_solver_iterations`
|
|
||||||
- Check for conflicting constraints
|
|
||||||
- Verify joint anchors are reasonable
|
|
||||||
- Reduce timestep if using large `dt`
|
|
||||||
|
|
||||||
### Poor Performance
|
|
||||||
- Check sleeping is enabled (`can_sleep(true)`)
|
|
||||||
- Use simpler shapes (capsules instead of meshes)
|
|
||||||
- Enable `parallel` feature
|
|
||||||
- Reduce `num_solver_iterations` if acceptable
|
|
||||||
- Use collision groups to avoid unnecessary checks
|
|
||||||
- Only enable events on colliders that need them
|
|
||||||
|
|
||||||
### Bodies Stuck/Not Moving
|
|
||||||
- Check if sleeping: `body.wake_up(true)`
|
|
||||||
- Verify mass > 0 (check collider density)
|
|
||||||
- Check locked axes aren't preventing movement
|
|
||||||
- Verify gravity scale isn't 0
|
|
||||||
|
|
||||||
## File Statistics
|
|
||||||
|
|
||||||
- **95 total Rust files** in `src/`
|
|
||||||
- **Top files by public function count:**
|
|
||||||
- `rigid_body.rs`: 126 functions
|
|
||||||
- `collider.rs`: 118 functions
|
|
||||||
- `rigid_body_components.rs`: 56 functions
|
|
||||||
- `generic_joint.rs`: 47 functions
|
|
||||||
- `query_pipeline.rs`: 29 functions
|
|
||||||
|
|
||||||
## Documentation Improvements
|
|
||||||
|
|
||||||
### Session 1: Comprehensive API Documentation
|
|
||||||
Comprehensively documented **300+ public functions** across **45+ files**:
|
|
||||||
|
|
||||||
**Fully Documented Modules:**
|
|
||||||
1. **PhysicsPipeline** - Main simulation loop
|
|
||||||
2. **RigidBody** (~60 methods) - All position, velocity, force, impulse, damping, CCD, locking methods
|
|
||||||
3. **RigidBodySet** - All collection management methods
|
|
||||||
4. **RigidBodyBuilder** (~40 methods) - All configuration methods
|
|
||||||
5. **Collider** (~50 methods) - All property accessors and setters
|
|
||||||
6. **ColliderSet** - All collection methods
|
|
||||||
7. **ColliderBuilder** (~60 methods) - All shape constructors and configuration
|
|
||||||
8. **All 6 joint types** - Comprehensive docs for Fixed, Revolute, Prismatic, Spherical, Rope, Spring
|
|
||||||
9. **ImpulseJointSet** - All joint collection methods
|
|
||||||
10. **QueryPipeline** - All spatial query methods
|
|
||||||
11. **EventHandler & events** - Complete event system
|
|
||||||
12. **InteractionGroups** - Collision filtering
|
|
||||||
13. **IntegrationParameters** - Simulation settings
|
|
||||||
14. **IslandManager** - Sleep/wake system
|
|
||||||
15. **CCDSolver** - Tunneling prevention
|
|
||||||
16. **BroadPhaseBvh, NarrowPhase** - Collision detection
|
|
||||||
17. **CharacterController** - Player movement
|
|
||||||
18. **ContactPair** - Contact information
|
|
||||||
19. **All major enums/flags**: RigidBodyType, LockedAxes, ActiveEvents, ActiveHooks, ActiveCollisionTypes, CoefficientCombineRule, MotorModel, CollisionEvent, QueryFilter
|
|
||||||
|
|
||||||
**Documentation Style:**
|
|
||||||
All functions include:
|
|
||||||
- **Plain language** ("hitbox" not "geometric entity")
|
|
||||||
- **Real-world use cases** (when/why to use)
|
|
||||||
- **Code examples** (copy-paste ready)
|
|
||||||
- **Value guides** (friction 0-1, density values for real materials)
|
|
||||||
- **Warnings** (teleporting, performance costs, common mistakes)
|
|
||||||
- **Comparisons** (forces vs impulses, mass vs density, when to use each)
|
|
||||||
|
|
||||||
### Session 2: Documentation Example Testing
|
|
||||||
**Converted 75+ ignored documentation examples to be tested by `cargo test --doc`**
|
|
||||||
|
|
||||||
**Goal:** Ensure all documentation examples remain valid and compilable as the codebase evolves.
|
|
||||||
|
|
||||||
**Files with Fixed Examples:**
|
|
||||||
|
|
||||||
*Dynamics Module (33 examples):*
|
|
||||||
- `dynamics/rigid_body.rs` (13)
|
|
||||||
- `dynamics/rigid_body_set.rs` (8)
|
|
||||||
- `dynamics/rigid_body_components.rs` (1) - LockedAxes
|
|
||||||
- `dynamics/coefficient_combine_rule.rs` (1)
|
|
||||||
- `dynamics/integration_parameters.rs` (1)
|
|
||||||
- `dynamics/island_manager.rs` (1)
|
|
||||||
- `dynamics/joint/rope_joint.rs` (1)
|
|
||||||
- `dynamics/joint/revolute_joint.rs` (1)
|
|
||||||
- `dynamics/joint/generic_joint.rs` (1) - JointMotor
|
|
||||||
- `dynamics/joint/impulse_joint/impulse_joint_set.rs` (5)
|
|
||||||
|
|
||||||
*Geometry Module (10 examples):*
|
|
||||||
- `geometry/interaction_groups.rs` (1)
|
|
||||||
- `geometry/collider_set.rs` (4)
|
|
||||||
- `geometry/collider_components.rs` (1) - ActiveCollisionTypes
|
|
||||||
- `geometry/contact_pair.rs` (2)
|
|
||||||
- `geometry/mod.rs` (1) - CollisionEvent
|
|
||||||
- `geometry/interaction_graph.rs` (1)
|
|
||||||
|
|
||||||
*Pipeline Module (14 examples):*
|
|
||||||
- `pipeline/query_pipeline.rs` (9) - Raycasting, shape casting, point queries
|
|
||||||
- `pipeline/event_handler.rs` (3) - ActiveEvents, EventHandler trait, ChannelEventCollector
|
|
||||||
- `pipeline/physics_pipeline.rs` (1)
|
|
||||||
- `pipeline/collision_pipeline.rs` (1)
|
|
||||||
|
|
||||||
*Control Module (1 example):*
|
|
||||||
- `control/character_controller.rs` (1) - Complete character controller setup
|
|
||||||
|
|
||||||
*Data Module (25 examples):*
|
|
||||||
- `data/arena.rs` (25) - All Arena API methods
|
|
||||||
|
|
||||||
*Other Modules (4 examples):*
|
|
||||||
- `dynamics/joint/multibody_joint/multibody_joint_set.rs` (1)
|
|
||||||
|
|
||||||
**Conversion Pattern:**
|
|
||||||
```rust
|
|
||||||
// Before:
|
|
||||||
/// ```ignore
|
|
||||||
/// let body = RigidBodyBuilder::dynamic().build();
|
|
||||||
/// bodies.insert(body);
|
|
||||||
/// ```
|
|
||||||
|
|
||||||
// After:
|
|
||||||
/// ```
|
|
||||||
/// # use rapier3d::prelude::*;
|
|
||||||
/// # let mut bodies = RigidBodySet::new();
|
|
||||||
/// let body_handle = bodies.insert(RigidBodyBuilder::dynamic());
|
|
||||||
/// ```
|
|
||||||
```
|
|
||||||
|
|
||||||
Hidden lines (prefixed with `#`) provide setup code while keeping examples readable.
|
|
||||||
|
|
||||||
**Key Fixes Required for Compilation:**
|
|
||||||
|
|
||||||
1. **Removed unnecessary `.build()` calls**: Builders implement `Into<T>`, so:
|
|
||||||
- `RigidBodyBuilder::dynamic().build()` → `RigidBodyBuilder::dynamic()`
|
|
||||||
- `ColliderBuilder::ball(0.5).build()` → `ColliderBuilder::ball(0.5)`
|
|
||||||
- These work directly with `insert()` and `insert_with_parent()`
|
|
||||||
|
|
||||||
2. **Fixed API calls to match actual implementation:**
|
|
||||||
- `&QueryDispatcher` → `narrow_phase.query_dispatcher()` (QueryPipeline needs a dispatcher reference)
|
|
||||||
- Added `NarrowPhase::new()` setup for query pipeline examples
|
|
||||||
|
|
||||||
3. **Corrected property/field names:**
|
|
||||||
- `hit.toi` → `hit.time_of_impact` (RayIntersection struct)
|
|
||||||
- `collider.shape()` → `collider.shared_shape()` (when printing/debugging)
|
|
||||||
|
|
||||||
4. **Added required setup for complex examples:**
|
|
||||||
- `project_point()` example: Added `IntegrationParameters`, `broad_phase.set_aabb()` call
|
|
||||||
- Character controller: Changed to `Ball::new(0.5)` instead of shape reference
|
|
||||||
- Joint examples: Fixed to use `Vector::y_axis()` instead of implicit axis
|
|
||||||
|
|
||||||
5. **Fixed joint constructor calls:**
|
|
||||||
- `RevoluteJoint::new()` → `RevoluteJoint::new(Vector::y_axis())` (axis required)
|
|
||||||
- `PrismaticJoint::new(...)` → `PrismaticJoint::new(Vector::x_axis())` (axis required)
|
|
||||||
|
|
||||||
**Remaining Work:**
|
|
||||||
- `geometry/collider.rs` has 12 ignored examples still marked as `ignore` (these are intentionally left as `ignore` for documentation purposes where full compilation context would be overly verbose)
|
|
||||||
|
|
||||||
**Impact:**
|
|
||||||
- ✅ Documentation examples now compile with `cargo test --doc`
|
|
||||||
- ✅ Examples stay correct as codebase evolves (tests will catch API changes)
|
|
||||||
- ✅ Copy-paste ready code that actually works
|
|
||||||
- ✅ Improved documentation quality and developer experience
|
|
||||||
- ✅ Builders work seamlessly without explicit `.build()` calls
|
|
||||||
|
|
||||||
## Examples Directory
|
|
||||||
|
|
||||||
`examples3d/` contains many demonstrations:
|
|
||||||
|
|
||||||
- `primitives3.rs` - Showcase of basic shapes
|
|
||||||
- `keva3.rs` - Large tower of blocks (stress test)
|
|
||||||
- `platform3.rs` - Moving kinematic platforms
|
|
||||||
- `joints3.rs` - All joint types demonstrated
|
|
||||||
- `character_controller3.rs` - Character movement
|
|
||||||
- `vehicle_controller3.rs` - Vehicle physics
|
|
||||||
- `ccd3.rs` - Fast bullets with CCD
|
|
||||||
- `sensor3.rs` - Trigger zones
|
|
||||||
- `despawn3.rs` - Removing objects
|
|
||||||
- `debug_boxes3.rs` - Visual debugging
|
|
||||||
- `rotating_floor_stacks3.rs` - **Custom example**: 20 pyramids (10×10 cube bases) on slowly rotating floor
|
|
||||||
|
|
||||||
**Run**: `cargo run --release --bin all_examples3`
|
|
||||||
|
|
||||||
## Building & Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Development build
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Release build (much faster!)
|
|
||||||
cargo build --release
|
|
||||||
|
|
||||||
# Run all 3D examples
|
|
||||||
cargo run --release --bin all_examples3
|
|
||||||
|
|
||||||
# Run all 2D examples
|
|
||||||
cargo run --release --bin all_examples2
|
|
||||||
|
|
||||||
# Run tests
|
|
||||||
cargo test
|
|
||||||
|
|
||||||
# With parallelism
|
|
||||||
cargo build --features parallel --release
|
|
||||||
|
|
||||||
# With SIMD
|
|
||||||
cargo build --features simd-stable --release
|
|
||||||
|
|
||||||
# Benchmarks
|
|
||||||
cargo run --release --manifest-path benchmarks3d/Cargo.toml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Cargo Features
|
|
||||||
|
|
||||||
- `parallel` - Multi-threaded solving (big performance gain on multi-core)
|
|
||||||
- `simd-stable` - SIMD optimizations on stable Rust
|
|
||||||
- `simd-nightly` - More SIMD opts on nightly
|
|
||||||
- `serde-serialize` - Snapshot/restore support
|
|
||||||
- `enhanced-determinism` - Stricter determinism (disables SIMD)
|
|
||||||
- `debug-render` - Visual debugging helpers
|
|
||||||
- `profiler` - Detailed performance counters
|
|
||||||
- `dim2` / `dim3` - 2D or 3D (set by crate, not user)
|
|
||||||
- `f32` / `f64` - Precision (set by crate, not user)
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
- **Official Site**: https://rapier.rs
|
|
||||||
- **User Guide**: https://rapier.rs/docs/
|
|
||||||
- **API Reference**: https://docs.rs/rapier3d
|
|
||||||
- **Discord**: https://discord.gg/vt9DJSW
|
|
||||||
- **GitHub**: https://github.com/dimforge/rapier
|
|
||||||
- **Blog**: https://www.dimforge.com/blog
|
|
||||||
- **Crates.io**: https://crates.io/crates/rapier3d
|
|
||||||
- **NPM** (JS/WASM): Available for web development
|
|
||||||
|
|
||||||
## Related Dimforge Projects
|
|
||||||
|
|
||||||
- **Parry**: Collision detection library (Rapier's foundation)
|
|
||||||
- **Salva**: SPH fluid simulation
|
|
||||||
- **nphysics**: Previous-gen physics engine (deprecated, use Rapier)
|
|
||||||
- **nalgebra**: Linear algebra library
|
|
||||||
- **Bevy_rapier**: Integration with Bevy game engine
|
|
||||||
|
|
||||||
## Quick Reference Card
|
|
||||||
|
|
||||||
### Most Common Operations
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Create world
|
|
||||||
let mut bodies = RigidBodySet::new();
|
|
||||||
let mut colliders = ColliderSet::new();
|
|
||||||
let mut joints = ImpulseJointSet::new();
|
|
||||||
let mut pipeline = PhysicsPipeline::new();
|
|
||||||
|
|
||||||
// Add dynamic ball
|
|
||||||
let body = bodies.insert(RigidBodyBuilder::dynamic().translation(vector![0.0, 5.0, 0.0]).build());
|
|
||||||
colliders.insert_with_parent(ColliderBuilder::ball(0.5).build(), body, &mut bodies);
|
|
||||||
|
|
||||||
// Add static floor
|
|
||||||
let floor = bodies.insert(RigidBodyBuilder::fixed().build());
|
|
||||||
colliders.insert_with_parent(ColliderBuilder::cuboid(10.0, 0.1, 10.0).build(), floor, &mut bodies);
|
|
||||||
|
|
||||||
// Simulate
|
|
||||||
pipeline.step(&gravity, ¶ms, &mut islands, &mut broad_phase, &mut narrow_phase,
|
|
||||||
&mut bodies, &mut colliders, &mut joints, &mut multibody_joints,
|
|
||||||
&mut ccd_solver, &(), &());
|
|
||||||
|
|
||||||
// Query
|
|
||||||
let pos = bodies[body].translation();
|
|
||||||
let vel = bodies[body].linvel();
|
|
||||||
|
|
||||||
// Modify
|
|
||||||
bodies[body].apply_impulse(vector![0.0, 100.0, 0.0], true);
|
|
||||||
bodies[body].set_linvel(vector![1.0, 0.0, 0.0], true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Material Presets
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Ice
|
|
||||||
.friction(0.01).restitution(0.1)
|
|
||||||
|
|
||||||
// Wood
|
|
||||||
.friction(0.5).restitution(0.2)
|
|
||||||
|
|
||||||
// Rubber
|
|
||||||
.friction(1.0).restitution(0.8)
|
|
||||||
|
|
||||||
// Metal
|
|
||||||
.friction(0.6).restitution(0.3)
|
|
||||||
|
|
||||||
// Bouncy ball
|
|
||||||
.friction(0.7).restitution(0.9)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Common Densities (kg/m³)
|
|
||||||
|
|
||||||
```rust
|
|
||||||
.density(1000.0) // Water
|
|
||||||
.density(2700.0) // Aluminum
|
|
||||||
.density(7850.0) // Steel
|
|
||||||
.density(11340.0) // Lead
|
|
||||||
.density(920.0) // Ice
|
|
||||||
.density(1.2) // Air
|
|
||||||
```
|
|
||||||
|
|
||||||
This documentation provides complete coverage of Rapier's architecture, APIs, usage patterns, and best practices for both beginners and advanced users!
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "rapier-benchmarks-2d"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
parallel = ["rapier2d/parallel", "rapier_testbed2d/parallel"]
|
|
||||||
simd-stable = ["rapier2d/simd-stable"]
|
|
||||||
simd-nightly = ["rapier2d/simd-nightly"]
|
|
||||||
other-backends = ["rapier_testbed2d/other-backends"]
|
|
||||||
enhanced-determinism = ["rapier2d/enhanced-determinism"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rand = "0.9"
|
|
||||||
Inflector = "0.11"
|
|
||||||
|
|
||||||
[dependencies.rapier_testbed2d]
|
|
||||||
path = "../crates/rapier_testbed2d"
|
|
||||||
|
|
||||||
[dependencies.rapier2d]
|
|
||||||
path = "../crates/rapier2d"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "all_benchmarks2"
|
|
||||||
path = "./all_benchmarks2.rs"
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use rapier_testbed2d::{Testbed, TestbedApp};
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod balls2;
|
|
||||||
mod boxes2;
|
|
||||||
mod capsules2;
|
|
||||||
mod convex_polygons2;
|
|
||||||
mod heightfield2;
|
|
||||||
mod joint_ball2;
|
|
||||||
mod joint_fixed2;
|
|
||||||
mod joint_prismatic2;
|
|
||||||
mod pyramid2;
|
|
||||||
mod vertical_stacks2;
|
|
||||||
|
|
||||||
fn demo_name_from_command_line() -> Option<String> {
|
|
||||||
let mut args = std::env::args();
|
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
|
||||||
if &arg[..] == "--example" {
|
|
||||||
return args.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
fn demo_name_from_url() -> Option<String> {
|
|
||||||
None
|
|
||||||
// let window = stdweb::web::window();
|
|
||||||
// let hash = window.location()?.search().ok()?;
|
|
||||||
// Some(hash[1..].to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
fn demo_name_from_url() -> Option<String> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
|
|
||||||
pub fn main() {
|
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
|
||||||
("Balls", balls2::init_world),
|
|
||||||
("Boxes", boxes2::init_world),
|
|
||||||
("Capsules", capsules2::init_world),
|
|
||||||
("Convex polygons", convex_polygons2::init_world),
|
|
||||||
("Heightfield", heightfield2::init_world),
|
|
||||||
("Pyramid", pyramid2::init_world),
|
|
||||||
("Verticals stacks", vertical_stacks2::init_world),
|
|
||||||
("(Stress test) joint ball", joint_ball2::init_world),
|
|
||||||
("(Stress test) joint fixed", joint_fixed2::init_world),
|
|
||||||
(
|
|
||||||
"(Stress test) joint prismatic",
|
|
||||||
joint_prismatic2::init_world,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with('('), b.0.starts_with('(')) {
|
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
|
||||||
(true, false) => Ordering::Greater,
|
|
||||||
(false, true) => Ordering::Less,
|
|
||||||
});
|
|
||||||
|
|
||||||
let testbed = TestbedApp::from_builders(builders);
|
|
||||||
|
|
||||||
testbed.run()
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "rapier-benchmarks-3d"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
parallel = ["rapier3d/parallel", "rapier_testbed3d/parallel"]
|
|
||||||
simd-stable = ["rapier3d/simd-stable"]
|
|
||||||
simd-nightly = ["rapier3d/simd-nightly"]
|
|
||||||
other-backends = ["rapier_testbed3d/other-backends"]
|
|
||||||
enhanced-determinism = ["rapier3d/enhanced-determinism"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rand = "0.9"
|
|
||||||
Inflector = "0.11"
|
|
||||||
oorandom = "11"
|
|
||||||
|
|
||||||
[dependencies.rapier_testbed3d]
|
|
||||||
path = "../crates/rapier_testbed3d"
|
|
||||||
|
|
||||||
[dependencies.rapier3d]
|
|
||||||
path = "../crates/rapier3d"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "all_benchmarks3"
|
|
||||||
path = "all_benchmarks3.rs"
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use inflector::Inflector;
|
|
||||||
|
|
||||||
use rapier_testbed3d::{Testbed, TestbedApp};
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod balls3;
|
|
||||||
mod boxes3;
|
|
||||||
mod capsules3;
|
|
||||||
mod ccd3;
|
|
||||||
mod compound3;
|
|
||||||
mod convex_polyhedron3;
|
|
||||||
mod heightfield3;
|
|
||||||
mod joint_ball3;
|
|
||||||
mod joint_fixed3;
|
|
||||||
mod joint_prismatic3;
|
|
||||||
mod joint_revolute3;
|
|
||||||
mod keva3;
|
|
||||||
mod many_kinematics3;
|
|
||||||
mod many_pyramids3;
|
|
||||||
mod many_sleep3;
|
|
||||||
mod many_static3;
|
|
||||||
mod pyramid3;
|
|
||||||
mod ray_cast3;
|
|
||||||
mod stacks3;
|
|
||||||
mod trimesh3;
|
|
||||||
|
|
||||||
enum Command {
|
|
||||||
Run(String),
|
|
||||||
List,
|
|
||||||
RunAll,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_command_line() -> Command {
|
|
||||||
let mut args = std::env::args();
|
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
|
||||||
if &arg[..] == "--example" {
|
|
||||||
return Command::Run(args.next().unwrap_or_default());
|
|
||||||
} else if &arg[..] == "--list" {
|
|
||||||
return Command::List;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Command::RunAll
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub fn demo_builders() -> Vec<(&'static str, fn(&mut Testbed))> {
|
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
|
||||||
("Balls", balls3::init_world),
|
|
||||||
("Boxes", boxes3::init_world),
|
|
||||||
("Capsules", capsules3::init_world),
|
|
||||||
("CCD", ccd3::init_world),
|
|
||||||
("Compound", compound3::init_world),
|
|
||||||
("Convex polyhedron", convex_polyhedron3::init_world),
|
|
||||||
("Many kinematics", many_kinematics3::init_world),
|
|
||||||
("Many static", many_static3::init_world),
|
|
||||||
("Many sleep", many_sleep3::init_world),
|
|
||||||
("Heightfield", heightfield3::init_world),
|
|
||||||
("Stacks", stacks3::init_world),
|
|
||||||
("Pyramid", pyramid3::init_world),
|
|
||||||
("Trimesh", trimesh3::init_world),
|
|
||||||
("ImpulseJoint ball", joint_ball3::init_world),
|
|
||||||
("ImpulseJoint fixed", joint_fixed3::init_world),
|
|
||||||
("ImpulseJoint revolute", joint_revolute3::init_world),
|
|
||||||
("ImpulseJoint prismatic", joint_prismatic3::init_world),
|
|
||||||
("Many pyramids", many_pyramids3::init_world),
|
|
||||||
("Keva tower", keva3::init_world),
|
|
||||||
("Ray cast", ray_cast3::init_world),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with('('), b.0.starts_with('(')) {
|
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
|
||||||
(true, false) => Ordering::Greater,
|
|
||||||
(false, true) => Ordering::Less,
|
|
||||||
});
|
|
||||||
builders
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
let command = parse_command_line();
|
|
||||||
let builders = demo_builders();
|
|
||||||
|
|
||||||
match command {
|
|
||||||
Command::Run(demo) => {
|
|
||||||
if let Some(i) = builders
|
|
||||||
.iter()
|
|
||||||
.position(|builder| builder.0.to_camel_case().as_str() == demo.as_str())
|
|
||||||
{
|
|
||||||
TestbedApp::from_builders(vec![builders[i]]).run()
|
|
||||||
} else {
|
|
||||||
eprintln!("Invalid example to run provided: '{demo}'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::RunAll => TestbedApp::from_builders(builders).run(),
|
|
||||||
Command::List => {
|
|
||||||
for builder in &builders {
|
|
||||||
println!("{}", builder.0.to_camel_case())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier2d-f64"
|
name = "rapier2d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "2-dimensional physics engine in Rust."
|
description = "2-dimensional physics engine in Rust."
|
||||||
documentation = "https://docs.rs/rapier2d"
|
documentation = "https://docs.rs/rapier2d"
|
||||||
@@ -24,7 +24,7 @@ maintenance = { status = "actively-developed" }
|
|||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
rust.unexpected_cfgs = { level = "warn", check-cfg = [
|
rust.unexpected_cfgs = { level = "warn", check-cfg = [
|
||||||
'cfg(feature, values("dim3", "f32"))',
|
'cfg(feature, values("dim3", "f32", "simd-is-enabled", "simd-stable", "simd-nightly"))',
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@@ -32,11 +32,12 @@ default = ["dim2", "f64"]
|
|||||||
dim2 = []
|
dim2 = []
|
||||||
f64 = []
|
f64 = []
|
||||||
parallel = ["dep:rayon"]
|
parallel = ["dep:rayon"]
|
||||||
simd-stable = ["simba/wide", "simd-is-enabled"]
|
# SoA SIMD not supported yet on f64
|
||||||
simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
|
#simd-stable = ["simba/wide", "simd-is-enabled"]
|
||||||
# Do not enable this feature directly. It is automatically
|
#simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
|
||||||
# enabled with the "simd-stable" or "simd-nightly" feature.
|
## Do not enable this feature directly. It is automatically
|
||||||
simd-is-enabled = ["dep:vec_map"]
|
## enabled with the "simd-stable" or "simd-nightly" feature.
|
||||||
|
#simd-is-enabled = []
|
||||||
serde-serialize = [
|
serde-serialize = [
|
||||||
"nalgebra/serde-serialize",
|
"nalgebra/serde-serialize",
|
||||||
"parry2d-f64/serde-serialize",
|
"parry2d-f64/serde-serialize",
|
||||||
@@ -66,11 +67,12 @@ required-features = ["dim2", "f64"]
|
|||||||
doctest = false # All doctests are written assuming the 3D version.
|
doctest = false # All doctests are written assuming the 3D version.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vec_map = { version = "0.8", optional = true }
|
vec_map = "0.8"
|
||||||
web-time = { version = "1.1", optional = true }
|
web-time = { version = "1.1", optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.34"
|
nalgebra = "0.34"
|
||||||
parry2d-f64 = "0.25.1"
|
glamx = { version = "0.1", features = ["nalgebra"] }
|
||||||
|
parry2d-f64 = "0.26.0"
|
||||||
simba = "0.9.1"
|
simba = "0.9.1"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier2d"
|
name = "rapier2d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "2-dimensional physics engine in Rust."
|
description = "2-dimensional physics engine in Rust."
|
||||||
documentation = "https://docs.rs/rapier2d"
|
documentation = "https://docs.rs/rapier2d"
|
||||||
@@ -37,7 +37,7 @@ simd-stable = ["simba/wide", "parry2d/simd-stable", "simd-is-enabled"]
|
|||||||
simd-nightly = ["simba/portable_simd", "parry2d/simd-nightly", "simd-is-enabled"]
|
simd-nightly = ["simba/portable_simd", "parry2d/simd-nightly", "simd-is-enabled"]
|
||||||
# Do not enable this feature directly. It is automatically
|
# Do not enable this feature directly. It is automatically
|
||||||
# enabled with the "simd-stable" or "simd-nightly" feature.
|
# enabled with the "simd-stable" or "simd-nightly" feature.
|
||||||
simd-is-enabled = ["dep:vec_map"]
|
simd-is-enabled = []
|
||||||
serde-serialize = [
|
serde-serialize = [
|
||||||
"nalgebra/serde-serialize",
|
"nalgebra/serde-serialize",
|
||||||
"parry2d/serde-serialize",
|
"parry2d/serde-serialize",
|
||||||
@@ -67,11 +67,12 @@ required-features = ["dim2", "f32"]
|
|||||||
doctest = false # All doctests are written assuming the 3D version.
|
doctest = false # All doctests are written assuming the 3D version.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vec_map = { version = "0.8", optional = true }
|
vec_map = "0.8"
|
||||||
web-time = { version = "1.1", optional = true }
|
web-time = { version = "1.1", optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.34"
|
nalgebra = "0.34"
|
||||||
parry2d = "0.25.1"
|
glamx = { version = "0.1", features = ["nalgebra"] }
|
||||||
|
parry2d = "0.26.0"
|
||||||
simba = "0.9.1"
|
simba = "0.9.1"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier3d-f64"
|
name = "rapier3d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "3-dimensional physics engine in Rust."
|
description = "3-dimensional physics engine in Rust."
|
||||||
documentation = "https://docs.rs/rapier3d"
|
documentation = "https://docs.rs/rapier3d"
|
||||||
@@ -24,7 +24,7 @@ maintenance = { status = "actively-developed" }
|
|||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
rust.unexpected_cfgs = { level = "warn", check-cfg = [
|
rust.unexpected_cfgs = { level = "warn", check-cfg = [
|
||||||
'cfg(feature, values("dim2", "f32"))',
|
'cfg(feature, values("dim2", "f32", "simd-is-enabled", "simd-stable", "simd-nightly"))',
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@@ -32,15 +32,16 @@ default = ["dim3", "f64"]
|
|||||||
dim3 = []
|
dim3 = []
|
||||||
f64 = []
|
f64 = []
|
||||||
parallel = ["dep:rayon"]
|
parallel = ["dep:rayon"]
|
||||||
simd-stable = ["parry3d-f64/simd-stable", "simba/wide", "simd-is-enabled"]
|
# SoA SIMD not supported yet on f64
|
||||||
simd-nightly = [
|
#simd-stable = ["parry3d-f64/simd-stable", "simba/wide", "simd-is-enabled"]
|
||||||
"parry3d-f64/simd-nightly",
|
#simd-nightly = [
|
||||||
"simba/portable_simd",
|
# "parry3d-f64/simd-nightly",
|
||||||
"simd-is-enabled",
|
# "simba/portable_simd",
|
||||||
]
|
# "simd-is-enabled",
|
||||||
# Do not enable this feature directly. It is automatically
|
#]
|
||||||
# enabled with the "simd-stable" or "simd-nightly" feature.
|
## Do not enable this feature directly. It is automatically
|
||||||
simd-is-enabled = ["dep:vec_map"]
|
## enabled with the "simd-stable" or "simd-nightly" feature.
|
||||||
|
#simd-is-enabled = []
|
||||||
serde-serialize = [
|
serde-serialize = [
|
||||||
"nalgebra/serde-serialize",
|
"nalgebra/serde-serialize",
|
||||||
"parry3d-f64/serde-serialize",
|
"parry3d-f64/serde-serialize",
|
||||||
@@ -69,11 +70,12 @@ required-features = ["dim3", "f64"]
|
|||||||
doctest = false # All doctests are written assuming the 3D f32 version.
|
doctest = false # All doctests are written assuming the 3D f32 version.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vec_map = { version = "0.8", optional = true }
|
vec_map = "0.8"
|
||||||
web-time = { version = "1.1", optional = true }
|
web-time = { version = "1.1", optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.34"
|
nalgebra = "0.34"
|
||||||
parry3d-f64 = "0.25.1"
|
glamx = { version = "0.1", features = ["nalgebra"] }
|
||||||
|
parry3d-f64 = "0.26.0"
|
||||||
simba = "0.9.1"
|
simba = "0.9.1"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier3d-meshloader"
|
name = "rapier3d-meshloader"
|
||||||
version = "0.12.0"
|
version = "0.13.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "STL file loader for the 3D rapier physics engine."
|
description = "STL file loader for the 3D rapier physics engine."
|
||||||
documentation = "https://docs.rs/rapier3d-meshloader"
|
documentation = "https://docs.rs/rapier3d-meshloader"
|
||||||
@@ -29,4 +29,4 @@ thiserror = "2"
|
|||||||
profiling = "1.0"
|
profiling = "1.0"
|
||||||
mesh-loader = "0.1.12"
|
mesh-loader = "0.1.12"
|
||||||
|
|
||||||
rapier3d = { version = "0.31.0", path = "../rapier3d" }
|
rapier3d = { version = "0.32.0", path = "../rapier3d" }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use mesh_loader::Mesh;
|
use mesh_loader::Mesh;
|
||||||
use rapier3d::geometry::{MeshConverter, SharedShape};
|
use rapier3d::geometry::{MeshConverter, SharedShape};
|
||||||
use rapier3d::math::{Isometry, Point, Real, Vector};
|
use rapier3d::math::{Pose, Vector};
|
||||||
use rapier3d::prelude::MeshConverterError;
|
use rapier3d::prelude::MeshConverterError;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@@ -11,8 +11,8 @@ use std::path::Path;
|
|||||||
pub struct LoadedShape {
|
pub struct LoadedShape {
|
||||||
/// The shape loaded from the file and converted by the [`MeshConverter`].
|
/// The shape loaded from the file and converted by the [`MeshConverter`].
|
||||||
pub shape: SharedShape,
|
pub shape: SharedShape,
|
||||||
/// The shape’s pose.
|
/// The shape's pose.
|
||||||
pub pose: Isometry<Real>,
|
pub pose: Pose,
|
||||||
/// The raw mesh read from the file without any modification.
|
/// The raw mesh read from the file without any modification.
|
||||||
pub raw_mesh: Mesh,
|
pub raw_mesh: Mesh,
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ pub enum MeshLoaderError {
|
|||||||
pub fn load_from_path(
|
pub fn load_from_path(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
converter: &MeshConverter,
|
converter: &MeshConverter,
|
||||||
scale: Vector<Real>,
|
scale: Vector,
|
||||||
) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> {
|
) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> {
|
||||||
let loader = mesh_loader::Loader::default();
|
let loader = mesh_loader::Loader::default();
|
||||||
let mut colliders = vec![];
|
let mut colliders = vec![];
|
||||||
@@ -71,16 +71,13 @@ pub fn load_from_path(
|
|||||||
pub fn load_from_raw_mesh(
|
pub fn load_from_raw_mesh(
|
||||||
raw_mesh: &Mesh,
|
raw_mesh: &Mesh,
|
||||||
converter: &MeshConverter,
|
converter: &MeshConverter,
|
||||||
scale: Vector<Real>,
|
scale: Vector,
|
||||||
) -> Result<(SharedShape, Isometry<Real>), MeshConverterError> {
|
) -> Result<(SharedShape, Pose), MeshConverterError> {
|
||||||
let mut vertices: Vec<_> = raw_mesh
|
let vertices: Vec<_> = raw_mesh
|
||||||
.vertices
|
.vertices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|xyz| Point::new(xyz[0], xyz[1], xyz[2]))
|
.map(|xyz| Vector::new(xyz[0], xyz[1], xyz[2]) * scale)
|
||||||
.collect();
|
.collect();
|
||||||
vertices
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|pt| pt.coords.component_mul_assign(&scale));
|
|
||||||
let indices: Vec<_> = raw_mesh.faces.clone();
|
let indices: Vec<_> = raw_mesh.faces.clone();
|
||||||
converter.convert(vertices, indices)
|
converter.convert(vertices, indices)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier3d-urdf"
|
name = "rapier3d-urdf"
|
||||||
version = "0.12.0"
|
version = "0.13.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "URDF file loader for the 3D rapier physics engine."
|
description = "URDF file loader for the 3D rapier physics engine."
|
||||||
documentation = "https://docs.rs/rapier3d-urdf"
|
documentation = "https://docs.rs/rapier3d-urdf"
|
||||||
@@ -31,5 +31,5 @@ anyhow = "1"
|
|||||||
bitflags = "2"
|
bitflags = "2"
|
||||||
urdf-rs = "0.9"
|
urdf-rs = "0.9"
|
||||||
|
|
||||||
rapier3d = { version = "0.31.0", path = "../rapier3d" }
|
rapier3d = { version = "0.32.0", path = "../rapier3d" }
|
||||||
rapier3d-meshloader = { version = "0.12.0", path = "../rapier3d-meshloader", default-features = false, optional = true }
|
rapier3d-meshloader = { version = "0.13.0", path = "../rapier3d-meshloader", default-features = false, optional = true }
|
||||||
|
|||||||
@@ -35,12 +35,13 @@ use rapier3d::{
|
|||||||
RigidBodyBuilder, RigidBodyHandle, RigidBodySet, RigidBodyType,
|
RigidBodyBuilder, RigidBodyHandle, RigidBodySet, RigidBodyType,
|
||||||
},
|
},
|
||||||
geometry::{Collider, ColliderBuilder, ColliderHandle, ColliderSet, SharedShape, TriMeshFlags},
|
geometry::{Collider, ColliderBuilder, ColliderHandle, ColliderSet, SharedShape, TriMeshFlags},
|
||||||
math::{Isometry, Point, Real, Vector},
|
glamx::EulerRot,
|
||||||
|
math::{Pose, Real, Rotation, Vector},
|
||||||
na,
|
na,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use urdf_rs::{Geometry, Inertial, Joint, Pose, Robot};
|
use urdf_rs::{Geometry, Inertial, Joint, Pose as UrdfPose, Robot};
|
||||||
|
|
||||||
#[cfg(doc)]
|
#[cfg(doc)]
|
||||||
use rapier3d::dynamics::Multibody;
|
use rapier3d::dynamics::Multibody;
|
||||||
@@ -104,8 +105,8 @@ pub struct UrdfLoaderOptions {
|
|||||||
/// Note that the default enables all the flags. This is operating under the assumption that the provided
|
/// Note that the default enables all the flags. This is operating under the assumption that the provided
|
||||||
/// mesh are generally well-formed and properly oriented (2-manifolds with outward normals).
|
/// mesh are generally well-formed and properly oriented (2-manifolds with outward normals).
|
||||||
pub trimesh_flags: TriMeshFlags,
|
pub trimesh_flags: TriMeshFlags,
|
||||||
/// The transform appended to every created rigid-bodies (default: [`Isometry::identity`]).
|
/// The transform appended to every created rigid-bodies (default: `Pose::IDENTITY`).
|
||||||
pub shift: Isometry<Real>,
|
pub shift: Pose,
|
||||||
/// A description of the collider properties that need to be applied to every collider created
|
/// A description of the collider properties that need to be applied to every collider created
|
||||||
/// by the loader (default: `ColliderBuilder::default().density(0.0)`).
|
/// by the loader (default: `ColliderBuilder::default().density(0.0)`).
|
||||||
///
|
///
|
||||||
@@ -136,7 +137,7 @@ impl Default for UrdfLoaderOptions {
|
|||||||
enable_joint_collisions: false,
|
enable_joint_collisions: false,
|
||||||
make_roots_fixed: false,
|
make_roots_fixed: false,
|
||||||
trimesh_flags: TriMeshFlags::all(),
|
trimesh_flags: TriMeshFlags::all(),
|
||||||
shift: Isometry::identity(),
|
shift: Pose::IDENTITY,
|
||||||
collider_blueprint: ColliderBuilder::default().density(0.0),
|
collider_blueprint: ColliderBuilder::default().density(0.0),
|
||||||
rigid_body_blueprint: RigidBodyBuilder::dynamic(),
|
rigid_body_blueprint: RigidBodyBuilder::dynamic(),
|
||||||
}
|
}
|
||||||
@@ -295,7 +296,8 @@ impl UrdfRobot {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
let mut body = urdf_to_rigid_body(&options, &link.inertial);
|
let mut body = urdf_to_rigid_body(&options, &link.inertial);
|
||||||
body.set_position(options.shift * body.position(), false);
|
let new_pos = options.shift * body.position();
|
||||||
|
body.set_position(new_pos, false);
|
||||||
UrdfLink { body, colliders }
|
UrdfLink { body, colliders }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -429,30 +431,30 @@ impl UrdfRobot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Appends a transform to all the rigid-bodie of this robot.
|
/// Appends a transform to all the rigid-bodie of this robot.
|
||||||
pub fn append_transform(&mut self, transform: &Isometry<Real>) {
|
pub fn append_transform(&mut self, transform: &Pose) {
|
||||||
for link in &mut self.links {
|
for link in &mut self.links {
|
||||||
link.body
|
let new_pos = transform * link.body.position();
|
||||||
.set_position(transform * link.body.position(), true);
|
link.body.set_position(new_pos, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn urdf_to_rigid_body(options: &UrdfLoaderOptions, inertial: &Inertial) -> RigidBody {
|
fn urdf_to_rigid_body(options: &UrdfLoaderOptions, inertial: &Inertial) -> RigidBody {
|
||||||
let origin = urdf_to_isometry(&inertial.origin);
|
let origin = urdf_to_pose(&inertial.origin);
|
||||||
let mut builder = options.rigid_body_blueprint.clone();
|
let mut builder = options.rigid_body_blueprint.clone();
|
||||||
builder.body_type = RigidBodyType::Dynamic;
|
builder.body_type = RigidBodyType::Dynamic;
|
||||||
|
|
||||||
if options.apply_imported_mass_props {
|
if options.apply_imported_mass_props {
|
||||||
builder = builder.additional_mass_properties(MassProperties::with_inertia_matrix(
|
builder = builder.additional_mass_properties(MassProperties::with_inertia_matrix(
|
||||||
origin.translation.vector.into(),
|
origin.translation,
|
||||||
inertial.mass.value as Real,
|
inertial.mass.value as Real,
|
||||||
// See http://wiki.ros.org/urdf/Tutorials/Adding%20Physical%20and%20Collision%20Properties%20to%20a%20URDF%20Model#Inertia
|
// See http://wiki.ros.org/urdf/Tutorials/Adding%20Physical%20and%20Collision%20Properties%20to%20a%20URDF%20Model#Inertia
|
||||||
na::Matrix3::new(
|
na::Matrix3::new(
|
||||||
inertial.inertia.ixx as Real, inertial.inertia.ixy as Real, inertial.inertia.ixz as Real,
|
inertial.inertia.ixx as Real, inertial.inertia.ixy as Real, inertial.inertia.ixz as Real,
|
||||||
inertial.inertia.ixy as Real, inertial.inertia.iyy as Real, inertial.inertia.iyz as Real,
|
inertial.inertia.ixy as Real, inertial.inertia.iyy as Real, inertial.inertia.iyz as Real,
|
||||||
inertial.inertia.ixz as Real, inertial.inertia.iyz as Real,inertial.inertia.izz as Real,
|
inertial.inertia.ixz as Real, inertial.inertia.iyz as Real,inertial.inertia.izz as Real,
|
||||||
),
|
).into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,9 +465,9 @@ fn urdf_to_colliders(
|
|||||||
options: &UrdfLoaderOptions,
|
options: &UrdfLoaderOptions,
|
||||||
_mesh_dir: &Path, // Unused if none of the meshloader features is enabled.
|
_mesh_dir: &Path, // Unused if none of the meshloader features is enabled.
|
||||||
geometry: &Geometry,
|
geometry: &Geometry,
|
||||||
origin: &Pose,
|
origin: &UrdfPose,
|
||||||
) -> Vec<Collider> {
|
) -> Vec<Collider> {
|
||||||
let mut shape_transform = Isometry::identity();
|
let mut shape_transform = Pose::IDENTITY;
|
||||||
|
|
||||||
let mut colliders = Vec::new();
|
let mut colliders = Vec::new();
|
||||||
|
|
||||||
@@ -480,7 +482,7 @@ fn urdf_to_colliders(
|
|||||||
Geometry::Cylinder { radius, length } => {
|
Geometry::Cylinder { radius, length } => {
|
||||||
// This rotation will make the cylinder Z-up as per the URDF spec,
|
// This rotation will make the cylinder Z-up as per the URDF spec,
|
||||||
// instead of rapier’s default Y-up.
|
// instead of rapier’s default Y-up.
|
||||||
shape_transform = Isometry::rotation(Vector::x() * Real::frac_pi_2());
|
shape_transform = Pose::rotation(Vector::X * Real::frac_pi_2());
|
||||||
colliders.push(SharedShape::cylinder(
|
colliders.push(SharedShape::cylinder(
|
||||||
*length as Real / 2.0,
|
*length as Real / 2.0,
|
||||||
*radius as Real,
|
*radius as Real,
|
||||||
@@ -506,7 +508,7 @@ fn urdf_to_colliders(
|
|||||||
let full_path = _mesh_dir.join(filename);
|
let full_path = _mesh_dir.join(filename);
|
||||||
let scale = scale
|
let scale = scale
|
||||||
.map(|s| Vector::new(s[0] as Real, s[1] as Real, s[2] as Real))
|
.map(|s| Vector::new(s[0] as Real, s[1] as Real, s[2] as Real))
|
||||||
.unwrap_or_else(|| Vector::<Real>::repeat(1.0));
|
.unwrap_or_else(|| Vector::splat(1.0));
|
||||||
|
|
||||||
let Ok(loaded_mesh) = rapier3d_meshloader::load_from_path(
|
let Ok(loaded_mesh) = rapier3d_meshloader::load_from_path(
|
||||||
full_path,
|
full_path,
|
||||||
@@ -530,21 +532,21 @@ fn urdf_to_colliders(
|
|||||||
let mut builder = options.collider_blueprint.clone();
|
let mut builder = options.collider_blueprint.clone();
|
||||||
builder.shape = shape;
|
builder.shape = shape;
|
||||||
builder
|
builder
|
||||||
.position(urdf_to_isometry(origin) * shape_transform)
|
.position(urdf_to_pose(origin) * shape_transform)
|
||||||
.build()
|
.build()
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn urdf_to_isometry(pose: &Pose) -> Isometry<Real> {
|
fn urdf_to_pose(pose: &UrdfPose) -> Pose {
|
||||||
Isometry::from_parts(
|
Pose::from_parts(
|
||||||
Point::new(
|
Vector::new(
|
||||||
pose.xyz[0] as Real,
|
pose.xyz[0] as Real,
|
||||||
pose.xyz[1] as Real,
|
pose.xyz[1] as Real,
|
||||||
pose.xyz[2] as Real,
|
pose.xyz[2] as Real,
|
||||||
)
|
),
|
||||||
.into(),
|
Rotation::from_euler(
|
||||||
na::UnitQuaternion::from_euler_angles(
|
EulerRot::XYZ,
|
||||||
pose.rpy[0] as Real,
|
pose.rpy[0] as Real,
|
||||||
pose.rpy[1] as Real,
|
pose.rpy[1] as Real,
|
||||||
pose.rpy[2] as Real,
|
pose.rpy[2] as Real,
|
||||||
@@ -555,7 +557,7 @@ fn urdf_to_isometry(pose: &Pose) -> Isometry<Real> {
|
|||||||
fn urdf_to_joint(
|
fn urdf_to_joint(
|
||||||
options: &UrdfLoaderOptions,
|
options: &UrdfLoaderOptions,
|
||||||
joint: &Joint,
|
joint: &Joint,
|
||||||
pose1: &Isometry<Real>,
|
pose1: &Pose,
|
||||||
link2: &mut RigidBody,
|
link2: &mut RigidBody,
|
||||||
) -> GenericJoint {
|
) -> GenericJoint {
|
||||||
let locked_axes = match joint.joint_type {
|
let locked_axes = match joint.joint_type {
|
||||||
@@ -568,25 +570,23 @@ fn urdf_to_joint(
|
|||||||
urdf_rs::JointType::Prismatic => JointAxesMask::LOCKED_PRISMATIC_AXES,
|
urdf_rs::JointType::Prismatic => JointAxesMask::LOCKED_PRISMATIC_AXES,
|
||||||
urdf_rs::JointType::Spherical => JointAxesMask::LOCKED_SPHERICAL_AXES,
|
urdf_rs::JointType::Spherical => JointAxesMask::LOCKED_SPHERICAL_AXES,
|
||||||
};
|
};
|
||||||
let joint_to_parent = urdf_to_isometry(&joint.origin);
|
let joint_to_parent = urdf_to_pose(&joint.origin);
|
||||||
let joint_axis = na::Unit::try_new(
|
let joint_axis = Vector::new(
|
||||||
Vector::new(
|
joint.axis.xyz[0] as Real,
|
||||||
joint.axis.xyz[0] as Real,
|
joint.axis.xyz[1] as Real,
|
||||||
joint.axis.xyz[1] as Real,
|
joint.axis.xyz[2] as Real,
|
||||||
joint.axis.xyz[2] as Real,
|
)
|
||||||
),
|
.normalize_or_zero();
|
||||||
1.0e-5,
|
|
||||||
);
|
|
||||||
|
|
||||||
link2.set_position(pose1 * joint_to_parent, false);
|
link2.set_position(pose1 * joint_to_parent, false);
|
||||||
|
|
||||||
let mut builder = GenericJointBuilder::new(locked_axes)
|
let mut builder = GenericJointBuilder::new(locked_axes)
|
||||||
.local_anchor1(joint_to_parent.translation.vector.into())
|
.local_anchor1(joint_to_parent.translation)
|
||||||
.contacts_enabled(options.enable_joint_collisions);
|
.contacts_enabled(options.enable_joint_collisions);
|
||||||
|
|
||||||
if let Some(joint_axis) = joint_axis {
|
if joint_axis != Vector::ZERO {
|
||||||
builder = builder
|
builder = builder
|
||||||
.local_axis1(joint_to_parent * joint_axis)
|
.local_axis1(joint_to_parent.rotation * joint_axis)
|
||||||
.local_axis2(joint_axis);
|
.local_axis2(joint_axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier3d"
|
name = "rapier3d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "3-dimensional physics engine in Rust."
|
description = "3-dimensional physics engine in Rust."
|
||||||
documentation = "https://docs.rs/rapier3d"
|
documentation = "https://docs.rs/rapier3d"
|
||||||
@@ -42,7 +42,7 @@ simd-nightly = [
|
|||||||
]
|
]
|
||||||
# Do not enable this feature directly. It is automatically
|
# Do not enable this feature directly. It is automatically
|
||||||
# enabled with the "simd-stable" or "simd-nightly" feature.
|
# enabled with the "simd-stable" or "simd-nightly" feature.
|
||||||
simd-is-enabled = ["dep:vec_map"]
|
simd-is-enabled = []
|
||||||
serde-serialize = [
|
serde-serialize = [
|
||||||
"nalgebra/serde-serialize",
|
"nalgebra/serde-serialize",
|
||||||
"parry3d/serde-serialize",
|
"parry3d/serde-serialize",
|
||||||
@@ -71,11 +71,12 @@ required-features = ["dim3", "f32"]
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vec_map = { version = "0.8", optional = true }
|
vec_map = "0.8"
|
||||||
web-time = { version = "1.1", optional = true }
|
web-time = { version = "1.1", optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.34"
|
nalgebra = "0.34"
|
||||||
parry3d = "0.25.1"
|
glamx = { version = "0.1", features = ["nalgebra"] }
|
||||||
|
parry3d = "0.26.0"
|
||||||
simba = "0.9.1"
|
simba = "0.9.1"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier_testbed2d-f64"
|
name = "rapier_testbed2d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "Testbed for the Rapier 2-dimensional physics engine in Rust."
|
description = "Testbed for the Rapier 2-dimensional physics engine in Rust."
|
||||||
homepage = "http://rapier.rs"
|
homepage = "http://rapier.rs"
|
||||||
@@ -44,6 +44,7 @@ features = ["parallel", "profiler_ui"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
||||||
|
glamx = "0.1"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rand_pcg = "0.9"
|
rand_pcg = "0.9"
|
||||||
web-time = { version = "1.1" }
|
web-time = { version = "1.1" }
|
||||||
@@ -52,51 +53,17 @@ num_cpus = { version = "1", optional = true }
|
|||||||
wrapped2d = { version = "0.4", optional = true }
|
wrapped2d = { version = "0.4", optional = true }
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
Inflector = "0.11"
|
Inflector = "0.11"
|
||||||
md5 = "0.7"
|
md5 = "0.8"
|
||||||
bevy_egui = "0.31"
|
egui = "0.33"
|
||||||
bevy_ecs = "0.15"
|
|
||||||
bevy_core_pipeline = "0.15"
|
|
||||||
bevy_pbr = "0.15"
|
|
||||||
bevy_sprite = "0.15"
|
|
||||||
profiling = "1.0"
|
profiling = "1.0"
|
||||||
puffin_egui = { version = "0.29", optional = true }
|
puffin_egui = { version = "0.29", optional = true }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
# Dependencies for native only.
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_asset",
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"x11",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
"serialize"
|
|
||||||
] }
|
|
||||||
|
|
||||||
# Dependencies for WASM only.
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_asset",
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
] }
|
|
||||||
#bevy_webgl2 = "0.5"
|
|
||||||
|
|
||||||
[dependencies.rapier]
|
[dependencies.rapier]
|
||||||
package = "rapier2d-f64"
|
package = "rapier2d-f64"
|
||||||
path = "../rapier2d-f64"
|
path = "../rapier2d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
features = ["serde-serialize", "debug-render", "profiler"]
|
features = ["serde-serialize", "debug-render", "profiler"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier_testbed2d"
|
name = "rapier_testbed2d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "Testbed for the Rapier 2-dimensional physics engine in Rust."
|
description = "Testbed for the Rapier 2-dimensional physics engine in Rust."
|
||||||
homepage = "http://rapier.rs"
|
homepage = "http://rapier.rs"
|
||||||
@@ -44,6 +44,7 @@ features = ["parallel", "other-backends", "profiler_ui"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
||||||
|
glamx = "0.1"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rand_pcg = "0.9"
|
rand_pcg = "0.9"
|
||||||
web-time = { version = "1.1" }
|
web-time = { version = "1.1" }
|
||||||
@@ -52,51 +53,17 @@ num_cpus = { version = "1", optional = true }
|
|||||||
wrapped2d = { version = "0.4", optional = true }
|
wrapped2d = { version = "0.4", optional = true }
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
Inflector = "0.11"
|
Inflector = "0.11"
|
||||||
md5 = "0.7"
|
md5 = "0.8"
|
||||||
bevy_egui = "0.31"
|
egui = "0.33"
|
||||||
bevy_ecs = "0.15"
|
|
||||||
bevy_core_pipeline = "0.15"
|
|
||||||
bevy_pbr = "0.15"
|
|
||||||
bevy_sprite = "0.15"
|
|
||||||
profiling = "1.0"
|
profiling = "1.0"
|
||||||
puffin_egui = { version = "0.29", optional = true }
|
puffin_egui = { version = "0.29", optional = true }
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
# Dependencies for native only.
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_sprite",
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"x11",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
"serialize"
|
|
||||||
] }
|
|
||||||
|
|
||||||
# Dependencies for WASM only.
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_sprite",
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
] }
|
|
||||||
#bevy_webgl2 = "0.5"
|
|
||||||
|
|
||||||
[dependencies.rapier]
|
[dependencies.rapier]
|
||||||
package = "rapier2d"
|
package = "rapier2d"
|
||||||
path = "../rapier2d"
|
path = "../rapier2d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
features = ["serde-serialize", "debug-render", "profiler"]
|
features = ["serde-serialize", "debug-render", "profiler"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier_testbed3d-f64"
|
name = "rapier_testbed3d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "Testbed for the Rapier 3-dimensional physics engine in Rust."
|
description = "Testbed for the Rapier 3-dimensional physics engine in Rust."
|
||||||
homepage = "http://rapier.rs"
|
homepage = "http://rapier.rs"
|
||||||
@@ -46,6 +46,7 @@ features = ["parallel", "profiler_ui"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
||||||
|
glamx = "0.1"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rand_pcg = "0.9"
|
rand_pcg = "0.9"
|
||||||
web-time = { version = "1.1" }
|
web-time = { version = "1.1" }
|
||||||
@@ -54,50 +55,16 @@ num_cpus = { version = "1", optional = true }
|
|||||||
bincode = "1"
|
bincode = "1"
|
||||||
md5 = "0.7"
|
md5 = "0.7"
|
||||||
Inflector = "0.11"
|
Inflector = "0.11"
|
||||||
|
egui = "0.33"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
bevy_egui = "0.31"
|
|
||||||
bevy_ecs = "0.15"
|
|
||||||
bevy_core_pipeline = "0.15"
|
|
||||||
bevy_pbr = "0.15"
|
|
||||||
bevy_sprite = "0.15"
|
|
||||||
profiling = "1.0"
|
profiling = "1.0"
|
||||||
puffin_egui = { version = "0.29", optional = true, git = "https://github.com/Vrixyz/puffin.git", branch = "expose_ui_options" }
|
puffin_egui = { version = "0.29", optional = true }
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
# Dependencies for native only.
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"x11",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
"serialize"
|
|
||||||
] }
|
|
||||||
|
|
||||||
# Dependencies for WASM only.
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"bevy_window",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
"serialize"
|
|
||||||
] }
|
|
||||||
#bevy_webgl2 = "0.5"
|
|
||||||
|
|
||||||
[dependencies.rapier]
|
[dependencies.rapier]
|
||||||
package = "rapier3d-f64"
|
package = "rapier3d-f64"
|
||||||
path = "../rapier3d-f64"
|
path = "../rapier3d-f64"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
features = ["serde-serialize", "debug-render", "profiler"]
|
features = ["serde-serialize", "debug-render", "profiler"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rapier_testbed3d"
|
name = "rapier_testbed3d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
authors = ["Sébastien Crozet <sebcrozet@dimforge.com>"]
|
||||||
description = "Testbed for the Rapier 3-dimensional physics engine in Rust."
|
description = "Testbed for the Rapier 3-dimensional physics engine in Rust."
|
||||||
homepage = "http://rapier.rs"
|
homepage = "http://rapier.rs"
|
||||||
@@ -44,6 +44,7 @@ features = ["parallel", "other-backends", "profiler_ui"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
nalgebra = { version = "0.34", features = ["rand", "glam029"] }
|
||||||
|
glamx = "0.1"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rand_pcg = "0.9"
|
rand_pcg = "0.9"
|
||||||
web-time = { version = "1.1" }
|
web-time = { version = "1.1" }
|
||||||
@@ -57,45 +58,14 @@ md5 = "0.7"
|
|||||||
Inflector = "0.11"
|
Inflector = "0.11"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
bevy_egui = "0.31"
|
egui = "0.33"
|
||||||
bevy_ecs = "0.15"
|
|
||||||
bevy_core_pipeline = "0.15"
|
|
||||||
bevy_pbr = "0.15"
|
|
||||||
bevy_sprite = "0.15"
|
|
||||||
profiling = "1.0"
|
profiling = "1.0"
|
||||||
puffin_egui = { version = "0.29", optional = true }
|
puffin_egui = { version = "0.29", optional = true }
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
# Dependencies for native only.
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_winit",
|
|
||||||
"bevy_window",
|
|
||||||
"x11",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
"serialize"
|
|
||||||
] }
|
|
||||||
|
|
||||||
# Dependencies for WASM only.
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
|
||||||
"bevy_winit",
|
|
||||||
"tonemapping_luts",
|
|
||||||
"ktx2",
|
|
||||||
"zstd",
|
|
||||||
"bevy_render",
|
|
||||||
"bevy_pbr",
|
|
||||||
"bevy_gizmos",
|
|
||||||
] }
|
|
||||||
#bevy_webgl2 = "0.5"
|
|
||||||
|
|
||||||
[dependencies.rapier]
|
[dependencies.rapier]
|
||||||
package = "rapier3d"
|
package = "rapier3d"
|
||||||
path = "../rapier3d"
|
path = "../rapier3d"
|
||||||
version = "0.31.0"
|
version = "0.32.0"
|
||||||
features = ["serde-serialize", "debug-render", "profiler"]
|
features = ["serde-serialize", "debug-render", "profiler"]
|
||||||
|
|||||||
@@ -15,12 +15,15 @@ enhanced-determinism = ["rapier2d/enhanced-determinism"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
lyon = "0.17"
|
lyon = "0.17"
|
||||||
usvg = "0.14"
|
|
||||||
dot_vox = "5"
|
dot_vox = "5"
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
|
|
||||||
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
|
usvg = "0.14"
|
||||||
|
|
||||||
[dependencies.rapier_testbed2d]
|
[dependencies.rapier_testbed2d]
|
||||||
path = "../crates/rapier_testbed2d"
|
path = "../crates/rapier_testbed2d"
|
||||||
features = ["profiler_ui"]
|
#features = ["profiler_ui"]
|
||||||
|
|
||||||
[dependencies.rapier2d]
|
[dependencies.rapier2d]
|
||||||
path = "../crates/rapier2d"
|
path = "../crates/rapier2d"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::{na::UnitComplex, prelude::*};
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
pub fn init_world(testbed: &mut Testbed) {
|
pub fn init_world(testbed: &mut Testbed) {
|
||||||
let mut bodies = RigidBodySet::new();
|
let mut bodies = RigidBodySet::new();
|
||||||
@@ -9,7 +9,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rad = 0.5;
|
let rad = 0.5;
|
||||||
|
|
||||||
let positions = [vector![5.0, -1.0], vector![-5.0, -1.0]];
|
let positions = [Vector::new(5.0, -1.0), Vector::new(-5.0, -1.0)];
|
||||||
|
|
||||||
let platform_handles = positions
|
let platform_handles = positions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -27,13 +27,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rot = -state.time;
|
let rot = -state.time;
|
||||||
for rb_handle in &platform_handles {
|
for rb_handle in &platform_handles {
|
||||||
let rb = physics.bodies.get_mut(*rb_handle).unwrap();
|
let rb = physics.bodies.get_mut(*rb_handle).unwrap();
|
||||||
rb.set_next_kinematic_rotation(UnitComplex::new(rot));
|
rb.set_next_kinematic_rotation(Rotation::new(rot));
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.timestep_id % 10 == 0 {
|
if state.timestep_id % 10 == 0 {
|
||||||
let x = rand::random::<f32>() * 10.0 - 5.0;
|
let x = rand::random::<f32>() * 10.0 - 5.0;
|
||||||
let y = rand::random::<f32>() * 10.0 + 10.0;
|
let y = rand::random::<f32>() * 10.0 + 10.0;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = physics.bodies.insert(rigid_body);
|
let handle = physics.bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
physics
|
physics
|
||||||
@@ -48,7 +48,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let to_remove: Vec<_> = physics
|
let to_remove: Vec<_> = physics
|
||||||
.bodies
|
.bodies
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, b)| b.position().translation.vector.y < -10.0)
|
.filter(|(_, b)| b.position().translation.y < -10.0)
|
||||||
.map(|e| e.0)
|
.map(|e| e.0)
|
||||||
.collect();
|
.collect();
|
||||||
for handle in to_remove {
|
for handle in to_remove {
|
||||||
@@ -71,5 +71,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 20.0);
|
testbed.look_at(Vec2::ZERO, 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
use rapier_testbed2d::{Example, TestbedApp};
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use rapier_testbed2d::{Testbed, TestbedApp};
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod add_remove2;
|
mod add_remove2;
|
||||||
mod ccd2;
|
mod ccd2;
|
||||||
@@ -44,66 +40,94 @@ mod s2d_high_mass_ratio_3;
|
|||||||
mod s2d_joint_grid;
|
mod s2d_joint_grid;
|
||||||
mod s2d_pyramid;
|
mod s2d_pyramid;
|
||||||
mod sensor2;
|
mod sensor2;
|
||||||
|
mod stress_tests;
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod trimesh2;
|
mod trimesh2;
|
||||||
mod voxels2;
|
mod voxels2;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
|
#[kiss3d::main]
|
||||||
pub fn main() {
|
pub async fn main() {
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
const COLLISIONS: &str = "Collisions";
|
||||||
("Add remove", add_remove2::init_world),
|
const DYNAMICS: &str = "Dynamics";
|
||||||
("CCD", ccd2::init_world),
|
const COMPLEX: &str = "Complex Shapes";
|
||||||
("Character controller", character_controller2::init_world),
|
const JOINTS: &str = "Joints";
|
||||||
("Collision groups", collision_groups2::init_world),
|
const CONTROLS: &str = "Controls";
|
||||||
("Convex polygons", convex_polygons2::init_world),
|
const DEBUG: &str = "Debug";
|
||||||
("Damping", damping2::init_world),
|
const S2D: &str = "Inspired by Solver 2D";
|
||||||
("Drum", drum2::init_world),
|
|
||||||
("Heightfield", heightfield2::init_world),
|
|
||||||
("Inverse kinematics", inverse_kinematics2::init_world),
|
|
||||||
("Inv pyramid", inv_pyramid2::init_world),
|
|
||||||
("Joints", joints2::init_world),
|
|
||||||
("Locked rotations", locked_rotations2::init_world),
|
|
||||||
("One-way platforms", one_way_platforms2::init_world),
|
|
||||||
("Platform", platform2::init_world),
|
|
||||||
("Polyline", polyline2::init_world),
|
|
||||||
("Pin Slot Joint", pin_slot_joint2::init_world),
|
|
||||||
("Pyramid", pyramid2::init_world),
|
|
||||||
("Restitution", restitution2::init_world),
|
|
||||||
("Rope Joints", rope_joints2::init_world),
|
|
||||||
("Sensor", sensor2::init_world),
|
|
||||||
("Trimesh", trimesh2::init_world),
|
|
||||||
("Voxels", voxels2::init_world),
|
|
||||||
("Joint motor position", joint_motor_position2::init_world),
|
|
||||||
("(Debug) box ball", debug_box_ball2::init_world),
|
|
||||||
("(Debug) compression", debug_compression2::init_world),
|
|
||||||
("(Debug) intersection", debug_intersection2::init_world),
|
|
||||||
("(Debug) total overlap", debug_total_overlap2::init_world),
|
|
||||||
(
|
|
||||||
"(Debug) vertical column",
|
|
||||||
debug_vertical_column2::init_world,
|
|
||||||
),
|
|
||||||
("(s2d) high mass ratio 1", s2d_high_mass_ratio_1::init_world),
|
|
||||||
("(s2d) high mass ratio 2", s2d_high_mass_ratio_2::init_world),
|
|
||||||
("(s2d) high mass ratio 3", s2d_high_mass_ratio_3::init_world),
|
|
||||||
("(s2d) confined", s2d_confined::init_world),
|
|
||||||
("(s2d) pyramid", s2d_pyramid::init_world),
|
|
||||||
("(s2d) card house", s2d_card_house::init_world),
|
|
||||||
("(s2d) arch", s2d_arch::init_world),
|
|
||||||
("(s2d) bridge", s2d_bridge::init_world),
|
|
||||||
("(s2d) ball and chain", s2d_ball_and_chain::init_world),
|
|
||||||
("(s2d) joint grid", s2d_joint_grid::init_world),
|
|
||||||
("(s2d) far pyramid", s2d_far_pyramid::init_world),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
let mut builders: Vec<Example> = vec![
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with('('), b.0.starts_with('(')) {
|
// ── Demos ──────────────────────────────────────────────────────────
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
Example::new(COLLISIONS, "Add remove", add_remove2::init_world),
|
||||||
(true, false) => Ordering::Greater,
|
Example::new(COLLISIONS, "Drum", drum2::init_world),
|
||||||
(false, true) => Ordering::Less,
|
Example::new(COLLISIONS, "Inv pyramid", inv_pyramid2::init_world),
|
||||||
});
|
Example::new(COLLISIONS, "Platform", platform2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Pyramid", pyramid2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Sensor", sensor2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Convex polygons", convex_polygons2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Heightfield", heightfield2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Polyline", polyline2::init_world),
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
Example::new(COLLISIONS, "Trimesh", trimesh2::init_world),
|
||||||
|
Example::new(COLLISIONS, "Voxels", voxels2::init_world),
|
||||||
|
Example::new(
|
||||||
|
COLLISIONS,
|
||||||
|
"Collision groups",
|
||||||
|
collision_groups2::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
COLLISIONS,
|
||||||
|
"One-way platforms",
|
||||||
|
one_way_platforms2::init_world,
|
||||||
|
),
|
||||||
|
// ── Dynamics ──────────────────────────────────────────────────────────
|
||||||
|
Example::new(DYNAMICS, "Locked rotations", locked_rotations2::init_world),
|
||||||
|
Example::new(DYNAMICS, "Restitution", restitution2::init_world),
|
||||||
|
Example::new(DYNAMICS, "Damping", damping2::init_world),
|
||||||
|
Example::new(DYNAMICS, "CCD", ccd2::init_world),
|
||||||
|
// ── Joints ─────────────────────────────────────────────────────────
|
||||||
|
Example::new(JOINTS, "Joints", joints2::init_world),
|
||||||
|
Example::new(JOINTS, "Rope Joints", rope_joints2::init_world),
|
||||||
|
Example::new(JOINTS, "Pin Slot Joint", pin_slot_joint2::init_world),
|
||||||
|
Example::new(
|
||||||
|
JOINTS,
|
||||||
|
"Joint motor position",
|
||||||
|
joint_motor_position2::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
JOINTS,
|
||||||
|
"Inverse kinematics",
|
||||||
|
inverse_kinematics2::init_world,
|
||||||
|
),
|
||||||
|
// ── Characters ─────────────────────────────────────────────────────
|
||||||
|
Example::new(
|
||||||
|
CONTROLS,
|
||||||
|
"Character controller",
|
||||||
|
character_controller2::init_world,
|
||||||
|
),
|
||||||
|
// ── Debug ──────────────────────────────────────────────────────────
|
||||||
|
Example::new(DEBUG, "Box ball", debug_box_ball2::init_world),
|
||||||
|
Example::new(DEBUG, "Compression", debug_compression2::init_world),
|
||||||
|
Example::new(DEBUG, "Intersection", debug_intersection2::init_world),
|
||||||
|
Example::new(DEBUG, "Total overlap", debug_total_overlap2::init_world),
|
||||||
|
Example::new(DEBUG, "Vertical column", debug_vertical_column2::init_world),
|
||||||
|
// ── Demos inspired by Solver2D ───────────────────────────────────────────────────
|
||||||
|
Example::new(S2D, "High mass ratio 1", s2d_high_mass_ratio_1::init_world),
|
||||||
|
Example::new(S2D, "High mass ratio 2", s2d_high_mass_ratio_2::init_world),
|
||||||
|
Example::new(S2D, "High mass ratio 3", s2d_high_mass_ratio_3::init_world),
|
||||||
|
Example::new(S2D, "Confined", s2d_confined::init_world),
|
||||||
|
Example::new(S2D, "Pyramid", s2d_pyramid::init_world),
|
||||||
|
Example::new(S2D, "Card house", s2d_card_house::init_world),
|
||||||
|
Example::new(S2D, "Arch", s2d_arch::init_world),
|
||||||
|
Example::new(S2D, "Bridge", s2d_bridge::init_world),
|
||||||
|
Example::new(S2D, "Ball and chain", s2d_ball_and_chain::init_world),
|
||||||
|
Example::new(S2D, "Joint grid", s2d_joint_grid::init_world),
|
||||||
|
Example::new(S2D, "Far pyramid", s2d_far_pyramid::init_world),
|
||||||
|
];
|
||||||
|
let mut benches = stress_tests::builders();
|
||||||
|
builders.append(&mut benches);
|
||||||
|
|
||||||
let testbed = TestbedApp::from_builders(builders);
|
let testbed = TestbedApp::from_builders(builders);
|
||||||
|
testbed.run().await
|
||||||
testbed.run()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
@@ -23,15 +24,15 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let collider =
|
let collider =
|
||||||
ColliderBuilder::cuboid(ground_thickness, ground_size).translation(vector![-3.0, 0.0]);
|
ColliderBuilder::cuboid(ground_thickness, ground_size).translation(Vector::new(-3.0, 0.0));
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let collider =
|
let collider =
|
||||||
ColliderBuilder::cuboid(ground_thickness, ground_size).translation(vector![6.0, 0.0]);
|
ColliderBuilder::cuboid(ground_thickness, ground_size).translation(Vector::new(6.0, 0.0));
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let collider = ColliderBuilder::cuboid(ground_thickness, ground_size)
|
let collider = ColliderBuilder::cuboid(ground_thickness, ground_size)
|
||||||
.translation(vector![2.5, 0.0])
|
.translation(Vector::new(2.5, 0.0))
|
||||||
.sensor(true)
|
.sensor(true)
|
||||||
.active_events(ActiveEvents::COLLISION_EVENTS);
|
.active_events(ActiveEvents::COLLISION_EVENTS);
|
||||||
let sensor_handle = colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
let sensor_handle = colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -42,9 +43,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let radx = 0.4;
|
let radx = 0.4;
|
||||||
let rady = 0.05;
|
let rady = 0.05;
|
||||||
|
|
||||||
let delta1 = Isometry::translation(0.0, radx - rady);
|
let delta1 = Pose::from_translation(Vector::new(0.0, radx - rady));
|
||||||
let delta2 = Isometry::translation(-radx + rady, 0.0);
|
let delta2 = Pose::from_translation(Vector::new(-radx + rady, 0.0));
|
||||||
let delta3 = Isometry::translation(radx - rady, 0.0);
|
let delta3 = Pose::from_translation(Vector::new(radx - rady, 0.0));
|
||||||
|
|
||||||
let mut compound_parts = Vec::new();
|
let mut compound_parts = Vec::new();
|
||||||
let vertical = SharedShape::cuboid(rady, radx);
|
let vertical = SharedShape::cuboid(rady, radx);
|
||||||
@@ -67,8 +68,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x, y])
|
.translation(Vector::new(x, y))
|
||||||
.linvel(vector![100.0, -10.0])
|
.linvel(Vector::new(100.0, -10.0))
|
||||||
.ccd_enabled(true);
|
.ccd_enabled(true);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
@@ -89,9 +90,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
testbed.add_callback(move |mut graphics, physics, events, _| {
|
testbed.add_callback(move |mut graphics, physics, events, _| {
|
||||||
while let Ok(prox) = events.collision_events.try_recv() {
|
while let Ok(prox) = events.collision_events.try_recv() {
|
||||||
let color = if prox.started() {
|
let color = if prox.started() {
|
||||||
[1.0, 1.0, 0.0]
|
Color::new(1.0, 1.0, 0.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
[0.5, 0.5, 1.0]
|
Color::new(0.5, 0.5, 1.0, 1.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_handle1 = physics
|
let parent_handle1 = physics
|
||||||
@@ -108,11 +109,11 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(graphics) = &mut graphics {
|
if let Some(graphics) = &mut graphics {
|
||||||
if parent_handle1 != ground_handle && prox.collider1() != sensor_handle {
|
if parent_handle1 != ground_handle && prox.collider1() != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle1, color);
|
graphics.set_body_color(parent_handle1, color, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if parent_handle2 != ground_handle && prox.collider2() != sensor_handle {
|
if parent_handle2 != ground_handle && prox.collider2() != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle2, color);
|
graphics.set_body_color(parent_handle2, color, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,5 +123,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::utils::character;
|
use crate::utils::character;
|
||||||
use crate::utils::character::CharacterControlMode;
|
use crate::utils::character::CharacterControlMode;
|
||||||
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::control::{KinematicCharacterController, PidController};
|
use rapier2d::control::{KinematicCharacterController, PidController};
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
@@ -20,7 +21,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 5.0;
|
let ground_size = 5.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
@@ -29,7 +30,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Character we will control manually.
|
* Character we will control manually.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::kinematic_position_based()
|
let rigid_body = RigidBodyBuilder::kinematic_position_based()
|
||||||
.translation(vector![-3.0, 5.0])
|
.translation(Vector::new(-3.0, 5.0))
|
||||||
// The two config below makes the character
|
// The two config below makes the character
|
||||||
// nicer to control with the PID control enabled.
|
// nicer to control with the PID control enabled.
|
||||||
.gravity_scale(10.0)
|
.gravity_scale(10.0)
|
||||||
@@ -37,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let character_handle = bodies.insert(rigid_body);
|
let character_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::capsule_y(0.3, 0.15);
|
let collider = ColliderBuilder::capsule_y(0.3, 0.15);
|
||||||
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
||||||
testbed.set_initial_body_color(character_handle, [0.8, 0.1, 0.1]);
|
testbed.set_initial_body_color(character_handle, Color::new(0.8, 0.1, 0.1, 1.0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
@@ -54,7 +55,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let x = i as f32 * shift - centerx;
|
let x = i as f32 * shift - centerx;
|
||||||
let y = j as f32 * shift + centery;
|
let y = j as f32 * shift + centery;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -71,7 +72,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = i as f32 * stair_height * 1.5 + 3.0;
|
let y = i as f32 * stair_height * 1.5 + 3.0;
|
||||||
|
|
||||||
let collider = ColliderBuilder::cuboid(stair_width / 2.0, stair_height / 2.0)
|
let collider = ColliderBuilder::cuboid(stair_width / 2.0, stair_height / 2.0)
|
||||||
.translation(vector![x, y]);
|
.translation(Vector::new(x, y));
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,32 +82,32 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let slope_angle = 0.2;
|
let slope_angle = 0.2;
|
||||||
let slope_size = 2.0;
|
let slope_size = 2.0;
|
||||||
let collider = ColliderBuilder::cuboid(slope_size, ground_height)
|
let collider = ColliderBuilder::cuboid(slope_size, ground_height)
|
||||||
.translation(vector![ground_size + slope_size, -ground_height + 0.4])
|
.translation(Vector::new(ground_size + slope_size, -ground_height + 0.4))
|
||||||
.rotation(slope_angle);
|
.rotation(slope_angle);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a slope we can’t climb.
|
* Create a slope we can't climb.
|
||||||
*/
|
*/
|
||||||
let impossible_slope_angle = 0.9;
|
let impossible_slope_angle = 0.9;
|
||||||
let impossible_slope_size = 2.0;
|
let impossible_slope_size = 2.0;
|
||||||
let collider = ColliderBuilder::cuboid(slope_size, ground_height)
|
let collider = ColliderBuilder::cuboid(slope_size, ground_height)
|
||||||
.translation(vector![
|
.translation(Vector::new(
|
||||||
ground_size + slope_size * 2.0 + impossible_slope_size - 0.9,
|
ground_size + slope_size * 2.0 + impossible_slope_size - 0.9,
|
||||||
-ground_height + 2.3
|
-ground_height + 2.3,
|
||||||
])
|
))
|
||||||
.rotation(impossible_slope_angle);
|
.rotation(impossible_slope_angle);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a wall we can’t climb.
|
* Create a wall we can't climb.
|
||||||
*/
|
*/
|
||||||
let wall_angle = PI / 2.;
|
let wall_angle = PI / 2.;
|
||||||
let wall_size = 2.0;
|
let wall_size = 2.0;
|
||||||
let wall_pos = vector![
|
let wall_pos = Vector::new(
|
||||||
ground_size + slope_size * 2.0 + impossible_slope_size + 0.35,
|
ground_size + slope_size * 2.0 + impossible_slope_size + 0.35,
|
||||||
-ground_height + 2.5 * 2.3
|
-ground_height + 2.5 * 2.3,
|
||||||
];
|
);
|
||||||
let collider = ColliderBuilder::cuboid(wall_size, ground_height)
|
let collider = ColliderBuilder::cuboid(wall_size, ground_height)
|
||||||
.translation(wall_pos)
|
.translation(wall_pos)
|
||||||
.rotation(wall_angle);
|
.rotation(wall_angle);
|
||||||
@@ -118,7 +119,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Create a moving platform.
|
* Create a moving platform.
|
||||||
*/
|
*/
|
||||||
let body = RigidBodyBuilder::kinematic_velocity_based().translation(vector![-8.0, 0.0]);
|
let body = RigidBodyBuilder::kinematic_velocity_based().translation(Vector::new(-8.0, 0.0));
|
||||||
// .rotation(-0.3);
|
// .rotation(-0.3);
|
||||||
let platform_handle = bodies.insert(body);
|
let platform_handle = bodies.insert(body);
|
||||||
let collider = ColliderBuilder::cuboid(2.0, ground_height);
|
let collider = ColliderBuilder::cuboid(2.0, ground_height);
|
||||||
@@ -130,20 +131,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = Vector::new(10.0, 1.0);
|
let ground_size = Vector::new(10.0, 1.0);
|
||||||
let nsubdivs = 20;
|
let nsubdivs = 20;
|
||||||
|
|
||||||
let heights = DVector::from_fn(nsubdivs + 1, |i, _| {
|
let heights = (0..nsubdivs + 1)
|
||||||
(i as f32 * ground_size.x / (nsubdivs as f32) / 2.0).cos() * 1.5
|
.map(|i| (i as f32 * ground_size.x / (nsubdivs as f32) / 2.0).cos() * 1.5)
|
||||||
});
|
.collect();
|
||||||
|
|
||||||
let collider =
|
let collider =
|
||||||
ColliderBuilder::heightfield(heights, ground_size).translation(vector![-8.0, 5.0]);
|
ColliderBuilder::heightfield(heights, ground_size).translation(Vector::new(-8.0, 5.0));
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A tilting dynamic body with a limited joint.
|
* A tilting dynamic body with a limited joint.
|
||||||
*/
|
*/
|
||||||
let ground = RigidBodyBuilder::fixed().translation(vector![0.0, 5.0]);
|
let ground = RigidBodyBuilder::fixed().translation(Vector::new(0.0, 5.0));
|
||||||
let ground_handle = bodies.insert(ground);
|
let ground_handle = bodies.insert(ground);
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![0.0, 5.0]);
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 5.0));
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let collider = ColliderBuilder::cuboid(1.0, 0.1);
|
let collider = ColliderBuilder::cuboid(1.0, 0.1);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -154,16 +155,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Setup a callback to move the platform.
|
* Setup a callback to move the platform.
|
||||||
*/
|
*/
|
||||||
testbed.add_callback(move |_, physics, _, run_state| {
|
testbed.add_callback(move |_, physics, _, run_state| {
|
||||||
let linvel = vector![
|
let linvel = Vector::new(
|
||||||
(run_state.time * 2.0).sin() * 2.0,
|
(run_state.time * 2.0).sin() * 2.0,
|
||||||
(run_state.time * 5.0).sin() * 1.5
|
(run_state.time * 5.0).sin() * 1.5,
|
||||||
];
|
);
|
||||||
// let angvel = run_state.time.sin() * 0.5;
|
// let angvel = run_state.time.sin() * 0.5;
|
||||||
|
|
||||||
// Update the velocity-based kinematic body by setting its velocity.
|
// Update the velocity-based kinematic body by setting its velocity.
|
||||||
if let Some(platform) = physics.bodies.get_mut(platform_handle) {
|
if let Some(platform) = physics.bodies.get_mut(platform_handle) {
|
||||||
platform.set_linvel(linvel, true);
|
platform.set_linvel(linvel, true);
|
||||||
// NOTE: interaction with rotating platforms isn’t handled very well yet.
|
// NOTE: interaction with rotating platforms isn't handled very well yet.
|
||||||
// platform.set_angvel(angvel, true);
|
// platform.set_angvel(angvel, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -197,5 +198,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::{BLUE, GREEN};
|
||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 5.0;
|
let ground_size = 5.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
@@ -33,22 +34,22 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* A green floor that will collide with the GREEN group only.
|
* A green floor that will collide with the GREEN group only.
|
||||||
*/
|
*/
|
||||||
let green_floor = ColliderBuilder::cuboid(1.0, 0.1)
|
let green_floor = ColliderBuilder::cuboid(1.0, 0.1)
|
||||||
.translation(vector![0.0, 1.0])
|
.translation(Vector::new(0.0, 1.0))
|
||||||
.collision_groups(GREEN_GROUP);
|
.collision_groups(GREEN_GROUP);
|
||||||
let green_collider_handle =
|
let green_collider_handle =
|
||||||
colliders.insert_with_parent(green_floor, floor_handle, &mut bodies);
|
colliders.insert_with_parent(green_floor, floor_handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_collider_color(green_collider_handle, [0.0, 1.0, 0.0]);
|
testbed.set_initial_collider_color(green_collider_handle, GREEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A blue floor that will collide with the BLUE group only.
|
* A blue floor that will collide with the BLUE group only.
|
||||||
*/
|
*/
|
||||||
let blue_floor = ColliderBuilder::cuboid(1.0, 0.1)
|
let blue_floor = ColliderBuilder::cuboid(1.0, 0.1)
|
||||||
.translation(vector![0.0, 2.0])
|
.translation(Vector::new(0.0, 2.0))
|
||||||
.collision_groups(BLUE_GROUP);
|
.collision_groups(BLUE_GROUP);
|
||||||
let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies);
|
let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_collider_color(blue_collider_handle, [0.0, 0.0, 1.0]);
|
testbed.set_initial_collider_color(blue_collider_handle, BLUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
@@ -67,12 +68,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Alternate between the green and blue groups.
|
// Alternate between the green and blue groups.
|
||||||
let (group, color) = if i % 2 == 0 {
|
let (group, color) = if i % 2 == 0 {
|
||||||
(GREEN_GROUP, [0.0, 1.0, 0.0])
|
(GREEN_GROUP, GREEN)
|
||||||
} else {
|
} else {
|
||||||
(BLUE_GROUP, [0.0, 0.0, 1.0])
|
(BLUE_GROUP, BLUE)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad).collision_groups(group);
|
let collider = ColliderBuilder::cuboid(rad, rad).collision_groups(group);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -85,5 +86,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![ground_size, ground_size * 2.0]);
|
.translation(Vector::new(ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![-ground_size, ground_size * 2.0]);
|
.translation(Vector::new(-ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -55,14 +55,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let x = i as f32 * shift - centerx;
|
let x = i as f32 * shift - centerx;
|
||||||
let y = j as f32 * shift * 2.0 + centery + 2.0;
|
let y = j as f32 * shift * 2.0 + centery + 2.0;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let pt: Point<f32> = distribution.sample(&mut rng);
|
let pt: SimdPoint<f32> = distribution.sample(&mut rng);
|
||||||
points.push(pt * scale);
|
points.push(Vector::new(pt.x, pt.y) * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
let collider = ColliderBuilder::convex_hull(&points).unwrap();
|
let collider = ColliderBuilder::convex_hull(&points).unwrap();
|
||||||
@@ -74,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
testbed.look_at(Vec2::new(0.0, 50.0), 10.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rb = RigidBodyBuilder::dynamic()
|
let rb = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x, y])
|
.translation(Vector::new(x, y))
|
||||||
.linvel(vector![x * 10.0, y * 10.0])
|
.linvel(Vector::new(x * 10.0, y * 10.0))
|
||||||
.angvel(100.0)
|
.angvel(100.0)
|
||||||
.linear_damping((i + 1) as f32 * subdiv * 10.0)
|
.linear_damping((i + 1) as f32 * subdiv * 10.0)
|
||||||
.angular_damping((num - i) as f32 * subdiv * 10.0);
|
.angular_damping((num - i) as f32 * subdiv * 10.0);
|
||||||
@@ -43,8 +43,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
Vector::zeros(),
|
Vector::ZERO,
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
testbed.look_at(point![3.0, 2.0], 50.0);
|
testbed.look_at(Vec2::new(3.0, 2.0), 50.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
let rad = 1.0;
|
let rad = 1.0;
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.translation(vector![0.0, -rad])
|
.translation(Vector::new(0.0, -rad))
|
||||||
.rotation(std::f32::consts::PI / 4.0);
|
.rotation(std::f32::consts::PI / 4.0);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
@@ -23,7 +23,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Build the dynamic box rigid body.
|
// Build the dynamic box rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![0.0, 3.0 * rad])
|
.translation(Vector::new(0.0, 3.0 * rad))
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
@@ -33,5 +33,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
testbed.look_at(Vec2::ZERO, 50.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ys = [-30.0 - thickness, 30.0 + thickness];
|
let ys = [-30.0 - thickness, 30.0 + thickness];
|
||||||
|
|
||||||
for y in ys {
|
for y in ys {
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, y]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(width, thickness);
|
let collider = ColliderBuilder::cuboid(width, thickness);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -30,7 +30,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let mut handles = [RigidBodyHandle::invalid(); 2];
|
let mut handles = [RigidBodyHandle::invalid(); 2];
|
||||||
|
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![xs[i], 0.0]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(xs[i], 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(thickness, half_height);
|
let collider = ColliderBuilder::cuboid(thickness, half_height);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -44,14 +44,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for j in 0..num {
|
for j in 0..num {
|
||||||
let x = i as f32 * rad * 2.0 - num as f32 * rad;
|
let x = i as f32 * rad * 2.0 - num as f32 * rad;
|
||||||
let y = j as f32 * rad * 2.0 - num as f32 * rad + rad;
|
let y = j as f32 * rad * 2.0 - num as f32 * rad + rad;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut force = vector![0.0, 0.0];
|
let mut force = Vector::new(0.0, 0.0);
|
||||||
|
|
||||||
testbed.add_callback(move |_, physics, _, _| {
|
testbed.add_callback(move |_, physics, _, _| {
|
||||||
let left_plank = &mut physics.bodies[handles[0]];
|
let left_plank = &mut physics.bodies[handles[0]];
|
||||||
@@ -71,5 +71,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
testbed.look_at(Vec2::ZERO, 50.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::{Color, GREY, RED};
|
||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
@@ -16,19 +17,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let count = 100;
|
let count = 100;
|
||||||
for x in 0..count {
|
for x in 0..count {
|
||||||
for y in 0..count {
|
for y in 0..count {
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(
|
||||||
(x as f32 - count as f32 / 2.0) * rad * 3.0,
|
(x as f32 - count as f32 / 2.0) * rad * 3.0,
|
||||||
(y as f32 - count as f32 / 2.0) * rad * 3.0
|
(y as f32 - count as f32 / 2.0) * rad * 3.0,
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(collider.clone(), handle, &mut bodies);
|
colliders.insert_with_parent(collider.clone(), handle, &mut bodies);
|
||||||
testbed.set_initial_body_color(
|
testbed.set_initial_body_color(
|
||||||
handle,
|
handle,
|
||||||
[
|
Color::new(
|
||||||
x as f32 / count as f32,
|
x as f32 / count as f32,
|
||||||
(count - y) as f32 / count as f32,
|
(count - y) as f32 / count as f32,
|
||||||
0.5,
|
0.5,
|
||||||
],
|
1.0,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +39,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
testbed.look_at(Vec2::ZERO, 50.0);
|
||||||
|
|
||||||
testbed.add_callback(move |mut graphics, physics, _, run| {
|
testbed.add_callback(move |mut graphics, physics, _, run| {
|
||||||
let slow_time = run.timestep_id as f32 / 3.0;
|
let slow_time = run.timestep_id as f32 / 3.0;
|
||||||
@@ -50,18 +52,18 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for intersection in query_pipeline.intersect_shape(
|
for intersection in query_pipeline.intersect_shape(
|
||||||
Isometry::translation(slow_time.cos() * 10.0, slow_time.sin() * 10.0),
|
Pose::from_translation(Vector::new(slow_time.cos() * 10.0, slow_time.sin() * 10.0)),
|
||||||
&Ball::new(rad / 2.0),
|
&Ball::new(rad / 2.0),
|
||||||
) {
|
) {
|
||||||
if let Some(graphics) = graphics.as_deref_mut() {
|
if let Some(graphics) = graphics.as_deref_mut() {
|
||||||
for (handle, _) in physics.bodies.iter() {
|
for (handle, _) in physics.bodies.iter() {
|
||||||
graphics.set_body_color(handle, [0.5, 0.5, 0.5]);
|
graphics.set_body_color(handle, GREY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let collider = physics.colliders.get(intersection.0).unwrap();
|
let collider = physics.colliders.get(intersection.0).unwrap();
|
||||||
let body_handle = collider.parent().unwrap();
|
let body_handle = collider.parent().unwrap();
|
||||||
|
|
||||||
graphics.set_body_color(body_handle, [1.0, 0.0, 0.0]);
|
graphics.set_body_color(body_handle, RED, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 50.0);
|
testbed.look_at(Vec2::ZERO, 50.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = i as f32 * rad * 2.0 + ground_thickness + rad;
|
let y = i as f32 * rad * 2.0 + ground_thickness + rad;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad).friction(0.3);
|
let collider = ColliderBuilder::cuboid(rad, rad).friction(0.3);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -43,5 +43,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
// testbed.harness_mut().physics.gravity.y = -981.0;
|
// testbed.harness_mut().physics.gravity.y = -981.0;
|
||||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 5.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift - centery;
|
let y = j as f32 * shift - centery;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -40,16 +40,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let velocity_based_platform_handle = bodies.insert(platform_body);
|
let velocity_based_platform_handle = bodies.insert(platform_body);
|
||||||
|
|
||||||
let sides = [
|
let sides = [
|
||||||
(10.0, 0.25, vector![0.0, 10.0]),
|
(10.0, 0.25, Vector::new(0.0, 10.0)),
|
||||||
(10.0, 0.25, vector![0.0, -10.0]),
|
(10.0, 0.25, Vector::new(0.0, -10.0)),
|
||||||
(0.25, 10.0, vector![10.0, 0.0]),
|
(0.25, 10.0, Vector::new(10.0, 0.0)),
|
||||||
(0.25, 10.0, vector![-10.0, 0.0]),
|
(0.25, 10.0, Vector::new(-10.0, 0.0)),
|
||||||
];
|
];
|
||||||
let balls = [
|
let balls = [
|
||||||
(1.25, vector![6.0, 6.0]),
|
(1.25, Vector::new(6.0, 6.0)),
|
||||||
(1.25, vector![-6.0, 6.0]),
|
(1.25, Vector::new(-6.0, 6.0)),
|
||||||
(1.25, vector![6.0, -6.0]),
|
(1.25, Vector::new(6.0, -6.0)),
|
||||||
(1.25, vector![-6.0, -6.0]),
|
(1.25, Vector::new(-6.0, -6.0)),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (hx, hy, pos) in sides {
|
for (hx, hy, pos) in sides {
|
||||||
@@ -75,5 +75,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Run the simulation.
|
* Run the simulation.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 40.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 40.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::na::DVector;
|
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
pub fn init_world(testbed: &mut Testbed) {
|
pub fn init_world(testbed: &mut Testbed) {
|
||||||
@@ -17,13 +16,15 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = Vector::new(50.0, 1.0);
|
let ground_size = Vector::new(50.0, 1.0);
|
||||||
let nsubdivs = 2000;
|
let nsubdivs = 2000;
|
||||||
|
|
||||||
let heights = DVector::from_fn(nsubdivs + 1, |i, _| {
|
let heights = (0..nsubdivs + 1)
|
||||||
if i == 0 || i == nsubdivs {
|
.map(|i| {
|
||||||
8.0
|
if i == 0 || i == nsubdivs {
|
||||||
} else {
|
8.0
|
||||||
(i as f32 * ground_size.x / (nsubdivs as f32)).cos() * 2.0
|
} else {
|
||||||
}
|
(i as f32 * ground_size.x / (nsubdivs as f32)).cos() * 2.0
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
@@ -46,7 +47,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery + 3.0;
|
let y = j as f32 * shift + centery + 3.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
if j % 2 == 0 {
|
if j % 2 == 0 {
|
||||||
@@ -63,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 10.0);
|
testbed.look_at(Vec2::ZERO, 10.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for _ in 0usize..num {
|
for _ in 0usize..num {
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body =
|
let rigid_body =
|
||||||
RigidBodyBuilder::dynamic().translation(vector![0.0, y + ground_thickness]);
|
RigidBodyBuilder::dynamic().translation(Vector::new(0.0, y + ground_thickness));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -43,5 +43,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 1.0;
|
let ground_size = 1.0;
|
||||||
let ground_height = 0.01;
|
let ground_height = 0.01;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
@@ -41,8 +41,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders.insert_with_parent(collider, new_body, &mut bodies);
|
colliders.insert_with_parent(collider, new_body, &mut bodies);
|
||||||
|
|
||||||
let link_ab = RevoluteJointBuilder::new()
|
let link_ab = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(point![0.0, size / 2.0 * (i != 0) as usize as f32])
|
.local_anchor1(Vector::new(0.0, size / 2.0 * (i != 0) as usize as f32))
|
||||||
.local_anchor2(point![0.0, -size / 2.0])
|
.local_anchor2(Vector::new(0.0, -size / 2.0))
|
||||||
.build()
|
.build()
|
||||||
.data;
|
.data;
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// We will have the endpoint track the mouse position.
|
// We will have the endpoint track the mouse position.
|
||||||
let target_point = mouse_point.coords;
|
let target_point = Vector::new(mouse_point.x, mouse_point.y);
|
||||||
|
|
||||||
let options = InverseKinematicsOption {
|
let options = InverseKinematicsOption {
|
||||||
constrained_axes: JointAxesMask::LIN_AXES,
|
constrained_axes: JointAxesMask::LIN_AXES,
|
||||||
@@ -81,7 +81,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
&physics.bodies,
|
&physics.bodies,
|
||||||
link_id,
|
link_id,
|
||||||
&options,
|
&options,
|
||||||
&Isometry::from(target_point),
|
&Pose::from_translation(target_point),
|
||||||
|_| true,
|
|_| true,
|
||||||
&mut displacements,
|
&mut displacements,
|
||||||
);
|
);
|
||||||
@@ -93,5 +93,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 300.0);
|
testbed.look_at(Vec2::ZERO, 300.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,15 +22,15 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for num in 0..9 {
|
for num in 0..9 {
|
||||||
let x_pos = -6.0 + 1.5 * num as f32;
|
let x_pos = -6.0 + 1.5 * num as f32;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x_pos, 2.0])
|
.translation(Vector::new(x_pos, 2.0))
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.1, 0.5);
|
let collider = ColliderBuilder::cuboid(0.1, 0.5);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(point![x_pos, 1.5])
|
.local_anchor1(Vector::new(x_pos, 1.5))
|
||||||
.local_anchor2(point![0.0, -0.5])
|
.local_anchor2(Vector::new(0.0, -0.5))
|
||||||
.motor_position(
|
.motor_position(
|
||||||
-std::f32::consts::PI + std::f32::consts::PI / 4.0 * num as f32,
|
-std::f32::consts::PI + std::f32::consts::PI / 4.0 * num as f32,
|
||||||
1000.0,
|
1000.0,
|
||||||
@@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for num in 0..8 {
|
for num in 0..8 {
|
||||||
let x_pos = -6.0 + 1.5 * num as f32;
|
let x_pos = -6.0 + 1.5 * num as f32;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x_pos, 4.5])
|
.translation(Vector::new(x_pos, 4.5))
|
||||||
.rotation(std::f32::consts::PI)
|
.rotation(std::f32::consts::PI)
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
@@ -53,8 +53,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(point![x_pos, 5.0])
|
.local_anchor1(Vector::new(x_pos, 5.0))
|
||||||
.local_anchor2(point![0.0, -0.5])
|
.local_anchor2(Vector::new(0.0, -0.5))
|
||||||
.motor_velocity(1.5, 30.0)
|
.motor_velocity(1.5, 30.0)
|
||||||
.motor_max_force(100.0)
|
.motor_max_force(100.0)
|
||||||
.limits([
|
.limits([
|
||||||
@@ -72,8 +72,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
vector![0.0, 0.0],
|
Vector::new(0.0, 0.0),
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
testbed.look_at(point![0.0, 0.0], 40.0);
|
testbed.look_at(Vec2::ZERO, 40.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body =
|
||||||
RigidBodyBuilder::new(status).translation(vector![fk * shift, -fi * shift]);
|
RigidBodyBuilder::new(status).translation(Vector::new(fk * shift, -fi * shift));
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||||
@@ -61,7 +61,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
let parent_handle = *body_handles.last().unwrap();
|
let parent_handle = *body_handles.last().unwrap();
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor2(point![0.0, shift])
|
.local_anchor2(Vector::new(0.0, shift))
|
||||||
.softness(softness);
|
.softness(softness);
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let parent_index = body_handles.len() - numi;
|
let parent_index = body_handles.len() - numi;
|
||||||
let parent_handle = body_handles[parent_index];
|
let parent_handle = body_handles[parent_index];
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor2(point![-shift, 0.0])
|
.local_anchor2(Vector::new(-shift, 0.0))
|
||||||
.softness(softness);
|
.softness(softness);
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
@@ -84,5 +84,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 20.0);
|
testbed.look_at(Vec2::new(numk as f32 * rad, numi as f32 * -rad), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 5.0;
|
let ground_size = 5.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -28,7 +28,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* A rectangle that only rotate.
|
* A rectangle that only rotate.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![0.0, 3.0])
|
.translation(Vector::new(0.0, 3.0))
|
||||||
.lock_translations();
|
.lock_translations();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(2.0, 0.6);
|
let collider = ColliderBuilder::cuboid(2.0, 0.6);
|
||||||
@@ -38,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* A tilted capsule that cannot rotate.
|
* A tilted capsule that cannot rotate.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![0.0, 5.0])
|
.translation(Vector::new(0.0, 5.0))
|
||||||
.rotation(1.0)
|
.rotation(1.0)
|
||||||
.lock_rotations();
|
.lock_rotations();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
@@ -49,5 +49,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 40.0);
|
testbed.look_at(Vec2::ZERO, 40.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,24 +20,24 @@ impl PhysicsHooks for OneWayPlatformHook {
|
|||||||
// - If context.collider_handle2 == self.platform1 then the allowed normal is -y.
|
// - If context.collider_handle2 == self.platform1 then the allowed normal is -y.
|
||||||
// - If context.collider_handle1 == self.platform2 then its allowed normal +y needs to be flipped to -y.
|
// - If context.collider_handle1 == self.platform2 then its allowed normal +y needs to be flipped to -y.
|
||||||
// - If context.collider_handle2 == self.platform2 then the allowed normal -y needs to be flipped to +y.
|
// - If context.collider_handle2 == self.platform2 then the allowed normal -y needs to be flipped to +y.
|
||||||
let mut allowed_local_n1 = Vector::zeros();
|
let mut allowed_local_n1 = Vector::ZERO;
|
||||||
|
|
||||||
if context.collider1 == self.platform1 {
|
if context.collider1 == self.platform1 {
|
||||||
allowed_local_n1 = Vector::y();
|
allowed_local_n1 = Vector::Y;
|
||||||
} else if context.collider2 == self.platform1 {
|
} else if context.collider2 == self.platform1 {
|
||||||
// Flip the allowed direction.
|
// Flip the allowed direction.
|
||||||
allowed_local_n1 = -Vector::y();
|
allowed_local_n1 = -Vector::Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.collider1 == self.platform2 {
|
if context.collider1 == self.platform2 {
|
||||||
allowed_local_n1 = -Vector::y();
|
allowed_local_n1 = -Vector::Y;
|
||||||
} else if context.collider2 == self.platform2 {
|
} else if context.collider2 == self.platform2 {
|
||||||
// Flip the allowed direction.
|
// Flip the allowed direction.
|
||||||
allowed_local_n1 = Vector::y();
|
allowed_local_n1 = Vector::Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the helper function that simulates one-way platforms.
|
// Call the helper function that simulates one-way platforms.
|
||||||
context.update_as_oneway_platform(&allowed_local_n1, 0.1);
|
context.update_as_oneway_platform(allowed_local_n1, 0.1);
|
||||||
|
|
||||||
// Set the surface velocity of the accepted contacts.
|
// Set the surface velocity of the accepted contacts.
|
||||||
let tangent_velocity =
|
let tangent_velocity =
|
||||||
@@ -69,11 +69,11 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
let collider = ColliderBuilder::cuboid(25.0, 0.5)
|
let collider = ColliderBuilder::cuboid(25.0, 0.5)
|
||||||
.translation(vector![30.0, 2.0])
|
.translation(Vector::new(30.0, 2.0))
|
||||||
.active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS);
|
.active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS);
|
||||||
let platform1 = colliders.insert_with_parent(collider, handle, &mut bodies);
|
let platform1 = colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
let collider = ColliderBuilder::cuboid(25.0, 0.5)
|
let collider = ColliderBuilder::cuboid(25.0, 0.5)
|
||||||
.translation(vector![-30.0, -2.0])
|
.translation(Vector::new(-30.0, -2.0))
|
||||||
.active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS);
|
.active_hooks(ActiveHooks::MODIFY_SOLVER_CONTACTS);
|
||||||
let platform2 = colliders.insert_with_parent(collider, handle, &mut bodies);
|
let platform2 = colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
if run_state.timestep_id % 200 == 0 && physics.bodies.len() <= 7 {
|
if run_state.timestep_id % 200 == 0 && physics.bodies.len() <= 7 {
|
||||||
// Spawn a new cube.
|
// Spawn a new cube.
|
||||||
let collider = ColliderBuilder::cuboid(1.5, 2.0);
|
let collider = ColliderBuilder::cuboid(1.5, 2.0);
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![20.0, 10.0]);
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(20.0, 10.0));
|
||||||
let handle = physics.bodies.insert(body);
|
let handle = physics.bodies.insert(body);
|
||||||
physics
|
physics
|
||||||
.colliders
|
.colliders
|
||||||
@@ -122,8 +122,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
vector![0.0, -9.81],
|
Vector::new(0.0, -9.81),
|
||||||
physics_hooks,
|
physics_hooks,
|
||||||
);
|
);
|
||||||
testbed.look_at(point![0.0, 0.0], 20.0);
|
testbed.look_at(Vec2::ZERO, 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 3.0;
|
let ground_size = 3.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body_floor = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body_floor = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let floor_handle = bodies.insert(rigid_body_floor);
|
let floor_handle = bodies.insert(rigid_body_floor);
|
||||||
let floor_collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let floor_collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(floor_collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(floor_collider, floor_handle, &mut bodies);
|
||||||
@@ -28,7 +28,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Character we will control manually.
|
* Character we will control manually.
|
||||||
*/
|
*/
|
||||||
let rigid_body_character =
|
let rigid_body_character =
|
||||||
RigidBodyBuilder::kinematic_position_based().translation(vector![0.0, 0.3]);
|
RigidBodyBuilder::kinematic_position_based().translation(Vector::new(0.0, 0.3));
|
||||||
let character_handle = bodies.insert(rigid_body_character);
|
let character_handle = bodies.insert(rigid_body_character);
|
||||||
let character_collider = ColliderBuilder::cuboid(0.15, 0.3);
|
let character_collider = ColliderBuilder::cuboid(0.15, 0.3);
|
||||||
colliders.insert_with_parent(character_collider, character_handle, &mut bodies);
|
colliders.insert_with_parent(character_collider, character_handle, &mut bodies);
|
||||||
@@ -39,16 +39,16 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rad = 0.4;
|
let rad = 0.4;
|
||||||
|
|
||||||
let rigid_body_cube =
|
let rigid_body_cube =
|
||||||
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(vector![1.0, 1.0]);
|
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(Vector::new(1.0, 1.0));
|
||||||
let cube_handle = bodies.insert(rigid_body_cube);
|
let cube_handle = bodies.insert(rigid_body_cube);
|
||||||
let cube_collider = ColliderBuilder::cuboid(rad, rad);
|
let cube_collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(cube_collider, cube_handle, &mut bodies);
|
colliders.insert_with_parent(cube_collider, cube_handle, &mut bodies);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rotation axis indicator ball.
|
* SimdRotation axis indicator ball.
|
||||||
*/
|
*/
|
||||||
let rigid_body_ball =
|
let rigid_body_ball =
|
||||||
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(vector![1.0, 1.0]);
|
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(Vector::new(1.0, 1.0));
|
||||||
let ball_handle = bodies.insert(rigid_body_ball);
|
let ball_handle = bodies.insert(rigid_body_ball);
|
||||||
let ball_collider = ColliderBuilder::ball(0.1);
|
let ball_collider = ColliderBuilder::ball(0.1);
|
||||||
colliders.insert_with_parent(ball_collider, ball_handle, &mut bodies);
|
colliders.insert_with_parent(ball_collider, ball_handle, &mut bodies);
|
||||||
@@ -57,25 +57,18 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Fixed joint between rotation axis indicator and cube.
|
* Fixed joint between rotation axis indicator and cube.
|
||||||
*/
|
*/
|
||||||
let fixed_joint = FixedJointBuilder::new()
|
let fixed_joint = FixedJointBuilder::new()
|
||||||
.local_anchor1(point![0.0, 0.0])
|
.local_anchor1(Vector::new(0.0, 0.0))
|
||||||
.local_anchor2(point![0.0, -0.4])
|
.local_anchor2(Vector::new(0.0, -0.4))
|
||||||
.build();
|
.build();
|
||||||
impulse_joints.insert(cube_handle, ball_handle, fixed_joint, true);
|
impulse_joints.insert(cube_handle, ball_handle, fixed_joint, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pin slot joint between cube and ground.
|
* Pin slot joint between cube and ground.
|
||||||
*/
|
*/
|
||||||
let axis: nalgebra::Unit<
|
let axis = Vector::new(1.0, 1.0).normalize();
|
||||||
nalgebra::Matrix<
|
|
||||||
f32,
|
|
||||||
nalgebra::Const<2>,
|
|
||||||
nalgebra::Const<1>,
|
|
||||||
nalgebra::ArrayStorage<f32, 2, 1>,
|
|
||||||
>,
|
|
||||||
> = UnitVector::new_normalize(vector![1.0, 1.0]);
|
|
||||||
let pin_slot_joint = PinSlotJointBuilder::new(axis)
|
let pin_slot_joint = PinSlotJointBuilder::new(axis)
|
||||||
.local_anchor1(point![2.0, 2.0])
|
.local_anchor1(Vector::new(2.0, 2.0))
|
||||||
.local_anchor2(point![0.0, 0.4])
|
.local_anchor2(Vector::new(0.0, 0.4))
|
||||||
.limits([-1.0, f32::INFINITY]) // Set the limits for the pin slot joint
|
.limits([-1.0, f32::INFINITY]) // Set the limits for the pin slot joint
|
||||||
.build();
|
.build();
|
||||||
impulse_joints.insert(character_handle, cube_handle, pin_slot_joint, true);
|
impulse_joints.insert(character_handle, cube_handle, pin_slot_joint, true);
|
||||||
@@ -104,5 +97,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 10.0;
|
let ground_size = 10.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -37,7 +37,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery;
|
let y = j as f32 * shift + centery;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -47,8 +47,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Setup a position-based kinematic rigid body.
|
* Setup a position-based kinematic rigid body.
|
||||||
*/
|
*/
|
||||||
let platform_body =
|
let platform_body = RigidBodyBuilder::kinematic_velocity_based()
|
||||||
RigidBodyBuilder::kinematic_velocity_based().translation(vector![-10.0 * rad, 1.5 + 0.8]);
|
.translation(Vector::new(-10.0 * rad, 1.5 + 0.8));
|
||||||
let velocity_based_platform_handle = bodies.insert(platform_body);
|
let velocity_based_platform_handle = bodies.insert(platform_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad * 10.0, rad);
|
let collider = ColliderBuilder::cuboid(rad * 10.0, rad);
|
||||||
colliders.insert_with_parent(collider, velocity_based_platform_handle, &mut bodies);
|
colliders.insert_with_parent(collider, velocity_based_platform_handle, &mut bodies);
|
||||||
@@ -57,7 +57,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Setup a velocity-based kinematic rigid body.
|
* Setup a velocity-based kinematic rigid body.
|
||||||
*/
|
*/
|
||||||
let platform_body = RigidBodyBuilder::kinematic_position_based()
|
let platform_body = RigidBodyBuilder::kinematic_position_based()
|
||||||
.translation(vector![-10.0 * rad, 2.0 + 1.5 + 0.8]);
|
.translation(Vector::new(-10.0 * rad, 2.0 + 1.5 + 0.8));
|
||||||
let position_based_platform_handle = bodies.insert(platform_body);
|
let position_based_platform_handle = bodies.insert(platform_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad * 10.0, rad);
|
let collider = ColliderBuilder::cuboid(rad * 10.0, rad);
|
||||||
colliders.insert_with_parent(collider, position_based_platform_handle, &mut bodies);
|
colliders.insert_with_parent(collider, position_based_platform_handle, &mut bodies);
|
||||||
@@ -66,7 +66,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Setup a callback to control the platform.
|
* Setup a callback to control the platform.
|
||||||
*/
|
*/
|
||||||
testbed.add_callback(move |_, physics, _, run_state| {
|
testbed.add_callback(move |_, physics, _, run_state| {
|
||||||
let velocity = vector![run_state.time.sin() * 5.0, (run_state.time * 5.0).sin()];
|
let velocity = Vector::new(run_state.time.sin() * 5.0, (run_state.time * 5.0).sin());
|
||||||
|
|
||||||
// Update the velocity-based kinematic body by setting its velocity.
|
// Update the velocity-based kinematic body by setting its velocity.
|
||||||
if let Some(platform) = physics.bodies.get_mut(velocity_based_platform_handle) {
|
if let Some(platform) = physics.bodies.get_mut(velocity_based_platform_handle) {
|
||||||
@@ -75,7 +75,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Update the position-based kinematic body by setting its next position.
|
// Update the position-based kinematic body by setting its next position.
|
||||||
if let Some(platform) = physics.bodies.get_mut(position_based_platform_handle) {
|
if let Some(platform) = physics.bodies.get_mut(position_based_platform_handle) {
|
||||||
let mut next_tra = *platform.translation();
|
let mut next_tra = platform.translation();
|
||||||
next_tra += velocity * physics.integration_parameters.dt;
|
next_tra += velocity * physics.integration_parameters.dt;
|
||||||
platform.set_next_kinematic_translation(next_tra);
|
platform.set_next_kinematic_translation(next_tra);
|
||||||
}
|
}
|
||||||
@@ -85,5 +85,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Run the simulation.
|
* Run the simulation.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 40.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 40.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let step_size = ground_size / (nsubdivs as f32);
|
let step_size = ground_size / (nsubdivs as f32);
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
|
|
||||||
points.push(point![-ground_size / 2.0, 40.0]);
|
points.push(Vector::new(-ground_size / 2.0, 40.0));
|
||||||
for i in 1..nsubdivs - 1 {
|
for i in 1..nsubdivs - 1 {
|
||||||
let x = -ground_size / 2.0 + i as f32 * step_size;
|
let x = -ground_size / 2.0 + i as f32 * step_size;
|
||||||
let y = ComplexField::cos(i as f32 * step_size) * 2.0;
|
let y = ComplexField::cos(i as f32 * step_size) * 2.0;
|
||||||
points.push(point![x, y]);
|
points.push(Vector::new(x, y));
|
||||||
}
|
}
|
||||||
points.push(point![ground_size / 2.0, 40.0]);
|
points.push(Vector::new(ground_size / 2.0, 40.0));
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
@@ -48,7 +48,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery + 3.0;
|
let y = j as f32 * shift + centery + 3.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
if j % 2 == 0 {
|
if j % 2 == 0 {
|
||||||
@@ -65,5 +65,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 0.0], 10.0);
|
testbed.look_at(Vec2::ZERO, 10.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = fi * shift + centery;
|
let y = fi * shift + centery;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -50,5 +50,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 20.;
|
let ground_size = 20.;
|
||||||
let ground_height = 1.0;
|
let ground_height = 1.0;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height).restitution(1.0);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height).restitution(1.0);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -27,8 +27,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for j in 0..2 {
|
for j in 0..2 {
|
||||||
for i in 0..=num {
|
for i in 0..=num {
|
||||||
let x = (i as f32) - num as f32 / 2.0;
|
let x = (i as f32) - num as f32 / 2.0;
|
||||||
let rigid_body =
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
RigidBodyBuilder::dynamic().translation(vector![x * 2.0, 10.0 * (j as f32 + 1.0)]);
|
.translation(Vector::new(x * 2.0, 10.0 * (j as f32 + 1.0)));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad).restitution((i as f32) / (num as f32));
|
let collider = ColliderBuilder::ball(rad).restitution((i as f32) / (num as f32));
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -39,5 +39,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 25.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 25.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,19 +19,19 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 0.75;
|
let ground_size = 0.75;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
RigidBodyBuilder::fixed().translation(vector![-ground_size - ground_height, ground_size]);
|
.translation(Vector::new(-ground_size - ground_height, ground_size));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
RigidBodyBuilder::fixed().translation(vector![ground_size + ground_height, ground_size]);
|
.translation(Vector::new(ground_size + ground_height, ground_size));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
@@ -39,7 +39,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Character we will control manually.
|
* Character we will control manually.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::kinematic_position_based().translation(vector![0.0, 0.3]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::kinematic_position_based().translation(Vector::new(0.0, 0.3));
|
||||||
let character_handle = bodies.insert(rigid_body);
|
let character_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.15, 0.3);
|
let collider = ColliderBuilder::cuboid(0.15, 0.3);
|
||||||
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
||||||
@@ -49,12 +50,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
let rad = 0.04;
|
let rad = 0.04;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(vector![1.0, 1.0]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(Vector::new(1.0, 1.0));
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||||
|
|
||||||
let joint = RopeJointBuilder::new(2.0).local_anchor2(point![0.0, 0.0]);
|
let joint = RopeJointBuilder::new(2.0).local_anchor2(Vector::new(0.0, 0.0));
|
||||||
impulse_joints.insert(character_handle, child_handle, joint, true);
|
impulse_joints.insert(character_handle, child_handle, joint, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -81,5 +83,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,28 +12,28 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
#[allow(clippy::excessive_precision)]
|
#[allow(clippy::excessive_precision)]
|
||||||
let mut ps1 = [
|
let mut ps1 = [
|
||||||
Point::new(16.0, 0.0),
|
Vector::new(16.0, 0.0),
|
||||||
Point::new(14.93803712795643, 5.133601056842984),
|
Vector::new(14.93803712795643, 5.133601056842984),
|
||||||
Point::new(13.79871746027416, 10.24928069555078),
|
Vector::new(13.79871746027416, 10.24928069555078),
|
||||||
Point::new(12.56252963284711, 15.34107019122473),
|
Vector::new(12.56252963284711, 15.34107019122473),
|
||||||
Point::new(11.20040987372525, 20.39856541571217),
|
Vector::new(11.20040987372525, 20.39856541571217),
|
||||||
Point::new(9.66521217819836, 25.40369899225096),
|
Vector::new(9.66521217819836, 25.40369899225096),
|
||||||
Point::new(7.87179930638133, 30.3179337000085),
|
Vector::new(7.87179930638133, 30.3179337000085),
|
||||||
Point::new(5.635199558196225, 35.03820717801641),
|
Vector::new(5.635199558196225, 35.03820717801641),
|
||||||
Point::new(2.405937953536585, 39.09554102558315),
|
Vector::new(2.405937953536585, 39.09554102558315),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[allow(clippy::excessive_precision)]
|
#[allow(clippy::excessive_precision)]
|
||||||
let mut ps2 = [
|
let mut ps2 = [
|
||||||
Point::new(24.0, 0.0),
|
Vector::new(24.0, 0.0),
|
||||||
Point::new(22.33619528222415, 6.02299846205841),
|
Vector::new(22.33619528222415, 6.02299846205841),
|
||||||
Point::new(20.54936888969905, 12.00964361211476),
|
Vector::new(20.54936888969905, 12.00964361211476),
|
||||||
Point::new(18.60854610798073, 17.9470321677465),
|
Vector::new(18.60854610798073, 17.9470321677465),
|
||||||
Point::new(16.46769273811807, 23.81367936585418),
|
Vector::new(16.46769273811807, 23.81367936585418),
|
||||||
Point::new(14.05325025774858, 29.57079353071012),
|
Vector::new(14.05325025774858, 29.57079353071012),
|
||||||
Point::new(11.23551045834022, 35.13775818285372),
|
Vector::new(11.23551045834022, 35.13775818285372),
|
||||||
Point::new(7.752568160730571, 40.30450679009583),
|
Vector::new(7.752568160730571, 40.30450679009583),
|
||||||
Point::new(3.016931552701656, 44.28891593799322),
|
Vector::new(3.016931552701656, 44.28891593799322),
|
||||||
];
|
];
|
||||||
|
|
||||||
let scale = 0.25;
|
let scale = 0.25;
|
||||||
@@ -47,7 +47,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let collider = ColliderBuilder::segment(point![-100.0, 0.0], point![100.0, 0.0]).friction(0.6);
|
let collider =
|
||||||
|
ColliderBuilder::segment(Vector::new(-100.0, 0.0), Vector::new(100.0, 0.0)).friction(0.6);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -65,10 +66,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
let ps = [
|
let ps = [
|
||||||
point![-ps2[i].x, ps2[i].y],
|
Vector::new(-ps2[i].x, ps2[i].y),
|
||||||
point![-ps1[i].x, ps1[i].y],
|
Vector::new(-ps1[i].x, ps1[i].y),
|
||||||
point![-ps1[i + 1].x, ps1[i + 1].y],
|
Vector::new(-ps1[i + 1].x, ps1[i + 1].y),
|
||||||
point![-ps2[i + 1].x, ps2[i + 1].y],
|
Vector::new(-ps2[i + 1].x, ps2[i + 1].y),
|
||||||
];
|
];
|
||||||
let rigid_body = RigidBodyBuilder::dynamic();
|
let rigid_body = RigidBodyBuilder::dynamic();
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
@@ -82,8 +83,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ps = [
|
let ps = [
|
||||||
ps1[8],
|
ps1[8],
|
||||||
ps2[8],
|
ps2[8],
|
||||||
point![-ps1[8].x, ps1[8].y],
|
Vector::new(-ps1[8].x, ps1[8].y),
|
||||||
point![-ps2[8].x, ps2[8].y],
|
Vector::new(-ps2[8].x, ps2[8].y),
|
||||||
];
|
];
|
||||||
let rigid_body = RigidBodyBuilder::dynamic();
|
let rigid_body = RigidBodyBuilder::dynamic();
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
@@ -94,8 +95,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
let rigid_body =
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
RigidBodyBuilder::dynamic().translation(vector![0.0, 0.5 + ps2[8].y + 1.0 * i as f32]);
|
.translation(Vector::new(0.0, 0.5 + ps2[8].y + 1.0 * i as f32));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(2.0, 0.5).friction(friction);
|
let collider = ColliderBuilder::cuboid(2.0, 0.5).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -105,5 +106,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.linear_damping(0.1)
|
.linear_damping(0.1)
|
||||||
.angular_damping(0.1)
|
.angular_damping(0.1)
|
||||||
.translation(vector![(1.0 + 2.0 * i as f32) * hx, count as f32 * hx]);
|
.translation(Vector::new((1.0 + 2.0 * i as f32) * hx, count as f32 * hx));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(capsule.clone(), handle, &mut bodies);
|
colliders.insert_with_parent(capsule.clone(), handle, &mut bodies);
|
||||||
|
|
||||||
let pivot = point![(2.0 * i as f32) * hx, count as f32 * hx];
|
let pivot = Vector::new((2.0 * i as f32) * hx, count as f32 * hx);
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(bodies[prev].position().inverse_transform_point(&pivot))
|
.local_anchor1(bodies[prev].position().inverse_transform_point(pivot))
|
||||||
.local_anchor2(bodies[handle].position().inverse_transform_point(&pivot))
|
.local_anchor2(bodies[handle].position().inverse_transform_point(pivot))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(prev, handle, joint, true);
|
impulse_joints.insert(prev, handle, joint, true);
|
||||||
prev = handle;
|
prev = handle;
|
||||||
@@ -48,20 +48,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.linear_damping(0.1)
|
.linear_damping(0.1)
|
||||||
.angular_damping(0.1)
|
.angular_damping(0.1)
|
||||||
.translation(vector![
|
.translation(Vector::new(
|
||||||
(1.0 + 2.0 * count as f32) * hx + radius - hx,
|
(1.0 + 2.0 * count as f32) * hx + radius - hx,
|
||||||
count as f32 * hx
|
count as f32 * hx,
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(radius)
|
let collider = ColliderBuilder::ball(radius)
|
||||||
.friction(friction)
|
.friction(friction)
|
||||||
.density(density);
|
.density(density);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let pivot = point![(2.0 * count as f32) * hx, count as f32 * hx];
|
let pivot = Vector::new((2.0 * count as f32) * hx, count as f32 * hx);
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(bodies[prev].position().inverse_transform_point(&pivot))
|
.local_anchor1(bodies[prev].position().inverse_transform_point(pivot))
|
||||||
.local_anchor2(bodies[handle].position().inverse_transform_point(&pivot))
|
.local_anchor2(bodies[handle].position().inverse_transform_point(pivot))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(prev, handle, joint, true);
|
impulse_joints.insert(prev, handle, joint, true);
|
||||||
|
|
||||||
@@ -69,5 +69,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,24 +27,24 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.linear_damping(0.1)
|
.linear_damping(0.1)
|
||||||
.angular_damping(0.1)
|
.angular_damping(0.1)
|
||||||
.translation(vector![x_base + 0.5 + 1.0 * i as f32, 20.0]);
|
.translation(Vector::new(x_base + 0.5 + 1.0 * i as f32, 20.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.5, 0.125).density(density);
|
let collider = ColliderBuilder::cuboid(0.5, 0.125).density(density);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let pivot = point![x_base + 1.0 * i as f32, 20.0];
|
let pivot = Vector::new(x_base + 1.0 * i as f32, 20.0);
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(bodies[prev].position().inverse_transform_point(&pivot))
|
.local_anchor1(bodies[prev].position().inverse_transform_point(pivot))
|
||||||
.local_anchor2(bodies[handle].position().inverse_transform_point(&pivot))
|
.local_anchor2(bodies[handle].position().inverse_transform_point(pivot))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(prev, handle, joint, true);
|
impulse_joints.insert(prev, handle, joint, true);
|
||||||
prev = handle;
|
prev = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pivot = point![x_base + 1.0 * count as f32, 20.0];
|
let pivot = Vector::new(x_base + 1.0 * count as f32, 20.0);
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(bodies[prev].position().inverse_transform_point(&pivot))
|
.local_anchor1(bodies[prev].position().inverse_transform_point(pivot))
|
||||||
.local_anchor2(bodies[ground].position().inverse_transform_point(&pivot))
|
.local_anchor2(bodies[ground].position().inverse_transform_point(pivot))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(prev, ground, joint, true);
|
impulse_joints.insert(prev, ground, joint, true);
|
||||||
|
|
||||||
@@ -52,5 +52,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -2.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -2.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(40.0, 2.0).friction(friction);
|
let collider = ColliderBuilder::cuboid(40.0, 2.0).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -42,14 +42,17 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for i in 0..nb {
|
for i in 0..nb {
|
||||||
if i != nb - 1 {
|
if i != nb - 1 {
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![z + 0.25 * scale, y + card_height - 0.015 * scale])
|
.translation(Vector::new(
|
||||||
|
z + 0.25 * scale,
|
||||||
|
y + card_height - 0.015 * scale,
|
||||||
|
))
|
||||||
.rotation(angle2);
|
.rotation(angle2);
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![z, y])
|
.translation(Vector::new(z, y))
|
||||||
.rotation(angle1);
|
.rotation(angle1);
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
||||||
@@ -57,7 +60,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
z += 0.175 * scale;
|
z += 0.175 * scale;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![z, y])
|
.translation(Vector::new(z, y))
|
||||||
.rotation(angle0);
|
.rotation(angle0);
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
colliders.insert_with_parent(card_box.clone(), ground_handle, &mut bodies);
|
||||||
@@ -74,5 +77,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,21 +18,33 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let collider =
|
let collider = ColliderBuilder::capsule_from_endpoints(
|
||||||
ColliderBuilder::capsule_from_endpoints(point![-10.5, 0.0], point![10.5, 0.0], radius)
|
Vector::new(-10.5, 0.0),
|
||||||
.friction(friction);
|
Vector::new(10.5, 0.0),
|
||||||
|
radius,
|
||||||
|
)
|
||||||
|
.friction(friction);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
let collider =
|
let collider = ColliderBuilder::capsule_from_endpoints(
|
||||||
ColliderBuilder::capsule_from_endpoints(point![-10.5, 0.0], point![-10.5, 20.5], radius)
|
Vector::new(-10.5, 0.0),
|
||||||
.friction(friction);
|
Vector::new(-10.5, 20.5),
|
||||||
|
radius,
|
||||||
|
)
|
||||||
|
.friction(friction);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
let collider =
|
let collider = ColliderBuilder::capsule_from_endpoints(
|
||||||
ColliderBuilder::capsule_from_endpoints(point![10.5, 0.0], point![10.5, 20.5], radius)
|
Vector::new(10.5, 0.0),
|
||||||
.friction(friction);
|
Vector::new(10.5, 20.5),
|
||||||
|
radius,
|
||||||
|
)
|
||||||
|
.friction(friction);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
let collider =
|
let collider = ColliderBuilder::capsule_from_endpoints(
|
||||||
ColliderBuilder::capsule_from_endpoints(point![-10.5, 20.5], point![10.5, 20.5], radius)
|
Vector::new(-10.5, 20.5),
|
||||||
.friction(friction);
|
Vector::new(10.5, 20.5),
|
||||||
|
radius,
|
||||||
|
)
|
||||||
|
.friction(friction);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -48,7 +60,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let x = -8.75 + column as f32 * 18.0 / (grid_count as f32);
|
let x = -8.75 + column as f32 * 18.0 / (grid_count as f32);
|
||||||
let y = 1.5 + row as f32 * 18.0 / (grid_count as f32);
|
let y = 1.5 + row as f32 * 18.0 / (grid_count as f32);
|
||||||
let body = RigidBodyBuilder::dynamic()
|
let body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x, y])
|
.translation(Vector::new(x, y))
|
||||||
.gravity_scale(0.0);
|
.gravity_scale(0.0);
|
||||||
let body_handle = bodies.insert(body);
|
let body_handle = bodies.insert(body);
|
||||||
let ball = ColliderBuilder::ball(radius).friction(friction);
|
let ball = ColliderBuilder::ball(radius).friction(friction);
|
||||||
@@ -65,5 +77,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let impulse_joints = ImpulseJointSet::new();
|
let impulse_joints = ImpulseJointSet::new();
|
||||||
let multibody_joints = MultibodyJointSet::new();
|
let multibody_joints = MultibodyJointSet::new();
|
||||||
|
|
||||||
let origin = vector![100_000.0, -80_000.0];
|
let origin = Vector::new(100_000.0, -80_000.0);
|
||||||
let friction = 0.6;
|
let friction = 0.6;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -1.0] + origin);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -1.0) + origin);
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(100.0, 1.0).friction(friction);
|
let collider = ColliderBuilder::cuboid(100.0, 1.0).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -35,7 +35,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for j in i..base_count {
|
for j in i..base_count {
|
||||||
let x = (i as f32 + 1.0) * shift + 2.0 * (j as f32 - i as f32) * shift
|
let x = (i as f32 + 1.0) * shift + 2.0 * (j as f32 - i as f32) * shift
|
||||||
- h * base_count as f32;
|
- h * base_count as f32;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y] + origin);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y) + origin);
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(h, h).friction(friction);
|
let collider = ColliderBuilder::cuboid(h, h).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -46,5 +46,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5] + origin, 20.0);
|
testbed.look_at(Vec2::new(origin.x + 0.0, origin.y + 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::segment(
|
let collider = ColliderBuilder::segment(
|
||||||
point![-0.5 * 2.0 * ground_width, 0.0],
|
Vector::new(-0.5 * 2.0 * ground_width, 0.0),
|
||||||
point![0.5 * 2.0 * ground_width, 0.0],
|
Vector::new(0.5 * 2.0 * ground_width, 0.0),
|
||||||
)
|
)
|
||||||
.friction(friction);
|
.friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -40,7 +40,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let coeff = i as f32 - 0.5 * count as f32;
|
let coeff = i as f32 - 0.5 * count as f32;
|
||||||
let yy = if count == 1 { y + 2.0 } else { y };
|
let yy = if count == 1 { y + 2.0 } else { y };
|
||||||
let position = vector![2.0 * coeff * extent + offset, yy];
|
let position = Vector::new(2.0 * coeff * extent + offset, yy);
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(position);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(position);
|
||||||
let parent = bodies.insert(rigid_body);
|
let parent = bodies.insert(rigid_body);
|
||||||
|
|
||||||
@@ -62,5 +62,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::segment(
|
let collider = ColliderBuilder::segment(
|
||||||
point![-0.5 * 2.0 * ground_width, 0.0],
|
Vector::new(-0.5 * 2.0 * ground_width, 0.0),
|
||||||
point![0.5 * 2.0 * ground_width, 0.0],
|
Vector::new(0.5 * 2.0 * ground_width, 0.0),
|
||||||
)
|
)
|
||||||
.friction(friction);
|
.friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -30,17 +30,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![-9.0 * extent, 0.5 * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(-9.0 * extent, 0.5 * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![9.0 * extent, 0.5 * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(9.0 * extent, 0.5 * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, (10.0 + 16.0) * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(0.0, (10.0 + 16.0) * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(10.0 * extent, 10.0 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(10.0 * extent, 10.0 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -49,5 +52,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -2.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -2.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(40.0, 2.0).friction(friction);
|
let collider = ColliderBuilder::cuboid(40.0, 2.0).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -24,17 +24,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![-9.0 * extent, 0.5 * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(-9.0 * extent, 0.5 * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![9.0 * extent, 0.5 * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(9.0 * extent, 0.5 * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(0.5 * extent, 0.5 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, (10.0 + 16.0) * extent]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(0.0, (10.0 + 16.0) * extent));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(10.0 * extent, 10.0 * extent).friction(friction);
|
let collider = ColliderBuilder::cuboid(10.0 * extent, 10.0 * extent).friction(friction);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -43,5 +46,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,23 +29,23 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::new(body_type)
|
let rigid_body = RigidBodyBuilder::new(body_type)
|
||||||
.translation(vector![k as f32 * shift, -(i as f32) * shift]);
|
.translation(Vector::new(k as f32 * shift, -(i as f32) * shift));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(point![0.0, -0.5 * shift])
|
.local_anchor1(Vector::new(0.0, -0.5 * shift))
|
||||||
.local_anchor2(point![0.0, 0.5 * shift])
|
.local_anchor2(Vector::new(0.0, 0.5 * shift))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(handles[index - 1], handle, joint, true);
|
impulse_joints.insert(handles[index - 1], handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if k > 0 {
|
if k > 0 {
|
||||||
let joint = RevoluteJointBuilder::new()
|
let joint = RevoluteJointBuilder::new()
|
||||||
.local_anchor1(point![0.5 * shift, 0.0])
|
.local_anchor1(Vector::new(0.5 * shift, 0.0))
|
||||||
.local_anchor2(point![-0.5 * shift, 0.0])
|
.local_anchor2(Vector::new(-0.5 * shift, 0.0))
|
||||||
.contacts_enabled(false);
|
.contacts_enabled(false);
|
||||||
impulse_joints.insert(handles[index - numi], handle, joint, true);
|
impulse_joints.insert(handles[index - numi], handle, joint, true);
|
||||||
}
|
}
|
||||||
@@ -59,5 +59,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -1.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -1.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(100.0, 1.0).friction(0.6);
|
let collider = ColliderBuilder::cuboid(100.0, 1.0).friction(0.6);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -34,7 +34,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for j in i..base_count {
|
for j in i..base_count {
|
||||||
let x = (i as f32 + 1.0) * shift + 2.0 * (j as f32 - i as f32) * shift
|
let x = (i as f32 + 1.0) * shift + 2.0 * (j as f32 - i as f32) * shift
|
||||||
- h * base_count as f32;
|
- h * base_count as f32;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(h, h).friction(0.6);
|
let collider = ColliderBuilder::cuboid(h, h).friction(0.6);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -45,5 +45,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 20.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 20.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 200.1;
|
let ground_size = 200.1;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -35,12 +36,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = 3.0;
|
let y = 3.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_body_color(handle, [0.5, 0.5, 1.0]);
|
testbed.set_initial_body_color(handle, Color::new(0.5, 0.5, 1.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -48,7 +49,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Rigid body so that the sensor can move.
|
// Rigid body so that the sensor can move.
|
||||||
let sensor = RigidBodyBuilder::dynamic().translation(vector![0.0, 10.0]);
|
let sensor = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 10.0));
|
||||||
let sensor_handle = bodies.insert(sensor);
|
let sensor_handle = bodies.insert(sensor);
|
||||||
|
|
||||||
// Solid cube attached to the sensor which
|
// Solid cube attached to the sensor which
|
||||||
@@ -64,15 +65,15 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
.active_events(ActiveEvents::COLLISION_EVENTS);
|
.active_events(ActiveEvents::COLLISION_EVENTS);
|
||||||
colliders.insert_with_parent(sensor_collider, sensor_handle, &mut bodies);
|
colliders.insert_with_parent(sensor_collider, sensor_handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_body_color(sensor_handle, [0.5, 1.0, 1.0]);
|
testbed.set_initial_body_color(sensor_handle, Color::new(0.5, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
// Callback that will be executed on the main loop to handle proximities.
|
// Callback that will be executed on the main loop to handle proximities.
|
||||||
testbed.add_callback(move |mut graphics, physics, events, _| {
|
testbed.add_callback(move |mut graphics, physics, events, _| {
|
||||||
while let Ok(prox) = events.collision_events.try_recv() {
|
while let Ok(prox) = events.collision_events.try_recv() {
|
||||||
let color = if prox.started() {
|
let color = if prox.started() {
|
||||||
[1.0, 1.0, 0.0]
|
Color::new(1.0, 1.0, 0.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
[0.5, 0.5, 1.0]
|
Color::new(0.5, 0.5, 1.0, 1.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_handle1 = physics.colliders[prox.collider1()].parent().unwrap();
|
let parent_handle1 = physics.colliders[prox.collider1()].parent().unwrap();
|
||||||
@@ -80,10 +81,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
if let Some(graphics) = &mut graphics {
|
if let Some(graphics) = &mut graphics {
|
||||||
if parent_handle1 != ground_handle && parent_handle1 != sensor_handle {
|
if parent_handle1 != ground_handle && parent_handle1 != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle1, color);
|
graphics.set_body_color(parent_handle1, color, false);
|
||||||
}
|
}
|
||||||
if parent_handle2 != ground_handle && parent_handle2 != sensor_handle {
|
if parent_handle2 != ground_handle && parent_handle2 != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle2, color);
|
graphics.set_body_color(parent_handle2, color, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,5 +94,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 1.0], 100.0);
|
testbed.look_at(Vec2::new(0.0, 1.0), 100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::new(status).translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::new(status).translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -59,5 +59,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 5.0);
|
||||||
}
|
}
|
||||||
@@ -22,14 +22,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![ground_size, ground_size * 2.0]);
|
.translation(Vec2::new(ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![-ground_size, ground_size * 2.0]);
|
.translation(Vec2::new(-ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -50,7 +50,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery + 2.0;
|
let y = j as f32 * shift + centery + 2.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -61,5 +61,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
testbed.look_at(Vec2::new(0.0, 50.0), 10.0);
|
||||||
}
|
}
|
||||||
@@ -22,14 +22,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![ground_size, ground_size * 4.0]);
|
.translation(Vec2::new(ground_size, ground_size * 4.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![-ground_size, ground_size * 4.0]);
|
.translation(Vec2::new(-ground_size, ground_size * 4.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 4.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -52,7 +52,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shifty + centery + 3.0;
|
let y = j as f32 * shifty + centery + 3.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::capsule_y(rad * 1.5, rad);
|
let collider = ColliderBuilder::capsule_y(rad * 1.5, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -63,5 +63,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
testbed.look_at(Vec2::new(0.0, 50.0), 10.0);
|
||||||
}
|
}
|
||||||
@@ -24,14 +24,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![ground_size, ground_size * 2.0]);
|
.translation(Vec2::new(ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![-ground_size, ground_size * 2.0]);
|
.translation(Vec2::new(-ground_size, ground_size * 2.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size * 2.0, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -55,14 +55,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let x = i as f32 * shift - centerx;
|
let x = i as f32 * shift - centerx;
|
||||||
let y = j as f32 * shift * 2.0 + centery + 2.0;
|
let y = j as f32 * shift * 2.0 + centery + 2.0;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let pt: Point<f32> = distribution.sample(&mut rng);
|
let pt: [f32; 2] = distribution.sample(&mut rng);
|
||||||
points.push(pt * scale);
|
points.push(Vec2::from(pt) * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
let collider = ColliderBuilder::convex_hull(&points).unwrap();
|
let collider = ColliderBuilder::convex_hull(&points).unwrap();
|
||||||
@@ -74,5 +74,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
testbed.look_at(Vec2::new(0.0, 50.0), 10.0);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
use rapier_testbed2d::Testbed;
|
use rapier_testbed2d::Testbed;
|
||||||
use rapier2d::na::DVector;
|
|
||||||
use rapier2d::prelude::*;
|
use rapier2d::prelude::*;
|
||||||
|
|
||||||
pub fn init_world(testbed: &mut Testbed) {
|
pub fn init_world(testbed: &mut Testbed) {
|
||||||
@@ -14,16 +13,18 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let ground_size = Vector::new(50.0, 1.0);
|
let ground_size = Vec2::new(50.0, 1.0);
|
||||||
let nsubdivs = 2000;
|
let nsubdivs = 2000;
|
||||||
|
|
||||||
let heights = DVector::from_fn(nsubdivs + 1, |i, _| {
|
let heights = (0..nsubdivs + 1)
|
||||||
if i == 0 || i == nsubdivs {
|
.map(|i| {
|
||||||
80.0
|
if i == 0 || i == nsubdivs {
|
||||||
} else {
|
80.0
|
||||||
(i as f32 * ground_size.x / (nsubdivs as f32)).cos() * 2.0
|
} else {
|
||||||
}
|
(i as f32 * ground_size.x / (nsubdivs as f32)).cos() * 2.0
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
@@ -46,7 +47,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery + 3.0;
|
let y = j as f32 * shift + centery + 3.0;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
if j % 2 == 0 {
|
if j % 2 == 0 {
|
||||||
@@ -63,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 50.0], 10.0);
|
testbed.look_at(Vec2::new(0.0, 50.0), 10.0);
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body =
|
||||||
RigidBodyBuilder::new(status).translation(vector![fk * shift, -fi * shift]);
|
RigidBodyBuilder::new(status).translation(Vec2::new(fk * shift, -fi * shift));
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||||
@@ -41,7 +41,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
// Vertical joint.
|
// Vertical joint.
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
let parent_handle = *body_handles.last().unwrap();
|
let parent_handle = *body_handles.last().unwrap();
|
||||||
let joint = RevoluteJointBuilder::new().local_anchor2(point![0.0, shift]);
|
let joint = RevoluteJointBuilder::new().local_anchor2(Vec2::new(0.0, shift));
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
if k > 0 {
|
if k > 0 {
|
||||||
let parent_index = body_handles.len() - numi;
|
let parent_index = body_handles.len() - numi;
|
||||||
let parent_handle = body_handles[parent_index];
|
let parent_handle = body_handles[parent_index];
|
||||||
let joint = RevoluteJointBuilder::new().local_anchor2(point![-shift, 0.0]);
|
let joint = RevoluteJointBuilder::new().local_anchor2(Vec2::new(-shift, 0.0));
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,5 +61,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![numk as f32 * rad, numi as f32 * -rad], 5.0);
|
testbed.look_at(Vec2::new(numk as f32 * rad, numi as f32 * -rad), 5.0);
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::new(status)
|
let rigid_body = RigidBodyBuilder::new(status)
|
||||||
.translation(vector![x + fk * shift, y - fi * shift]);
|
.translation(Vec2::new(x + fk * shift, y - fi * shift));
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad);
|
let collider = ColliderBuilder::ball(rad);
|
||||||
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
colliders.insert_with_parent(collider, child_handle, &mut bodies);
|
||||||
@@ -46,8 +46,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
// Vertical joint.
|
// Vertical joint.
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
let parent_handle = *body_handles.last().unwrap();
|
let parent_handle = *body_handles.last().unwrap();
|
||||||
let joint = FixedJointBuilder::new()
|
let joint =
|
||||||
.local_frame2(Isometry::translation(0.0, shift));
|
FixedJointBuilder::new().local_frame2(Pose2::translation(0.0, shift));
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
if k > 0 {
|
if k > 0 {
|
||||||
let parent_index = body_handles.len() - num;
|
let parent_index = body_handles.len() - num;
|
||||||
let parent_handle = body_handles[parent_index];
|
let parent_handle = body_handles[parent_index];
|
||||||
let joint = FixedJointBuilder::new()
|
let joint =
|
||||||
.local_frame2(Isometry::translation(-shift, 0.0));
|
FixedJointBuilder::new().local_frame2(Pose2::translation(-shift, 0.0));
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,5 +70,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![50.0, 50.0], 5.0);
|
testbed.look_at(Vec2::new(50.0, 50.0), 5.0);
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for j in 0..50 {
|
for j in 0..50 {
|
||||||
let x = j as f32 * shift * 4.0;
|
let x = j as f32 * shift * 4.0;
|
||||||
|
|
||||||
let ground = RigidBodyBuilder::fixed().translation(vector![x, y]);
|
let ground = RigidBodyBuilder::fixed().translation(Vec2::new(x, y));
|
||||||
let mut curr_parent = bodies.insert(ground);
|
let mut curr_parent = bodies.insert(ground);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, curr_parent, &mut bodies);
|
colliders.insert_with_parent(collider, curr_parent, &mut bodies);
|
||||||
@@ -32,19 +32,19 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
let y = y - (i + 1) as f32 * shift;
|
let y = y - (i + 1) as f32 * shift;
|
||||||
let density = 1.0;
|
let density = 1.0;
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let curr_child = bodies.insert(rigid_body);
|
let curr_child = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad).density(density);
|
let collider = ColliderBuilder::cuboid(rad, rad).density(density);
|
||||||
colliders.insert_with_parent(collider, curr_child, &mut bodies);
|
colliders.insert_with_parent(collider, curr_child, &mut bodies);
|
||||||
|
|
||||||
let axis = if i % 2 == 0 {
|
let axis = if i % 2 == 0 {
|
||||||
UnitVector::new_normalize(vector![1.0, 1.0])
|
Vec2::new(1.0, 1.0).normalize()
|
||||||
} else {
|
} else {
|
||||||
UnitVector::new_normalize(vector![-1.0, 1.0])
|
Vec2::new(-1.0, 1.0).normalize()
|
||||||
};
|
};
|
||||||
|
|
||||||
let prism = PrismaticJointBuilder::new(axis)
|
let prism = PrismaticJointBuilder::new(axis)
|
||||||
.local_anchor2(point![0.0, shift])
|
.local_anchor2(Vec2::new(0.0, shift))
|
||||||
.limits([-1.5, 1.5]);
|
.limits([-1.5, 1.5]);
|
||||||
impulse_joints.insert(curr_parent, curr_child, prism, true);
|
impulse_joints.insert(curr_parent, curr_child, prism, true);
|
||||||
|
|
||||||
@@ -57,5 +57,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![80.0, 80.0], 15.0);
|
testbed.look_at(Vec2::new(80.0, 80.0), 15.0);
|
||||||
}
|
}
|
||||||
37
examples2d/stress_tests/mod.rs
Normal file
37
examples2d/stress_tests/mod.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use rapier_testbed2d::Example;
|
||||||
|
|
||||||
|
mod balls2;
|
||||||
|
mod boxes2;
|
||||||
|
mod capsules2;
|
||||||
|
mod convex_polygons2;
|
||||||
|
mod heightfield2;
|
||||||
|
mod joint_ball2;
|
||||||
|
mod joint_fixed2;
|
||||||
|
mod joint_prismatic2;
|
||||||
|
mod pyramid2;
|
||||||
|
mod vertical_stacks2;
|
||||||
|
|
||||||
|
pub fn builders() -> Vec<Example> {
|
||||||
|
const STRESS: &str = "Stress Tests";
|
||||||
|
|
||||||
|
vec![
|
||||||
|
Example::new(STRESS, "Balls", balls2::init_world),
|
||||||
|
Example::new(STRESS, "Boxes", boxes2::init_world),
|
||||||
|
Example::new(STRESS, "Capsules", capsules2::init_world),
|
||||||
|
Example::new(STRESS, "Convex polygons", convex_polygons2::init_world),
|
||||||
|
Example::new(STRESS, "Heightfield", heightfield2::init_world),
|
||||||
|
Example::new(STRESS, "Pyramid", pyramid2::init_world),
|
||||||
|
Example::new(STRESS, "Verticals stacks", vertical_stacks2::init_world),
|
||||||
|
Example::new(STRESS, "(Stress test) joint ball", joint_ball2::init_world),
|
||||||
|
Example::new(
|
||||||
|
STRESS,
|
||||||
|
"(Stress test) joint fixed",
|
||||||
|
joint_fixed2::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
STRESS,
|
||||||
|
"(Stress test) joint prismatic",
|
||||||
|
joint_prismatic2::init_world,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -39,7 +39,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = fi * shift + centery;
|
let y = fi * shift + centery;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -50,5 +50,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 5.0);
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = (num as f32 - fi - 1.0) * shifty + centery;
|
let y = (num as f32 - fi - 1.0) * shifty + centery;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vec2::new(x, y));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -57,5 +57,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 2.5], 5.0);
|
testbed.look_at(Vec2::new(0.0, 2.5), 5.0);
|
||||||
}
|
}
|
||||||
@@ -22,14 +22,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![ground_size, ground_size]);
|
.translation(Vector::new(ground_size, ground_size));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed()
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
.rotation(std::f32::consts::FRAC_PI_2)
|
.rotation(std::f32::consts::FRAC_PI_2)
|
||||||
.translation(vector![-ground_size, ground_size]);
|
.translation(Vector::new(-ground_size, ground_size));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, 1.2);
|
let collider = ColliderBuilder::cuboid(ground_size, 1.2);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.contact_skin(0.2);
|
.contact_skin(0.2);
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![ith as f32 * 8.0 - 20.0, 20.0 + k as f32 * 11.0]);
|
.translation(Vector::new(ith as f32 * 8.0 - 20.0, 20.0 + k as f32 * 11.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
}
|
}
|
||||||
@@ -55,5 +55,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 20.0], 17.0);
|
testbed.look_at(Vec2::new(0.0, 20.0), 17.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use rapier_testbed2d::ui::egui::Align2;
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed2d::{
|
use rapier_testbed2d::{
|
||||||
KeyCode, PhysicsState, TestbedGraphics,
|
KeyCode, PhysicsState, TestbedGraphics,
|
||||||
ui::egui::{ComboBox, Slider, Ui, Window},
|
egui::{Align2, ComboBox, Slider, Ui, Window},
|
||||||
};
|
};
|
||||||
use rapier2d::{
|
use rapier2d::{
|
||||||
control::{CharacterLength, KinematicCharacterController, PidController},
|
control::{CharacterLength, KinematicCharacterController, PidController},
|
||||||
@@ -51,24 +51,24 @@ fn character_movement_from_inputs(
|
|||||||
gfx: &TestbedGraphics,
|
gfx: &TestbedGraphics,
|
||||||
mut speed: Real,
|
mut speed: Real,
|
||||||
artificial_gravity: bool,
|
artificial_gravity: bool,
|
||||||
) -> Vector<Real> {
|
) -> Vector {
|
||||||
let mut desired_movement = Vector::zeros();
|
let mut desired_movement = Vector::ZERO;
|
||||||
|
|
||||||
for key in gfx.keys().get_pressed() {
|
for key in gfx.keys().get_pressed() {
|
||||||
match *key {
|
match *key {
|
||||||
KeyCode::ArrowRight => {
|
KeyCode::Right => {
|
||||||
desired_movement += Vector::x();
|
desired_movement += Vector::X;
|
||||||
}
|
}
|
||||||
KeyCode::ArrowLeft => {
|
KeyCode::Left => {
|
||||||
desired_movement -= Vector::x();
|
desired_movement -= Vector::X;
|
||||||
}
|
}
|
||||||
KeyCode::Space => {
|
KeyCode::Space => {
|
||||||
desired_movement += Vector::y() * 2.0;
|
desired_movement += Vector::Y * 2.0;
|
||||||
}
|
}
|
||||||
KeyCode::ControlRight => {
|
KeyCode::RControl => {
|
||||||
desired_movement -= Vector::y();
|
desired_movement -= Vector::Y;
|
||||||
}
|
}
|
||||||
KeyCode::ShiftRight => {
|
KeyCode::RShift => {
|
||||||
speed /= 10.0;
|
speed /= 10.0;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -78,7 +78,7 @@ fn character_movement_from_inputs(
|
|||||||
desired_movement *= speed;
|
desired_movement *= speed;
|
||||||
|
|
||||||
if artificial_gravity {
|
if artificial_gravity {
|
||||||
desired_movement -= Vector::y() * speed;
|
desired_movement -= Vector::Y * speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
desired_movement
|
desired_movement
|
||||||
@@ -97,11 +97,11 @@ fn update_pid_controller(
|
|||||||
|
|
||||||
// Adjust the controlled axis depending on the keys pressed by the user.
|
// Adjust the controlled axis depending on the keys pressed by the user.
|
||||||
// - If the user is jumping, enable control over Y.
|
// - If the user is jumping, enable control over Y.
|
||||||
// - If the user isn’t pressing any key, disable all linear controls to let
|
// - If the user isn't pressing any key, disable all linear controls to let
|
||||||
// gravity/collision do their thing freely.
|
// gravity/collision do their thing freely.
|
||||||
let mut axes = AxesMask::ANG_Z;
|
let mut axes = AxesMask::ANG_Z;
|
||||||
|
|
||||||
if desired_movement.norm() != 0.0 {
|
if desired_movement.length() != 0.0 {
|
||||||
axes |= if desired_movement.y == 0.0 {
|
axes |= if desired_movement.y == 0.0 {
|
||||||
AxesMask::LIN_X
|
AxesMask::LIN_X
|
||||||
} else {
|
} else {
|
||||||
@@ -114,7 +114,7 @@ fn update_pid_controller(
|
|||||||
let corrective_vel = pid.rigid_body_correction(
|
let corrective_vel = pid.rigid_body_correction(
|
||||||
phx.integration_parameters.dt,
|
phx.integration_parameters.dt,
|
||||||
character_body,
|
character_body,
|
||||||
(character_body.translation() + desired_movement).into(),
|
Pose::from_translation(character_body.translation() + desired_movement),
|
||||||
RigidBodyVelocity::zero(),
|
RigidBodyVelocity::zero(),
|
||||||
);
|
);
|
||||||
let new_vel = *character_body.vels() + corrective_vel;
|
let new_vel = *character_body.vels() + corrective_vel;
|
||||||
@@ -150,14 +150,14 @@ fn update_kinematic_controller(
|
|||||||
&query_pipeline.as_ref(),
|
&query_pipeline.as_ref(),
|
||||||
&*character_shape,
|
&*character_shape,
|
||||||
&character_collider_pose,
|
&character_collider_pose,
|
||||||
desired_movement.cast::<Real>(),
|
desired_movement,
|
||||||
|c| collisions.push(c),
|
|c| collisions.push(c),
|
||||||
);
|
);
|
||||||
|
|
||||||
if mvt.grounded {
|
if mvt.grounded {
|
||||||
gfx.set_body_color(character_handle, [0.1, 0.8, 0.1]);
|
gfx.set_body_color(character_handle, Color::new(0.1, 0.8, 0.1, 1.0), false);
|
||||||
} else {
|
} else {
|
||||||
gfx.set_body_color(character_handle, [0.8, 0.1, 0.1]);
|
gfx.set_body_color(character_handle, Color::new(0.8, 0.1, 0.1, 1.0), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.solve_character_collision_impulses(
|
controller.solve_character_collision_impulses(
|
||||||
@@ -170,7 +170,7 @@ fn update_kinematic_controller(
|
|||||||
|
|
||||||
let character_body = &mut phx.bodies[character_handle];
|
let character_body = &mut phx.bodies[character_handle];
|
||||||
let pose = character_body.position();
|
let pose = character_body.position();
|
||||||
character_body.set_next_kinematic_translation(pose.translation.vector + mvt.translation);
|
character_body.set_next_kinematic_translation(pose.translation + mvt.translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn character_control_ui(
|
fn character_control_ui(
|
||||||
@@ -181,7 +181,7 @@ fn character_control_ui(
|
|||||||
) {
|
) {
|
||||||
Window::new("Character Control")
|
Window::new("Character Control")
|
||||||
.anchor(Align2::RIGHT_TOP, [-15.0, 15.0])
|
.anchor(Align2::RIGHT_TOP, [-15.0, 15.0])
|
||||||
.show(gfx.ui_context_mut().ctx_mut(), |ui| {
|
.show(gfx.egui_context(), |ui| {
|
||||||
ComboBox::from_label("control mode")
|
ComboBox::from_label("control mode")
|
||||||
.selected_text(format!("{:?}", *control_mode))
|
.selected_text(format!("{:?}", *control_mode))
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
@@ -220,9 +220,9 @@ fn pid_control_ui(ui: &mut Ui, pid_controller: &mut PidController, speed: &mut R
|
|||||||
ui.add(Slider::new(&mut ang_ki, 0.0..=10.0).text("angular Ki"));
|
ui.add(Slider::new(&mut ang_ki, 0.0..=10.0).text("angular Ki"));
|
||||||
ui.add(Slider::new(&mut ang_kd, 0.0..=1.0).text("angular Kd"));
|
ui.add(Slider::new(&mut ang_kd, 0.0..=1.0).text("angular Kd"));
|
||||||
|
|
||||||
pid_controller.pd.lin_kp.fill(lin_kp);
|
pid_controller.pd.lin_kp = Vector::splat(lin_kp);
|
||||||
pid_controller.lin_ki.fill(lin_ki);
|
pid_controller.lin_ki = Vector::splat(lin_ki);
|
||||||
pid_controller.pd.lin_kd.fill(lin_kd);
|
pid_controller.pd.lin_kd = Vector::splat(lin_kd);
|
||||||
pid_controller.pd.ang_kp = ang_kp;
|
pid_controller.pd.ang_kp = ang_kp;
|
||||||
pid_controller.ang_ki = ang_ki;
|
pid_controller.ang_ki = ang_ki;
|
||||||
pid_controller.pd.ang_kd = ang_kd;
|
pid_controller.pd.ang_kd = ang_kd;
|
||||||
@@ -240,12 +240,12 @@ fn kinematic_control_ui(
|
|||||||
#[allow(clippy::useless_conversion)]
|
#[allow(clippy::useless_conversion)]
|
||||||
{
|
{
|
||||||
ui.add(Slider::new(&mut character_controller.max_slope_climb_angle, 0.0..=std::f32::consts::TAU.into()).text("max_slope_climb_angle"))
|
ui.add(Slider::new(&mut character_controller.max_slope_climb_angle, 0.0..=std::f32::consts::TAU.into()).text("max_slope_climb_angle"))
|
||||||
.on_hover_text("The maximum angle (radians) between the floor’s normal and the `up` vector that the character is able to climb.");
|
.on_hover_text("The maximum angle (radians) between the floor's normal and the `up` vector that the character is able to climb.");
|
||||||
ui.add(Slider::new(&mut character_controller.min_slope_slide_angle, 0.0..=std::f32::consts::FRAC_PI_2.into()).text("min_slope_slide_angle"))
|
ui.add(Slider::new(&mut character_controller.min_slope_slide_angle, 0.0..=std::f32::consts::FRAC_PI_2.into()).text("min_slope_slide_angle"))
|
||||||
.on_hover_text("The minimum angle (radians) between the floor’s normal and the `up` vector before the character starts to slide down automatically.");
|
.on_hover_text("The minimum angle (radians) between the floor's normal and the `up` vector before the character starts to slide down automatically.");
|
||||||
}
|
}
|
||||||
let mut is_snapped = character_controller.snap_to_ground.is_some();
|
let mut is_snapped = character_controller.snap_to_ground.is_some();
|
||||||
if ui.checkbox(&mut is_snapped, "snap_to_ground").changed {
|
if ui.checkbox(&mut is_snapped, "snap_to_ground").changed() {
|
||||||
match is_snapped {
|
match is_snapped {
|
||||||
true => {
|
true => {
|
||||||
character_controller.snap_to_ground = Some(CharacterLength::Relative(0.1));
|
character_controller.snap_to_ground = Some(CharacterLength::Relative(0.1));
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
pub mod character;
|
pub mod character;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub mod svg;
|
pub mod svg;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use lyon::math::Point;
|
|||||||
use lyon::path::PathEvent;
|
use lyon::path::PathEvent;
|
||||||
use lyon::tessellation::geometry_builder::*;
|
use lyon::tessellation::geometry_builder::*;
|
||||||
use lyon::tessellation::{self, FillOptions, FillTessellator};
|
use lyon::tessellation::{self, FillOptions, FillTessellator};
|
||||||
use rapier2d::na::{Point2, Rotation2};
|
|
||||||
use usvg::prelude::*;
|
use usvg::prelude::*;
|
||||||
|
|
||||||
const RAPIER_SVG_STR: &str = r#"
|
const RAPIER_SVG_STR: &str = r#"
|
||||||
@@ -37,11 +36,11 @@ const RAPIER_SVG_STR: &str = r#"
|
|||||||
</svg>
|
</svg>
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
pub fn rapier_logo() -> Vec<(Vec<Point2<f32>>, Vec<[u32; 3]>)> {
|
pub fn rapier_logo() -> Vec<(Vec<Vector>, Vec<[u32; 3]>)> {
|
||||||
tessellate_svg_str(RAPIER_SVG_STR)
|
tessellate_svg_str(RAPIER_SVG_STR)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tessellate_svg_str(svg_str: &str) -> Vec<(Vec<Point2<f32>>, Vec<[u32; 3]>)> {
|
pub fn tessellate_svg_str(svg_str: &str) -> Vec<(Vec<Vector>, Vec<[u32; 3]>)> {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
let mut fill_tess = FillTessellator::new();
|
let mut fill_tess = FillTessellator::new();
|
||||||
let opt = usvg::Options::default();
|
let opt = usvg::Options::default();
|
||||||
@@ -80,7 +79,7 @@ pub fn tessellate_svg_str(svg_str: &str) -> Vec<(Vec<Point2<f32>>, Vec<[u32; 3]>
|
|||||||
.vertices
|
.vertices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
Rotation2::new(angle) * point![v.position[0] * sx, v.position[1] * -sy]
|
Rotation::new(angle) * Vector::new(v.position[0] * sx, v.position[1] * -sy)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let nx = 50;
|
let nx = 50;
|
||||||
for i in 0..nx {
|
for i in 0..nx {
|
||||||
for j in 0..10 {
|
for j in 0..10 {
|
||||||
let mut rb = RigidBodyBuilder::dynamic().translation(vector![
|
let mut rb = RigidBodyBuilder::dynamic().translation(Vector::new(
|
||||||
i as f32 * 2.0 - nx as f32 / 2.0,
|
i as f32 * 2.0 - nx as f32 / 2.0,
|
||||||
20.0 + j as f32 * 2.0
|
20.0 + j as f32 * 2.0,
|
||||||
]);
|
));
|
||||||
if test_ccd {
|
if test_ccd {
|
||||||
rb = rb.linvel(vector![0.0, -1000.0]).ccd_enabled(true);
|
rb = rb.linvel(Vector::new(0.0, -1000.0)).ccd_enabled(true);
|
||||||
}
|
}
|
||||||
let rb_handle = bodies.insert(rb);
|
let rb_handle = bodies.insert(rb);
|
||||||
|
|
||||||
@@ -69,19 +69,19 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Voxelization.
|
* Voxelization.
|
||||||
*/
|
*/
|
||||||
let polyline = vec![
|
let polyline = vec![
|
||||||
point![0.0, 0.0],
|
Vector::new(0.0, 0.0),
|
||||||
point![0.0, 10.0],
|
Vector::new(0.0, 10.0),
|
||||||
point![7.0, 4.0],
|
Vector::new(7.0, 4.0),
|
||||||
point![14.0, 10.0],
|
Vector::new(14.0, 10.0),
|
||||||
point![14.0, 0.0],
|
Vector::new(14.0, 0.0),
|
||||||
point![13.0, 7.0],
|
Vector::new(13.0, 7.0),
|
||||||
point![7.0, 2.0],
|
Vector::new(7.0, 2.0),
|
||||||
point![1.0, 7.0],
|
Vector::new(1.0, 7.0),
|
||||||
];
|
];
|
||||||
let indices: Vec<_> = (0..polyline.len() as u32)
|
let indices: Vec<_> = (0..polyline.len() as u32)
|
||||||
.map(|i| [i, (i + 1) % polyline.len() as u32])
|
.map(|i| [i, (i + 1) % polyline.len() as u32])
|
||||||
.collect();
|
.collect();
|
||||||
let rb = bodies.insert(RigidBodyBuilder::fixed().translation(vector![-20.0, -10.0]));
|
let rb = bodies.insert(RigidBodyBuilder::fixed().translation(Vector::new(-20.0, -10.0)));
|
||||||
let shape = SharedShape::voxelized_mesh(&polyline, &indices, 0.2, FillMode::default());
|
let shape = SharedShape::voxelized_mesh(&polyline, &indices, 0.2, FillMode::default());
|
||||||
|
|
||||||
colliders.insert_with_parent(ColliderBuilder::new(shape), rb, &mut bodies);
|
colliders.insert_with_parent(ColliderBuilder::new(shape), rb, &mut bodies);
|
||||||
@@ -92,7 +92,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let voxels: Vec<_> = (0..300)
|
let voxels: Vec<_> = (0..300)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let y = (i as f32 / 20.0).sin().clamp(-0.5, 0.5) * 20.0;
|
let y = (i as f32 / 20.0).sin().clamp(-0.5, 0.5) * 20.0;
|
||||||
point![(i as f32 - 125.0) * voxel_size.x / 2.0, y * voxel_size.y]
|
Vector::new((i as f32 - 125.0) * voxel_size.x / 2.0, y * voxel_size.y)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
colliders.insert(ColliderBuilder::voxels_from_points(voxel_size, &voxels));
|
colliders.insert(ColliderBuilder::voxels_from_points(voxel_size, &voxels));
|
||||||
@@ -101,5 +101,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![0.0, 20.0], 17.0);
|
testbed.look_at(Vec2::new(0.0, 20.0), 17.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ default-run = "all_examples3-f64"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
parallel = ["rapier3d-f64/parallel", "rapier_testbed3d-f64/parallel"]
|
parallel = ["rapier3d-f64/parallel", "rapier_testbed3d-f64/parallel"]
|
||||||
simd-stable = ["rapier3d-f64/simd-stable"]
|
#simd-stable = ["rapier3d-f64/simd-stable"]
|
||||||
simd-nightly = ["rapier3d-f64/simd-nightly"]
|
#simd-nightly = ["rapier3d-f64/simd-nightly"]
|
||||||
enhanced-determinism = ["rapier3d-f64/enhanced-determinism"]
|
enhanced-determinism = ["rapier3d-f64/enhanced-determinism"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -18,6 +18,7 @@ wasm-bindgen = "0.2"
|
|||||||
obj-rs = { version = "0.7", default-features = false }
|
obj-rs = { version = "0.7", default-features = false }
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
|
|
||||||
[dependencies.rapier_testbed3d-f64]
|
[dependencies.rapier_testbed3d-f64]
|
||||||
path = "../crates/rapier_testbed3d-f64"
|
path = "../crates/rapier_testbed3d-f64"
|
||||||
|
|||||||
@@ -5,26 +5,22 @@ use wasm_bindgen::prelude::*;
|
|||||||
extern crate rapier3d_f64 as rapier3d;
|
extern crate rapier3d_f64 as rapier3d;
|
||||||
extern crate rapier_testbed3d_f64 as rapier_testbed3d;
|
extern crate rapier_testbed3d_f64 as rapier_testbed3d;
|
||||||
|
|
||||||
use rapier_testbed3d::{Testbed, TestbedApp};
|
use rapier_testbed3d::{Example, TestbedApp};
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod debug_serialized3;
|
mod debug_serialized3;
|
||||||
mod trimesh3_f64;
|
mod trimesh3_f64;
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
|
#[kiss3d::main]
|
||||||
pub fn main() {
|
pub async fn main() {
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
let builders: Vec<_> = vec![
|
||||||
("Trimesh", trimesh3_f64::init_world),
|
Example::new("Demos f64", "Trimesh", trimesh3_f64::init_world),
|
||||||
("(Debug) serialized", debug_serialized3::init_world),
|
Example::new(
|
||||||
|
"Demos f64",
|
||||||
|
"(Debug) serialized",
|
||||||
|
debug_serialized3::init_world,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with('('), b.0.starts_with('(')) {
|
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
|
||||||
(true, false) => Ordering::Greater,
|
|
||||||
(false, true) => Ordering::Less,
|
|
||||||
});
|
|
||||||
|
|
||||||
let testbed = TestbedApp::from_builders(builders);
|
let testbed = TestbedApp::from_builders(builders);
|
||||||
testbed.run()
|
testbed.run().await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
testbed.harness_mut().physics.narrow_phase = state.narrow_phase;
|
testbed.harness_mut().physics.narrow_phase = state.narrow_phase;
|
||||||
testbed.harness_mut().physics.ccd_solver = state.ccd_solver;
|
testbed.harness_mut().physics.ccd_solver = state.ccd_solver;
|
||||||
|
|
||||||
testbed.set_graphics_shift(vector![-541.0, -6377257.0, -61.0]);
|
testbed.set_graphics_shift([-541.0, -6377257.0, -61.0].into());
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], point![0.0, 0.0, 0.0]);
|
testbed.look_at([10.0, 10.0, 10.0].into(), [0.0, 0.0, 0.0].into());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use rapier_testbed3d::Testbed;
|
use rapier_testbed3d::Testbed;
|
||||||
|
use rapier3d::glamx::{DVec3, Vec3};
|
||||||
use rapier3d::na::ComplexField;
|
use rapier3d::na::ComplexField;
|
||||||
use rapier3d::prelude::*;
|
use rapier3d::prelude::*;
|
||||||
|
|
||||||
@@ -14,10 +15,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Ground
|
* Ground
|
||||||
*/
|
*/
|
||||||
let ground_size = vector![200.0, 1.0, 200.0];
|
let ground_size = DVec3::new(200.0, 1.0, 200.0);
|
||||||
let nsubdivs = 20;
|
let nsubdivs = 20;
|
||||||
|
|
||||||
let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
let heights = Array2::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
||||||
if i == 0 || i == nsubdivs || j == 0 || j == nsubdivs {
|
if i == 0 || i == nsubdivs || j == 0 || j == nsubdivs {
|
||||||
10.0
|
10.0
|
||||||
} else {
|
} else {
|
||||||
@@ -60,7 +61,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let z = k as f64 * shift - centerz;
|
let z = k as f64 * shift - centerz;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(DVec3::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
if j % 2 == 0 {
|
if j % 2 == 0 {
|
||||||
@@ -78,5 +79,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ serde = "1"
|
|||||||
bincode = "1"
|
bincode = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
dot_vox = "5"
|
dot_vox = "5"
|
||||||
|
glam = { version = "0.30.9", features = ["fast-math"] }
|
||||||
|
kiss3d = { version = "0.40.0", features = ["egui", "parry", "serde"] }
|
||||||
|
|
||||||
[dependencies.rapier_testbed3d]
|
[dependencies.rapier_testbed3d]
|
||||||
path = "../crates/rapier_testbed3d"
|
path = "../crates/rapier_testbed3d"
|
||||||
features = ["profiler_ui"]
|
#features = ["profiler_ui"]
|
||||||
|
|
||||||
[dependencies.rapier3d]
|
[dependencies.rapier3d]
|
||||||
path = "../crates/rapier3d"
|
path = "../crates/rapier3d"
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
use rapier_testbed3d::{Example, TestbedApp};
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use rapier_testbed3d::{Testbed, TestbedApp};
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
mod ccd3;
|
mod ccd3;
|
||||||
|
mod character_controller3;
|
||||||
mod collision_groups3;
|
mod collision_groups3;
|
||||||
mod compound3;
|
mod compound3;
|
||||||
mod convex_decomposition3;
|
mod convex_decomposition3;
|
||||||
@@ -20,36 +17,34 @@ mod debug_articulations3;
|
|||||||
mod debug_balls3;
|
mod debug_balls3;
|
||||||
mod debug_big_colliders3;
|
mod debug_big_colliders3;
|
||||||
mod debug_boxes3;
|
mod debug_boxes3;
|
||||||
|
mod debug_chain_high_mass_ratio3;
|
||||||
|
mod debug_cube_high_mass_ratio3;
|
||||||
mod debug_cylinder3;
|
mod debug_cylinder3;
|
||||||
mod debug_deserialize3;
|
mod debug_deserialize3;
|
||||||
|
mod debug_disabled3;
|
||||||
mod debug_dynamic_collider_add3;
|
mod debug_dynamic_collider_add3;
|
||||||
mod debug_friction3;
|
mod debug_friction3;
|
||||||
mod debug_infinite_fall3;
|
mod debug_infinite_fall3;
|
||||||
|
mod debug_internal_edges3;
|
||||||
|
mod debug_long_chain3;
|
||||||
|
mod debug_multibody_ang_motor_pos3;
|
||||||
mod debug_pop3;
|
mod debug_pop3;
|
||||||
mod debug_prismatic3;
|
mod debug_prismatic3;
|
||||||
mod debug_rollback3;
|
mod debug_rollback3;
|
||||||
mod debug_shape_modification3;
|
mod debug_shape_modification3;
|
||||||
|
mod debug_sleeping_kinematic3;
|
||||||
mod debug_thin_cube_on_mesh3;
|
mod debug_thin_cube_on_mesh3;
|
||||||
mod debug_triangle3;
|
mod debug_triangle3;
|
||||||
mod debug_trimesh3;
|
mod debug_trimesh3;
|
||||||
|
mod debug_two_cubes3;
|
||||||
mod domino3;
|
mod domino3;
|
||||||
mod dynamic_trimesh3;
|
mod dynamic_trimesh3;
|
||||||
mod fountain3;
|
mod fountain3;
|
||||||
mod heightfield3;
|
|
||||||
mod joints3;
|
|
||||||
// mod joints3;
|
|
||||||
mod character_controller3;
|
|
||||||
mod debug_chain_high_mass_ratio3;
|
|
||||||
mod debug_cube_high_mass_ratio3;
|
|
||||||
mod debug_disabled3;
|
|
||||||
mod debug_internal_edges3;
|
|
||||||
mod debug_long_chain3;
|
|
||||||
mod debug_multibody_ang_motor_pos3;
|
|
||||||
mod debug_sleeping_kinematic3;
|
|
||||||
mod debug_two_cubes3;
|
|
||||||
mod gyroscopic3;
|
mod gyroscopic3;
|
||||||
|
mod heightfield3;
|
||||||
mod inverse_kinematics3;
|
mod inverse_kinematics3;
|
||||||
mod joint_motor_position3;
|
mod joint_motor_position3;
|
||||||
|
mod joints3;
|
||||||
mod keva3;
|
mod keva3;
|
||||||
mod locked_rotations3;
|
mod locked_rotations3;
|
||||||
mod newton_cradle3;
|
mod newton_cradle3;
|
||||||
@@ -60,101 +55,162 @@ mod restitution3;
|
|||||||
mod rope_joints3;
|
mod rope_joints3;
|
||||||
mod sensor3;
|
mod sensor3;
|
||||||
mod spring_joints3;
|
mod spring_joints3;
|
||||||
|
mod stress_tests;
|
||||||
mod trimesh3;
|
mod trimesh3;
|
||||||
mod urdf3;
|
mod urdf3;
|
||||||
mod vehicle_controller3;
|
mod vehicle_controller3;
|
||||||
mod vehicle_joints3;
|
mod vehicle_joints3;
|
||||||
mod voxels3;
|
mod voxels3;
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
|
#[kiss3d::main]
|
||||||
pub fn main() {
|
pub async fn main() {
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
const COLLISIONS: &str = "Collisions";
|
||||||
("Character controller", character_controller3::init_world),
|
const DYNAMICS: &str = "Dynamics";
|
||||||
("Fountain", fountain3::init_world),
|
const COMPLEX: &str = "Complex Shapes";
|
||||||
("Primitives", primitives3::init_world),
|
const JOINTS: &str = "Joints";
|
||||||
("Multibody joints", joints3::init_world_with_articulations),
|
const CONTROLS: &str = "Controls";
|
||||||
("CCD", ccd3::init_world),
|
const DEBUG: &str = "Debug";
|
||||||
("Collision groups", collision_groups3::init_world),
|
const ROBOTICS: &str = "Robotics";
|
||||||
("Compound", compound3::init_world),
|
|
||||||
("Convex decomposition", convex_decomposition3::init_world),
|
let mut builders: Vec<Example> = vec![
|
||||||
("Convex polyhedron", convex_polyhedron3::init_world),
|
// ── Collisions ──────────────────────────────────────────────────────────
|
||||||
("Damping", damping3::init_world),
|
Example::new(COLLISIONS, "Fountain", fountain3::init_world),
|
||||||
("Gyroscopic", gyroscopic3::init_world),
|
Example::new(COLLISIONS, "Primitives", primitives3::init_world),
|
||||||
("Domino", domino3::init_world),
|
Example::new(COLLISIONS, "Keva tower", keva3::init_world),
|
||||||
("Dynamic trimeshes", dynamic_trimesh3::init_world),
|
Example::new(COLLISIONS, "Newton cradle", newton_cradle3::init_world),
|
||||||
("Heightfield", heightfield3::init_world),
|
Example::new(COLLISIONS, "Domino", domino3::init_world),
|
||||||
("Impulse Joints", joints3::init_world_with_joints),
|
Example::new(COLLISIONS, "Platform", platform3::init_world),
|
||||||
("Inverse kinematics", inverse_kinematics3::init_world),
|
Example::new(COLLISIONS, "Sensor", sensor3::init_world),
|
||||||
("Joint Motor Position", joint_motor_position3::init_world),
|
Example::new(COLLISIONS, "Compound", compound3::init_world),
|
||||||
("Locked rotations", locked_rotations3::init_world),
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
("One-way platforms", one_way_platforms3::init_world),
|
Example::new(
|
||||||
("Platform", platform3::init_world),
|
COLLISIONS,
|
||||||
("Restitution", restitution3::init_world),
|
"Convex decomposition",
|
||||||
("Rope Joints", rope_joints3::init_world),
|
convex_decomposition3::init_world,
|
||||||
("Sensor", sensor3::init_world),
|
),
|
||||||
("Spring Joints", spring_joints3::init_world),
|
Example::new(
|
||||||
("TriMesh", trimesh3::init_world),
|
COLLISIONS,
|
||||||
("Urdf", urdf3::init_world),
|
"Convex polyhedron",
|
||||||
("Voxels", voxels3::init_world),
|
convex_polyhedron3::init_world,
|
||||||
("Vehicle controller", vehicle_controller3::init_world),
|
),
|
||||||
("Vehicle joints", vehicle_joints3::init_world),
|
Example::new(COLLISIONS, "TriMesh", trimesh3::init_world),
|
||||||
("Keva tower", keva3::init_world),
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
("Newton cradle", newton_cradle3::init_world),
|
Example::new(
|
||||||
("(Debug) multibody_joints", debug_articulations3::init_world),
|
COLLISIONS,
|
||||||
(
|
"Dynamic trimeshes",
|
||||||
"(Debug) add/rm collider",
|
dynamic_trimesh3::init_world,
|
||||||
|
),
|
||||||
|
Example::new(COLLISIONS, "Heightfield", heightfield3::init_world),
|
||||||
|
Example::new(COLLISIONS, "Voxels", voxels3::init_world),
|
||||||
|
Example::new(
|
||||||
|
COLLISIONS,
|
||||||
|
"Collision groups",
|
||||||
|
collision_groups3::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
COLLISIONS,
|
||||||
|
"One-way platforms",
|
||||||
|
one_way_platforms3::init_world,
|
||||||
|
),
|
||||||
|
// ── Dynamics ─────────────────────────────────────────────────────────
|
||||||
|
Example::new(DYNAMICS, "Locked rotations", locked_rotations3::init_world),
|
||||||
|
Example::new(DYNAMICS, "Restitution", restitution3::init_world),
|
||||||
|
Example::new(DYNAMICS, "Damping", damping3::init_world),
|
||||||
|
Example::new(DYNAMICS, "Gyroscopic", gyroscopic3::init_world),
|
||||||
|
Example::new(DYNAMICS, "CCD", ccd3::init_world),
|
||||||
|
// ── Joints ─────────────────────────────────────────────────────────
|
||||||
|
Example::new(JOINTS, "Impulse Joints", joints3::init_world_with_joints),
|
||||||
|
Example::new(
|
||||||
|
JOINTS,
|
||||||
|
"Multibody Joints",
|
||||||
|
joints3::init_world_with_articulations,
|
||||||
|
),
|
||||||
|
Example::new(JOINTS, "Rope Joints", rope_joints3::init_world),
|
||||||
|
Example::new(JOINTS, "Spring Joints", spring_joints3::init_world),
|
||||||
|
Example::new(
|
||||||
|
JOINTS,
|
||||||
|
"Joint Motor Position",
|
||||||
|
joint_motor_position3::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
JOINTS,
|
||||||
|
"Inverse kinematics",
|
||||||
|
inverse_kinematics3::init_world,
|
||||||
|
),
|
||||||
|
// ── Controls ─────────────────────────────────────────────────────
|
||||||
|
Example::new(
|
||||||
|
CONTROLS,
|
||||||
|
"Character controller",
|
||||||
|
character_controller3::init_world,
|
||||||
|
),
|
||||||
|
Example::new(
|
||||||
|
CONTROLS,
|
||||||
|
"Vehicle controller",
|
||||||
|
vehicle_controller3::init_world,
|
||||||
|
),
|
||||||
|
Example::new(CONTROLS, "Vehicle joints", vehicle_joints3::init_world),
|
||||||
|
// ── Robotics ───────────────────────────────────────────────────────
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
Example::new(ROBOTICS, "URDF", urdf3::init_world),
|
||||||
|
// ── Debug ──────────────────────────────────────────────────────────
|
||||||
|
Example::new(DEBUG, "Multibody joints", debug_articulations3::init_world),
|
||||||
|
Example::new(
|
||||||
|
DEBUG,
|
||||||
|
"Add/rm collider",
|
||||||
debug_add_remove_collider3::init_world,
|
debug_add_remove_collider3::init_world,
|
||||||
),
|
),
|
||||||
("(Debug) big colliders", debug_big_colliders3::init_world),
|
Example::new(DEBUG, "Big colliders", debug_big_colliders3::init_world),
|
||||||
("(Debug) boxes", debug_boxes3::init_world),
|
Example::new(DEBUG, "Boxes", debug_boxes3::init_world),
|
||||||
("(Debug) balls", debug_balls3::init_world),
|
Example::new(DEBUG, "Balls", debug_balls3::init_world),
|
||||||
("(Debug) disabled", debug_disabled3::init_world),
|
Example::new(DEBUG, "Disabled", debug_disabled3::init_world),
|
||||||
("(Debug) two cubes", debug_two_cubes3::init_world),
|
Example::new(DEBUG, "Two cubes", debug_two_cubes3::init_world),
|
||||||
("(Debug) pop", debug_pop3::init_world),
|
Example::new(DEBUG, "Pop", debug_pop3::init_world),
|
||||||
(
|
Example::new(
|
||||||
"(Debug) dyn. coll. add",
|
DEBUG,
|
||||||
|
"Dyn. collider add",
|
||||||
debug_dynamic_collider_add3::init_world,
|
debug_dynamic_collider_add3::init_world,
|
||||||
),
|
),
|
||||||
("(Debug) friction", debug_friction3::init_world),
|
Example::new(DEBUG, "Friction", debug_friction3::init_world),
|
||||||
("(Debug) internal edges", debug_internal_edges3::init_world),
|
Example::new(DEBUG, "Internal edges", debug_internal_edges3::init_world),
|
||||||
("(Debug) long chain", debug_long_chain3::init_world),
|
Example::new(DEBUG, "Long chain", debug_long_chain3::init_world),
|
||||||
(
|
Example::new(
|
||||||
"(Debug) high mass ratio: chain",
|
DEBUG,
|
||||||
|
"High mass ratio: chain",
|
||||||
debug_chain_high_mass_ratio3::init_world,
|
debug_chain_high_mass_ratio3::init_world,
|
||||||
),
|
),
|
||||||
(
|
Example::new(
|
||||||
"(Debug) high mass ratio: cube",
|
DEBUG,
|
||||||
|
"High mass ratio: cube",
|
||||||
debug_cube_high_mass_ratio3::init_world,
|
debug_cube_high_mass_ratio3::init_world,
|
||||||
),
|
),
|
||||||
("(Debug) triangle", debug_triangle3::init_world),
|
Example::new(DEBUG, "Triangle", debug_triangle3::init_world),
|
||||||
("(Debug) trimesh", debug_trimesh3::init_world),
|
Example::new(DEBUG, "Trimesh", debug_trimesh3::init_world),
|
||||||
("(Debug) thin cube", debug_thin_cube_on_mesh3::init_world),
|
Example::new(DEBUG, "Thin cube", debug_thin_cube_on_mesh3::init_world),
|
||||||
("(Debug) cylinder", debug_cylinder3::init_world),
|
Example::new(DEBUG, "Cylinder", debug_cylinder3::init_world),
|
||||||
("(Debug) infinite fall", debug_infinite_fall3::init_world),
|
Example::new(DEBUG, "Infinite fall", debug_infinite_fall3::init_world),
|
||||||
("(Debug) prismatic", debug_prismatic3::init_world),
|
Example::new(DEBUG, "Prismatic", debug_prismatic3::init_world),
|
||||||
("(Debug) rollback", debug_rollback3::init_world),
|
Example::new(DEBUG, "Rollback", debug_rollback3::init_world),
|
||||||
(
|
Example::new(
|
||||||
"(Debug) shape modification",
|
DEBUG,
|
||||||
|
"Shape modification",
|
||||||
debug_shape_modification3::init_world,
|
debug_shape_modification3::init_world,
|
||||||
),
|
),
|
||||||
(
|
Example::new(
|
||||||
"(Debug) sleeping kinematics",
|
DEBUG,
|
||||||
|
"Sleeping kinematics",
|
||||||
debug_sleeping_kinematic3::init_world,
|
debug_sleeping_kinematic3::init_world,
|
||||||
),
|
),
|
||||||
("(Debug) deserialize", debug_deserialize3::init_world),
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
(
|
Example::new(DEBUG, "Deserialize", debug_deserialize3::init_world),
|
||||||
"(Debug) multibody ang. motor pos.",
|
Example::new(
|
||||||
|
DEBUG,
|
||||||
|
"Multibody ang. motor pos.",
|
||||||
debug_multibody_ang_motor_pos3::init_world,
|
debug_multibody_ang_motor_pos3::init_world,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
let mut benches = stress_tests::builders();
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
builders.append(&mut benches);
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with('('), b.0.starts_with('(')) {
|
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
|
||||||
(true, false) => Ordering::Greater,
|
|
||||||
(false, true) => Ordering::Less,
|
|
||||||
});
|
|
||||||
|
|
||||||
let testbed = TestbedApp::from_builders(builders);
|
let testbed = TestbedApp::from_builders(builders);
|
||||||
testbed.run()
|
testbed.run().await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use rapier_testbed3d::{Testbed, TestbedApp};
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
mod ccd3;
|
|
||||||
mod collision_groups3;
|
|
||||||
mod compound3;
|
|
||||||
mod convex_decomposition3;
|
|
||||||
mod convex_polyhedron3;
|
|
||||||
mod damping3;
|
|
||||||
mod debug_add_remove_collider3;
|
|
||||||
mod debug_big_colliders3;
|
|
||||||
mod debug_boxes3;
|
|
||||||
mod debug_cylinder3;
|
|
||||||
mod debug_dynamic_collider_add3;
|
|
||||||
mod debug_friction3;
|
|
||||||
mod debug_infinite_fall3;
|
|
||||||
mod debug_prismatic3;
|
|
||||||
mod debug_rollback3;
|
|
||||||
mod debug_shape_modification3;
|
|
||||||
mod debug_triangle3;
|
|
||||||
mod debug_trimesh3;
|
|
||||||
mod domino3;
|
|
||||||
mod fountain3;
|
|
||||||
mod heightfield3;
|
|
||||||
mod joints3;
|
|
||||||
mod keva3;
|
|
||||||
mod locked_rotations3;
|
|
||||||
mod one_way_platforms3;
|
|
||||||
mod platform3;
|
|
||||||
mod primitives3;
|
|
||||||
mod restitution3;
|
|
||||||
mod sensor3;
|
|
||||||
mod trimesh3;
|
|
||||||
|
|
||||||
fn demo_name_from_command_line() -> Option<String> {
|
|
||||||
let mut args = std::env::args();
|
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
|
||||||
if &arg[..] == "--example" {
|
|
||||||
return args.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
fn demo_name_from_url() -> Option<String> {
|
|
||||||
None
|
|
||||||
// let window = stdweb::web::window();
|
|
||||||
// let hash = window.location()?.search().ok()?;
|
|
||||||
// if hash.len() > 0 {
|
|
||||||
// Some(hash[1..].to_string())
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
fn demo_name_from_url() -> Option<String> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
|
|
||||||
pub fn main() {
|
|
||||||
let demo = demo_name_from_command_line()
|
|
||||||
.or_else(|| demo_name_from_url())
|
|
||||||
.unwrap_or(String::new())
|
|
||||||
.to_camel_case();
|
|
||||||
|
|
||||||
let mut builders: Vec<(_, fn(&mut Testbed))> = vec![
|
|
||||||
("Fountain", fountain3::init_world),
|
|
||||||
("Primitives", primitives3::init_world),
|
|
||||||
("CCD", ccd3::init_world),
|
|
||||||
("Collision groups", collision_groups3::init_world),
|
|
||||||
("Compound", compound3::init_world),
|
|
||||||
("Convex decomposition", convex_decomposition3::init_world),
|
|
||||||
("Convex polyhedron", convex_polyhedron3::init_world),
|
|
||||||
("Damping", damping3::init_world),
|
|
||||||
("Domino", domino3::init_world),
|
|
||||||
("Heightfield", heightfield3::init_world),
|
|
||||||
("Joints", joints3::init_world),
|
|
||||||
("Locked rotations", locked_rotations3::init_world),
|
|
||||||
("One-way platforms", one_way_platforms3::init_world),
|
|
||||||
("Platform", platform3::init_world),
|
|
||||||
("Restitution", restitution3::init_world),
|
|
||||||
("Sensor", sensor3::init_world),
|
|
||||||
("TriMesh", trimesh3::init_world),
|
|
||||||
("Keva tower", keva3::init_world),
|
|
||||||
(
|
|
||||||
"(Debug) add/rm collider",
|
|
||||||
debug_add_remove_collider3::init_world,
|
|
||||||
),
|
|
||||||
("(Debug) big colliders", debug_big_colliders3::init_world),
|
|
||||||
("(Debug) boxes", debug_boxes3::init_world),
|
|
||||||
(
|
|
||||||
"(Debug) dyn. coll. add",
|
|
||||||
debug_dynamic_collider_add3::init_world,
|
|
||||||
),
|
|
||||||
("(Debug) friction", debug_friction3::init_world),
|
|
||||||
("(Debug) triangle", debug_triangle3::init_world),
|
|
||||||
("(Debug) trimesh", debug_trimesh3::init_world),
|
|
||||||
("(Debug) cylinder", debug_cylinder3::init_world),
|
|
||||||
("(Debug) infinite fall", debug_infinite_fall3::init_world),
|
|
||||||
("(Debug) prismatic", debug_prismatic3::init_world),
|
|
||||||
("(Debug) rollback", debug_rollback3::init_world),
|
|
||||||
(
|
|
||||||
"(Debug) shape modification",
|
|
||||||
debug_shape_modification3::init_world,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Lexicographic sort, with stress tests moved at the end of the list.
|
|
||||||
builders.sort_by(|a, b| match (a.0.starts_with("("), b.0.starts_with("(")) {
|
|
||||||
(true, true) | (false, false) => a.0.cmp(b.0),
|
|
||||||
(true, false) => Ordering::Greater,
|
|
||||||
(false, true) => Ordering::Less,
|
|
||||||
});
|
|
||||||
|
|
||||||
let testbed = TestbedApp::from_builders(builders);
|
|
||||||
testbed.run()
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed3d::Testbed;
|
use rapier_testbed3d::Testbed;
|
||||||
use rapier3d::prelude::*;
|
use rapier3d::prelude::*;
|
||||||
|
|
||||||
@@ -5,9 +6,9 @@ fn create_wall(
|
|||||||
testbed: &mut Testbed,
|
testbed: &mut Testbed,
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
offset: Vector<f32>,
|
offset: Vector,
|
||||||
stack_height: usize,
|
stack_height: usize,
|
||||||
half_extents: Vector<f32>,
|
half_extents: Vector,
|
||||||
) {
|
) {
|
||||||
let shift = half_extents * 2.0;
|
let shift = half_extents * 2.0;
|
||||||
let mut k = 0;
|
let mut k = 0;
|
||||||
@@ -21,15 +22,17 @@ fn create_wall(
|
|||||||
- stack_height as f32 * half_extents.z;
|
- stack_height as f32 * half_extents.z;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
let collider = ColliderBuilder::cuboid(half_extents.x, half_extents.y, half_extents.z);
|
||||||
colliders.insert_with_parent(collider, handle, bodies);
|
colliders.insert_with_parent(collider, handle, bodies);
|
||||||
k += 1;
|
k += 1;
|
||||||
if k % 2 == 0 {
|
if k % 2 == 0 {
|
||||||
testbed.set_initial_body_color(handle, [1., 131. / 255., 244.0 / 255.]);
|
testbed
|
||||||
|
.set_initial_body_color(handle, Color::new(1., 131. / 255., 244.0 / 255., 1.0));
|
||||||
} else {
|
} else {
|
||||||
testbed.set_initial_body_color(handle, [131. / 255., 1., 244.0 / 255.]);
|
testbed
|
||||||
|
.set_initial_body_color(handle, Color::new(131. / 255., 1., 244.0 / 255., 1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +53,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 50.0;
|
let ground_size = 50.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
|
||||||
@@ -69,18 +72,18 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
testbed,
|
testbed,
|
||||||
&mut bodies,
|
&mut bodies,
|
||||||
&mut colliders,
|
&mut colliders,
|
||||||
vector![x, shift_y, 0.0],
|
Vector::new(x, shift_y, 0.0),
|
||||||
num_z,
|
num_z,
|
||||||
vector![0.5, 0.5, 1.0],
|
Vector::new(0.5, 0.5, 1.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
create_wall(
|
create_wall(
|
||||||
testbed,
|
testbed,
|
||||||
&mut bodies,
|
&mut bodies,
|
||||||
&mut colliders,
|
&mut colliders,
|
||||||
vector![x, shift_y, shift_z],
|
Vector::new(x, shift_y, shift_z),
|
||||||
num_z,
|
num_z,
|
||||||
vector![0.5, 0.5, 1.0],
|
Vector::new(0.5, 0.5, 1.0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +97,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
.sensor(true)
|
.sensor(true)
|
||||||
.active_events(ActiveEvents::COLLISION_EVENTS);
|
.active_events(ActiveEvents::COLLISION_EVENTS);
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.linvel(vector![1000.0, 0.0, 0.0])
|
.linvel(Vector::new(1000.0, 0.0, 0.0))
|
||||||
.translation(vector![-20.0, shift_y + 2.0, 0.0])
|
.translation(Vector::new(-20.0, shift_y + 2.0, 0.0))
|
||||||
.ccd_enabled(true);
|
.ccd_enabled(true);
|
||||||
let sensor_handle = bodies.insert(rigid_body);
|
let sensor_handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(collider, sensor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, sensor_handle, &mut bodies);
|
||||||
@@ -103,20 +106,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
// Second rigid-body with CCD enabled.
|
// Second rigid-body with CCD enabled.
|
||||||
let collider = ColliderBuilder::ball(1.0).density(10.0);
|
let collider = ColliderBuilder::ball(1.0).density(10.0);
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.linvel(vector![1000.0, 0.0, 0.0])
|
.linvel(Vector::new(1000.0, 0.0, 0.0))
|
||||||
.translation(vector![-20.0, shift_y + 2.0, shift_z])
|
.translation(Vector::new(-20.0, shift_y + 2.0, shift_z))
|
||||||
.ccd_enabled(true);
|
.ccd_enabled(true);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(collider.clone(), handle, &mut bodies);
|
colliders.insert_with_parent(collider.clone(), handle, &mut bodies);
|
||||||
testbed.set_initial_body_color(handle, [0.2, 0.2, 1.0]);
|
testbed.set_initial_body_color(handle, Color::new(0.2, 0.2, 1.0, 1.0));
|
||||||
|
|
||||||
// Callback that will be executed on the main loop to handle proximities.
|
// Callback that will be executed on the main loop to handle proximities.
|
||||||
testbed.add_callback(move |mut graphics, physics, events, _| {
|
testbed.add_callback(move |mut graphics, physics, events, _| {
|
||||||
while let Ok(prox) = events.collision_events.try_recv() {
|
while let Ok(prox) = events.collision_events.try_recv() {
|
||||||
let color = if prox.started() {
|
let color = if prox.started() {
|
||||||
[1.0, 1.0, 0.0]
|
Color::new(1.0, 1.0, 0.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
[0.5, 0.5, 1.0]
|
Color::new(0.5, 0.5, 1.0, 1.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_handle1 = physics
|
let parent_handle1 = physics
|
||||||
@@ -134,10 +137,10 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
if let Some(graphics) = &mut graphics {
|
if let Some(graphics) = &mut graphics {
|
||||||
if parent_handle1 != ground_handle && parent_handle1 != sensor_handle {
|
if parent_handle1 != ground_handle && parent_handle1 != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle1, color);
|
graphics.set_body_color(parent_handle1, color, false);
|
||||||
}
|
}
|
||||||
if parent_handle2 != ground_handle && parent_handle2 != sensor_handle {
|
if parent_handle2 != ground_handle && parent_handle2 != sensor_handle {
|
||||||
graphics.set_body_color(parent_handle2, color);
|
graphics.set_body_color(parent_handle2, color, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,5 +150,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::utils::character::{self, CharacterControlMode};
|
use crate::utils::character::{self, CharacterControlMode};
|
||||||
|
use kiss3d::color::Color;
|
||||||
use rapier_testbed3d::Testbed;
|
use rapier_testbed3d::Testbed;
|
||||||
use rapier3d::{
|
use rapier3d::{
|
||||||
control::{KinematicCharacterController, PidController},
|
control::{KinematicCharacterController, PidController},
|
||||||
@@ -22,7 +23,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body =
|
||||||
RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0] * scale);
|
RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0) * scale);
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(
|
let collider = ColliderBuilder::cuboid(
|
||||||
ground_size * scale,
|
ground_size * scale,
|
||||||
@@ -31,8 +32,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
);
|
);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
|
|
||||||
let rigid_body =
|
let rigid_body = RigidBodyBuilder::fixed()
|
||||||
RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, -ground_size] * scale); //.rotation(vector![-0.1, 0.0, 0.0]);
|
.translation(Vector::new(0.0, -ground_height, -ground_size) * scale); //.rotation(Vector::new(-0.1, 0.0, 0.0));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(
|
let collider = ColliderBuilder::cuboid(
|
||||||
ground_size * scale,
|
ground_size * scale,
|
||||||
@@ -45,7 +46,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Character we will control manually.
|
* Character we will control manually.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::kinematic_position_based()
|
let rigid_body = RigidBodyBuilder::kinematic_position_based()
|
||||||
.translation(vector![0.0, 0.5, 0.0] * scale)
|
.translation(Vector::new(0.0, 0.5, 0.0) * scale)
|
||||||
// The two config below makes the character
|
// The two config below makes the character
|
||||||
// nicer to control with the PID control enabled.
|
// nicer to control with the PID control enabled.
|
||||||
.gravity_scale(10.0)
|
.gravity_scale(10.0)
|
||||||
@@ -53,7 +54,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let character_handle = bodies.insert(rigid_body);
|
let character_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::capsule_y(0.3 * scale, 0.15 * scale); // 0.15, 0.3, 0.15);
|
let collider = ColliderBuilder::capsule_y(0.3 * scale, 0.15 * scale); // 0.15, 0.3, 0.15);
|
||||||
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
colliders.insert_with_parent(collider, character_handle, &mut bodies);
|
||||||
testbed.set_initial_body_color(character_handle, [0.8, 0.1, 0.1]);
|
testbed.set_initial_body_color(character_handle, Color::new(0.8, 0.1, 0.1, 1.0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
@@ -72,7 +73,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let y = j as f32 * shift + centery;
|
let y = j as f32 * shift + centery;
|
||||||
let z = k as f32 * shift + centerx;
|
let z = k as f32 * shift + centerx;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z] * scale);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z) * scale);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad * scale, rad * scale, rad * scale);
|
let collider = ColliderBuilder::cuboid(rad * scale, rad * scale, rad * scale);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -94,7 +96,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
stair_height / 2.0 * scale,
|
stair_height / 2.0 * scale,
|
||||||
stair_width * scale,
|
stair_width * scale,
|
||||||
)
|
)
|
||||||
.translation(vector![x * scale, y * scale, 0.0]);
|
.translation(Vector::new(x * scale, y * scale, 0.0));
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +106,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let slope_angle = 0.2;
|
let slope_angle = 0.2;
|
||||||
let slope_size = 2.0;
|
let slope_size = 2.0;
|
||||||
let collider = ColliderBuilder::cuboid(slope_size, ground_height, slope_size)
|
let collider = ColliderBuilder::cuboid(slope_size, ground_height, slope_size)
|
||||||
.translation(vector![0.1 + slope_size, -ground_height + 0.4, 0.0])
|
.translation(Vector::new(0.1 + slope_size, -ground_height + 0.4, 0.0))
|
||||||
.rotation(Vector::z() * slope_angle);
|
.rotation(Vector::Z * slope_angle);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -119,20 +121,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
ground_size * scale,
|
ground_size * scale,
|
||||||
)
|
)
|
||||||
.translation(
|
.translation(
|
||||||
vector![
|
Vector::new(
|
||||||
0.1 + slope_size * 2.0 + impossible_slope_size - 0.9,
|
0.1 + slope_size * 2.0 + impossible_slope_size - 0.9,
|
||||||
-ground_height + 1.7,
|
-ground_height + 1.7,
|
||||||
0.0
|
0.0,
|
||||||
] * scale,
|
) * scale,
|
||||||
)
|
)
|
||||||
.rotation(Vector::z() * impossible_slope_angle);
|
.rotation(Vector::Z * impossible_slope_angle);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a moving platform.
|
* Create a moving platform.
|
||||||
*/
|
*/
|
||||||
let body =
|
let body = RigidBodyBuilder::kinematic_velocity_based()
|
||||||
RigidBodyBuilder::kinematic_velocity_based().translation(vector![-8.0, 0.0, 0.0] * scale);
|
.translation(Vector::new(-8.0, 0.0, 0.0) * scale);
|
||||||
// .rotation(-0.3);
|
// .rotation(-0.3);
|
||||||
let platform_handle = bodies.insert(body);
|
let platform_handle = bodies.insert(body);
|
||||||
let collider = ColliderBuilder::cuboid(2.0 * scale, ground_height * scale, 2.0 * scale);
|
let collider = ColliderBuilder::cuboid(2.0 * scale, ground_height * scale, 2.0 * scale);
|
||||||
@@ -144,36 +146,36 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = Vector::new(10.0, 1.0, 10.0);
|
let ground_size = Vector::new(10.0, 1.0, 10.0);
|
||||||
let nsubdivs = 20;
|
let nsubdivs = 20;
|
||||||
|
|
||||||
let heights = DMatrix::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
let heights = Array2::from_fn(nsubdivs + 1, nsubdivs + 1, |i, j| {
|
||||||
(i as f32 * ground_size.x / (nsubdivs as f32) / 2.0).cos()
|
(i as f32 * ground_size.x / (nsubdivs as f32) / 2.0).cos()
|
||||||
+ (j as f32 * ground_size.z / (nsubdivs as f32) / 2.0).cos()
|
+ (j as f32 * ground_size.z / (nsubdivs as f32) / 2.0).cos()
|
||||||
});
|
});
|
||||||
|
|
||||||
let collider = ColliderBuilder::heightfield(heights, ground_size * scale)
|
let collider = ColliderBuilder::heightfield(heights, ground_size * scale)
|
||||||
.translation(vector![-8.0, 5.0, 0.0] * scale);
|
.translation(Vector::new(-8.0, 5.0, 0.0) * scale);
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A tilting dynamic body with a limited joint.
|
* A tilting dynamic body with a limited joint.
|
||||||
*/
|
*/
|
||||||
let ground = RigidBodyBuilder::fixed().translation(vector![0.0, 5.0, 0.0] * scale);
|
let ground = RigidBodyBuilder::fixed().translation(Vector::new(0.0, 5.0, 0.0) * scale);
|
||||||
let ground_handle = bodies.insert(ground);
|
let ground_handle = bodies.insert(ground);
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![0.0, 5.0, 0.0] * scale);
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 5.0, 0.0) * scale);
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let collider = ColliderBuilder::cuboid(1.0 * scale, 0.1 * scale, 2.0 * scale);
|
let collider = ColliderBuilder::cuboid(1.0 * scale, 0.1 * scale, 2.0 * scale);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
let joint = RevoluteJointBuilder::new(Vector::z_axis()).limits([-0.3, 0.3]);
|
let joint = RevoluteJointBuilder::new(Vector::Z).limits([-0.3, 0.3]);
|
||||||
impulse_joints.insert(ground_handle, handle, joint, true);
|
impulse_joints.insert(ground_handle, handle, joint, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup a callback to move the platform.
|
* Setup a callback to move the platform.
|
||||||
*/
|
*/
|
||||||
testbed.add_callback(move |_, physics, _, run_state| {
|
testbed.add_callback(move |_, physics, _, run_state| {
|
||||||
let linvel = vector![
|
let linvel = Vector::new(
|
||||||
(run_state.time * 2.0).sin() * 2.0,
|
(run_state.time * 2.0).sin() * 2.0,
|
||||||
(run_state.time * 5.0).sin() * 1.5,
|
(run_state.time * 5.0).sin() * 1.5,
|
||||||
0.0
|
0.0,
|
||||||
] * scale;
|
) * scale;
|
||||||
// let angvel = run_state.time.sin() * 0.5;
|
// let angvel = run_state.time.sin() * 0.5;
|
||||||
|
|
||||||
// Update the velocity-based kinematic body by setting its velocity.
|
// Update the velocity-based kinematic body by setting its velocity.
|
||||||
@@ -213,5 +215,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point!(10.0, 10.0, 10.0), Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use kiss3d::color::{BLUE, GREEN};
|
||||||
use rapier_testbed3d::Testbed;
|
use rapier_testbed3d::Testbed;
|
||||||
use rapier3d::prelude::*;
|
use rapier3d::prelude::*;
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 5.0;
|
let ground_size = 5.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let floor_handle = bodies.insert(rigid_body);
|
let floor_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
colliders.insert_with_parent(collider, floor_handle, &mut bodies);
|
||||||
@@ -33,22 +34,22 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* A green floor that will collide with the GREEN group only.
|
* A green floor that will collide with the GREEN group only.
|
||||||
*/
|
*/
|
||||||
let green_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0)
|
let green_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0)
|
||||||
.translation(vector![0.0, 1.0, 0.0])
|
.translation(Vector::new(0.0, 1.0, 0.0))
|
||||||
.collision_groups(GREEN_GROUP);
|
.collision_groups(GREEN_GROUP);
|
||||||
let green_collider_handle =
|
let green_collider_handle =
|
||||||
colliders.insert_with_parent(green_floor, floor_handle, &mut bodies);
|
colliders.insert_with_parent(green_floor, floor_handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_collider_color(green_collider_handle, [0.0, 1.0, 0.0]);
|
testbed.set_initial_collider_color(green_collider_handle, BLUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A blue floor that will collide with the BLUE group only.
|
* A blue floor that will collide with the BLUE group only.
|
||||||
*/
|
*/
|
||||||
let blue_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0)
|
let blue_floor = ColliderBuilder::cuboid(1.0, 0.1, 1.0)
|
||||||
.translation(vector![0.0, 2.0, 0.0])
|
.translation(Vector::new(0.0, 2.0, 0.0))
|
||||||
.collision_groups(BLUE_GROUP);
|
.collision_groups(BLUE_GROUP);
|
||||||
let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies);
|
let blue_collider_handle = colliders.insert_with_parent(blue_floor, floor_handle, &mut bodies);
|
||||||
|
|
||||||
testbed.set_initial_collider_color(blue_collider_handle, [0.0, 0.0, 1.0]);
|
testbed.set_initial_collider_color(blue_collider_handle, GREEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the cubes
|
* Create the cubes
|
||||||
@@ -70,12 +71,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Alternate between the green and blue groups.
|
// Alternate between the green and blue groups.
|
||||||
let (group, color) = if k % 2 == 0 {
|
let (group, color) = if k % 2 == 0 {
|
||||||
(GREEN_GROUP, [0.0, 1.0, 0.0])
|
(GREEN_GROUP, GREEN)
|
||||||
} else {
|
} else {
|
||||||
(BLUE_GROUP, [0.0, 0.0, 1.0])
|
(BLUE_GROUP, BLUE)
|
||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad, rad).collision_groups(group);
|
let collider = ColliderBuilder::cuboid(rad, rad, rad).collision_groups(group);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -89,5 +90,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point!(10.0, 10.0, 10.0), Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 50.0;
|
let ground_size = 50.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -43,32 +43,29 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let z = k as f32 * shift * 2.0 - centerz + offset;
|
let z = k as f32 * shift * 2.0 - centerz + offset;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
|
|
||||||
// First option: attach several colliders to a single rigid-body.
|
// First option: attach several colliders to a single rigid-body.
|
||||||
if j < numy / 2 {
|
if j < numy / 2 {
|
||||||
let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad);
|
let collider1 = ColliderBuilder::cuboid(rad * 10.0, rad, rad);
|
||||||
let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
let collider2 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
||||||
.translation(vector![rad * 10.0, rad * 10.0, 0.0]);
|
.translation(Vector::new(rad * 10.0, rad * 10.0, 0.0));
|
||||||
let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
let collider3 = ColliderBuilder::cuboid(rad, rad * 10.0, rad)
|
||||||
.translation(vector![-rad * 10.0, rad * 10.0, 0.0]);
|
.translation(Vector::new(-rad * 10.0, rad * 10.0, 0.0));
|
||||||
colliders.insert_with_parent(collider1, handle, &mut bodies);
|
colliders.insert_with_parent(collider1, handle, &mut bodies);
|
||||||
colliders.insert_with_parent(collider2, handle, &mut bodies);
|
colliders.insert_with_parent(collider2, handle, &mut bodies);
|
||||||
colliders.insert_with_parent(collider3, handle, &mut bodies);
|
colliders.insert_with_parent(collider3, handle, &mut bodies);
|
||||||
} else {
|
} else {
|
||||||
// Second option: create a compound shape and attach it to a single collider.
|
// Second option: create a compound shape and attach it to a single collider.
|
||||||
let shapes = vec![
|
let shapes = vec![
|
||||||
|
(Pose::IDENTITY, SharedShape::cuboid(rad * 10.0, rad, rad)),
|
||||||
(
|
(
|
||||||
Isometry::identity(),
|
Pose::from_translation(Vector::new(rad * 10.0, rad * 10.0, 0.0)),
|
||||||
SharedShape::cuboid(rad * 10.0, rad, rad),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Isometry::translation(rad * 10.0, rad * 10.0, 0.0),
|
|
||||||
SharedShape::cuboid(rad, rad * 10.0, rad),
|
SharedShape::cuboid(rad, rad * 10.0, rad),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Isometry::translation(-rad * 10.0, rad * 10.0, 0.0),
|
Pose::from_translation(Vector::new(-rad * 10.0, rad * 10.0, 0.0)),
|
||||||
SharedShape::cuboid(rad, rad * 10.0, rad),
|
SharedShape::cuboid(rad, rad * 10.0, rad),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@@ -86,5 +83,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 40.0;
|
let ground_size = 40.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -47,12 +47,12 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let pt: Point<f32> = distribution.sample(&mut rng);
|
let pt: SimdPoint<f32> = distribution.sample(&mut rng);
|
||||||
points.push(pt * scale);
|
points.push(Vector::new(pt.x, pt.y, pt.z) * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::round_convex_hull(&points, border_rad).unwrap();
|
let collider = ColliderBuilder::round_convex_hull(&points, border_rad).unwrap();
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -64,5 +64,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![30.0, 30.0, 30.0], Point::origin());
|
testbed.look_at(Vec3::new(30.0, 30.0, 30.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rb = RigidBodyBuilder::dynamic()
|
let rb = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![x, y, 0.0])
|
.translation(Vector::new(x, y, 0.0))
|
||||||
.linvel(vector![x * 10.0, y * 10.0, 0.0])
|
.linvel(Vector::new(x * 10.0, y * 10.0, 0.0))
|
||||||
.angvel(Vector::z() * 100.0)
|
.angvel(Vector::Z * 100.0)
|
||||||
.linear_damping((i + 1) as f32 * subdiv * 10.0)
|
.linear_damping((i + 1) as f32 * subdiv * 10.0)
|
||||||
.angular_damping((num - i) as f32 * subdiv * 10.0);
|
.angular_damping((num - i) as f32 * subdiv * 10.0);
|
||||||
let rb_handle = bodies.insert(rb);
|
let rb_handle = bodies.insert(rb);
|
||||||
@@ -43,8 +43,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
Vector::zeros(),
|
Vector::ZERO,
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
testbed.look_at(point![2.0, 2.5, 20.0], point![2.0, 2.5, 0.0]);
|
testbed.look_at(Vec3::new(2.0, 2.5, 20.0), Vec3::new(2.0, 2.5, 0.0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 3.0;
|
let ground_size = 3.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4);
|
||||||
let mut ground_collider_handle =
|
let mut ground_collider_handle =
|
||||||
@@ -26,7 +26,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Rolling ball
|
* Rolling ball
|
||||||
*/
|
*/
|
||||||
let ball_rad = 0.1;
|
let ball_rad = 0.1;
|
||||||
let rb = RigidBodyBuilder::dynamic().translation(vector![0.0, 0.2, 0.0]);
|
let rb = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 0.2, 0.0));
|
||||||
let ball_handle = bodies.insert(rb);
|
let ball_handle = bodies.insert(rb);
|
||||||
let collider = ColliderBuilder::ball(ball_rad).density(100.0);
|
let collider = ColliderBuilder::ball(ball_rad).density(100.0);
|
||||||
colliders.insert_with_parent(collider, ball_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ball_handle, &mut bodies);
|
||||||
@@ -53,5 +53,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ fn create_ball_articulations(
|
|||||||
RigidBodyType::Dynamic
|
RigidBodyType::Dynamic
|
||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::new(status).translation(vector![
|
let rigid_body = RigidBodyBuilder::new(status).translation(Vector::new(
|
||||||
fk * shift,
|
fk * shift,
|
||||||
0.0,
|
0.0,
|
||||||
fi * shift * 2.0
|
fi * shift * 2.0,
|
||||||
]);
|
));
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::capsule_z(rad * 1.25, rad);
|
let collider = ColliderBuilder::capsule_z(rad * 1.25, rad);
|
||||||
colliders.insert_with_parent(collider, child_handle, bodies);
|
colliders.insert_with_parent(collider, child_handle, bodies);
|
||||||
@@ -38,7 +38,7 @@ fn create_ball_articulations(
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
let parent_handle = *body_handles.last().unwrap();
|
let parent_handle = *body_handles.last().unwrap();
|
||||||
let joint =
|
let joint =
|
||||||
SphericalJointBuilder::new().local_anchor2(point![0.0, 0.0, -shift * 2.0]);
|
SphericalJointBuilder::new().local_anchor2(Vector::new(0.0, 0.0, -shift * 2.0));
|
||||||
multibody_joints.insert(parent_handle, child_handle, joint, true);
|
multibody_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +46,13 @@ fn create_ball_articulations(
|
|||||||
if k > 0 && i > 0 {
|
if k > 0 && i > 0 {
|
||||||
let parent_index = body_handles.len() - num;
|
let parent_index = body_handles.len() - num;
|
||||||
let parent_handle = body_handles[parent_index];
|
let parent_handle = body_handles[parent_index];
|
||||||
let joint = SphericalJointBuilder::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
let joint =
|
||||||
|
SphericalJointBuilder::new().local_anchor2(Vector::new(-shift, 0.0, 0.0));
|
||||||
// let joint =
|
// let joint =
|
||||||
// PrismaticJoint::new(Vector::y_axis()).local_anchor2(point![-shift, 0.0, 0.0]);
|
// PrismaticJoint::new(Vector::Y).local_anchor2(Vector::new(-shift, 0.0, 0.0));
|
||||||
// let joint = FixedJoint::new().local_anchor2(point![-shift, 0.0, 0.0]);
|
// let joint = FixedJoint::new().local_anchor2(Vector::new(-shift, 0.0, 0.0));
|
||||||
// let joint =
|
// let joint =
|
||||||
// RevoluteJoint::new(Vector::x_axis()).local_anchor2(point![-shift, 0.0, 0.0]);
|
// RevoluteJoint::new(Vector::X).local_anchor2(Vector::new(-shift, 0.0, 0.0));
|
||||||
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
impulse_joints.insert(parent_handle, child_handle, joint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +71,14 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let mut multibody_joints = MultibodyJointSet::new();
|
let mut multibody_joints = MultibodyJointSet::new();
|
||||||
|
|
||||||
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0)
|
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0)
|
||||||
.translation(vector![0.0, -3.02, 0.0])
|
.translation(Vector::new(0.0, -3.02, 0.0))
|
||||||
.rotation(vector![0.1, 0.0, 0.1]);
|
.rotation(Vector::new(0.1, 0.0, 0.1));
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic();
|
let rigid_body = RigidBodyBuilder::dynamic();
|
||||||
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0)
|
let collider = ColliderBuilder::cuboid(30.0, 0.01, 30.0)
|
||||||
.translation(vector![0.0, -3.0, 0.0])
|
.translation(Vector::new(0.0, -3.0, 0.0))
|
||||||
.rotation(vector![0.1, 0.0, 0.1]);
|
.rotation(Vector::new(0.1, 0.0, 0.1));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
@@ -93,5 +94,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![15.0, 5.0, 42.0], point![13.0, 1.0, 1.0]);
|
testbed.look_at(Vec3::new(15.0, 5.0, 42.0), Vec3::new(13.0, 1.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::new(status)
|
let rigid_body = RigidBodyBuilder::new(status)
|
||||||
.translation(vector![x, y, z])
|
.translation(Vector::new(x, y, z))
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(rad).friction(0.0);
|
let collider = ColliderBuilder::ball(rad).friction(0.0);
|
||||||
@@ -55,5 +55,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::fixed();
|
let rigid_body = RigidBodyBuilder::fixed();
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let halfspace = SharedShape::new(HalfSpace::new(Vector::y_axis()));
|
let halfspace = SharedShape::new(HalfSpace::new(Vector::Y));
|
||||||
let collider = ColliderBuilder::new(halfspace);
|
let collider = ColliderBuilder::new(halfspace);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let curr_height = 0.1f32.min(curr_width);
|
let curr_height = 0.1f32.min(curr_width);
|
||||||
curr_y += curr_height * 4.0;
|
curr_y += curr_height * 4.0;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, curr_y, 0.0]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, curr_y, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(curr_width, curr_height, curr_width);
|
let collider = ColliderBuilder::cuboid(curr_width, curr_height, curr_width);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -38,5 +38,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
for _ in 0..6 {
|
for _ in 0..6 {
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body =
|
||||||
|
RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -26,8 +27,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
// Build the dynamic box rigid body.
|
// Build the dynamic box rigid body.
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![1.1, 0.0, 0.0])
|
.translation(Vector::new(1.1, 0.0, 0.0))
|
||||||
// .rotation(vector![0.8, 0.2, 0.1])
|
// .rotation(Vector::new(0.8, 0.2, 0.1))
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(2.0, 0.1, 1.0);
|
let collider = ColliderBuilder::cuboid(2.0, 0.1, 1.0);
|
||||||
@@ -38,5 +39,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::new(status)
|
let rigid_body = RigidBodyBuilder::new(status)
|
||||||
.translation(vector![0.0, 0.0, z])
|
.translation(Vector::new(0.0, 0.0, z))
|
||||||
.additional_solver_iterations(16);
|
.additional_solver_iterations(16);
|
||||||
let child_handle = bodies.insert(rigid_body);
|
let child_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::ball(ball_rad);
|
let collider = ColliderBuilder::ball(ball_rad);
|
||||||
@@ -48,11 +48,11 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
let parent_handle = *body_handles.last().unwrap();
|
let parent_handle = *body_handles.last().unwrap();
|
||||||
let joint = if i == 1 {
|
let joint = if i == 1 {
|
||||||
SphericalJointBuilder::new().local_anchor2(point![0.0, 0.0, -shift1 * 2.0])
|
SphericalJointBuilder::new().local_anchor2(Vector::new(0.0, 0.0, -shift1 * 2.0))
|
||||||
} else {
|
} else {
|
||||||
SphericalJointBuilder::new()
|
SphericalJointBuilder::new()
|
||||||
.local_anchor1(point![0.0, 0.0, shift1])
|
.local_anchor1(Vector::new(0.0, 0.0, shift1))
|
||||||
.local_anchor2(point![0.0, 0.0, -shift2])
|
.local_anchor2(Vector::new(0.0, 0.0, -shift2))
|
||||||
};
|
};
|
||||||
|
|
||||||
if use_articulations {
|
if use_articulations {
|
||||||
@@ -69,5 +69,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Floor.
|
* Floor.
|
||||||
*/
|
*/
|
||||||
let floor_body =
|
let floor_body =
|
||||||
RigidBodyBuilder::fixed().translation(vector![0.0, -stick_len - stick_rad, 0.0]);
|
RigidBodyBuilder::fixed().translation(Vector::new(0.0, -stick_len - stick_rad, 0.0));
|
||||||
let floor_handle = bodies.insert(floor_body);
|
let floor_handle = bodies.insert(floor_body);
|
||||||
let floor_cube = ColliderBuilder::cuboid(stick_len, stick_len, stick_len);
|
let floor_cube = ColliderBuilder::cuboid(stick_len, stick_len, stick_len);
|
||||||
colliders.insert_with_parent(floor_cube, floor_handle, &mut bodies);
|
colliders.insert_with_parent(floor_cube, floor_handle, &mut bodies);
|
||||||
@@ -29,38 +29,38 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
for i in 0..num_levels {
|
for i in 0..num_levels {
|
||||||
let fi = i as f32;
|
let fi = i as f32;
|
||||||
|
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(
|
||||||
0.0,
|
0.0,
|
||||||
fi * stick_rad * 4.0,
|
fi * stick_rad * 4.0,
|
||||||
-(stick_len / 2.0 - stick_rad)
|
-(stick_len / 2.0 - stick_rad),
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let capsule = ColliderBuilder::cuboid(stick_len / 2.0, stick_rad, stick_rad);
|
let capsule = ColliderBuilder::cuboid(stick_len / 2.0, stick_rad, stick_rad);
|
||||||
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
||||||
|
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(
|
||||||
0.0,
|
0.0,
|
||||||
fi * stick_rad * 4.0,
|
fi * stick_rad * 4.0,
|
||||||
(stick_len / 2.0 - stick_rad)
|
stick_len / 2.0 - stick_rad,
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let capsule = ColliderBuilder::cuboid(stick_len / 2.0, stick_rad, stick_rad);
|
let capsule = ColliderBuilder::cuboid(stick_len / 2.0, stick_rad, stick_rad);
|
||||||
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
||||||
|
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(
|
||||||
-(stick_len / 2.0 - stick_rad),
|
-(stick_len / 2.0 - stick_rad),
|
||||||
(fi + 0.5) * stick_rad * 4.0,
|
(fi + 0.5) * stick_rad * 4.0,
|
||||||
0.0
|
0.0,
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let capsule = ColliderBuilder::cuboid(stick_rad, stick_rad, stick_len / 2.0);
|
let capsule = ColliderBuilder::cuboid(stick_rad, stick_rad, stick_len / 2.0);
|
||||||
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
||||||
|
|
||||||
let body = RigidBodyBuilder::dynamic().translation(vector![
|
let body = RigidBodyBuilder::dynamic().translation(Vector::new(
|
||||||
(stick_len / 2.0 - stick_rad),
|
stick_len / 2.0 - stick_rad,
|
||||||
(fi + 0.5) * stick_rad * 4.0,
|
(fi + 0.5) * stick_rad * 4.0,
|
||||||
0.0
|
0.0,
|
||||||
]);
|
));
|
||||||
let handle = bodies.insert(body);
|
let handle = bodies.insert(body);
|
||||||
let capsule = ColliderBuilder::cuboid(stick_rad, stick_rad, stick_len / 2.0);
|
let capsule = ColliderBuilder::cuboid(stick_rad, stick_rad, stick_len / 2.0);
|
||||||
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
colliders.insert_with_parent(capsule, handle, &mut bodies);
|
||||||
@@ -71,21 +71,23 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
let cube_len = stick_len * 2.0;
|
let cube_len = stick_len * 2.0;
|
||||||
let floor_body = RigidBodyBuilder::dynamic()
|
let floor_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![
|
.translation(Vector::new(
|
||||||
0.0,
|
0.0,
|
||||||
cube_len / 2.0 + (num_levels as f32 - 0.25) * stick_rad * 4.0,
|
cube_len / 2.0 + (num_levels as f32 - 0.25) * stick_rad * 4.0,
|
||||||
0.0
|
0.0,
|
||||||
])
|
))
|
||||||
.additional_solver_iterations(36);
|
.additional_solver_iterations(36);
|
||||||
let floor_handle = bodies.insert(floor_body);
|
let floor_handle = bodies.insert(floor_body);
|
||||||
let floor_cube = ColliderBuilder::cuboid(cube_len / 2.0, cube_len / 2.0, cube_len / 2.0);
|
let floor_cube = ColliderBuilder::cuboid(cube_len / 2.0, cube_len / 2.0, cube_len / 2.0);
|
||||||
colliders.insert_with_parent(floor_cube, floor_handle, &mut bodies);
|
colliders.insert_with_parent(floor_cube, floor_handle, &mut bodies);
|
||||||
|
|
||||||
let small_mass =
|
let small_mass =
|
||||||
MassProperties::from_cuboid(1.0, vector![stick_rad, stick_rad, stick_len / 2.0]).mass();
|
MassProperties::from_cuboid(1.0, Vector::new(stick_rad, stick_rad, stick_len / 2.0)).mass();
|
||||||
let big_mass =
|
let big_mass = MassProperties::from_cuboid(
|
||||||
MassProperties::from_cuboid(1.0, vector![cube_len / 2.0, cube_len / 2.0, cube_len / 2.0])
|
1.0,
|
||||||
.mass();
|
Vector::new(cube_len / 2.0, cube_len / 2.0, cube_len / 2.0),
|
||||||
|
)
|
||||||
|
.mass();
|
||||||
println!(
|
println!(
|
||||||
"debug_cube_high_mass_ratio3: small stick mass: {small_mass}, big cube mass: {big_mass}, mass_ratio: {}",
|
"debug_cube_high_mass_ratio3: small stick mass: {small_mass}, big cube mass: {big_mass}, mass_ratio: {}",
|
||||||
big_mass / small_mass
|
big_mass / small_mass
|
||||||
@@ -95,5 +97,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 100.1;
|
let ground_size = 100.1;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -44,7 +44,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let z = -centerz + offset;
|
let z = -centerz + offset;
|
||||||
|
|
||||||
// Build the rigid body.
|
// Build the rigid body.
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(x, y, z));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cylinder(rad, rad);
|
let collider = ColliderBuilder::cylinder(rad, rad);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -53,5 +53,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
testbed.look_at(Vec3::new(100.0, 100.0, 100.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use rapier3d::prelude::*;
|
|||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
struct PhysicsState {
|
struct PhysicsState {
|
||||||
pub gravity: Vector<f32>,
|
pub gravity: Vector,
|
||||||
pub integration_parameters: IntegrationParameters,
|
pub integration_parameters: IntegrationParameters,
|
||||||
pub islands: IslandManager,
|
pub islands: IslandManager,
|
||||||
pub broad_phase: DefaultBroadPhase,
|
pub broad_phase: DefaultBroadPhase,
|
||||||
@@ -41,7 +41,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
println!("\timpulse_joints: {:?}", state.impulse_joints.len());
|
println!("\timpulse_joints: {:?}", state.impulse_joints.len());
|
||||||
|
|
||||||
for (_, rb) in state.bodies.iter() {
|
for (_, rb) in state.bodies.iter() {
|
||||||
if rb.linvel().norm() != 0.0 {
|
if rb.linvel().length() != 0.0 {
|
||||||
println!("\tlinvel: {:?}", rb.linvel());
|
println!("\tlinvel: {:?}", rb.linvel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
testbed.harness_mut().physics.integration_parameters = state.integration_parameters;
|
testbed.harness_mut().physics.integration_parameters = state.integration_parameters;
|
||||||
testbed.harness_mut().physics.gravity = state.gravity;
|
testbed.harness_mut().physics.gravity = state.gravity;
|
||||||
|
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], point![0.0, 0.0, 0.0]);
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::new(0.0, 0.0, 0.0));
|
||||||
}
|
}
|
||||||
Err(err) => println!("Failed to deserialize the world state: {err}"),
|
Err(err) => println!("Failed to deserialize the world state: {err}"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 10.1;
|
let ground_size = 10.1;
|
||||||
let ground_height = 2.1;
|
let ground_height = 2.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -23,7 +23,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
/*
|
/*
|
||||||
* Platform that will be enabled/disabled.
|
* Platform that will be enabled/disabled.
|
||||||
*/
|
*/
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, 5.0, 0.0]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 5.0, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(5.0, 1.0, 5.0);
|
let collider = ColliderBuilder::cuboid(5.0, 1.0, 5.0);
|
||||||
let handle_to_disable = colliders.insert_with_parent(collider, handle, &mut bodies);
|
let handle_to_disable = colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
@@ -38,7 +38,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if run_state.timestep_id % 25 == 0 {
|
if run_state.timestep_id % 25 == 0 {
|
||||||
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, 20.0, 0.0]);
|
let rigid_body = RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 20.0, 0.0));
|
||||||
let handle = physics.bodies.insert(rigid_body);
|
let handle = physics.bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
let collider = ColliderBuilder::cuboid(rad, rad, rad);
|
||||||
physics
|
physics
|
||||||
@@ -55,5 +55,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![-30.0, 4.0, -30.0], point![0.0, 1.0, 0.0]);
|
testbed.look_at(Vec3::new(30.0, 4.0, 30.0), Vec3::new(0.0, 1.0, 0.0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 20.0;
|
let ground_size = 20.0;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let ground_handle = bodies.insert(rigid_body);
|
let ground_handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4)
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, 0.4)
|
||||||
.friction(0.15)
|
.friction(0.15)
|
||||||
@@ -29,15 +29,15 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
*/
|
*/
|
||||||
let ball_rad = 0.1;
|
let ball_rad = 0.1;
|
||||||
let rb = RigidBodyBuilder::dynamic()
|
let rb = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![0.0, 0.2, 0.0])
|
.translation(Vector::new(0.0, 0.2, 0.0))
|
||||||
.linvel(vector![10.0, 0.0, 0.0]);
|
.linvel(Vector::new(10.0, 0.0, 0.0));
|
||||||
let ball_handle = bodies.insert(rb);
|
let ball_handle = bodies.insert(rb);
|
||||||
let collider = ColliderBuilder::ball(ball_rad).density(100.0);
|
let collider = ColliderBuilder::ball(ball_rad).density(100.0);
|
||||||
colliders.insert_with_parent(collider, ball_handle, &mut bodies);
|
colliders.insert_with_parent(collider, ball_handle, &mut bodies);
|
||||||
|
|
||||||
let mut linvel = Vector::zeros();
|
let mut linvel = Vector::ZERO;
|
||||||
let mut angvel = Vector::zeros();
|
let mut angvel = AngVector::ZERO;
|
||||||
let mut pos = Isometry::identity();
|
let mut pos = Pose::IDENTITY;
|
||||||
let mut step = 0;
|
let mut step = 0;
|
||||||
let mut extra_colliders = Vec::new();
|
let mut extra_colliders = Vec::new();
|
||||||
let snapped_frame = 51;
|
let snapped_frame = 51;
|
||||||
@@ -62,8 +62,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ball = physics.bodies.get_mut(ball_handle).unwrap();
|
let ball = physics.bodies.get_mut(ball_handle).unwrap();
|
||||||
|
|
||||||
if step == snapped_frame {
|
if step == snapped_frame {
|
||||||
linvel = *ball.linvel();
|
linvel = ball.linvel();
|
||||||
angvel = *ball.angvel();
|
angvel = ball.angvel();
|
||||||
pos = *ball.position();
|
pos = *ball.position();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
for handle in &extra_colliders {
|
for handle in &extra_colliders {
|
||||||
if let Some(graphics) = &mut graphics {
|
if let Some(graphics) = &mut graphics {
|
||||||
graphics.remove_collider(*handle, &physics.colliders);
|
graphics.remove_collider(*handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
physics
|
physics
|
||||||
@@ -88,7 +88,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
// Remove then re-add the ground collider.
|
// Remove then re-add the ground collider.
|
||||||
// let ground = physics.bodies.get_mut(ground_handle).unwrap();
|
// let ground = physics.bodies.get_mut(ground_handle).unwrap();
|
||||||
// ground.set_position(Isometry::translation(0.0, step as f32 * 0.001, 0.0), false);
|
// ground.set_position(Pose::from_translation(Vector::new(0.0, step as f32 * 0.001, 0.0)), false);
|
||||||
// let coll = physics
|
// let coll = physics
|
||||||
// .colliders
|
// .colliders
|
||||||
// .remove(ground_collider_handle, &mut physics.bodies, true)
|
// .remove(ground_collider_handle, &mut physics.bodies, true)
|
||||||
@@ -111,5 +111,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,20 +16,20 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
let ground_size = 100.1;
|
let ground_size = 100.1;
|
||||||
let ground_height = 0.1;
|
let ground_height = 0.1;
|
||||||
|
|
||||||
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
|
let rigid_body = RigidBodyBuilder::fixed().translation(Vector::new(0.0, -ground_height, 0.0));
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
|
||||||
colliders.insert_with_parent(collider, handle, &mut bodies);
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
|
||||||
// Build the dynamic box rigid body.
|
// Build the dynamic box rigid body.
|
||||||
let (mut vtx, idx) = Cuboid::new(vector![1.0, 1.0, 1.0]).to_trimesh();
|
let (mut vtx, idx) = Cuboid::new(Vector::new(1.0, 1.0, 1.0)).to_trimesh();
|
||||||
vtx.iter_mut()
|
vtx.iter_mut()
|
||||||
.for_each(|pt| *pt += vector![100.0, 100.0, 100.0]);
|
.for_each(|pt| *pt += Vector::new(100.0, 100.0, 100.0));
|
||||||
let shape = SharedShape::convex_mesh(vtx, &idx).unwrap();
|
let shape = SharedShape::convex_mesh(vtx, &idx).unwrap();
|
||||||
|
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
let rigid_body = RigidBodyBuilder::dynamic()
|
let rigid_body = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![-100.0, -100.0 + 10.0, -100.0])
|
.translation(Vector::new(-100.0, -100.0 + 10.0, -100.0))
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let handle = bodies.insert(rigid_body);
|
let handle = bodies.insert(rigid_body);
|
||||||
let collider = ColliderBuilder::new(shape.clone());
|
let collider = ColliderBuilder::new(shape.clone());
|
||||||
@@ -40,5 +40,5 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
* Set up the testbed.
|
* Set up the testbed.
|
||||||
*/
|
*/
|
||||||
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
|
testbed.look_at(Vec3::new(10.0, 10.0, 10.0), Vec3::ZERO);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user