Comments (15)
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.
I think center
would be better named target
.
from nalgebra.
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.
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.
Ah... I can understand why you do &mut self, but it is kinda ergonomically annoying. :(
from nalgebra.
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.
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.
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.
@sebcrozet What would be the best way to set up a model * view * proj
transform be with nalgebra?
from nalgebra.
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.
Awesome, thanks! I did get it to work in the end!
from nalgebra.
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.
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.
@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.
Thanks for the help!
from nalgebra.
Related Issues (20)
- Wrong eigenvector sorting in nalgebra::SymmetricEigen, while correct in nalgebra_lapack::SymmetricEigen HOT 1
- Make some RealField functions const HOT 1
- `tr_solve_upper_triangular` proptest failure
- Hash for Matrix doesn't match `Borrow<[[T; R]; C]>` semantics
- Cannot compute the SVD of an empty matrix. HOT 2
- Matrix Display output alignment is not Unicode-aware HOT 4
- Multiply matrix by vector row-wise HOT 2
- matrix literals or const constructors HOT 1
- `normalize` docs need expansion HOT 1
- Test flake in `f64::symmetric_eigen`
- Unit Quaternion logarithm inconsistent with exp HOT 1
- Matrix Views: non contiguous/regular slices
- Minimizing trait bound complexity when working with dimensional generics HOT 3
- SVD Computes Wrong Singular Values for Very Small-Valued Matrices HOT 1
- Make nalgebra_lapack::qr::QRScalar trait public
- Homographic transform via SVD/DLT - is it broken or am I doing it wrong?
- Inconsistency between Numpy/MATLAB and and nalgebra HOT 2
- Export crates used in public APIs
- unit quaternions and orthonormal matrices are only closed under successive multiplications in theory HOT 1
- Memory leak in generic_resize/reallocate_copy
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nalgebra.