登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

~AVALON~

- The Ever Distant Utopia -

 
 
 

日志

 
 

获取DS模型T-pose的方法  

2011-04-25 06:03:01|  分类: DeSmuMe |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

提取解压什么的暂不考虑,难度较大。

首先尝试的是屏蔽掉部分GL变换函数,效果很惨,大概没有实用价值。

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~屏蔽glTranslate
获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~

这里的思路就是破坏动画数据,使带骨胳绑定的原模无法改变动作。

1。改动画文件的文件头,使之变成空白无效的动画。

优点是更接近于实际模型的T-pose。

需要参考nsbmd的源码注释,其中有一部分对动画的解读。

 ///////////////////////////////////////////////////////
 // try to load NSBCA file, if any
/*
 getfilepath( szfilename, szfilepath );
 getfiletitle( szfilename, szfiletitle );
 strcat( szfiletitle, ".nsbca" );
 strcat( szfilepath, szfiletitle );
 printf( "DEBUG: trying to open '%s'.\n", szfilepath );
 FILE *fnsbca = fopen( szfilepath, "rb" );
 if ( !fnsbca ) {
  getfilepath( szfilename, szfilepath );
  getfiletitle( szfilename, szfiletitle );
  strcat( szfiletitle, ".bca" );
  strcat( szfilepath, szfiletitle );
  printf( "DEBUG: trying to open '%s'.\n", szfilepath );
  fnsbca = fopen( szfilepath, "rb" );
  if ( !fnsbca ) puts( "No animation found." );
 }
 if ( fnsbca ) {
  fseek( fnsbca, 0, SEEK_END );
  filesize = ftell( fnsbca );
  rewind( fnsbca );

  fread( &id, 4, 1, fnsbca );
  if ( id == NDS_TYPE_BCA0 ) {
   fread( &i, 4, 1, fnsbca );
   if ( i == NDS_TYPE_MAGIC1 ) {
    fread( &i, 4, 1, fnsbca );
    if ( i == filesize ) {
     fread( &numblock, 4, 1, fnsbca );
     numblock >>= 16;
     fread( &r, 4, 1, fnsbca );
     fread( &id, 4, 1, fnsbca );
     if (numblock == 1 && r == 0x14 && id == NDS_TYPE_JNT0) {
      puts( "=================================\nreading 'JNT0'..." );
      g_anim = readjnt0( fnsbca, 0x14, &g_animlen );
      if ( !g_anim ) {
       puts("ERROR readjnt0");
       return 1;
      }
     } else
      printf("DEBUG: no. of block != 1.\n");
    } else
     printf("DEBUG: file size mismatch.\n");
   } else
    printf("DEBUG: magic1 not found.\n");
  } else
   printf("DEBUG: file is not BCA0.\n");
  fclose( fnsbca );
 }
*/

 


ANIMATION *readjnt0 ( FILE *fnsbca, int blockoffset, int *animlen )
{
 int blocksize, blockptr, blocklimit;
 int num, objnum, i, j, r;
 int *dataoffset;
 int sec1offset, sec2offset;
 ANIMATION *animation;

 ////////////////////////////////////////////////
 // joint
 blockptr = blockoffset + 4;   // already read the ID, skip 4 bytes
 fread( &blocksize, 4, 1, fnsbca );  // block size
 blocklimit = blocksize + blockoffset;

 getc( fnsbca );     // skip dummy 0
 num = getc( fnsbca ); assert( num > 0 ); // no of joint must == 1
 printf( "No. of Joint = %02x\n", num );

 dataoffset = (int *)malloc( sizeof( int ) );
 if ( !dataoffset ) return NULL;

 fseek( fnsbca, 10 + (num<<2), 1 );  // skip [char xyz], useless
 blockptr += 10;

 fseek( fnsbca, 4, 1 );    // go straight to joint data offset
 blockptr += 4;
 for ( i = 0; i < num; i++ )
  dataoffset[i] = getdword( fnsbca ) + blockoffset;

 //fseek( fnsbca, 16 * num, SEEK_CUR );  // skip names
 blockptr += 16 * num;

 for ( i = 0; i < num; i++ )
 {
  fseek( fnsbca, dataoffset[i], SEEK_SET );
  j = getdword( fnsbca );
  if ( j != NDS_TYPE_J_AC ) return NULL;
  blockptr += 4;

  *animlen = getword( fnsbca );
  objnum = getword( fnsbca );
  if ( objnum != g_model[0].objnum ) return NULL;
  blockptr += 4;

  animation = (ANIMATION *)calloc( sizeof( ANIMATION ), objnum );
  if ( !animation ) return NULL;

  fseek( fnsbca, 4, SEEK_CUR ); // skip 4 zeros
  blockptr += 4;

  sec1offset = getdword( fnsbca ) + dataoffset[i];
  sec2offset = getdword( fnsbca ) + dataoffset[i];
  blockptr += 8;

  for ( j = 0; j < objnum; j++ )
   animation[j].dataoffset = getword( fnsbca ) + dataoffset[i];

  for ( j = 0; j < objnum; j++ )
  {
   ANIMATION *anim = &animation[j];
   r = getdword( fnsbca );
   anim->flag = r;
   if ( (r&1) == 0 ) {  // any transformation?
    if ( (r&2) == 0 ) { // translation
     if ( (r&4) == 1 ) { // use Base T
     } else {
      if ( (r&8) == 1 ) { // consTX
       anim->m_trans[0] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
      if ( (r&0x10) == 1 ) { // consTY
       anim->m_trans[1] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
      if ( (r&0x20) == 1 ) { // consTZ
       anim->m_trans[0] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
     }
    }
    if ( (r&0x40) == 0 ) { // rotation
     if ( (r&0x100) == 1 ) { // constR
      anim->a = ((float)getword(fnsbca)) / 4096.0f;
      anim->b = ((float)getword(fnsbca)) / 4096.0f;
     } else {
     }
    }
    if ( (r&0x200) == 0 ) { // scale
     if ( (r&0x400) == 1 ) { // use Base S
     } else {
      if ( (r&0x800) == 1 ) { // consSX
       anim->m_scale[0] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
      if ( (r&0x1000) == 1 ) {// consSY
       anim->m_scale[0] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
      if ( (r&0x2000) == 1 ) {// consSZ
       anim->m_scale[0] = ((float)getdword(fnsbca)) / 4096.0f;
      } else {
      }
     }
    }
   }
  }

 }

 free( dataoffset );
 return animation;
}

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~25h=37

 

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~0ch=12

 

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~ 1

 

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~ 1

 

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~6

0ch=12 - 103h=259
6 - a0h=160
1 - 28h=40
130h
16+24*n
00 00 10 00 ,00 01 28 00 ,……

 

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~

Pad:

UE正则表达式:

JNT0^(????????^)^(????^),JNT0^(????????^)????,^(JNT0????????^)???? —— JNT0^1AFA0:Buggy

^(BCA0????????????????JNT0????????^)????:Buggy,无效

^(BCA0????????????????JNT0????????^)?:Buggy,无效

WinHex:

4A4E54303F3F3F3F3F3F3F3F——4A4E54303F3F3F3F00001800

·替换Header4字节标记完全无所用,说明其不参与构成绘图指令

但是目前对.nsbtx(BCA0)的编码格式及作用原理不明,改出来的大都是错的;

严重情况下可导致后续的CPU指令错误,整个崩溃掉。

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~

2。改内置文件名,或改内置文件名的索引。

优点就是更具普遍性。

获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~获取DS原始模型的方法 - szfzafa - ~Infinite Nightmare~

  评论这张
 
阅读(1508)| 评论(2)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018