huiliang yang wrote:
> First, Thank you Paul, answer my question, I am new to this newsletter 
> so I didn't write thank you at last letter.
> 
> huiliang yang wrote:
>  > Hi,
>  >
>  > Hello
>  >
>  > >huiliang yang wrote:
>  > > I have a question about computeLocalToWorldMatrix in camera class.
>  > > First, since the openscenegraph use row matrix instead column matrix
>  > >like opengl, I thought the default matrix multiply should be post
>  > > multiply so that :
>  > >      V' = M*V  (opengl premultiply) chanage to
>  > >    V' = VT*MT  ( osg post multiply)
>  > Ok
>  > > but looks like the camera still use pre_multiply as default, but the
>  > > _viewmatrix define in camera class is apparently  is  a  row 
> matrix  MT.
>  > How do you get to this statement, which section of the code do you
>  > refer to?
>  >
>  > no any specific code for above statement. but I do trace the code and
>  > find _viewmatrix in camera class
>  > is a row matrix, which means the translation (x, y, z) is at last row.
> Ok
>  > So, if the matrix is a row matrix, only way for multiply is
>  > by  matrix = matrix*_viewmatrix. or matrix.postmultiply(_viewmatrix).
>  > is that correct?
> No, why would that be the case?
> 
> All matrices in OSG are of type osg::Matrixd (or Matrixf), which as you
> mentioned, has the translation part at the bottom row. In your multiply
> statement above (matrix = matrix*_viewmatrix) you say that because
> _viewmatrix is a row matrix it can only be post-multiplied. But what
> about "matrix"? It's also a row matrix, but it's being PRE-multiplied.
> As long as two matrices A and B have the same structure (translation at
> the bottom row/right-most column) you can compute both A*B and B*A. The
> results will be different, of course, but it's both "legal" in the
> mathematical sense. The fact that _viewmatrix is a model-view matrix
> doesn't matter, as that is simply also a form of linear transformation
> expressed by a 4x4 matrix.
> 
> What I mean is: if both matrix are col matrix, then a transformation 
> from local to world should
> matrix(world) = _viewmatrix*matrix(local);

The Camera node you're looking at can also be used as a scenegraph node.
I think the computeLocalToWorldMatrix and vice-versa methods are used 
during traversal of the scene graph to accumulate a leaf node's matrix.
Suppose you have a piece of scene graph A -> B -> C -> geometry, where A 
and B are transformations and C is a Camera node. A node visitor will 
then be used to traverse the graph in the order A, B, C, geometry. The 
computeLocalToWorldMatrix method would be called on each and the nodes 
will pre-multiply their local transformation onto the matrix passed. The 
final matrix 'arriving' at the leaf geometry will then be C * B * A.
Assuming pre-multiplying of vertices onto the final matrix (v*M), C*B*A 
makes sense, as the view transformation of C should be applied first, 
followed by B's transformation, finally followed by A's.

At least, I think this is what happens... :)

What might be confusing w.r.t. OpenGL is that the OSG uses the same 
storage layout in memory as OpenGL, i.e. the underlying element array of 
an osg::Matrix instance can be passed directly to OpenGL with 
glLoadMatrix(matrix->ptr()). However, OpenGL uses a vector post-multiply 
convention (v' = T2*T1*v), while the OSG uses a pre-multiply convention 
(v' = v*T1*T2).

Thanks for your help. At first I thought this functions is used to create 
transformation matrix that transform vertex into Opengl Eye space, that is why 
I thought _viewMatrix should always be multiplied at very last. not matter 
premulti or postmult, But actually this function is used to transfer camera 
into world coordinate. Thanks for you answers. :)

> Then back to osg's row matrix, which is the transpose of col matrix, then
> matrix(world)T = (_viewmatrix*matrix(local))T   ; T mean transpose.
>                        =  matrix(local)T*_viewmatrixT   :
>                        = matrix(local).postmult(_viewmatrix) ; should be 
> post multiply.
> but look computeLocalToWorldMatrix: it is using
>                           if( premultiply)
>                           matrix(local).premult(_viewmatrix); which is
>                           _viewmatrixT*matrix(local)T;    since they are 
> both row matrix, transposed. 
>                          = matrix*_viewmatrix;         here it totally 
> change the order of transformation.
> I agree matrix multiplication can be done either way, but I if the order 
> of transformation shouldn't be changed. Thanks for answer my question.
> 
>  > That is why I say why the default multiply in camera class is
>  > premultiply, in computeLocalToWorldMatrix,
>  > it  use matrix = _viewmatrix*matrix or
>  > matrix.premultiply(_viewmatrix), if _viewmatrix is a row matrix, it
>  > looks weird.
> 
>  >
>  > It also depends on your definition of 'pre-multiply'. If you say VT*MT
>  > is "post multiply" (as you do above), then this implies that you
>  > actually mean "MT post-multiplies VT". This is turn also means that "VT
>  > pre-multiplies MT". So it depends from which operand you look at it how
>  > you describe the operation.
>  > >
>  > > Second, even as the default pre_multiply, then let's say:
>  > >      V' = M*V  if (_transformOrder==PRE_MULTIPLY)
>  > > then its inverse should be
>  > >      V = M-1* V' ,
>  > > why in function computeWorldToLocalMatrix
>  > Which class? You say "V", which implies a vector usually, but, for
>  > example, Camera::computeWorldToLocalMatrix works on a matrix as input.
>  > If you indeed refer to Camera::computeWorldToLocalMatrix() then I would
>  > say that that method does the inverse operation of
>  > computeLocalToWorldMatrix(). Assuming _referenceFrame==RELATIVE_RF and
>  > _transformOrder==PRE_MULTIPLY then the method computeLocalToWorldMatrix
>  > pre-multiplies its argument "matrix" with "_viewMatrix". I.e.
>  >
>  >  matrix.preMult(_viewMatrix);
>  >
>  > actually does
>  >
>  >  matrix = _viewMatrix * matrix;
>  >
>  > Method computeWorldToLocalMatrix() does the inverse of this operation,
>  > so instead of pre-multiplying with _viewMatrix it post-multiplies with
>  > the inverse of _viewMatrix (the comments also say this).
>  >
>  > That is I don't understand, if matrix' = _viewMatrix*matrix, then the
>  > inverse operation is
>  > matrix = _viewMatrix-1*matrix', right?
>  > why here it change the order of multiply?
> local_to_world = _viewMatrix * matrix
> =>
> world_to_local = [local_to_world]^{-1} = [_viewMatrix * matrix]^{-1} =
> matrix^{-1} * _viewMatrix^{-1}
> 
> (inverse_of_A*B = inverse_of_B * inverse_of_A)
> 
> Ok I get it, the function is to create a transformation matrix, I 
> thought it is using for vector transformation. Thanks.

Well, the argument passed is a Matrix, not a vector.

Paul


      
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to