bool LWOFile::LoadWeightMap(unsigned int iChunkSize) { Layer *pLayer=GetLastLayer(); const char *pChunkEndPos=m_pData+iChunkSize-4; unsigned short iDimension=0; if(!ReadU2(iDimension)) { return false; } // is not 1 float per vertex if(iDimension!=1) { // just skip m_pData+=iChunkSize-4-2; AddError("Warning: WeightMap has "+ConvertToString(iDimension)+" floats per vertex (1 expected)"); return true; } unsigned int iStrBytes=0; std::string strName; if(!ReadS0(strName,iStrBytes)) { return false; } // VMAP { type[ID4], dimension[U2], name[S0], // ( vert[VX], value[F4] # dimension )* } WeightMap *pWeightMap=new WeightMap(); pWeightMap->m_strName=strName; pWeightMap->m_Values.resize(1*pLayer->m_iPoints); pLayer->m_WeightMaps.push_back(pWeightMap); float *pValues=&pWeightMap->m_Values[0]; memset(pValues,0,sizeof(float)*1*pLayer->m_iPoints); while(m_pData<pChunkEndPos) { unsigned int iVertexID=0; if(!ReadVX(iVertexID)) return false; if(iVertexID>=pLayer->m_iPoints) return false; if(!ReadF4(pValues[iVertexID])) return false; } return true; }
bool LWOFile::LoadLAYR(unsigned int iChunkSize) { Layer *pLayer=new Layer(); m_Layers.push_back(pLayer); // LAYR { number[U2], flags[U2], pivot[VEC12], name[S0], parent[U2] ? } const char *pChunkEndPos=m_pData+iChunkSize; if(!ReadU2(pLayer->m_iID)) return false; if(!ReadU2(pLayer->m_iFlags)) return false; if(!ReadF4(pLayer->m_vPivot[0])) return false; if(!ReadF4(pLayer->m_vPivot[1])) return false; if(!ReadF4(pLayer->m_vPivot[2])) return false; if(!ReadS0(pLayer->m_strName)) return false; // parent id is optional, so read it only if theres data left if(m_pData<pChunkEndPos) { if(!ReadU2(pLayer->m_iParentID)) return false; } else { pLayer->m_iParentID=0; } return true; }
bool LWOFile::LoadPTAG(unsigned int iChunkSize) { Layer *pLayer=GetLastLayer(); if(pLayer==NULL) { AddError("No LAYR before PTAG"); return false; } if(pLayer->m_Polygons.size()==0) { AddError("No POLS before PTAG"); return false; } const char *pChunkEndPos=m_pData+iChunkSize; // read type unsigned int iType=0; if(!ReadID4(iType)) { return false; } if(iType!=ID4("SURF")) { // unknown type - skip m_pData+=iChunkSize-4; AddError("Warning: Unknown PTAG type "+ID4ToString(iType)); return true; } while(m_pData<pChunkEndPos) { // read poly id unsigned int iPolyID; if(!ReadVX(iPolyID)) return false; // read tag unsigned short iTag; if(!ReadU2(iTag)) return false; if(iPolyID>=pLayer->m_Polygons.size()) return false; pLayer->m_Polygons[iPolyID].m_iSurface=iTag; } return true; }
bool LWOFile::LoadVMAD(unsigned int iChunkSize) { Layer *pLayer=GetLastLayer(); if(pLayer==NULL) { AddError("No LAYR before VMAD"); return false; } const char *pChunkEndPos=m_pData+iChunkSize; // VMAD { type[ID4], dimension[U2], name[S0], // ( vert[VX], poly[VX], value[F4] # dimension )* } unsigned int iType=0; if(!ReadID4(iType)) return false; // type must be uvmap if(iType!=ID4("TXUV")) { AddError("Warning: Unknown discontinuous vertex map type "+ID4ToString(iType)); m_pData+=iChunkSize-4; return true; } // dimension unsigned short iDimension=0; if(!ReadU2(iDimension)) { return false; } // not 2 floats per vertex if(iDimension!=2) { AddError("Warning: Discontinuous UVMap has "+ConvertToString(iDimension)+" floats per vertex (2 expected)"); // skip m_pData+=iChunkSize-4-2; return true; } // name unsigned int iStrBytes=0; std::string strName; if(!ReadS0(strName,iStrBytes)) { return false; } // for each uvmap UVMap *pUV=NULL; for(unsigned int iUV=0;iUV<pLayer->m_UVMaps.size();iUV++) { if(pLayer->m_UVMaps[iUV]->m_strName==strName) { pUV=pLayer->m_UVMaps[iUV]; } } if(pUV==NULL) { AddError("No matching UVMap for discontinuous UVMap \""+strName+"\""); return false; } // read rest of chunk to memory // unsigned int iBytesLeft=iChunkSize-4-2-iStrBytes; UVMapD *pUVMap=new UVMapD(); pUVMap->m_strName=strName; pUVMap->m_pUVMap=pUV; // worst case estimate pUVMap->m_Entries.reserve(iBytesLeft/(2+2+4+4)); pLayer->m_UVMapDs.push_back(pUVMap); while(m_pData<pChunkEndPos) { unsigned int iVertexID=0; if(!ReadVX(iVertexID)) return false; unsigned int iPolyID=0; if(!ReadVX(iPolyID)) return false; UVMapD::Entry e; e.iVertex=iVertexID; e.iPolygon=iPolyID; if(!ReadF4(e.u)) return false; if(!ReadF4(e.v)) return false; // flip v coordinate e.v=1-e.v; pUVMap->m_Entries.push_back(e); } return true; }
void LWOReader::ReadBLOK( LWSurface* pSurface, UInt32 pChunkSize ) { UInt32 dataRead = 0; UInt16 subChunkSize; UInt32 subChunkTag; UInt32 bytesHold; LWSurfaceBlock* newSurfaceBlock = GD_NEW(LWSurfaceBlock, this, "SurfaceBlock"); //dataRead += ReadS0( newSurfaceBlock->mOrdinalString ); // Read all subchunks while( dataRead < pChunkSize ) { subChunkTag = ReadSubChunk(subChunkSize,1); dataRead += sizeof(subChunkTag); // Subchunk tag. dataRead += sizeof(subChunkSize); // Subchunk size. bytesHold = dataRead; switch( subChunkTag ) { case ID_IMAP: case ID_PROC: case ID_GRAD: case ID_SHDR: newSurfaceBlock->mType = subChunkTag; ReadHEAD( newSurfaceBlock, subChunkSize ); dataRead += subChunkSize; break; case ID_TMAP: ReadTMAP( &newSurfaceBlock->mTextureMapping, subChunkSize ); dataRead += subChunkSize; break; case ID_PROJ: dataRead += ReadU2( newSurfaceBlock->mImageMap.mProjectionMode ); break; case ID_AXIS: dataRead += ReadU2( newSurfaceBlock->mImageMap.mProjectionAxis ); break; case ID_IMAG: newSurfaceBlock->mImageMap.mValid = true; dataRead += ReadVX( newSurfaceBlock->mImageMap.mImageMap ); break; case ID_WRAP: dataRead += ReadU2( newSurfaceBlock->mImageMap.mWrapModeWidth ); dataRead += ReadU2( newSurfaceBlock->mImageMap.mWrapModeHeight ); break; case ID_VMAP: dataRead += ReadS0( newSurfaceBlock->mImageMap.mUVVertexMapName ); break; default: dataRead += Skip( subChunkSize ); break; } // Make sure we've read all subchunk bytes (given by the size). if( (subChunkSize - dataRead + bytesHold) > 0 ) dataRead += Skip( subChunkSize - dataRead + bytesHold ); } pSurface->mBlocks.push_back( newSurfaceBlock ); }
void LWOReader::ReadSURF( UInt32 pChunkSize ) { UInt32 dataRead = 0; UInt16 subChunkSize; UInt32 subChunkTag; UInt32 bytesHold; LWIndex env; LWSurface* newSurface = GD_NEW(LWSurface, this, "Surface"); dataRead += ReadS0( newSurface->mSurfaceName ); dataRead += ReadS0( newSurface->mSurfaceFile ); // Read all subchunks while( dataRead < pChunkSize ) { if( (pChunkSize - dataRead) < 6 ) { dataRead += Skip( pChunkSize - dataRead ); return; } subChunkTag = ReadSubChunk(subChunkSize); dataRead += sizeof(subChunkTag); // Subchunk tag. dataRead += sizeof(subChunkSize); // Subchunk size. bytesHold = dataRead; switch( subChunkTag ) { case ID_COLR: dataRead += ReadCOL12( newSurface->mBaseColor ); dataRead += ReadVX( env ); break; case ID_DIFF: dataRead += ReadFP4( newSurface->mDiffuse ); dataRead += ReadVX( env ); break; case ID_LUMI: dataRead += ReadFP4( newSurface->mLuminosity ); dataRead += ReadVX( env ); break; case ID_SPEC: dataRead += ReadFP4( newSurface->mSpecular ); dataRead += ReadVX( env ); break; case ID_REFL: dataRead += ReadFP4( newSurface->mReflection ); dataRead += ReadVX( env ); break; case ID_TRAN: dataRead += ReadFP4( newSurface->mTransparency ); dataRead += ReadVX( env ); break; case ID_TRNL: dataRead += ReadFP4( newSurface->mTranslucency ); dataRead += ReadVX( env ); break; case ID_GLOS: dataRead += ReadFP4( newSurface->mSpecularGlossiness ); dataRead += ReadVX( env ); break; case ID_SHRP: dataRead += ReadFP4( newSurface->mDiffuseSharpness ); dataRead += ReadVX( env ); break; case ID_BUMP: dataRead += ReadFP4( newSurface->mBumpStrength ); dataRead += ReadVX( env ); break; case ID_SIDE: dataRead += ReadU2( newSurface->mPolySide ); break; case ID_SMAN: dataRead += ReadANG4( newSurface->mMaxSmoothingAngle ); break; case ID_RFOP: dataRead += ReadU2( newSurface->mReflectionOptions ); break; case ID_RIMG: dataRead += ReadVX( newSurface->mReflectionMapImage ); break; case ID_RSAN: dataRead += ReadANG4( newSurface->mReflMapSeamAngle ); dataRead += ReadVX( env ); break; case ID_RBLR: dataRead += ReadFP4( newSurface->mReflBlurPercent ); dataRead += ReadVX( env ); break; case ID_CLRH: dataRead += ReadFP4( newSurface->mColorHighlights ); dataRead += ReadVX( env ); break; case ID_TROP: dataRead += ReadU2( newSurface->mTransparencyOptions ); dataRead += Skip( subChunkSize - sizeof(UInt16) ); break; case ID_CLRF: dataRead += ReadFP4( newSurface->mColorFilter ); dataRead += ReadVX( env ); break; case ID_ADTR: dataRead += ReadFP4( newSurface->mAdditiveTransparency ); dataRead += ReadVX( env ); break; case ID_ALPH: dataRead += ReadU2( newSurface->mAlphaMode ); dataRead += ReadFP4( newSurface->mAlphaValue ); break; case ID_BLOK: ReadBLOK( newSurface, subChunkSize ); dataRead += subChunkSize; break; case ID_VCOL: case ID_LINE: case ID_GLOW: case ID_TBLR: case ID_TIMG: case ID_RIND: default: dataRead += Skip( subChunkSize ); break; } // Make sure we've read all subchunk bytes (given by the size). if( (subChunkSize - dataRead + bytesHold) > 0 ) dataRead += Skip( subChunkSize - dataRead + bytesHold ); } mObject->mSurfaces.push_back( newSurface ); }
void LWOReader::ReadVMAP( UInt32 pChunkSize, Bool pPerPoly ) { UInt32 dataRead = 0; UInt16 dimension; LWIndex vertexIndex; LWIndex polygonIndex; LWVertexMap* newVertexMap = GD_NEW(LWVertexMap, this, "VertexMap"); newVertexMap->mPerPoly = pPerPoly; dataRead += ReadID4( newVertexMap->mType ); dataRead += ReadU2( dimension ); dataRead += ReadS0( newVertexMap->mName ); while( dataRead < pChunkSize ) { dataRead += ReadVX( vertexIndex ); newVertexMap->mVertexIndex.push_back( vertexIndex ); if( pPerPoly ) { dataRead += ReadVX( polygonIndex ); newVertexMap->mPolygonIndex.push_back( polygonIndex ); } LWMapValue mapping; switch( newVertexMap->mType ) { case ID_PICK: mapping.mPick = vertexIndex; break; case ID_WGHT: dataRead += ReadF4( mapping.mWeight ); break; case ID_TXUV: dataRead += ReadF4( mapping.mUV.U ); dataRead += ReadF4( mapping.mUV.V ); break; case ID_RGB: dataRead += ReadF4( mapping.mRGB.R ); dataRead += ReadF4( mapping.mRGB.G ); dataRead += ReadF4( mapping.mRGB.B ); break; case ID_RGBA: dataRead += ReadF4( mapping.mRGBA.R ); dataRead += ReadF4( mapping.mRGBA.G ); dataRead += ReadF4( mapping.mRGBA.B ); dataRead += ReadF4( mapping.mRGBA.A ); break; case ID_MORF: case ID_SPOT: case ID_MNVW: default: dataRead += Skip( dimension * sizeof(Float) ); break; } newVertexMap->mValues.push_back( mapping ); } GetCurrentLayer()->mVertexMaps.push_back( newVertexMap ); }