dimforge / bevy_rapier

Official Rapier plugin for the Bevy game engine.
https://rapier.rs
Apache License 2.0
1.25k stars 261 forks source link

Support for bevy::math::Vec3 in addition to nalgebra vectors #50

Closed sburris0 closed 3 years ago

sburris0 commented 3 years ago

I think it would be fitting for a bevy plugin to accept bevy's vector type.

Currently I do the following to use RapierConfiguration:

use bevy::prelude::*;
use bevy_rapier3d::physics::{RapierPhysicsPlugin, RapierConfiguration};
use bevy_rapier3d::rapier::na::Vector;

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin)
        .add_resource(RapierConfiguration {
            gravity: Vector::y(),
            ..Default::default()
        })
        .run();
}

It would be nice if there was a way to use Bevy's Vec3 type rather than having to import nalgebra's vector. Ultimately, I don't think anything can implement From or Into for this besides nalgebra (which shouldn't depend/care about Bevy of course), but functions in bevy_rapier could be made generic to accept Bevy's Vec3:

        .add_resource(RapierConfiguration {
            gravity: Vec3::unit_y(),
            ..Default::default()
        })
sebcrozet commented 3 years ago

The Bevy's Vec3 is actually the vector from glam. So implementing From or Into requires either glam or nalgebra to (optionally) depend on the other. nalgebra will never have a dependency to bevy, but having an optional dependency to glam could make sense to add this conversions.

Regarding using Bevy's math types as part of the bevy_rapier API: I am not sure whether this is a good thing or not. First, it would be impossible to completely remove the need for the user to use nalgebra types because that's what rapier uses everywhere. So we could make some types like the RapierConfiguration use Bevy's vector, and leave the types coming from rapier as-is, requiring the end user to use nalgebra types at some point anyways. Or we could keep using nalgebra types in RapierConfiguration and say that nalgebra is used for everything in bevy_rapier. This second options sounds more coherent to me.

sburris0 commented 3 years ago

EDIT: I realized this wouldn't work, a custom trait might though

What about a supertrait that implements From? This is new to me but it might look like this:

trait FromVec: std::convert::From<Vec3> {
    fn from_vec(&self);
}

impl FromVec for Vector3<f32> {
    fn from_vec(&self, vec: Vec3) -> Vector3<f32> {
        Vector3::new(vec.x, vec.y, vec.z)
    }
}

I know you can't implement foreign traits on foreign types, but implementing an extension trait should be possible.

I think this would allow users to supply either type and bevy_rapier to only care about the nalgebra one.

EDIT: Or bevy_rapier could use the newtype pattern to impl From both?

sburris0 commented 3 years ago
struct MutualVec {
    x: f32,
    y: f32,
    z: f32,
}

impl From<Vec3> for MutualVec {
    fn from(vec: Vec3) -> Self {
        MutualVec {
            x: vec.x,
            y: vec.y,
            z: vec.z
        }
    }
}

impl Into<Vector3<f32>> for MutualVec {
    fn into(self) -> Vector3<f32> {
        Vector3::new(self.x, self.y, self.z) 
    }
}

// ...
        .add_resource(RapierConfiguration {
            // The conversion could be done behind the scenes
            gravity: MutualVec::from(-Vec3::unit_y()).into(),
            ..Default::default()
        })

This would work, whether it's advisable or worth it... 🤷

sebcrozet commented 3 years ago

This MutualVec solution you are mentioning here is actually very similar to what the mint crate allows you to do. And it turns out that nalgebra implements the traits from mint if you enable the mint feature of nalgebra.

vultix commented 3 years ago

Bevy's Vec3 can be turned directly .into() nalgebra's vector by adding the following to your Cargo.toml:

nalgebra = {version = "0.25", features = ["convert-glam"]}

bevy_rapier should probably turn on this feature by default

sebcrozet commented 3 years ago

I'm closing this since the enabling the nalgebra feature convert-glam013 (for glam 0.13/bevy 0.5) or the convert-glam015 (for glam 0.15/bevy master) allows easy conversions between nalgebra and glam. See that page of the user-guide.