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:
Sébastien Crozet
2026-01-09 17:26:36 +01:00
committed by GitHub
parent 48de83817e
commit 0b7c3b34ec
265 changed files with 8501 additions and 8575 deletions

4
.cargo/config.toml Normal file
View 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"']

View File

@@ -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`.

View File

@@ -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
View File

@@ -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, &params, &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!

View File

@@ -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"

View File

@@ -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()
}

View File

@@ -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"

View File

@@ -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())
}
}
}
}

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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" }

View File

@@ -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 shapes 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)
} }

View File

@@ -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 }

View File

@@ -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 rapiers default Y-up. // instead of rapiers 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);
} }

View File

@@ -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 }

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"

View File

@@ -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);
} }

View File

@@ -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()
} }

View File

@@ -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);
} }

View File

@@ -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 cant 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 cant 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 isnt 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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }
} }
}); });

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View 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,
),
]
}

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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 isnt 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 floors 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 floors 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));

View File

@@ -1,2 +1,4 @@
pub mod character; pub mod character;
#[cfg(not(target_arch = "wasm32"))]
pub mod svg; pub mod svg;

View File

@@ -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();

View File

@@ -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);
} }

View File

@@ -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"

View File

@@ -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
} }

View File

@@ -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());
} }

View File

@@ -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);
} }

View File

@@ -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"

View File

@@ -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
} }

View File

@@ -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()
}

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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));
} }

View File

@@ -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);
} }

View File

@@ -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));
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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}"),
} }

View File

@@ -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));
} }

View File

@@ -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);
} }

View File

@@ -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