Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (527)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (594)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Bug in Transform3D (test-program included)  (Read 952 times)
0 Members and 1 Guest are viewing this topic.
Offline Ifadolai

Junior Devvie




Java forever!!


« Posted 2003-11-10 18:01:15 »

import javax.media.j3d.*;
import javax.vecmath.*;

public class scaleTest {

      public scaleTest () {
      }

      public static void main (String[] args) {
              Transform3D t1 = new Transform3D();
              Transform3D t2 = new Transform3D();

              Vector3d s1 = new Vector3d(1.0,1.0,3.0);
              Vector3d s2 = new Vector3d();

              t1.set(new AxisAngle4d(0,1,0,1.57));

              t1.setScale (s1);
              t1.normalizeCP ();

              t2.set(t1); // even if normalizeCP is flawed this should make t1==t2
              t1.getScale (s1);
              t2.getScale (s2);

              System.out.println(s1+" == "+s2);
      }
}


Expected Output:

(1.0, 1.0, 3.0) == (1.0, 1.0, 3.0)

Actual Output:

(1.0, 1.0, 3.0) == (2.9999991544849074, 1.0, 1.0000025365417038)


Why normalizeCP() is important when we have normalize():

Because normalize() also fails, see bug 4751283 "Transform3D.normalize()
and Matrix4d.get(Matrix3d) permute matrix columns.":
http://archives.java.sun.com/cgi-bin/wa?A2=ind0209&L=java3d-interest&D=0&I=-3&P=30861

So I am left with no working normalize method?

I will be grateful for any code suggestions able to cope with
non-uniform scales.


Btw. Rather strange Sun has removed bug 4751283 from the BugParade.
Does that mean they regard it as closed?

Nikolai V. Christensen, Computer Engineer,
Simulation and Training department
IFAD, Forskerparken 10A, DK-5230 Odense M
Denmark, EU
Phone: +45 63 15 71 31  Fax: +45 65 93 29 99
Offline crystalsquid

Junior Devvie




... Boing ...


« Reply #1 - Posted 2003-11-16 10:27:01 »

Normalize & normalize3d work just fine, they just aren't doing the operation you seem to think they should be.
'Normalize' is simple ensuring the matrix is 'ortho-normal', i.e. that the rotation part (the 3x3 top left corner) contains 3 unit vectors. The scale is stored seperately, and should not be affected by a normalise operation, and the rotation & position will not be changed either. What exactly do you expect a normalize() to do?

The scale & normalise functions do behave in the normal way from what I can tell. NormalizeCp is a cheaper & slightly less accurate method to enforce an othonormal rotation matrix than the default SVP method. However, it is normally suffiecient for most 3d applications, particularly games.

Furthermore, you have to distinguish which space an operation is being performed in. You are applying the scale after the transform has been rotated out of unit position. The scale function you call attempts to set a world based scale, and thus back-transforms the scale vector by the transforms matrix to obtain the actual local scale required to give the requested world scale. This gives the (3,1,1) local scale that you observed.
Sadly I don't have Java3d installed, & Im not going to install it, so I cannot check the validity of your code.
It seems the issue is more the 's2.set(s1)' doesnt appear to be working properly, as that should force s1.scale == s2.scale as you suggest.

I would further suggest that Sun removed the bug report as it was based on your similarly flawed expectations of what the functions 'should' be doing. Bear in mind that there are many varying opinions worldwide on what a 'normal' matrix operation is - pre/post multiply, column/row ordering, Rigt/Left handedness in notation & rotation... Its a nightmare. However, if 95% of developers seem happy with an interface that you are having problems with, the weight of probability is that your basic assumptions on the matrix math are wrong. Direct3D & openGL can't even agree on a standard, & PS2's use a different coordinate system again.

Sorry if this seems a bit harsh, but Ive been in the situation you were in before many times (American & UK standards appear to be opposites with matrices. I have my own desk in Matrix Hell) & it is all to easy to start pointing fingers at other peoples work without correctly establishing the validity of your own assumptions.


- Dom
Offline Ifadolai

Junior Devvie




Java forever!!


« Reply #2 - Posted 2003-11-17 09:52:28 »

Quote
Normalize & normalize3d work just fine, they just aren't doing the operation you seem to think they should be.
'Normalize' is simple ensuring the matrix is 'ortho-normal', i.e. that the rotation part (the 3x3 top left corner) contains 3 unit vectors. The scale is stored seperately, and should not be affected by a normalise operation, and the rotation & position will not be changed either. What exactly do you expect a normalize() to do?


As you say yourself: "The scale is stored seperately, and should not be affected by a normalise operation"

Quote
Furthermore, you have to distinguish which space an operation is being performed in. You are applying the scale after the transform has been rotated out of unit position. The scale function you call attempts to set a world based scale, and thus back-transforms the scale vector by the transforms matrix to obtain the actual local scale required to give the requested world scale. This gives the (3,1,1) local scale that you observed.


Sorry you lost me there.

Quote
It seems the issue is more the 's2.set(s1)' doesnt appear to be working properly, as that should force s1.scale == s2.scale as you suggest.


Maybe, but when I print out the matrixes and compare the doubles, I cannot find a single difference. If we asume the only information in a Transform3D is the 16 matrix doubles, there should be no difference at at all. It confuses me.

Quote
I would further suggest that Sun removed the bug report as it was based on your similarly flawed expectations of what the functions 'should' be doing.


As you can see above my expectation is the same as yours. I only expect it to preserve the scale, which it does not.

Quote
it is all to easy to start pointing fingers at other peoples work without correctly establishing the validity of your own assumptions.


I didn't point fingers at anyone, I just reported a bug, And requested for people more skilled than myself to submit some code to do the job properly.

Regards
Nikolai

Nikolai V. Christensen, Computer Engineer,
Simulation and Training department
IFAD, Forskerparken 10A, DK-5230 Odense M
Denmark, EU
Phone: +45 63 15 71 31  Fax: +45 65 93 29 99
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Ifadolai

Junior Devvie




Java forever!!


« Reply #3 - Posted 2003-11-17 09:55:54 »

Here follows the reply from Sun:


Nikolai,
  Thanks for your bug report and test program. Your program reveal the
same
bug as reported in BugId : 4751283 -
Transform3D.normalize() and Matrix4d.get(Matrix3d) permute matrix columns.

The SVD algorithm that Java 3D uses will sort the columns of the output
matrix by descending order of their scale factors.  This is useful for
many types of problems, but is inappropriate for the normalization of
rotation matrices.

BTW, BugId : 4751283 is still open and I'm able to view it  with our
internal
bug tool. I will try to resolve the discrepancy with BugParade.

thanks,
  Chien Yang
  Java 3D, Sun Microsystems Inc.

Nikolai V. Christensen, Computer Engineer,
Simulation and Training department
IFAD, Forskerparken 10A, DK-5230 Odense M
Denmark, EU
Phone: +45 63 15 71 31  Fax: +45 65 93 29 99
Offline Ifadolai

Junior Devvie




Java forever!!


« Reply #4 - Posted 2003-11-17 09:58:56 »

The bug itself can be viewed here:

http://developer.java.sun.com/developer/bugParade/bugs/4751283.html

Nikolai V. Christensen, Computer Engineer,
Simulation and Training department
IFAD, Forskerparken 10A, DK-5230 Odense M
Denmark, EU
Phone: +45 63 15 71 31  Fax: +45 65 93 29 99
Offline crystalsquid

Junior Devvie




... Boing ...


« Reply #5 - Posted 2003-11-17 12:15:24 »

Ah, ok.
The issue here is the bit you said I lost you with. That I think is the source of the problem.

The thing is, you are applying a scale of 3x in the x-axis only to the matrix.

However, the matrix is rotated 90 degrees around the y axis. This means the matrixes x axis now lies along the -z axis in world space, and the matrix z axis points along world space x. i.e. the matrix will be (using rows for axis, which is my personal favourite):
x - ( 0,  0,  -1 )
y - ( 0,  1,  0 )  = R, a rotation matrix
z - ( 1,  0,  0 )
You then scale the WORLD z-axis by 3 using a matrix:
(1, 0, 0)
(0, 1, 0) = S, a scale matrix
(0, 0, 3)
This is the scale matrix. Multiplying these (R*S) gives:
(0, 0, -3)
(0, 1, 0)
(1, 0, 0) which looks like what you get.

Note that this is not the same as a LOCAL z axis scale (S * R), which would have given:
(0, 0, -1)
(0, 1, 0)
(3, 0, 0) which is what you seem to be after.

The only difference is how the scale is applied. The first way was post-multiplied, the second was pre-multiplied. This can be seen as 'the order which you apply the matrices', or (from a physics viewpoint) the space in which the scale is applied.

Admittedly, I would side with you on the expected behaviour of a function called 'scale', but my previous point was that conventions differ, and there is no real 'right' way. You just have to deal with the conventions used by the library your using.


The best way to ortho-normalise a matrix is this (in pseudo code):

vector x = matrix.getXaxis();
float xl = x.length();
x /= xl;  // normalise
vector y = matrix.getYaxis();
float yl = y.length();
y /= yl; // normalise

vector z = matrix.getZaxis();
float zl = z.length();

// Now build a new z-axis that is orthogonal to x and y:
z.crossProduct( x, y );  // z = x ^ y
z.normalise();

// z is now a true z-axis, both 'normal', and orthogonal to x and y.
y.crossProduct( z, x );  // y = z ^ x

// Rebuild the matrix, multiplying scale back in:
matrix.setXaxis( x * xl );
matrix.setYaxis( y * yl );
matrxi.setZaxis( z * zl );

This _should_ be what the normalizeCP() is doing, guessing from the name.

Hope this makes more sense  Smiley

- Dom
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

PocketCrafter7 (14 views)
2014-11-28 16:25:35

PocketCrafter7 (9 views)
2014-11-28 16:25:09

PocketCrafter7 (10 views)
2014-11-28 16:24:29

toopeicgaming1999 (76 views)
2014-11-26 15:22:04

toopeicgaming1999 (67 views)
2014-11-26 15:20:36

toopeicgaming1999 (16 views)
2014-11-26 15:20:08

SHC (30 views)
2014-11-25 12:00:59

SHC (28 views)
2014-11-25 11:53:45

Norakomi (32 views)
2014-11-25 11:26:43

Gibbo3771 (28 views)
2014-11-24 19:59:16
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!