⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winmain.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    CombineTransformation(&Bones[0], &matIdentity);
  }

  // Open the target file
  if((fp_out = fopen(DestFilename, "wb"))==NULL)
    return FALSE;

  // Write the target .X file header and templates
  fprintf(fp_out, "xof 0303txt 0032\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "// This file was created with MeshConv (c) 2003 by Jim Adams\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "template XSkinMeshHeader {\r\n");
  fprintf(fp_out, " <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\r\n");
  fprintf(fp_out, " WORD nMaxSkinWeightsPerVertex;\r\n");
  fprintf(fp_out, " WORD nMaxSkinWeightsPerFace;\r\n");
  fprintf(fp_out, " WORD nBones;\r\n");
  fprintf(fp_out, "}\r\n");
  fprintf(fp_out, "\r\n");
  fprintf(fp_out, "template SkinWeights {\r\n");
  fprintf(fp_out, " <6f0d123b-bad2-4167-a0d0-80224f25fabb>\r\n");
  fprintf(fp_out, " STRING transformNodeName;\r\n");
  fprintf(fp_out, " DWORD nWeights;\r\n");
  fprintf(fp_out, " array DWORD vertexIndices[nWeights];\r\n");
  fprintf(fp_out, " array FLOAT weights[nWeights];\r\n");
  fprintf(fp_out, " Matrix4x4 matrixOffset;\r\n");
  fprintf(fp_out, "}\r\n");
  fprintf(fp_out, "\r\n");

  // Write out bone hierarchy if it exists
  char Indent[256]; Indent[0] = 0;
  if(msNumBones) {
    // Write root frame and recursively write out remaining
    WriteFrame(&Bones[0], fp_out, 0, FALSE);

    // Don't close out last frame - stick mesh into it
    strcpy(Indent, "  ");
  }

  // Name the mesh by clipping out mesh filename (without path and extension)
  char *NamePtr = strrchr(SrcFilename, '\\');
  if(!NamePtr)
    NamePtr= &SrcFilename[0];
  else 
    NamePtr++;
  char MeshName[MAX_PATH];
  for(i=0;i<strlen(NamePtr)+1;i++) {
    if(NamePtr[i] == 32 || NamePtr[i] == '.')
      MeshName[i] = '_';
    else
      MeshName[i] = NamePtr[i];
  }

  // Write out mesh header
  fprintf(fp_out, "%sMesh %s {\r\n", Indent, MeshName);

  // Write out vertices
  fprintf(fp_out, "%s  %lu;\r\n", Indent, NumMeshVertices);
  for(i=0;i<NumMeshVertices;i++) {
    fprintf(fp_out, "%s  %06lf;%06lf;%06lf;", Indent, Vertices[i].x, Vertices[i].y, Vertices[i].z);
    if(i < (NumMeshVertices-1))
      fprintf(fp_out, ",\r\n");
    else
      fprintf(fp_out, ";\r\n");
  }

  // Write out face data
  fprintf(fp_out, "%s  %lu;\r\n", Indent, msNumFaces);
  for(i=0;i<msNumFaces;i++) {
    fprintf(fp_out, "%s  3;%lu,%lu,%lu;", Indent, Faces[i*3], Faces[i*3+2], Faces[i*3+1]);
    if(i < ((DWORD)msNumFaces-1))
      fprintf(fp_out, ",\r\n");
    else
      fprintf(fp_out, ";\r\n");
  }

  // Write out normal data
  fprintf(fp_out, "%s  MeshNormals {\r\n", Indent);
  fprintf(fp_out, "%s    %lu;\r\n", Indent, NumMeshVertices);
  for(i=0;i<NumMeshVertices;i++) {
    fprintf(fp_out, "%s    %06lf;%06lf;%06lf;", Indent, Vertices[i].nx, Vertices[i].ny, Vertices[i].nz);
    if(i == (NumMeshVertices-1))
      fprintf(fp_out, ";\r\n");
    else
      fprintf(fp_out, ",\r\n");
  }
  fprintf(fp_out, "%s    %lu;\r\n", Indent, msNumFaces);
  for(i=0;i<msNumFaces;i++) {
    fprintf(fp_out, "%s    3;%lu,%lu,%lu;", Indent, Faces[i*3], Faces[i*3+2], Faces[i*3+1]);
    if(i < ((DWORD)msNumFaces-1))
      fprintf(fp_out, ",\r\n");
    else
      fprintf(fp_out, ";\r\n");
  }
  fprintf(fp_out, "  }\r\n");

  // Write mesh material list
  fprintf(fp_out, "%s  MeshMaterialList {\r\n", Indent);
  fprintf(fp_out, "%s    %lu;\r\n", Indent, msNumMaterials);
  fprintf(fp_out, "%s    %lu;\r\n", Indent, msNumFaces);
  for(i=0;i<msNumFaces;i++) {
    fprintf(fp_out, "%s    %lu", Indent, msGroups[msFaces[i].GroupIndex].Material);
    if(i < ((DWORD)msNumFaces-1))
      fprintf(fp_out, ",\r\n");
    else
      fprintf(fp_out, ";\r\n");
  }

  // Write materials
  for(i=0;i<msNumMaterials;i++) {
    fprintf(fp_out, "%s    Material {\r\n", Indent);
    fprintf(fp_out, "%s      %06lf;%06lf;%06lf;%06lf;;\r\n", Indent, msMaterials[i].Diffuse[0], msMaterials[i].Diffuse[1], msMaterials[i].Diffuse[2], msMaterials[i].Diffuse[3]);
    fprintf(fp_out, "%s      %06lf;\r\n", Indent, msMaterials[i].Shininess);
    fprintf(fp_out, "%s      %06lf;%06lf;%06lf;%06lf;;\r\n", Indent, msMaterials[i].Specular[0], msMaterials[i].Specular[1], msMaterials[i].Specular[2]);
    fprintf(fp_out, "%s      %06lf;%06lf;%06lf;%06lf;;\r\n", Indent, msMaterials[i].Emissive[0], msMaterials[i].Emissive[1], msMaterials[i].Emissive[2]);

    // Write texture filename
    if(msMaterials[i].Texture[0]) {
      fprintf(fp_out, "%s      TextureFileName {\r\n", Indent);

      // Only write out local filenames
      char *Ptr = strrchr(msMaterials[i].Texture, '\\');
      if(!Ptr)
        Ptr = msMaterials[i].Texture;
      else
        Ptr++;
      fprintf(fp_out, "%s        %c%s%c;\r\n", Indent, '"', Ptr, '"');
      fprintf(fp_out, "%s      }\r\n", Indent);
    }

    fprintf(fp_out, "%s    }\r\n", Indent);
  }
  fprintf(fp_out, "%s  }\r\n", Indent);

  // Write mesh texture coordinates
  fprintf(fp_out, "%s  MeshTextureCoords {\r\n", Indent);
  fprintf(fp_out, "%s    %lu;\r\n", Indent, NumMeshVertices);
  for(i=0;i<NumMeshVertices;i++) {
    fprintf(fp_out, "%s    %06lf;%06lf;", Indent, Vertices[i].u, Vertices[i].v);
    if(i < (NumMeshVertices-1))
      fprintf(fp_out, ",\r\n");
    else
      fprintf(fp_out, ";\r\n");
  }
  fprintf(fp_out, "%s  }\r\n", Indent);

  // Count the number of bones actually used
  DWORD NumBonesUsed = 0;
  for(i=0;i<msNumBones;i++) {
    for(j=0;j<NumMeshVertices;j++) {
      if(Vertices[j].BoneNum == i) {
        NumBonesUsed++;
        break;
      }
    }
  }

  // Write bone data (if any)
  if(NumBonesUsed) {

    // Write skin weight header
    fprintf(fp_out, "%s  XSkinMeshHeader {\r\n", Indent);
    fprintf(fp_out, "%s    2;\r\n", Indent);
    fprintf(fp_out, "%s    4;\r\n", Indent);
    fprintf(fp_out, "%s    %lu;\r\n", Indent, NumBonesUsed);
    fprintf(fp_out, "%s  }\r\n", Indent);

    // Write out skin weights
    for(i=0;i<msNumBones;i++) {

      // Count number of vertices attached
      DWORD Count = 0;
      for(j=0;j<NumMeshVertices;j++) {
        if(Vertices[j].BoneNum == i)
          Count++;
      }

      if(Count) {

        fprintf(fp_out, "%s  SkinWeights {\r\n", Indent);
        fprintf(fp_out, "%s    %c%s%c;\r\n", Indent, '"', Bones[i].Name, '"');
        fprintf(fp_out, "%s    %lu;\r\n", Indent, Count);
      
        // Write vertex indices
        DWORD Num=0;
        for(j=0;j<NumMeshVertices;j++) {
          if(Vertices[j].BoneNum == i) {
            fprintf(fp_out, "%s    %lu", Indent, j);
            if(Num < (Count-1))
              fprintf(fp_out, ",\r\n");
            else 
              fprintf(fp_out, ";\r\n");
            Num++;
          }
        }

        // Write weights
        for(j=0;j<Count;j++) {
          fprintf(fp_out, "%s    1.000000", Indent);
          if(j < (Count-1))
            fprintf(fp_out, ",\r\n");
          else 
            fprintf(fp_out, ";\r\n");
        }

        // Write inverse bone matrix
        fprintf(fp_out, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  Indent, Bones[i].matInvCombined._11, Bones[i].matInvCombined._12, Bones[i].matInvCombined._13, Bones[i].matInvCombined._14);
        fprintf(fp_out, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  Indent, Bones[i].matInvCombined._21, Bones[i].matInvCombined._22, Bones[i].matInvCombined._23, Bones[i].matInvCombined._24);
        fprintf(fp_out, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  Indent, Bones[i].matInvCombined._31, Bones[i].matInvCombined._32, Bones[i].matInvCombined._33, Bones[i].matInvCombined._34);
        fprintf(fp_out, "%s    %06lf,%06lf,%06lf,%06lf;;\r\n", Indent, Bones[i].matInvCombined._41, Bones[i].matInvCombined._42, Bones[i].matInvCombined._43, Bones[i].matInvCombined._44);

        // Clear data object
        fprintf(fp_out, "%s  }\r\n", Indent);
      }
    }
  }

  // Close mesh data object
  fprintf(fp_out, "%s}\r\n", Indent);

  // Close frame hierarchy (if any)
  if(msNumBones)
    fprintf(fp_out, "}\r\n");

  // Output keyframes (if any)
  if(msTotalFrames) {

    // Add a space to seperate frame/mesh data from animation data
    fprintf(fp_out, "\r\n");

    // Output animation set data object 
    fprintf(fp_out, "AnimationSet %s_Anim {\r\n", MeshName);

    // Go through each bone and look for ones that have keys
    for(i=0;i<msNumBones;i++) {
      
      // Write animation data object is bone has keyframes
      if(msBones[i].Header.NumRotFrames || msBones[i].Header.NumPosFrames) {

        // Write animation data object header
        fprintf(fp_out, "  Animation %s_Anim {\r\n", Bones[i].Name);
        fprintf(fp_out, "    {%s}\r\n", Bones[i].Name);

        // Write keyframes
        fprintf(fp_out, "    AnimationKey {\r\n");
        fprintf(fp_out, "      4;\r\n");
        fprintf(fp_out, "      %lu;\r\n", msBones[i].Header.NumRotFrames);

        for(j=0;j<msBones[i].Header.NumPosFrames;j++) {
          fprintf(fp_out, "      %lu;16;\r\n", (DWORD)(msAnimationFPS * msBones[i].RotKeyFrames[j].Time)-1);

          // Build a transformation matrix based off values
          D3DXMATRIX matAnim, matRotation, matTranslation;
          CreateYawPitchRollRotationMatrix(&matRotation,
                                           msBones[i].RotKeyFrames[j].Value[1],
                                           msBones[i].RotKeyFrames[j].Value[0],
                                           -msBones[i].RotKeyFrames[j].Value[2]);
          D3DXMatrixTranslation(&matTranslation,
                                msBones[i].PosKeyFrames[j].Value[0],
                                msBones[i].PosKeyFrames[j].Value[1],
                                -msBones[i].PosKeyFrames[j].Value[2]);
          matAnim = matRotation * matTranslation;

          // Combine animation transformation w/bone transformation
          matAnim *= Bones[i].matTransformation;

          // Write transformation matrix
          fprintf(fp_out, "      %06lf,%06lf,%06lf,%06lf,\r\n",  matAnim._11, matAnim._12, matAnim._13, matAnim._14);
          fprintf(fp_out, "      %06lf,%06lf,%06lf,%06lf,\r\n",  matAnim._21, matAnim._22, matAnim._23, matAnim._24);
          fprintf(fp_out, "      %06lf,%06lf,%06lf,%06lf,\r\n",  matAnim._31, matAnim._32, matAnim._33, matAnim._34);
          fprintf(fp_out, "      %06lf,%06lf,%06lf,%06lf;;\r\n", matAnim._41, matAnim._42, matAnim._43, matAnim._44);
        }

        // Close keyframe data object
        fprintf(fp_out, "    }\r\n");
      }

      // Close animation data object
      fprintf(fp_out, "  }\r\n");
    }

    // Close animation set data object
    fprintf(fp_out, "}\r\n");
  }

  // Close files
  fclose(fp_out);
  fclose(fp_in);

  // Release all used data
  delete [] Vertices;
  delete [] Faces;
  delete [] msVertices;
  delete [] msFaces;
  delete [] msGroups;
  delete [] msMaterials;
  delete [] msBones;

  // Return success
  return TRUE;
}

void WriteFrame(sMS3DBoneContainer *Bone, FILE *fp, DWORD Indent, BOOL Close)
{
  char IndentText[256];
  
  // Write siblings
  if(Bone->Sibling)
    WriteFrame(Bone->Sibling, fp, Indent, TRUE);

  // Create some bit of text to indent frame information
  memset(IndentText, 32, 256);
  IndentText[Indent] = 0;

  // Write frame data object
  fprintf(fp, "%sFrame %s {\r\n", IndentText, Bone->Name);
  fprintf(fp, "%s  FrameTransformMatrix {\r\n", IndentText);
  fprintf(fp, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  IndentText, Bone->matTransformation._11, Bone->matTransformation._12, Bone->matTransformation._13, Bone->matTransformation._14);
  fprintf(fp, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  IndentText, Bone->matTransformation._21, Bone->matTransformation._22, Bone->matTransformation._23, Bone->matTransformation._24);
  fprintf(fp, "%s    %06lf,%06lf,%06lf,%06lf,\r\n",  IndentText, Bone->matTransformation._31, Bone->matTransformation._32, Bone->matTransformation._33, Bone->matTransformation._34);
  fprintf(fp, "%s    %06lf,%06lf,%06lf,%06lf;;\r\n", IndentText, Bone->matTransformation._41, Bone->matTransformation._42, Bone->matTransformation._43, Bone->matTransformation._44);
  fprintf(fp, "%s  }\r\n", IndentText);

  // Write child objects
  if(Bone->Child)
    WriteFrame(Bone->Child, fp, Indent+2, TRUE);

  // Close data template (only if not first frame)
  if(Close == TRUE)
    fprintf(fp, "%s}\r\n", IndentText);
}

void CombineTransformation(sMS3DBoneContainer *Bone, D3DXMATRIX *Matrix)
{
  // Combine matrix
  Bone->matCombined = Bone->matTransformation * (*Matrix);

  // Compute inverse combined matrix
  D3DXMatrixInverse(&Bone->matInvCombined, NULL, &Bone->matCombined);

  // Combine child
  if(Bone->Child)
    CombineTransformation(Bone->Child, &Bone->matCombined);

  // Combine sibling
  if(Bone->Sibling)
    CombineTransformation(Bone->Sibling, Matrix);
}

void CreateYawPitchRollRotationMatrix(D3DXMATRIX *matRotation,
                                      float Yaw,
                                      float Pitch,
                                      float Roll)
{
  D3DXMATRIX matX, matY, matZ;

  D3DXMatrixRotationX(&matX, -Pitch);
  D3DXMatrixRotationY(&matY, -Yaw);
  D3DXMatrixRotationZ(&matZ, -Roll);

  (*matRotation) = matX * matY * matZ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -