-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gvdb.SetTransform() does not appear to calculate the inverse transform correctly #94
Comments
Ah ha, nice work! I was investigating this as well and came to the same conclusion. The SetTransform was not computing those correctly. Here is my updated code for comparison:
This should be a lot cleaner/clearer. One thing that bothered me for a while was that the Matrix/Vector classes didn't have composing operators. I have added those and used them here. They apply the correct matrix multiplications to clean up the code a lot.
Regarding the OptiX rendering, what I have now is:
This works correctly now, including shadows, with OptiX. Nice find on SetTransform! Glad we found that independently as confirmation. |
Haha - thank you, Rama! I'm glad you could confirm it -- I wanted to make really sure I was interpreting things correctly. It looks like you fixed a bunch of things today; I can test all of these out in the next day or so and then close them out/confirm the fixes if that works for you (including depth merge, which I am also using). Thanks again for digging in and providing the updates! |
Hi, Rama - I am still getting orbiting behavior (for basic meshes/models and volumes that use the computed matrix using this code) and when checking the inverse:
I don't get an identity matrix using the new code... I also get different mXform values when compared against this code:
Which appears to give the desired behavior. I'm still poking around, but wanted to share the results so you knew there seems to still be some issues with the transform... Is InvertTRS() still valid when called using a matrix where translate and scale have not been set? |
I will be traveling the next few weeks, so I won't be able to take a look for a while. It is concerning that mXform * mInvXform doesn't result in identity, so that would be interesting to understand better. The difference between the new mXform and the older RotateTZYXS /w PreTrans may be due to the order of operations. My latest code is doing p'=T S R PT p, where as the original may have been doing p'=T R S PT p.. The ordering of the pretrans, scale, rotate, translate is a matter of API design, but of course in either case mXform * mInvXform should be identity. |
Not a problem, I appreciate the earlier confirmation as it helps me focus in on the problem spots. The process is still useful as it helps me understand the library better as I navigate through the design. I'll let you know what I find out! Thanks again and safe travels. |
I think I have this fixed now.. Here is my latest SetTransform:
The test at the end confirms mXform * mInvXform is identity. It was also necessary to modify the camera ray generation in cuda_gvdb_geom.cuh:
|
So, I'm looking at integrating this into GVDB at the moment, and I think there's confusion inside the library about whether To sum it up (no pun intended!), most GVDB functions and comments seem to refer to column-major matrices and column vectors. For instance,
where However, there are also parts in the codebase that seem to imply row-major matrices with row vectors. For instance, I feel like the best thing to do would be to define that Also, I'm looking at removing |
Hi Nick, That would be my inclination as well. I generally conceived of gvdb following the opengl paradigm with column-major notation, with the vector on right, and matrix multiply order right-to-left. As you say many funcs are documented this way, and the naming of funcs follows this. You are probably already aware, but this is keeping in mind that column-major is only about notation w opengl, not storage ordering. From OpenGL docs: " rght-side vector, with pre-multiplied matrices, in column-major order has an identical memory layout to left-side vector, with post-multiplied matrices, in row-major order." So, in column-major notation used by opengl and gvdb, the translation elements are still in the 13th, 14th and 15th memory slots of the 16 contiguous elements. The operator v * = m was for performance reasons, as it avoids the extra temporary variable generated by compiler when one does v = m * v. I could see adding a new func: vector3df& matrix4f::operator* (const vector3df op), which follows the proper column-major ordering notation. The func v *= m could be kept around for performance with a clear note as to why. Lately I favor functions being closer to the desired notation ordering (easier to read). Hence the matrix compositing operations I've added and made use of in SetTransform. PS. Another important change imo for user-friendliness. Matrix4F constructor: |
… warnings. - Matrix4F objects are now defined to be column-major, and a matrix `M` now transforms a vector `v` by multiplying with the column vector on the right, like `Mv`. This shouldn't impact your code unless you were using `GetRowVec` or `GetF` - `sample_utils`' `vec.h`, `vec.cpp`, `camera.h`, and `camera.cpp` have been removed. These were copies of their corresponding GVDB classes that were slowly diverging over time, and are not needed (the only sample impacted as a result is `gFluidSurface`). If you were using these, include the GVDB headers for drop-in replacements. - `Vector3DI` and `Vector3DF` are now templatized instantiations of a single `Vector3D` class. To accomodate this, its functions have been moved inline to `gvdb_vec.h`. This might increase compilation times a bit - sorry about that! - `Matrix4F::operator* (const Vector3DF &op)` now returns a `Vector3DF`, the result of transforming the vector by the matrix, instead of a `Matrix4F`, the result of multiplying the matrix by `diag(op.x, op.y, op.z, 1)`. The old behavior has been renamed to `Matrix4F::ScaleInPlace`. - `ActivateSpaceAtLevel` and `isActive` now take a `Vector3DI` pos instead of a `Vector3DF`. Previously, the `Vector3DF` was internally casted to a `Vector3DI`. - `getNumNodes`, `getNumUsedNodes`, and `getNumTotalNodes` now return 64-bit unsigned integers in order to represent the underlying `DataPtr` structure more accurately. However, most users of these functions cast them to `ints` in any case. - The order of arguments in `mmult` have been swapped. - Removes unused variables `camivprow0...camivprow3` from `ScnInfo`. - `AllocateNeighbors` now takes a `uint64` instead of an `int`. However, this change is not very impactful. - Renames the variables in `Matrix4F::operator()`. By coincidence, this produces exactly the same behavior as before, so no code changes are needed. Also includes changes throughout the codebase to fix the type casting warnings VS 2019 was warning about, removes the `GVDB_VEC`... variables, and adds documentation for math class functions. Note that you may have to do a clean rebuild of the project after pulling this commit, as the mangled type names for the `Vector3` classes have changed.
Hi all, I think this should be fixed in the latest version now! Please see the summary of changes at #89 (comment). Thanks, |
This has been fixed with all the related changes - thank you both! |
I was debugging some issues getting a volume to spin around its center of mass and noted that when rendering in GVDB, the volume was orbiting the origin instead of spinning. As a sanity check, I passed the same computed mXform to a mesh object in the scene and it spun correctly and it did not orbit.
The orbiting behavior of the volume looked like what you might see if rotation was happening after the translation (assuming in the inverse transform because the mXform appeared to be correct). As I began to look into the transform more closely, I wanted to double check the mInvXform that was being calculated in SetTransform(), so I added this to the end of the function:
And found that I was not getting an identity matrix from the result. So, I modified SetTransform as follows. Note I left the mInvXrot unchanged as there were issues I couldn't immediately diagnose, but I changed the mInvXform to calculate the inverse matrix using the RotateTZYXS function and a new tmp2 variable to make things readable below. As a result, I was now getting an identity matrix from the newly calculated mInvXform and the spinning behavior works correctly for volumes:
This seems to have broken some things in the Optix rendering that I am still investigating.
Comments and thoughts are welcomed here. Thanks!
The text was updated successfully, but these errors were encountered: