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 

Quaternions

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



Joined: 03 Apr 2007
Posts: 73

PostPosted: Fri Apr 04, 2008 12:32 pm    Post subject: Quaternions Reply with quote

Alright, quaternion support has been added to the .x loader! I tried applying quaternions loaded from an .x file to my transformation matrices. Eventually, I'll be working with interpolated animation that will drastically cut down on key-frames needed, but so far, no go.. I'm pretty close though.

Here's my code for applying a quaternion to a matrix that I multiply with a translation and scale matrix:
Code:

if(NumAnimations > 0) {
      ScePspFMatrix4 mat;
      for(int i=0;i<Animations[0].NumFrames;i++) {
         Animations[0].Frames[i].Keys = new ScePspFMatrix4[Animations[0].Frames[i].NumKeys];
         
         for(int e=0;e<Animations[0].Frames[i].NumKeys;e++) {
            gumLoadIdentity(&mat);
            gumLoadIdentity(&Animations[0].Frames[i].Keys[e]);


            // manually plug the quaternion into the matrix
            mat.x.x =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) +
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) -
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) -
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            mat.x.y =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].y) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].z);
            mat.x.z =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].z) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].y);


            mat.y.x =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].y) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].z);
            mat.y.y =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) +
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) -
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) -
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            mat.y.z =
                  (2.0f * Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].z) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].x);


            mat.z.x =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].z) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].y);
            mat.z.y =
                  (2.0f * Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].z) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].x);
            mat.z.z =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) +
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) -
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) -
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            
            gumMultMatrix(&Animations[0].Frames[i].Keys[e], &mat, &Animations[0].Frames[i].Keys[e]);
            gumTranslate(&Animations[0].Frames[i].Keys[e], Animations[0].Frames[i].translate);
            //gumScale(&Animations[0].Frames[i].Keys[e], Animations[0].Frames[i].scale);
         }
      }
   }


This is a pretty crude application, but it is just to see if it works. There's no concern for performance or memory savings here. As soon as this works, I'll get quaternion interpolation to work, and move on from there. I was looking at how Raphael converted his quaternions to matrices with the triEngine, but it is all done in VFPU, and I don't understand that yet. I need to learn that already...

Anyway, the motion appears to be correct from what it looks like. For some reason, all the boxes attached to my biped model are squashed, but they do appear to move, and from what it looks like, rotate the right way. If anyone has any suggestions, I'm more than happy to hear them! =)

EDIT: Never mind about what I said earlier about the motion. It is wrong!
Back to top
View user's profile Send private message
Vincent_M



Joined: 03 Apr 2007
Posts: 73

PostPosted: Fri Apr 04, 2008 12:45 pm    Post subject: Reply with quote

Sorry for posting twice, but this is kinda huge. I think I solved the problem. Here's my code:
Code:

   if(NumAnimations > 0) {
      ScePspFMatrix4 mat;
      printf("number of frames: %i\n", Animations[0].NumFrames);
      for(int i=0;i<Animations[0].NumFrames;i++) {
         Animations[0].Frames[i].Keys = new ScePspFMatrix4[Animations[0].Frames[i].NumKeys];
         
         for(int e=0;e<Animations[0].Frames[i].NumKeys;e++) {
            gumLoadIdentity(&mat);
            gumLoadIdentity(&Animations[0].Frames[i].Keys[e]);


            // manually plug the quaternion into the matrix
            mat.x.x =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) +
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) -
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) -
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            mat.x.y =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].y) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].z);
            mat.x.z =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].z) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].y);
            mat.x.w = 0.0f;


            mat.y.x =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].y) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].z);
            mat.y.y =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) -
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) +
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) -
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            mat.y.z =
                  (2.0f * Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].z) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].x);
            mat.y.w = 0.0f;


            mat.z.x =
                  (2.0f * Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].z) -
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].y);
            mat.z.y =
                  (2.0f * Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].z) +
                  (2.0f * Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].x);
            mat.z.z =
                  (Animations[0].Frames[i].quaternion[e].w * Animations[0].Frames[i].quaternion[e].w) -
                  (Animations[0].Frames[i].quaternion[e].x * Animations[0].Frames[i].quaternion[e].x) -
                  (Animations[0].Frames[i].quaternion[e].y * Animations[0].Frames[i].quaternion[e].y) +
                  (Animations[0].Frames[i].quaternion[e].z * Animations[0].Frames[i].quaternion[e].z);
            mat.z.w = 0.0f;
            
            mat.w.x = 0.0f;
            mat.w.y = 0.0f;
            mat.w.z = 0.0f;
            mat.w.w = 1.0f;

            gumTranslate(&Animations[0].Frames[i].Keys[e], Animations[0].Frames[i].translate);
            gumMultMatrix(&Animations[0].Frames[i].Keys[e], &Animations[0].Frames[i].Keys[e], &mat);
            gumScale(&Animations[0].Frames[i].Keys[e], Animations[0].Frames[i].scale);
         }
      }
   }


I'm posting this just in case anyone has any suggestions on applying quaternions to matrices and combining that new rotation matrix with a translation and scale matrix. That, and it could help others in the future once I know for sure that this is right. ;)
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sat Apr 05, 2008 8:44 am    Post subject: Reply with quote

huh, mrmr[ice]'s libvfpumath deals quaternions with vfpu. You should have a look into it.
Back to top
View user's profile Send private message
Vincent_M



Joined: 03 Apr 2007
Posts: 73

PostPosted: Tue Apr 08, 2008 12:14 pm    Post subject: Reply with quote

Hmm... I'm going to check it out. I have interpolated implemented through my own way, but I think there is a small error. All orientations are perfect except that some of the objects scale down to 0.0f and then back up to 1,0f even though all scale keys are set to 1.0f. The scaling is implemented correctly, so it has nothing to do with that. This glitch happens the same way even when I don't even apply scaling. This did not happen when I was using pure key frames and not scaling at all.

Here's my code:
Code:

// set the start and end elements
startQuat = model->FrameArray[e]->AnimationFrame->quaternionKey[currentKey].quaternion;
endQuat   = model->FrameArray[e]->AnimationFrame->quaternionKey[currentKey+1].quaternion;
                        
startScale = model->FrameArray[e]->AnimationFrame->scaleKey[currentKey].scale;
endScale   = model->FrameArray[e]->AnimationFrame->scaleKey[currentKey+1].scale;
                        
startTrans = model->FrameArray[e]->AnimationFrame->translationKey[currentKey].translate;
endTrans   = model->FrameArray[e]->AnimationFrame->translationKey[currentKey+1].translate;

t = (float)(frameNum - interStart) / (float)(interEnd - interStart);

// setup the interpolated quaternion
quaternion.x = startQuat.x + ((endQuat.x - startQuat.x) * t);
quaternion.y = startQuat.y + ((endQuat.y - startQuat.y) * t);
quaternion.z = startQuat.z + ((endQuat.z - startQuat.z) * t);
quaternion.w = startQuat.w + ((endQuat.w - startQuat.w) * t);
                        
// setup the interpolated translation
interTrans.x = startTrans.x + ((endTrans.x - startTrans.x) * t);
interTrans.y = startTrans.y + ((endTrans.y - startTrans.y) * t);
interTrans.z = startTrans.z + ((endTrans.z - startTrans.z) * t);
                        
// setup the interpolated scale
interScale.x = startScale.x + ((endScale.x - startScale.x) * t);
interScale.y = startScale.y + ((endScale.y - startScale.y) * t);
interScale.z = startScale.z + ((endScale.z - startScale.z) * t);


The code above is the actual interpolation happening. I apply the interpolated keys to the matrix just as I did above.
Back to top
View user's profile Send private message
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