PhysX 3.2中RAW格式文件的解析

来源:互联网 发布:千锋教育java怎么样 编辑:程序博客网 时间:2024/06/04 22:27
在PhysX 3.2中 ,Sample结合了D3D9来做显示。

在SampleVehicle中,使用了raw格式的文件来存储车辆模型和天空。

最初的时候,我以为这个raw格式就是网上说的那个原生照片格式,但是后来跟进到程序里面发现这个raw格式包含的有更多的内容。

下面从一个函数来说明,这个raw格式的文件是怎么回事。

  1 bool loadRAWfile(const char* filename, RAWImportCallback& cb, PxReal scale)  2 {  3     FILE* fp = NULL;  4     physx::fopen_s(&fp, filename, "rb");  5     if(!fp)  6         return false;  7   8     // General info        从文件中读取的通用信息  9     const PxU32 tag                = read32(fp); 10     const PxU32 generalVersion    = read32(fp); 11     const PxU32 nbMaterials        = read32(fp); 12     const PxU32 nbTextures        = read32(fp); 13     const PxU32 nbMeshes        = read32(fp);    //mesh的部分数 14     const PxU32 nbShapes        = read32(fp); 15     const PxU32 nbHelpers        = read32(fp); 16  17     char objectName[512]; 18  19     // Textures 20     for(PxU32 i=0;i<nbTextures;i++) 21     { 22         RAWTexture data; 23  24         readName(fp, objectName); 25         data.mName                = objectName; 26         data.mTransform            = PxTransform::createIdentity();    // PT: texture transform not supported yet 27         data.mID                = read32(fp); 28  29         RendererColorAlloc* pixels = NULL; 30         if(read8(fp)) 31         { 32             data.mWidth            = read32(fp); 33             data.mHeight        = read32(fp); 34             data.mHasAlpha        = read8(fp)!=0; 35             const PxU32 nbPixels = data.mWidth*data.mHeight;  36             pixels                = SAMPLE_NEW(RendererColorAlloc)[nbPixels]; 37             data.mPixels        = pixels; 38             for(PxU32 i=0;i<nbPixels;i++) 39             { 40                 pixels[i].r = read8(fp); 41                 pixels[i].g = read8(fp); 42                 pixels[i].b = read8(fp); 43                 if(data.mHasAlpha) 44                     pixels[i].a = read8(fp); 45                 else 46                     pixels[i].a = 0xff; 47             } 48         } 49         else 50         { 51             data.mWidth            = 0; 52             data.mHeight        = 0; 53             data.mHasAlpha        = false; 54             data.mPixels        = NULL; 55         } 56  57         cb.newTexture(data); 58         DELETEARRAY(pixels); 59     } 60  61     // Materials 62     for(PxU32 i=0;i<nbMaterials;i++) 63     { 64         RAWMaterial data; 65         data.mID                = read32(fp); 66         data.mDiffuseID            = read32(fp); 67         data.mOpacity            = readFloat(fp); 68         data.mDoubleSided        = read32(fp)!=0; 69  70         data.mAmbientColor.x    = readFloat(fp); 71         data.mAmbientColor.y    = readFloat(fp); 72         data.mAmbientColor.z    = readFloat(fp); 73  74         data.mDiffuseColor.x    = readFloat(fp); 75         data.mDiffuseColor.y    = readFloat(fp); 76         data.mDiffuseColor.z    = readFloat(fp); 77  78         data.mSpecularColor.x    = readFloat(fp); 79         data.mSpecularColor.y    = readFloat(fp); 80         data.mSpecularColor.z    = readFloat(fp); 81  82         cb.newMaterial(data); 83     } 84  85     // Meshes   这个nbMeshes是凸包的个数 86     for(PxU32 i=0;i<nbMeshes;i++) 87     { 88         RAWMesh data; 89  90         readName(fp, objectName); 91         data.mName                    = objectName; 92         data.mTransform                = readTransform(fp, scale); 93         // 94         data.mNbVerts                = read32(fp); 95         data.mNbFaces                = read32(fp); 96         const PxU32 hasVertexColors = read32(fp); 97         const PxU32 hasUVs            = read32(fp); 98         data.mMaterialID            = read32(fp); 99 100         PxVec3Alloc* tmpVerts        = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];101         PxVec3Alloc* tmpNormals        = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];102         PxVec3Alloc* tmpColors        = NULL;103         PxReal* tmpUVs                = NULL;104 105         data.mVerts                    = tmpVerts;106         data.mVertexNormals            = tmpNormals;107         data.mVertexColors            = NULL;108         data.mUVs                    = NULL;109 110         readVertices(fp, tmpVerts, data.mNbVerts, scale);111         readNormals(fp, tmpNormals, data.mNbVerts);112 113         if(hasVertexColors)114         {115             tmpColors = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];116             data.mVertexColors = tmpColors;117             readVertexColors(fp, tmpColors, data.mNbVerts);118         }119 120         if(hasUVs)121         {122             tmpUVs = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*data.mNbVerts*2);123             data.mUVs = tmpUVs;124             readUVs(fp, tmpUVs, data.mNbVerts);125         }126 127         PxU32* tmpIndices = (PxU32*)SAMPLE_ALLOC(sizeof(PxU32)*data.mNbFaces*3);128         data.mIndices = tmpIndices;129         fread(tmpIndices, 4*3*data.mNbFaces, 1, fp);130         if(gFlip)131         {132             for(PxU32 j=0;j<data.mNbFaces*3;j++)133             {134                 Flip(tmpIndices[j]);135             }136         }137 138         cb.newMesh(data);139 140         SAMPLE_FREE(tmpIndices);141         SAMPLE_FREE(tmpUVs);142         DELETEARRAY(tmpColors);143         DELETEARRAY(tmpNormals);144         DELETEARRAY(tmpVerts);145     }146 147     // Shapes148     for(PxU32 i=0;i<nbShapes;i++)149     {150         RAWShape data;151 152         readName(fp, objectName);153         data.mName        = objectName;154         data.mTransform = readTransform(fp, scale);155         //156         data.mNbVerts    = read32(fp);157         PxVec3Alloc* tmp = SAMPLE_NEW(PxVec3Alloc)[data.mNbVerts];158         data.mVerts        = tmp;159         readVertices(fp, tmp, data.mNbVerts, scale);160 161         cb.newShape(data);162 163         DELETEARRAY(tmp);164     }165 166     // Helpers167     for(PxU32 i=0;i<nbHelpers;i++)168     {169         RAWHelper data;170 171         readName(fp, objectName);172         data.mName        = objectName;173         data.mTransform    = readTransform(fp, scale);174     }175     return true;176 }

 

1.首先,从 physx::fopen_s(&fp, filename, "rb"); 看出,.raw格式文件是以二进制方式读取的。

这里的filename是 car2.raw,在PhysXSample中提供,大小为136k。

2.这几个read32(fp)分别从文件中读取到了,tag信息、通用版本信息、材质数目、纹理数目、Mesh数目、Shape数目、还有Helper的数目。

    // General info        从文件中读取的通用信息    const PxU32 tag                = read32(fp);    const PxU32 generalVersion    = read32(fp);    const PxU32 nbMaterials        = read32(fp);    const PxU32 nbTextures        = read32(fp);    const PxU32 nbMeshes        = read32(fp);    //mesh的部分数    const PxU32 nbShapes        = read32(fp);    const PxU32 nbHelpers        = read32(fp);

下面这个函数是在RawLoader.cpp里面定义的,其调用了fread(buffer, elemSize, count , stream),这里用的是fread( data, 4, 1, fb),表示一次从文件中读取4个字节,32位数据。

//从FILE中读32个字节,并返回static PxU32 read32(FILE* fp){    PxU32 data;    fread(&data, 4, 1, fp);    if(gFlip)        Flip(data);    return data;}

 文件的开头4个字节是RAW!,表示了文件的格式是raw。

接下来4个字节是generalVersion,表示版本号。

接下来4个字节是nbMaterials,表示材质数目。

接下来4个字节是nbTextTures,表示纹理数目。

接下来4个字节是nbMeshes,表示网格数目。

接下来4个字节是nbShapes,表示形状数目。

接下来4个字节是nbHelpers,表示帮助信息数目。

  • 接下来文件中存储的是纹理信息。

根据从文件头中读取的纹理数目,来读取纹理数据:包含储存纹理的文件名(长度不定),纹理的ID(4个字节)。还有可能包含的纹理的宽度、高度、alpha值,以及RGB值等。

最后根据这些纹理data,来NewTexture。

  • 接下来文件中存储的是材质信息。

根据从文件头中读取的材质数目,来读取材质数据:包括材质ID(4个字节),漫反射ID(4个字节),不透明度(浮点类型,4个字节),是否双面(bool类型,在文件中是2个字节),之后就是环境光、漫反射光和镜面反射光(高光)的三个颜色分量的值,各占4个字节,共(3*3*4)=9个字节。

最后根据这些材质data,来NewMaterial。

  • 接下来文件中存储的是网格(Mesh)数据。

根据从文件头中读取的网格数目,来读取网格数据:包含储存网格的文件名(长度不定),网格的Transform(7*4个字节),顶点个数(4个字节),面片个数(4个字节),是否包含顶点颜色(bool型,4个字节),是否包含UV坐标(bool型,4个字节),材质的ID(4个字节),然后根据从之前文件中读取的顶点数目,来读取相应数目的顶点和法线

下面根据是否包含顶点颜色和UV的情况,读取文件中存储的相应个数的顶点颜色和UV(这两个不一定有)。

然后是读取 (4*3*data.mNbFaces)个字节数的数据,这些包含的就是网格的顶点数据。

最后根据这些data,来NewMesh。

  • 接下来文件中存储的是形状数据。

根据从文件头中读取的形状数目,来读取形状数据:包含存储形状的文件名(长度不定),形状的Transform(7*4个字节),然后是顶点的数目(4个字节),之后是根据顶点的数目,来读取(顶点数目*4)个字节的顶点数据。

最后根据这些data,来NewShape。

  • 接下来文件中存储的是帮助信息。

根据从文件头中读取的帮助信息数目,来读取帮助信息:包含存储帮助信息的文件名(长度不定),帮助信息的Transform(7*4个字节)。然后就没有了,帮助信息比较简单。

Conclusion:这个RAW格式的文件,并非度娘说的和大家所认识的raw格式。而是一种nvidia自己搞的格式,可以看成是类似索引文件,其中包含索引信息(指向存储纹理、网格、形状等的文件),和一些其它的数据(包括各类数据的数目、顶点数据等等。)

题外话:本来打算弄清楚这个raw格式是怎么回事之后,把这个用起来。结果弄完发现是这么个货,要用这个raw格式,就必须用到RawLoader,虽然提供了源文件,但是你以为他是独立的吗?拿过去就能用了?图样图森破!他里面包含了PhysXSample里面的newTexture之类的回调函数啊。最重要的是,这raw格式的东西没几个呀,就车、天空,桥,车就只有一个样式。就算用起来了,到时候你的场景里面所有的车都长一样,你乐意啊?而且这个raw格式的东东,也不知道他们是怎么弄出来的,你想自己弄吧,还不行,上网搜吧,也没有。所以我决定要放弃使用这个东西,我还是回归我的3ds和flt吧,毕竟可以网上搜到大把,只是数据和车辆的结构(主要是轮子与车身)需要自己组织罢了。

——————————分割线—7月25号补充————————————

在继续研究了程序之后,发现这个raw文件包含的东西还真不少,就我关心的Mesh部分的数据来说,它包含了顶点的个数,mesh的个数,每一个顶点的数据,然后还有Transform!(在车轮的Mesh里面,Transform表示了车轮的位置)。Nvidia你弄这个Sample真的是逗我们玩呢。哼!

0 0
原创粉丝点击