GF_Err Q_DecFloat(GF_BifsDecoder *codec, GF_BitStream *bs, u32 FieldType, SFVec3f BMin, SFVec3f BMax, u32 NbBits, void *field_ptr) { switch (FieldType) { case GF_SG_VRML_SFINT32: return GF_NON_COMPLIANT_BITSTREAM; case GF_SG_VRML_SFFLOAT: *((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); return GF_OK; case GF_SG_VRML_SFVEC2F: ((SFVec2f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); ((SFVec2f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits)); return GF_OK; case GF_SG_VRML_SFVEC3F: ((SFVec3f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); ((SFVec3f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits)); ((SFVec3f *)field_ptr)->z = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits)); return GF_OK; case GF_SG_VRML_SFCOLOR: ((SFColor *)field_ptr)->red = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); ((SFColor *)field_ptr)->green = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits)); ((SFColor *)field_ptr)->blue = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits)); return GF_OK; case GF_SG_VRML_SFROTATION: //forbidden in this Q mode return GF_NON_COMPLIANT_BITSTREAM; } return GF_OK; }
M4Err Q_DecFloat(BifsDecoder *codec, BitStream *bs, u32 FieldType, SFVec3f BMin, SFVec3f BMax, u32 NbBits, void *field_ptr) { switch (FieldType) { case FT_SFInt32: return M4InvalidNode; case FT_SFFloat: *((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, BS_ReadInt(bs, NbBits)); return M4OK; case FT_SFVec2f: ((SFVec2f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, BS_ReadInt(bs, NbBits)); ((SFVec2f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, BS_ReadInt(bs, NbBits)); return M4OK; case FT_SFVec3f: ((SFVec3f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, BS_ReadInt(bs, NbBits)); ((SFVec3f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, BS_ReadInt(bs, NbBits)); ((SFVec3f *)field_ptr)->z = Q_InverseQuantize(BMin.z, BMax.z, NbBits, BS_ReadInt(bs, NbBits)); return M4OK; case FT_SFColor: ((SFColor *)field_ptr)->red = Q_InverseQuantize(BMin.x, BMax.x, NbBits, BS_ReadInt(bs, NbBits)); ((SFColor *)field_ptr)->green = Q_InverseQuantize(BMin.y, BMax.y, NbBits, BS_ReadInt(bs, NbBits)); ((SFColor *)field_ptr)->blue = Q_InverseQuantize(BMin.z, BMax.z, NbBits, BS_ReadInt(bs, NbBits)); return M4OK; case FT_SFRotation: //forbidden in this Q mode return M4InvalidNode; } return M4OK; }
//SFRotation and SFVec3f are quantized as normalized vectors ,mapped on a cube //in the UnitSphere (R=1.0) GF_Err Q_DecCoordOnUnitSphere(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBits, u32 NbComp, Fixed *m_ft) { u32 i, orient, sign; s32 value; Fixed tang[4], delta; s32 dir; if (NbComp != 2 && NbComp != 3) return GF_BAD_PARAM; //only 2 or 3 comp in the quantized version dir = 1; if(NbComp == 2) dir -= 2 * gf_bs_read_int(bs, 1); orient = gf_bs_read_int(bs, 2); for(i=0; i<NbComp; i++) { value = gf_bs_read_int(bs, NbBits) - (1 << (NbBits-1) ); sign = (value >= 0) ? 1 : -1; m_ft[i] = sign * Q_InverseQuantize(0, 1, NbBits-1, sign*value); } delta = 1; for (i=0; i<NbComp; i++) { tang[i] = gf_tan(gf_mulfix(GF_PI/4, m_ft[i]) ); delta += gf_mulfix(tang[i], tang[i]); } delta = gf_divfix(INT2FIX(dir), gf_sqrt(delta) ); m_ft[orient] = delta; for (i=0; i<NbComp; i++) { m_ft[ (orient + i+1) % (NbComp+1) ] = gf_mulfix(tang[i], delta); } return GF_OK; }
//SFRotation and SFVec3f are quantized as normalized vectors ,mapped on a cube //in the UnitSphere (R=1.0) M4Err Q_DecCoordOnUnitSphere(BifsDecoder *codec, BitStream *bs, u32 NbBits, u32 NbComp, SFFloat *m_ft) { u32 i, orient, value, sign; SFFloat tang[4]; SFFloat dir, delta; if (NbComp != 2 && NbComp != 3) return M4BadParam; //only 2 or 3 comp in the quantized version dir = 1; if(NbComp == 2) dir -= (SFFloat) (2 * BS_ReadInt(bs, 1) ); //the main orientation of the vector is coded IN the bitstream (eg //the prnincipal component of the vector 0, 1, 2) orient = BS_ReadInt(bs, 2); //extract composantes for(i=0; i<NbComp; i++) { value = BS_ReadInt(bs, NbBits) - (1 << (NbBits-1) ); sign = (value >=0 ) ? 1 : -1; m_ft[i] = sign * Q_InverseQuantize(0, 1, NbBits-1, sign*value); } //extract angle delta = 1; for (i=0; i<NbComp; i++) { tang[i] = (SFFloat) tan( QP_PI * m_ft[i] / 4); delta += tang[i] * tang[i]; } delta = (SFFloat) ( dir / sqrt(delta) ); m_ft[orient] = delta; for (i=0;i<NbComp;i++) { m_ft[ (orient + i+1) % (NbComp+1) ] = tang[i] * delta; } return M4OK; }