iPhone and matrix palettes

This topic contains 9 replies, has 2 voices, and was last updated by  johnburkert 7 years, 9 months ago.

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #30019

    i am able to render the green guy from the skinning example in my current code base, however the pod files my artists are giving me (exported from maya) are not. the bone batch count is > 8 which means the program bonks when i try to render with matrix palettes on the iphone device. is there an export setting or is there something maya specific that needs to be done?

    #33640

    i would add that everything renders correctly in the emulator. i believe the bonk is the result of more than 8 matrix palettes on the iphone hardware.

    #33641

    warmi
    Member

    I think the POD exporter has an option to break up your model into different parts to handle more than whatever hardware limit you are facing in terms of available matrix palettes.

    It is all done more-less automatically (bone batches) …

    #33642

    thank you for the reply. i was able to get skinning working on the device by changing the export settings to the following:

    rendering is fine on the emulator and but on the iphone it has visual weirdness going on:

    below is the rendering code, almost exactly the same as the skinning example. does anyone have any insight into this?

    void PVRShot::DrawActor(PVRActor * actor)

    {

         CPVRTModelPOD * pModel = actor->GetMesh()->GetModel();

         

         glEnableClientState(GL_VERTEX_ARRAY);

         glEnableClientState(GL_NORMAL_ARRAY);

         glEnableClientState(GL_TEXTURE_COORD_ARRAY);

         for (int iNode = 0; iNode < (int)pModel->nNumMeshNode; ++iNode)

         {

              SPODNode * pNode = &pModel->pNode[iNode];

              SPODMesh * pMesh = &pModel->pMesh[pNode->nIdx];

              glBindBuffer(GL_ARRAY_BUFFER, actor->GetMesh()->GetVertexBuffer()[pNode->nIdx]);

              glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, actor->GetMesh()->GetIndexBuffer()[pNode->nIdx]);

              PVRTexture * pTex = actor->GetMesh()->GetTextures()[pNode->nIdxMaterial];

              if (pTex != NULL)

              {

                   glBindTexture(GL_TEXTURE_2D, pTex->GetTexId());

                   SPODMaterial * pMat = &pModel->pMaterial[pNode->nIdxMaterial];

                   myglMaterialv(GL_FRONT_AND_BACK, GL_AMBIENT, PVRTVec4(pMat->pfMatAmbient, f2vt(1.0f)).ptr());

                   myglMaterialv(GL_FRONT_AND_BACK, GL_DIFFUSE, PVRTVec4(pMat->pfMatDiffuse, f2vt(1.0f)).ptr());

              }

              bool bSkinning = (pMesh->sBoneWeight.pData != 0);

              glPushMatrix();

              {

                   myglMultMatrix(actor->GetTransform().f);

                   if (bSkinning)

                   {

                        glEnableClientState(GL_MATRIX_INDEX_ARRAY_OES);

                        glEnableClientState(GL_WEIGHT_ARRAY_OES);

                   }

                   glVertexPointer(pMesh->sVertex.n, VERTTYPEENUM, pMesh->sVertex.nStride, pMesh->sVertex.pData);

                   glNormalPointer(VERTTYPEENUM, pMesh->sNormals.nStride, pMesh->sNormals.pData);

                   glTexCoordPointer(pMesh->psUVW[0].n, VERTTYPEENUM, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);

                   if (bSkinning)

                   {

                        extensions->glMatrixIndexPointerOES(pMesh->sBoneIdx.n, GL_UNSIGNED_BYTE, pMesh->sBoneIdx.nStride, pMesh->sBoneIdx.pData);

                        extensions->glWeightPointerOES(pMesh->sBoneWeight.n, VERTTYPEENUM, pMesh->sBoneWeight.nStride, pMesh->sBoneWeight.pData);

                   }

                   int nStrip = 0;

                   int nOffset = 0;

                   for (int iBatch = 0; iBatch < pMesh->sBoneBatches.nBatchCnt; ++iBatch)

                   {

                        if (bSkinning)

                        {

                             glEnable(GL_MATRIX_PALETTE_OES);

                             glMatrixMode(GL_MATRIX_PALETTE_OES);

                             PVRTMat4 mBone;

                             int nNodeId;

                             const int nCount = pMesh->sBoneBatches.pnBatchBoneCnt[iBatch];

                             for (int j = 0; j < nCount; ++j)

                             {

                                  extensions->glCurrentPaletteMatrixOES(j);

                                  nNodeId = pMesh->sBoneBatches.pnBatches[iBatch * pMesh->sBoneBatches.nBatchBoneMax + j];

                                  pModel->GetBoneWorldMatrix(mBone, *pNode, pModel->pNode[nNodeId]);

                                  myglLoadMatrix((camera->GetTransform() * actor->GetTransform() * mBone).f);

                             }

                        }

                        else

                        {

                             glDisable(GL_MATRIX_PALETTE_OES);

                        }

                        glMatrixMode(GL_MODELVIEW);

                        int nTris;

                        if (iBatch + 1 < pMesh->sBoneBatches.nBatchCnt)

                        {

                             nTris = pMesh->sBoneBatches.pnBatchOffset[iBatch + 1] – pMesh->sBoneBatches.pnBatchOffset[iBatch];

                        }

                        else

                        {

                             nTris = pMesh->nNumFaces – pMesh->sBoneBatches.pnBatchOffset[iBatch];

                        }

                        if (pMesh->nNumStrips == 0)

                        {

                             glDrawElements(GL_TRIANGLES, nTris * 3, GL_UNSIGNED_SHORT, &((unsigned short *)0)[3 * pMesh->sBoneBatches.pnBatchOffset[iBatch]]);

                        }

                        else

                        {

                             int nTrisDrawn = 0;

                             while (nTrisDrawn < nTris)

                             {

                                  glDrawElements(GL_TRIANGLE_STRIP, pMesh->pnStripLength[nStrip] + 2, GL_UNSIGNED_SHORT, &((GLshort *)0)[nOffset]);

                                  nOffset += pMesh->pnStripLength[nStrip] + 2;

                                  nTrisDrawn += pMesh->pnStripLength[nStrip];

                                  

                                  ++nStrip;

                             }

                        }

                   }

                   if (bSkinning)

                   {

                        glDisableClientState(GL_MATRIX_INDEX_ARRAY_OES);

                        glDisableClientState(GL_WEIGHT_ARRAY_OES);

                        glDisable(GL_MATRIX_PALETTE_OES);

                   }

              }

              glPopMatrix();

         }

         glDisableClientState(GL_VERTEX_ARRAY);

         glDisableClientState(GL_NORMAL_ARRAY);

         glDisableClientState(GL_TEXTURE_COORD_ARRAY);

         glBindBuffer(GL_ARRAY_BUFFER, 0);

         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    }

    #33643

    the image links aren’t working.

    the image showing the maya exporter settings:

    http://img160.yfrog.com/i/pvrpod.png/

    the image showing rendering weirdness:

    http://img159.yfrog.com/i/20100105113338.jpg/

    #33644

    the above code correctly renders the man_float.pod from the skinning example. it is only with the pods that my artists export that this problem occurs.

    #33645

    warmi
    Member

    It is hard to say what is going on given a static blurry image…

    I am not even sure what is wrong there … the gun is not positioned correctly ?

    #33646

    there is no gun, it is a boxer

    #33647

    warmi
    Member

    Ah ok … it looks like parts of glove geometry don’t have weights assigned to them ( and thus are not being transformed )

    #33648

    this has been resolved. it was a maya/export problem. this is my artists explanation:

    As most people are aware, the iphone can only handle a max of 3 bone influences. Shaman however, can correctly display boned meshes with up to 4 inlfuences, which creates a disconnect between what you see in the previewer and the actual device.

    To properly export a boned, skinned, and animated 3d mesh that works on the device, follow these rules:

    1) You cannot use a straight rigid bind. It will not animate.

    2) When binding the skeleton to the mesh, use a max bone influence of 3. Do not maintain max influences after bind.

    3) When exporting, use these settings:

         X Export Geometry

         X Export materials

         – Fixed point

         

         X Export controllers

         

         OpenGL     

         X Normals

         – Vertex colours

         X Mapping CHannels

         – Flip V

         – Generate tangent-space

         X Interleave vectors

         X Export Matrices

         X Export skin modifiers

              MAx matrices: 8

         Triangle strips

              X Indexed

         PVRTGeometrySort

              X Sort vertices

    Under Vertex vector formats, change Bone indices to ‘unsigned byte’ and uncheck the box under ‘a3’. Leave Bone weights as ‘float’ and uncheck the box under ‘a3’. Your UVW settings may need to change based on your situation, but generally, you wont need UVW2 and up, so uncheck all the boxes for those. For UVW0 and 1, uncheck the boxes under ‘a2’.

    This should produce a working model for the device, tweak as neccesary for your needs.

Viewing 10 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic.