Coder Social home page Coder Social logo

Mat4 look_at function about nalgebra HOT 15 CLOSED

dimforge avatar dimforge commented on May 14, 2024
Mat4 look_at function

from nalgebra.

Comments (15)

brendanzab avatar brendanzab commented on May 14, 2024

Implementation:

    pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> Matrix4<S> {
        let f = center.sub_p(eye).normalize();
        let s = f.cross(up).normalize();
        let u = s.cross(&f);

        Matrix4::new( s.x.clone(),  u.x.clone(), -f.x.clone(), zero(),
                      s.y.clone(),  u.y.clone(), -f.y.clone(), zero(),
                      s.z.clone(),  u.z.clone(), -f.z.clone(), zero(),
                     -eye.dot(&s), -eye.dot(&u),  eye.dot(&f),  one())
    }

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

I think center would be better named target.

from nalgebra.

sebcrozet avatar sebcrozet commented on May 14, 2024

There is one (kind of), but not with Mat4 (those matrices don't hold any strong geometric meaning, so they don't include those kind of stuff). You will find it in the Iso3 (and Rot3) structure: http://nalgebra.org/doc/nalgebra/struct.Iso3.html#method.look_at_z.

Note that this is not the view matrix used in computer graphics, but its inverse (it will send the origin to the eye point, instead of sending the eye point to the origin). Another difference with your version is that the axis system is right-handed (yours seems to be left-handed).

Then you can use na::to_homogeneous(...) to obtain a Mat4 with the translation vector located vertically on the right (and not at the bottom like yours).

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

OH! Iso3::look_at_z definitely looks like what I want. I wonder if we could have some docs for common 'recipes' like this.

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

Ah... I can understand why you do &mut self, but it is kinda ergonomically annoying. :(

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024
        let view = to_homogeneous(&{
            let mut transform: Iso3<f32> = One::one();
            transform.look_at_z(&Pnt3::new(0.0,  0.0, 0.0),
                                &Pnt3::new(1.5, -5.0, 3.0),
                                &Vec3::z());
            transform
        });

from nalgebra.

sebcrozet avatar sebcrozet commented on May 14, 2024

Yes, documenting common patterns could definitely be useful.
For the ergonomic issue, perhaps we could add constructors like new_look_at(...) and new_look_at_z(...) ?

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

assign_look_at_z or self_look_at_z? or from_look_at_z. I tend to prefer from_ as a prefix for constructors 'with stuff', but that is just personal taste.

I wonder if @aturon has a better idea.

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

@sebcrozet What would be the best way to set up a model * view * proj transform be with nalgebra?

from nalgebra.

sebcrozet avatar sebcrozet commented on May 14, 2024

Something like:

let proj = PerspMat3::new(...);
let view = Iso3::new(...);
let model = Iso3::new(...);

// If your prefer right-multiplication: `proj_view_model * some_vector_in_model_space`
let proj_view_model = *proj.as_mat() * na::to_homogeneous(&(view * model));

// Otherwise you have to transpose this.
let model_view_proj = na::transpose(&proj_view_model);

Depending on how you built the view (i-e, with a look-at, as the transform of the camera, etc.), you might have to invert it with na::inv(&view).unwrap() (the inversion of an Iso3 never fails).

from nalgebra.

brendanzab avatar brendanzab commented on May 14, 2024

Awesome, thanks! I did get it to work in the end!

from nalgebra.

milibopp avatar milibopp commented on May 14, 2024

Your perspective projection is not only transposed as compared to PistonDevelopers/cam, but also has a different sign in two places. Is this due to different handedness, too? I'm experimenting with nalgebra for cam projections atm and not getting quite what I want. When I use the function in the suggested manner, my model gets drawn back-to-front.

from nalgebra.

tyoc213 avatar tyoc213 commented on May 14, 2024

A little off topic, but I also don't want to open an extra ticked for ask this I'm following https://open.gl/transformations and on the part A simple transformation they use some like

glm::mat4 trans;
trans = glm::rotate(trans, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));

glm::vec4 result = trans * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
printf("%f, %f, %f\n", result.x, result.y, result.z);

I have used

let a = Vec3::new(0.0, 0.0, 0.5 * mypi);
    let mut ro = Rot3::new(na::zero());
    ro.append_rotation_mut(&a);

    let rotMat = na::to_rot_mat(&ro);

If I wanted to do exactly the "same" procedure, how I will achieve it (I get a 3x3 matrix in this case)?

Also I have found that if I wanted to create a rot4 I will use 2 quaternions? #74 but from https://github.com/sebcrozet/nalgebra/blob/44df67bde2875eba733a2580d10f15e455cdd23d/src/structs/rot.rs#L349 it seem commented out?

Also I see that there are some panics, thought nobody has asked or run in them for those implementations, you could use std::unimplemented! or do like #141

Also an extra question, I feel my question is not an issue to make a new ticket... so, where I should ask for help when I'm stuck?

from nalgebra.

sebcrozet avatar sebcrozet commented on May 14, 2024

@tyoc213: Rot4 is definitely not what you want to use here. Rot4 is a rotation on a 4-dimensional space where what you want is a rotation in 3D euclidean space (the "regular" one). The problem here comes from an usual confusion due to simplifications (on the math-theoretical side) most computer-graphics-related tutorials often make.

One should make the distinction between an actual rotation in 3D space and in 3D projective space. The first one is usually represented as a 3x3 orthogonal matrix with determinant 1 while the second one is a 4x4 matrix but with its last row and column set to 0 except for its last entry (which is set to one). So the computations you are trying to reproduce here (using glm::mat4) are preformed in projective space instead of the regular one.

In nalgebra structures like Rot3, Vec3 and Pnt3 live in the regular 3D space so transforming Rot3 to a matrix will give you a 3x3 matrix. If you want to obtain its analogous in 3D projective space, you have to perform a conversion using the ::to_homogeneous(...) function (named after the concept of homogeneous coordinates you have probably encountered already). You can call this function on a Vec3 or Pnt3 as well to get 4D vectors with its last entry set to 0 or 1 respectively. In other words, the path from euclidean space to the projective space is the na::to_homogeneous(...) function while the reverse operation is the na::from_homogeneous(...) function.

There are two ways to reproduce the example you cited:

glm::mat4 trans;
trans = glm::rotate(trans, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));

glm::vec4 result = trans * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
printf("%f, %f, %f\n", result.x, result.y, result.z);

The first option is to simply perform all your operations in the regular 3D space:

let trans = Rot3::new(Vec3::new(0.0f32, 0.0, 0.5 * mypi));
let result = trans * Pnt3::new(1.0f32, 0.0, 0.0);
println!("{:?}", result); // Displays a Pnt3.

The second option is to perform all your operations in the 3D projective space:

let trans = Rot3::new(Vec3::new(0.0f32, 0.0, 0.5 * mypi));
let projective_trans = na:.to_homogeneous(&trans.to_homogeneous); // obtain a Mat4
let pt = Pnt3::new(1.0f32, 0.0, 0.0);
let projective_pt = na::to_homogeneous(&pt); // obtain a Vec4
let result = projective_trans * projective_pt; // obtain a Vec4
println!("{:?}", result); // Displays a Vec4.

To go further, I guess you might want to use a combination of rotation and translation later. Such combination is done by the Iso3::new(translation, rotation) function. As usual, its analogous into projective space is obtained with na::to_homogeneous(...) and you will obtain a 4x4 matrix arranged just like the description given on the tutorial you pointed to.

Also an extra question, I feel my question is not an issue to make a new ticket...
so, where I should ask for help when I'm stuck?

Currently, opening an issue or sending me a mail directly are unfortunately the ways to go. I intend to open a forum at some point in the near future.

Also I see that there are some panics, thought nobody has asked or run in them for those implementations, you could use std::unimplemented! or do like #141

You're right, I should use std::unimplemented! there. Well spotted!

from nalgebra.

tyoc213 avatar tyoc213 commented on May 14, 2024

Thanks for the help!

from nalgebra.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.