www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: AGP on September 24, 2010, 05:12:42 pm

Title: Max Camera Matrix to JPCT
Post by: AGP on September 24, 2010, 05:12:42 pm
The following have been my attempts at converting 3ds max's camera matrix into jPCT's. None have worked (and I've since forgotten the Maxscript to even get the camera's matrix!). Anyway, if anyone could help with this I would really appreciate it.

Code: [Select]
      private Matrix convertMaxToJpctMatrix(Matrix toConvert) {
Matrix newMatrix = new Matrix(toConvert);
Matrix transformer = new Matrix();
float[] transformerValues = {1f, 0f, 0f, 0f,0f, 0f, -1f, 0f,0f, 1f, 0f, 0f,0f,0f,0f,1f};
// float[] transformerValues = {1f, 0f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 0f, -1f, 0f, 0f,0f,0f,1f};
transformer.setDump(transformerValues);
/**
[ 1 0 0 ]
[ 0 0 1 ]
[ 0 1 0 ]*/
/**1st
 1  0  0  0
 0  0 -1  0
 0  1  0  0
 0  0  0  1
2nd:
 0  -1  0  0
 0  0 -1  0
 1  0  0  0
 0  0  0  1
3rd (ON THE LEFT:
1.0     -0.0    0.0     0.0
0.0     -1.0    0.0f     0.0
0.0     0.0f    -1.0    0.0
0.0     0.0     0.0     1.0
*/
newMatrix.matMul(transformer);
// transformer.matMul(newMatrix);
return newMatrix;
      }
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 25, 2010, 09:22:08 pm
I'm confused...what is the input matrix and what's the expected result and the actual result?
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 25, 2010, 09:30:21 pm
The input matrix are the values I got from 3ds max maxscript console. The above method is called like so:

Code: [Select]
theCamera.setFOVLimits((float)Math.toRadians(10), (float)Math.toRadians(170));
theCamera.setFOV((float)Math.toRadians(34.254));
Matrix cameraMatrix = new Matrix();
// float[] maxMatrix = {-0.0860526f,-0.996188f,-0.0143083f, 0.543894f,-0.0590056f,0.837077f,-0.83473f,0.0642504f,0.546898f,-86.031f,21.7374f,75.9077f};
float[] maxMatrix = {-0.0860526f,0.543894f,-0.83473f,0f,-0.996188f,-0.0590056f,0.0642504f,0f,-0.0143083f,0.837077f,0.546898f,0f,15.3374f,-15.4662f,-114.723f,1f};
cameraMatrix.setDump(maxMatrix);
cameraMatrix = convertMaxToJpctMatrix(cameraMatrix);
SimpleVector cameraPosition = new SimpleVector(-86.031f, 21.7374f, 75.9077f);//IN MAX: -86.031,21.7374,75.9077
theCamera.setBack(cameraMatrix);
theCamera.setPosition(cameraPosition);
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 25, 2010, 09:33:42 pm
What i actually meant was something like:

This is the max matrix: <matrix>...it rotates the camera around <whatever> <some> degrees

This is the jPCT is would expect: <matrix>

This is what i get: <matrix>

I'm having a real hard time figuring out how to convert them, if i have no idea what the initial matrix looks like and what it is supposed to do.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 25, 2010, 09:40:47 pm
OK, the variable named maxMatrix is the Max Matrix. The expected result is that I would be looking at the exact same thing in a jPCT scene as I am in Max, but instead the camera is always facing (and is positioned) somewhere else. The scene is of that QG 2.5d game I've been doing for nearly two years and, since I'm nearly finished now, I need to address this issue. Right now, I have made an approximation with the following method, but I need an exact result, since the backgrounds in this game are all 2D.

Oh, and the camera will never move in this game (the backgrounds, as said, are 2D screens). I can't get the position and rotation in Max of the camera until Monday, when I can get to the Max scene and check, sorry.

Code: [Select]
     private void oldCamera() {
SimpleVector cameraPosition = hero.getTransformedCenter();
cameraPosition.z -= 32;
theCamera.rotateCameraX((float)Math.toRadians(35));//ORIGINALLY 20
theCamera.setPosition(cameraPosition);
theCamera.moveCamera(Camera.CAMERA_MOVEUP, 33.2f);
theCamera.moveCamera(Camera.CAMERA_MOVELEFT, 12f);//14f
theCamera.moveCamera(Camera.CAMERA_MOVEOUT, 140f);//14f ORIGINALLY
theCamera.setFOVLimits((float)Math.toRadians(5), (float)Math.toRadians(175));
theCamera.setFOV(theCamera.getFOV()/3.2f);
      }
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 25, 2010, 09:50:53 pm
Do you have any information about the kind of matrix (row-/column-major) and the coordinate system max is using? How, you example, does a matrix look like that makes the camera facing 90° down?
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 25, 2010, 10:10:16 pm
I'm fairly sure Max uses 4x4 row major matrices, and, I also read that rotations in max are backwards (Max is right-handed, but the rotations are left-handed). In the Max orthographic viewports, X points right, Y points up, and Z points out of the screen toward you. Worldspace coordinate system is such that X runs in a positive direction to the right, Z runs in a positive direction upward, and Y runs in a positive direction away from you.
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 25, 2010, 10:21:49 pm
Can you access max matrix represention so that you can post a matrix from max that does that simple 90° down look?
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 25, 2010, 10:35:40 pm
I'm downloading a Max trial right now, since I'm not home, but it'll take a little while, buddy.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 26, 2010, 01:36:14 am
Got it. Took me longer to remember the damn dollar sign than to download it :- )

This camera faces down on the viewport. Again, in worldspace coordinate system X runs in a positive direction to the right, and Y runs in a positive direction away from you, Z runs in a positive direction upward. $Camera001.transform gives: (matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0])
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 26, 2010, 10:06:05 am
That's an identity matrix, i.e. the camera hasn't roated at all. What i meant was a matrix from a camera that has a simple but defined rotation like 90° around X or something like that.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 26, 2010, 06:07:18 pm
Sorry, I was in a hurry to leave for a wedding last night but I wanted to get this done first. The thing is, I don't know anything about MaxScript and Google isn't helping much. I'll look up how to get the rotation matrix and post back.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 01:46:47 am
When I rotate it so that the camera is facing forward on the viewport, the camera's matrix reads (matrix3 [1,0,0] [0,0,1] [0,-1,0] [0,0,0]). Does that help?

That was positive 90º on x, by the way.
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 12:25:26 pm
I'm not sure, if my thinking is correct, but this looks very much like a normal GL like matrix. So to convert it, it would think that
   
   
Code: [Select]
    float[] mat={1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1};
    Matrix m=new Matrix();
    m.setDump(mat);
        m.transformToGL();
   
should do the trick. I'm abusing the transformToGL-method here to actually do the opposite. A simple rotation around X with 90° will have the same effect, but this is cheaper.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 05:15:35 pm
I don't get it: where do these values come from? I mean, I noticed the pattern of the extra 0 for the first rows and the extra 1 for the last, but is that what I need to add every time?
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 05:54:46 pm
This is just to make a 4x4 matrix out of this 3x4 matrix. Just add a 0 in each row but the last and a 1 in the last.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 07:08:40 pm
Didn't work, Egon. I can't see anything.
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 08:57:42 pm
Then...be creative. I mean, what can be different between 3ds and jPCT? The matrix order (row/column-major), the coordinates system...or 3ds stores something really strange in that matrix.

So i would do the following to find out:


Create yourself a simple testcase in 3ds with a cube or something that is viewed by a camera with a simple transformation. Load that cube, place it like in 3ds and try to make the jPCT matrix match the view in 3ds.
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 09:01:14 pm
And don't forget to make this 3x4->4x4 step every time. That's definitely needed no matter what else you do to the matrix.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 09:05:01 pm
I added the 0s and the 1. When I commented-out the entire matrix thing and set the FOV to 45 (as it is in Max), and entered the position of the camera (-y/z flipped) and set camera.lookAt to the position of Max's camera's target, I got a camera looking sideways at the scene (as if it had been jpctY-rotated 90º around the center of the scene). But I got to see the characters (the height was right). Bizarre, right?

Code: [Select]
   theCamera.setFOVLimits((float)Math.toRadians(10), (float)Math.toRadians(170));
    theCamera.setFOV((float)Math.toRadians(45));
    theCamera.setPosition(new SimpleVector(-51.598f, -59.977f, 26.276f));
/*    float[] mat = {-0.147809f,-0.989015f,0f,0f,
 0.581329f,-0.0868801f,0.809016f,0f,
 -0.80013f,0.11958f,0.587785f,0f,
 -51.5975f,26.2763f,59.9766f,1f};
    Matrix m = new Matrix();
    m.setDump(mat);
    m.transformToGL();
    theCamera.setBack(m);
*/

    theCamera.lookAt(new SimpleVector(-24.935f, -40.39f, 22.292f));
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 09:25:30 pm
Might be an artifact of lookAt(). There are unlimited ways to stand at some position and look at another, because you can always rotate around the direction vector and "look at" is still true. If you already have the camera's position and a target to look at...maybe you have an up vector too? In that case, you might want to use setOrientation() instead, where the direction vector is the vector between the target and the position (i.e. target-position).
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 09:28:24 pm
Without the transformToGL call some of the characters show up rotated as if they were lying on the ground, but in a weird position on screen. I wish I was on more sure-footing on this, man, so I can't very well get creative.

How do I get an up-vector?
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 09:44:46 pm
How do I get an up-vector?
No idea...it's possible to derive it from the cam's rotation matrix, but if that one would be working, you wouldn't need it in the first place...so...isn't it possible to get it from max? I mean you can get obviously get the position and the target. Both are worth nothing without the up vector, so there should be a way to get it!?
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 10:15:45 pm
Question: is the up-vector just, say, a (0, 1, 0)-type of vector? Meaning are there only three (or six with negative values) possibilities for it?
Title: Re: Max Camera Matrix to JPCT
Post by: paulscode on September 28, 2010, 10:22:01 pm
When I commented-out the entire matrix thing and set the FOV to 45 (as it is in Max), and entered the position of the camera (-y/z flipped) and set camera.lookAt to the position of Max's camera's target, I got a camera looking sideways at the scene (as if it had been jpctY-rotated 90º around the center of the scene). But I got to see the characters (the height was right). Bizarre, right?
This sounds like you have the wrong coordinate system.  The fact that you see the characters should mean that the target position is in the same coordinate system as the camera lookAt position, but the fact that in jPCT's coordinate system everything is rotated and you are looking from the side could mean that the entire scene (including the lookAt vector you are using) is rotated 90 around the jPCT camera's y-axis.  You should be able to just flip the x and z coordinates (in camera space) for the object positions and the camera lookAt vector (leave the camera in the position you have it), to have everything oriented properly.

Question: is the up-vector just, say, a (0, 1, 0)-type of vector? Meaning are there only three (or six with negative values) possibilities for it?
Correct as long as the camera is aligned with the cardinal directions.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 10:31:09 pm
Quote
This sounds like you have the wrong coordinate system.  The fact that you see the characters should mean that the target position is in the same coordinate system as the camera lookAt position, but the fact that in jPCT's coordinate system everything is rotated and you are looking from the side could mean that the entire scene (including the lookAt vector you are using) is rotated 90 around the jPCT camera's y-axis.  You should be able to just flip the x and z coordinates (in camera space) for the object positions and the camera lookAt vector (leave the camera in the position you have it), to have everything oriented properly.

Well, jPCT's up axis is -y, whereas worldspace up for max is +z. I accounted for that. Or do you mean something else?

Quote
Correct as long as the camera is aligned with the cardinal directions.

Cool, so I go at it by trial-and-error. But here's another thing: there is no setOrientation method in Camera! : -)
Title: Re: Max Camera Matrix to JPCT
Post by: paulscode on September 28, 2010, 10:34:08 pm
Well, jPCT's up axis is -y, whereas worldspace up for max is +z. I accounted for that. Or do you mean something else?

No, I mean more like the x-axis you are using is equivalent to jPCT's z-axis.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 10:45:13 pm
I flipped the values now and, unfortunately, no cigar. I see nothing on screen.
Title: Re: Max Camera Matrix to JPCT
Post by: EgonOlsen on September 28, 2010, 10:49:54 pm
Cool, so I go at it by trial-and-error. But here's another thing: there is no setOrientation method in Camera! : -)
There is: http://www.jpct.net/doc/com/threed/jpct/Camera.html#setOrientation(com.threed.jpct.SimpleVector,%20com.threed.jpct.SimpleVector) (http://www.jpct.net/doc/com/threed/jpct/Camera.html#setOrientation(com.threed.jpct.SimpleVector,%20com.threed.jpct.SimpleVector))   Which version are you using ???
Title: Re: Max Camera Matrix to JPCT
Post by: paulscode on September 28, 2010, 10:52:56 pm
I flipped the values now and, unfortunately, no cigar. I see nothing on screen.
Is camera at 0,0,0?  If not, you'll need to subtract it from the converted vectors.  Also try reversing the sign of x, z, or both.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 10:58:00 pm
Quote
Which version are you using?

I had already updated it to 1.21 today to use the transformToGL() method, but I guess it was a Firefox caching thing. I see it now.

Quote
Is camera at 0,0,0?  If not, you'll need to subtract it from the converted vectors.  Also try reversing the sign of x, z, or both.

Cool, I'll try and be right back, thanks.
Title: Re: Max Camera Matrix to JPCT
Post by: AGP on September 28, 2010, 11:21:56 pm
OK, I tested all 12 possibilities for up vectors with setOrientation (12 because I tried flipping x and z as well). Nothing showed me anything. What I didn't try is flipping the x and z of setPosition, but that shouldn't be the difference between me seeing SOMETHING and nothing, right?
Title: Re: Max Camera Matrix to JPCT
Post by: paulscode on September 29, 2010, 12:05:54 am
That is very strange.  I can't imagine a scenario where you can see something then flipping the x and z coordinates in camera space of that thing plus the x and z values of the camera's look direction in camera space and no longer being able to see the thing - seems like that should always result in the equivalent of rotating the thing 90 degrees around its y-axis.  Obviously such a scenario exists in your case, so I guess it is just a limitation of my imagination..
Title: Re: Max Camera Matrix to JPCT
Post by: paulscode on September 29, 2010, 01:43:59 pm
Ok, give this a try (to see if my logic about flipping x and z in camera space to rotate the scene properly is incorrect).  Set up your scene as you did earlier where you can see the characters from looking sideways at the scene (i.e. comment out matrix thing, FOV to 45, position of camera -y/z flipped and camera.lookAt to the position of Max's camera's target).  Then call the following method:

Code: [Select]
    public void rotateScene90( Object3D[] sceneObjects, SimpleVector lookTarget, Camera camera )
    {
        SimpleVector sourcePosition, targetPosition, translation;
        for( int x = 0; x < sceneObjects.length; x++ )
        {
            // convert object's position into camera space:
            sourcePosition = new SimpleVector( sceneObjects[x].getTransformedCenter() );
            sourcePosition = sourcePosition.calcSub( camera.getPosition() );
            sourcePosition.matMul( camera.getBack() );
            // determine the new position (in camera space):
            targetPosition = new SimpleVector(sourcePosition.z, sourcePosition.y, sourcePosition.x );
            // convert new position into world space:
            targetPosition.matMul( camera.getBack().invert3x3() );
            targetPosition.add( camera.getPosition() );
            // translate to the new position:
            sceneObjects[x].translate( targetPosition.calcSub( sceneObjects[x].getTransformedCenter() ) );
        }

        // convert the look-target into camera space:
        sourcePosition = new SimpleVector( lookTarget );
        sourcePosition = sourcePosition.calcSub( camera.getPosition() );
        sourcePosition.matMul( camera.getBack() );
        // determine the new look-target (in camera space):
        targetPosition = new SimpleVector(sourcePosition.z, sourcePosition.y, sourcePosition.x );
        // convert the new look-target into world space:
        targetPosition.matMul( camera.getBack().invert3x3() );
        targetPosition.add( camera.getPosition() );

        // look toward the new look-target:
        SimpleVector look = targetPosition.calcSub( camera.getPosition() ).normalize();
        SimpleVector up = camera.getYAxis();
        up.scalarMul( -1 );  // Bug fix, shouldn't be necessary?  Try removing if scene is upside-down
        camera.setOrientation( look, up );
    }

Notice the bug fix for the setOrientation issue.  Depending on the scene, the call to up.scalarMul( -1 ) may or may not be necessary (remove it if the scene winds up upside-down).