forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED & COMMITED]sceGumLookAt(vfpu) is broken

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Zettablade



Joined: 05 May 2006
Posts: 71

PostPosted: Sun Mar 04, 2007 4:44 pm    Post subject: [SOLVED & COMMITED]sceGumLookAt(vfpu) is broken Reply with quote

Just got the most recent update from the pspsdk's svn today. Apparently, there were some changes, and now sceGumLookAt from gum vfpu is working improperly. It severely warps the view. Just thought I'd point it out.
Sooo, if anyone would like to point out a viable solution, that would be awsome :)


Last edited by Zettablade on Mon Mar 05, 2007 4:52 am; edited 1 time in total
Back to top
View user's profile Send private message
Zettablade



Joined: 05 May 2006
Posts: 71

PostPosted: Sun Mar 04, 2007 11:18 pm    Post subject: Reply with quote

so, I've done a temp "fix", involving going back to the previous revisions code for sceGumLookAt _vfpu. A lot has changed between the new "broken" and the old stable code. I'll post the differences. I hope this issue is addressed in the next revision, as sceGumLookAt is a very useful function, and sceGum_vfpu, which may not be as fast as possible, is still faster then sceGum.

old, stable (vfpu)
Code:
#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   ScePspFMatrix4* t = GUM_ALIGNED_MATRIX();
   gumLoadIdentity(t);
   gumLookAt(t,eye,center,up);
   
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

   __asm__ volatile (
         "lv.q C000.q, 0 + %0\n"
         "lv.q C010.q, 16 + %0\n"
         "lv.q C020.q, 32 + %0\n"
         "lv.q C030.q, 48 + %0\n"
         "vmmul.q M100, M300, M000\n"
         "vmmov.q M300, M100\n"
   : : "m"(*t) );

   gum_current_matrix_update = 1;
}
#endif


new, "broken" (vfpu)
Code:
#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

    __asm__ volatile (
        "vmidt.q M100\n"
        // load eye, center, up vectors
        "ulv.q    C000, %0\n"
        "ulv.q    C010, %1\n"
        "ulv.q    C020, %2\n"
 
        // forward = center - eye
        "vsub.t  R102, C010, C000\n"
 
         // normalize forward
        "vdot.t  S033, R102, R102\n"
        "vrcp.s  S033, S033\n"
        "vscl.t  R102, R102, S033\n"
 
         // side = forward cross up
        "vcrsp.t R100, R102, C020\n"
        "vdot.t  S033, R100, R100\n"
        "vrcp.s  S003, S033\n"
        "vscl.t  R100, R100, S033\n"
 
         // lup = side cross forward
        "vcrsp.t R101, R100, R102\n"
        "vneg.t  R102, R102\n"
 
        "vmidt.q M200\n"
        "vneg.t  C230, C000\n"
   "vmmul.q M300, M100, M200\n"
    : : "m"(*eye), "m"(*center), "m"(*up));

   gum_current_matrix_update = 1;
}
#endif


current, stable (c implementation)
Code:
#ifdef F_gumLookAt
void gumLookAt(ScePspFMatrix4* m, ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   ScePspFVector3 forward, side, lup,ieye;
   ScePspFMatrix4 t;

   forward.x = center->x - eye->x;
   forward.y = center->y - eye->y;
   forward.z = center->z - eye->z;

   gumNormalize(&forward);

   gumCrossProduct(&side,&forward,up);
   gumNormalize(&side);

   gumCrossProduct(&lup,&side,&forward);
   gumLoadIdentity(&t);

   t.x.x = side.x;
   t.y.x = side.y;
   t.z.x = side.z;

   t.x.y = lup.x;
   t.y.y = lup.y;
   t.z.y = lup.z;

   t.x.z = -forward.x;
   t.y.z = -forward.y;
   t.z.z = -forward.z;

   ieye.x = -eye->x; ieye.y = -eye->y; ieye.z = -eye->z;
   gumMultMatrix(m,m,&t);
   gumTranslate(m,&ieye);
}
#endif

#ifdef F_sceGumLookAt
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   gumLookAt(gum_current_matrix,eye,center,up);
   gum_current_matrix_update = 1;
}
#endif


Last edited by Zettablade on Mon Mar 05, 2007 12:00 am; edited 1 time in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sun Mar 04, 2007 11:28 pm    Post subject: Reply with quote

Zettablade wrote:

new, "broken" (vfpu)
Code:
#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

    __asm__ volatile (
        "vmidt.q M100\n"
        // load eye, center, up vectors
        "ulv.q    C000, %0\n"
        "ulv.q    C010, %1\n"
        "ulv.q    C020, %2\n"
 
        // forward = center - eye
        "vsub.t  R102, C010, C000\n"
 
         // normalize forward
        "vdot.t  S033, R102, R102\n"
        "vrcp.s  S033, S033\n"
        "vscl.t  R102, R102, S033\n"
 
         // side = forward cross up
        "vcrsp.t R100, R102, C020\n"
        "vdot.t  S033, R100, R100\n"
        ---------->>> "vrcp.s  S003, S033\n" <<<-----------
        ---------->>> "vscl.t  R100, R100, S033\n" <<<-----------
 
         // lup = side cross forward
        "vcrsp.t R101, R100, R102\n"
        "vneg.t  R102, R102\n"
 
        "vmidt.q M200\n"
        "vneg.t  C230, C000\n"
   "vmmul.q M300, M100, M200\n"
    : : "m"(*eye), "m"(*center), "m"(*up));

   gum_current_matrix_update = 1;
}
#endif


the line "vscl.t R100, R100, S033\n" should be "vscl.t R100, R100, S003\n"

or

the "vrcp.s S003, S033\n" should be "vrcp.s S033, S033\n", which I think to be the correct one.
Back to top
View user's profile Send private message
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Sun Mar 04, 2007 11:56 pm    Post subject: Reply with quote

I'll take a closer look at this asap. I got the code from MrMr[iCE] and I tested the changed sceGumPerspective() so that it worked, I'll go through the math on the other changes more thoroughly.
_________________
GE Dominator
Back to top
View user's profile Send private message
Zettablade



Joined: 05 May 2006
Posts: 71

PostPosted: Mon Mar 05, 2007 12:00 am    Post subject: Reply with quote

chp wrote:
I'll take a closer look at this asap. I got the code from MrMr[iCE] and I tested the changed sceGumPerspective() so that it worked, I'll go through the math on the other changes more thoroughly.

Awsome, thx, and keep up the good work.
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Mon Mar 05, 2007 1:44 am    Post subject: Reply with quote

MrMrICE forgot that normalization involves the reciprocal square root of the vector length :) So exchange vrcp.s with vrsq.s and it should work.
Also, after the crossproduct of side and forward to fix the up vector, shouldn't that be normalized again afterwards? IIRC the cross of two unit vectors needs not necessarily be a unit vector again. Could be wrong though.

Regards.


EDIT:
Code:

#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

    __asm__ volatile (
        "vmidt.q M100\n"
        // load eye, center, up vectors
        "ulv.q    C000, %0\n"
        "ulv.q    C010, %1\n"
        "ulv.q    C020, %2\n"
 
        // forward = center - eye
        "vsub.t  R102, C010, C000\n"
 
         // normalize forward
        "vdot.t  S033, R102, R102\n"
        "vrsq.s  S033, S033\n"
        "vscl.t  R102, R102, S033\n"
 
         // side = forward cross up
        "vcrsp.t R100, R102, C020\n"
        "vdot.t  S033, R100, R100\n"
        "vrsq.s  S033, S033\n"
        "vscl.t  R100, R100, S033\n"
 
         // lup = side cross forward
        "vcrsp.t R101, R100, R102\n"

        "vneg.t  R102, R102\n"
 
        "vmidt.q M200\n"
        "vneg.t  C230, C000\n"
   "vmmul.q M300, M100, M200\n"
    : : "m"(*eye), "m"(*center), "m"(*up));

   gum_current_matrix_update = 1;
}
#endif


EDIT2: I was wrong, the renormalization of the up vector is NOT necessary. I removed that code.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl


Last edited by Raphael on Mon Mar 05, 2007 2:20 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Zettablade



Joined: 05 May 2006
Posts: 71

PostPosted: Mon Mar 05, 2007 1:54 am    Post subject: Reply with quote

Raphael wrote:

Code:

#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

    __asm__ volatile (
        "vmidt.q M100\n"
        // load eye, center, up vectors
        "ulv.q    C000, %0\n"
        "ulv.q    C010, %1\n"
        "ulv.q    C020, %2\n"
 
        // forward = center - eye
        "vsub.t  R102, C010, C000\n"
 
         // normalize forward
        "vdot.t  S033, R102, R102\n"
        "vrsq.s  S033, S033\n"
        "vscl.t  R102, R102, S033\n"
 
         // side = forward cross up
        "vcrsp.t R100, R102, C020\n"
        "vdot.t  S033, R100, R100\n"
        "vrsq.s  S033, S033\n"
        "vscl.t  R100, R100, S033\n"
 
         // lup = side cross forward
        "vcrsp.t R101, R100, R102\n"
        // not sure if following three lines really needed:
        "vdot.t S033, R101, R101\n"
        "vrsq.s S003, S033\n"
        "vscl.t R101, R101, S033\n"

        "vneg.t  R102, R102\n"
 
        "vmidt.q M200\n"
        "vneg.t  C230, C000\n"
   "vmmul.q M300, M100, M200\n"
    : : "m"(*eye), "m"(*center), "m"(*up));

   gum_current_matrix_update = 1;
}
#endif


Tested an it works perfectly! But here's the modfied code. This should go in the svn...

Code:
#ifdef F_sceGumLookAt_vfpu
void sceGumLookAt(ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up)
{
   pspvfpu_use_matrices(gum_vfpucontext, VMAT3, VMAT0 | VMAT1);

   __asm__ volatile (
      "vmidt.q M100\n"
      // load eye, center, up vectors
      "ulv.q    C000, %0\n"
      "ulv.q    C010, %1\n"
      "ulv.q    C020, %2\n"

      // forward = center - eye
      "vsub.t  R102, C010, C000\n"

      // normalize forward
      "vdot.t  S033, R102, R102\n"
      "vrsq.s  S033, S033\n"
      "vscl.t  R102, R102, S033\n"

      // side = forward cross up
      "vcrsp.t R100, R102, C020\n"
      "vdot.t  S033, R100, R100\n"
      "vrsq.s  S033, S033\n"
      "vscl.t  R100, R100, S033\n"

      // lup = side cross forward
      "vcrsp.t R101, R100, R102\n"

      "vneg.t  R102, R102\n"

      "vmidt.q M200\n"
      "vneg.t  C230, C000\n"
      "vmmul.q M300, M100, M200\n"
   : : "m"(*eye), "m"(*center), "m"(*up));

   gum_current_matrix_update = 1;
}
#endif


There you go! Put that in the svn!


Last edited by Zettablade on Mon Mar 05, 2007 2:07 am; edited 1 time in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 05, 2007 2:02 am    Post subject: Reply with quote

Raphael wrote:

Code:

         // lup = side cross forward
        "vcrsp.t R101, R100, R102\n"
        // not sure if following three lines really needed:
        "vdot.t S033, R101, R101\n"
        "vrsq.s S003, S033\n"
        "vscl.t R101, R101, S033\n"


in the C version, this normalization is not present so you should be right. By the way, S003 meseems to be still wrong (should be S033 if this normalization makes sense).

the result of a cross-product of two normalized vectors should be normalized.
Back to top
View user's profile Send private message
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Mon Mar 05, 2007 2:06 am    Post subject: Reply with quote

If you use two normalised vectors to do the cross product, you will get a normalised vector as a result. I don't have the proof readily around, but that's the way it is. :) I'll change the usage vrcp.s into vrsq.s like you did (excluding the last normalisation) and commit.
_________________
GE Dominator
Back to top
View user's profile Send private message
Zettablade



Joined: 05 May 2006
Posts: 71

PostPosted: Mon Mar 05, 2007 2:09 am    Post subject: Reply with quote

chp wrote:
If you use two normalised vectors to do the cross product, you will get a normalised vector as a result. I don't have the proof readily around, but that's the way it is. :) I'll change the usage vrcp.s into vrsq.s like you did (excluding the last normalisation) and commit.
Glad this is over with now. It was worth staying up all night!
Back to top
View user's profile Send private message
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Mon Mar 05, 2007 2:15 am    Post subject: Reply with quote

At closer examination the code for sceGumLookAt() is not properly written to be used in the matrix stack. I'll take a closer look at it soon, but for now the older version is back in.
_________________
GE Dominator
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Mon Mar 05, 2007 2:31 am    Post subject: Reply with quote

Yeah, I did the proof myself to get sure :) (wiki didn't spit out a fact about it).
Should be ok though, because behaviour is same as stable vfpu version (writing resulting matrix to M300 and setting gum_update_current_matrix).
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 05, 2007 2:34 am    Post subject: Reply with quote

chp wrote:
If you use two normalised vectors to do the cross product, you will get a normalised vector as a result. I don't have the proof readily around, but that's the way it is. :)


in theory, yes. If you just try to normalized several vectors initially then cross-product the results in a loop without subsequent normalizations, you may get a degradation in the long run due to the limitation of float precision. This is why when computing with quaternions, you need to normalize vectors as soon as possible to avoid degradation in the long run.

But here, it shouldn't be a problem.
Back to top
View user's profile Send private message
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Mon Mar 05, 2007 8:16 am    Post subject: Reply with quote

Indeed, float-precision is always a problem, but normalizing the vector after a single cross-product is a slight overkill. If only all math could be in perfect precision. ;)
_________________
GE Dominator
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Mon Mar 05, 2007 9:46 am    Post subject: Reply with quote

chp, I just noticed what you meant with wrong application of the matrices. The original version was supposed to multiplicate the new lookAt matrix into the current M300 matrix. Should just need an additional vmmul.q, no?

Code:

    "vmmul.q M200, M300, M200\n"
    "vmmul.q M300, M100, M200\n"


BTW: chp, is there a specific reason as to why sceGuLookAt/Perspective/Ortho multiplicate the result into the current matrix on stack, rather than replace it? I think OpenGL does that too, but I just can't seem to find any use in it (especially since we have three status matrices on PSP). I know they aren't time critical functions so it shouldn't matter, but I was just wondering.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 05, 2007 4:14 pm    Post subject: Reply with quote

Raphael wrote:
chp, I just noticed what you meant with wrong application of the matrices. The original version was supposed to multiplicate the new lookAt matrix into the current M300 matrix. Should just need an additional vmmul.q, no?

Code:

    "vmmul.q M200, M300, M200\n"
    "vmmul.q M300, M100, M200\n"


BTW: chp, is there a specific reason as to why sceGuLookAt/Perspective/Ortho multiplicate the result into the current matrix on stack, rather than replace it? I think OpenGL does that too, but I just can't seem to find any use in it (especially since we have three status matrices on PSP). I know they aren't time critical functions so it shouldn't matter, but I was just wondering.


huh, i'm not sure "vmmul.q *M200*, M300, *M200*\n" would work because if i'm not wrong MD must be different from MS and MT (you cannot do a matrix product inplace).

And by the way, if you look at sceGumLookAt more thoroughly (which calls gumLookAt), it happens that a matrix identity always loaded in M300 before so it is like you replace it at the end indeed, so I think you dont need to have two multiplications here.
Back to top
View user's profile Send private message
chp



Joined: 23 Jun 2004
Posts: 313

PostPosted: Mon Mar 05, 2007 6:29 pm    Post subject: Reply with quote

It is not unthinkable that someone would like to do more than one projection-step, and I don't want to be the one telling them "no, because we didn't want to allow that flexibility". :)

And hlide, if you look more closely at the sceGumLookAt()-code in pspgum_vfpu.c, it loads the resulting matrix into registers and multiplies with the current one. gumLoadIdentity() does not load into vfpu-registers, it's writing directly to memory (sceGumLoadIdentity() would touch the registers).

The approach I'll look at rewriting it will make it use only one vmmul.q anyway, it's all about ordering and the vfpu is flexible.
_________________
GE Dominator
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Mon Mar 05, 2007 7:59 pm    Post subject: Reply with quote

That's what I thought :) thanks for the answer
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group