Vertices order and location

ZModeler2-related discussion. General questions, howto, etc.

Moderators: Oleg, _RicH_

Vertices order and location

Postby Seb » Fri Jun 19, 2015 5:29 am

Hello,

I'd like to know how to read the order of vertices in the .z3d file and their axis datas. I have 2 identical files, on one of them I moved 1 vertice in one axis only and comparing those 2 files in hexadecimal format the 2/3 of the whole file have been tweaked it seems, I can't really read anything. How can I detect those datas in a file please ?

Thanks in advance.
Seb
 
Posts: 5
Joined: Thu Nov 08, 2012 7:04 pm

Re: Vertices order and location

Postby Oleg » Fri Jun 19, 2015 7:31 am

What ZModeler version is in a question? File format is completely different in old zmodeler1 and "new" zmodeler2 & 3.
User avatar
Oleg
Site Admin
 
Posts: 7390
Joined: Fri Feb 06, 2004 3:54 am

Re: Vertices order and location

Postby Seb » Fri Jun 19, 2015 9:07 am

Oleg it is a zmodeler2 file.
Seb
 
Posts: 5
Joined: Thu Nov 08, 2012 7:04 pm

Re: Vertices order and location

Postby Oleg » Fri Jun 19, 2015 9:52 am

zmod2&3 .z3d files are not intended to be read by any other software than zmodeler. These are very alike to .max files of 3dsmax. The concept is that any part of program can store it's own data in it's own preferable way.

.z3d is made out of chunks:
http://www.zmodeler2.com/docs/sdk/refs/ ... 3D_ID.html

you can skim the declaration part of the file (DECL chunks), locate those wrtten by "scene::CPolyMesh", and collect respective unique IDs of these chunks. Then skim the DATA chunks for these IDs and read respective mesh data.

The following part of code is from ZModeler3, but it reads zmod2 poly mesh too.
Code: Select all
ZRESULT CPolyMesh::loadData(core::io::IStream* pStream, services::IOpenSaveService* pSrv, DWORD dwSize, DWORD dwVersion, bool bMerge)
{
  DWORD dwVFormat;
  DWORD dwVCount;
  DWORD dwPFormat;
  long dwPCount;
  pStream->read(&dwVFormat,sizeof(DWORD));
  pStream->read(&dwVCount, sizeof(DWORD));
  pStream->read(&dwPFormat,sizeof(DWORD));
  pStream->read(&dwPCount ,sizeof(DWORD));
  m_pPolyBuf  = NULL;//deleted
  m_pVertBuf  = NULL;
  DWORD dwFormatAsInFile = dwVFormat;
  if (dwVFormat & VERTEX_HAS_BONES_MASK_DEPRICATED)
  {
    long numBonesDepricated = (dwVFormat & VERTEX_HAS_BONES_MASK_DEPRICATED) == 0xF000 ? 4 :
                              (dwVFormat & VERTEX_HAS_BONES_MASK_DEPRICATED) == 0x7000 ? 3 :
                              (dwVFormat & VERTEX_HAS_BONES_MASK_DEPRICATED) == 0x3000 ? 2 :
                              (dwVFormat & VERTEX_HAS_BONES_MASK_DEPRICATED) == 0x1000 ? 1 : 0;
    dwVFormat = (dwVFormat & ~VERTEX_HAS_BONES_MASK_DEPRICATED) | VERTEX_SET_BONES(numBonesDepricated);
  }
  m_pVertBuf  = new ZVertexBuf(dwVFormat, dwVCount);
  m_pPolyBuf  = new ZPolyBuf(ZPoly::MIXED == dwPFormat ? ZPoly::NONE : (ZPoly::ePolyType)dwPFormat, dwPCount);
  long i;
  for (i = 0; i < (long)dwVCount; i++)
    core::io::read((*m_pVertBuf)[i], pStream);

  for (i = 0; i < dwPCount; i++)
  {
    if (ZPoly::MIXED == dwPFormat)
    {
      DWORD dwType;
      pStream->read(&dwType, sizeof(DWORD));
      m_pPolyBuf->at(i, (ZPoly::ePolyType)dwType);
    }
    core::io::read((*m_pPolyBuf)[i], pStream);
  }
  //restore materials mapping array;
  if (dwVersion >= 0x203)
  {
    ZPtr<services::IMaterialsService> pMatSrv;
    services::getMaterialsService(&pMatSrv);
    if (pMatSrv)
    {
      //create material-mapping array
      g_mapMaterials.length(pMatSrv->getCount());
      ZPtr<rend::IMaterial> pMat;
      for (i = 0; i < g_mapMaterials.length(); i++)
      {
        pMat = NULL;
        pMatSrv->getMaterial(i, &pMat);
        g_mapMaterials[i] = pSrv->getUnknownID(pMat->GetControllingUnknown());
      }
    }//done mapping
    else
      return ZRESULT_FAIL;

    for (i = 0; i < dwPCount; i++)
      if (-1 == ((*m_pPolyBuf)[i].material() = g_mapMaterials.indexOf((*m_pPolyBuf)[i].material())))
        (*m_pPolyBuf)[i].material() = 0;
  }

  //
  // update lookup tables after loading:
  updateLookupTables();

  return ZRESULT_OK;
}


the following code fragment is the vertex reader. it reads vertex components with respect to vertex format initialized earlier:
Code: Select all
DLL_LINKAGE void read(ZEntityBase& b, IStream*& pStream)
{
  pStream->read(&b.status(), sizeof(DWORD));
  pStream->read(&b.userDword(), sizeof(DWORD));
  pStream->read(&b.extension(), sizeof(DWORD));
}

DLL_LINKAGE void read (ZVertex& v, IStream*& pStream)
{
  read((ZEntityBase&)v, pStream);
  DWORD fmt;
  pStream->read(&fmt, sizeof(DWORD));
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_POSITION))
    pStream->read((float*)v.position(), sizeof(float)*3);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_NORMAL))
    pStream->read((float*)v.normal(), sizeof(float)*3);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_TANGENT))
    pStream->read((float*)v.tangent(), sizeof(float)*4);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_1COLOR))
    pStream->read(&v.color(ZVertex::DIFFUSE), sizeof(ZColor));//?
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_2COLOR))
    pStream->read(&v.color(ZVertex::SPECULAR), sizeof(ZColor));//?
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_1UV))
    pStream->read((float*)v.uv(0), sizeof(float)*2);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_2UV))
    pStream->read((float*)v.uv(1), sizeof(float)*2);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_3UV))
    pStream->read((float*)v.uv(2), sizeof(float)*2);
  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_4UV))
    pStream->read((float*)v.uv(3), sizeof(float)*2);

  //
  // old-style bones:
  DWORD bones = 0;  //depricated;
  pStream->read(&bones, sizeof(DWORD));
  if (fmt & VERTEX_HAS_BONES_MASK_DEPRICATED)
  {
    if (VERTEX_FORMAT_HAS(fmt, 0x1000))
      v.boneID(0, (BYTE)(bones&0xFF));
    if (VERTEX_FORMAT_HAS(fmt, 0x2000))
      v.boneID(1, (BYTE)((bones&0xFF00)>>8));
    if (VERTEX_FORMAT_HAS(fmt, 0x4000))
      v.boneID(2, (BYTE)((bones&0xFF0000)>>16));
    if (VERTEX_FORMAT_HAS(fmt, 0x8000))
      v.boneID(3, (BYTE)((bones&0xFF000000)>>24));
    float fWeight = 0.0f;
    if (VERTEX_FORMAT_HAS(fmt, 0x1000))
    {
      pStream->read(&fWeight, sizeof(float));
      v.boneW(0, fWeight);
    }
    if (VERTEX_FORMAT_HAS(fmt, 0x2000))
    {
      pStream->read(&fWeight, sizeof(float));
      v.boneW(1, fWeight);
    }
    if (VERTEX_FORMAT_HAS(fmt, 0x4000))
    {
      pStream->read(&fWeight, sizeof(float));
      v.boneW(2, fWeight);
    }
    if (VERTEX_FORMAT_HAS(fmt, 0x8000)) //?
    {
      pStream->read(&fWeight, sizeof(float));
      v.boneW(3, fWeight);
    }
  }//old style bones;
  else
  if (fmt & VERTEX_HAS_BONES_MASK)
  {//new-style bones
    //bone IDs \ base 8-bit slots;
    v.boneIDPacked(0) = bones;
    pStream->read(&v.boneIDPacked(1), 4);
    //bone weights :
    pStream->read(&v.boneWPacked(0), 8);
    pStream->read(&v.boneWPacked(1), 8);
  }//new-style bones

  if (VERTEX_FORMAT_HAS(fmt, VERTEX_HAS_DEFORMATION))
  {
    pStream->read((float*)v.offsetPosition(), sizeof(float)*3);
    pStream->read(&v.offsetNormalPacked(), sizeof(DWORD));
  }
}


note, zmod3 has different per-vertex components, so you see a "mess" with deprecated/new bones count, bones weight and bones ids and their mask in vertex format. you can pin to a code marked as "old" or "deprecated" in comments and respect vertex format bits defined in scene/zmSceneTypes.h in ZMod2 SDK.
User avatar
Oleg
Site Admin
 
Posts: 7390
Joined: Fri Feb 06, 2004 3:54 am

Re: Vertices order and location

Postby Oleg » Fri Jun 19, 2015 9:53 am

also, if the chunk "SBST" is available, it's probably a container for a LZ-compressed (I use zlib) of file content. You need to unpack data prior to read it in such a case.
User avatar
Oleg
Site Admin
 
Posts: 7390
Joined: Fri Feb 06, 2004 3:54 am

Re: Vertices order and location

Postby Seb » Sat Jun 20, 2015 2:01 pm

Thanks Oleg, I'll see what I can do.
Seb
 
Posts: 5
Joined: Thu Nov 08, 2012 7:04 pm


Return to ZModeler2 General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron