/* -*-c++-*- */ //****************************************************************************// // loader.cpp // // Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger // //****************************************************************************// // This library is free software; you can redistribute it and/or modify it // // under the terms of the GNU Lesser General Public License as published by // // the Free Software Foundation; either version 2.1 of the License, or (at // // your option) any later version. // //****************************************************************************// /*****************************************************************************/ /** Loads a core compressed keyframe instance. * * This function loads a core compressed keyframe instance from a data source. * * @param dataSrc The data source to load the core compressed keyframe instance from. * * @return One of the following values: * \li a pointer to the core keyframe * \li \b 0 if an error happened * Authors * Igor Kravchenko * Cedric Pinson *****************************************************************************/ #ifndef OSGANIMATION_PACKED_H #define OSGANIMATION_PACKED_H #include #include #include #include namespace osgAnimation { struct Vec3Packed { typedef unsigned int uint32_t; uint32_t m32bits; Vec3Packed(uint32_t val): m32bits(val) {} Vec3Packed(): m32bits(0) {} void uncompress(const osg::Vec3& scale, const osg::Vec3& min, osg::Vec3& result) const { uint32_t pt[3]; pt[0] = m32bits & 0x7ff; pt[1] = (m32bits >> 11) & 0x7ff; pt[2] = m32bits >> 22; result[0] = scale[0] * pt[0] + min[0]; result[1] = scale[1] * pt[1] + min[1]; result[2] = scale[2] * pt[2] + min[2]; } void compress(const osg::Vec3f& src, const osg::Vec3f& min, const osg::Vec3f& scaleInv) { uint32_t srci[3]; srci[0] = osg::minimum(static_cast(((src[0] - min[0] )*scaleInv[0])), uint32_t(2047)); srci[1] = osg::minimum(static_cast(((src[1] - min[1] )*scaleInv[1])), uint32_t(2047)); srci[2] = osg::minimum(static_cast(((src[2] - min[2] )*scaleInv[2])), uint32_t(1023)); m32bits = srci[0] + (srci[1] << 11) + (srci[2] << 22); } }; struct Vec3ArrayPacked { std::vector mVecCompressed; osg::Vec3 mMin; osg::Vec3 mScale; osg::Vec3 mScaleInv; void analyze(const std::vector& src) { //analyze the keys mMin.set(FLT_MAX, FLT_MAX, FLT_MAX); osg::Vec3 maxp(-FLT_MAX, -FLT_MAX, -FLT_MAX); int nb = (int)src.size(); for(int i = 0; i < nb; i++) { const osg::Vec3 &pos = src[i]; for(int j = 0; j < 3; j++) { maxp[j] = osg::maximum(pos[j],maxp[j]); mMin[j] = osg::minimum(pos[j],mMin[j]); } } osg::Vec3 diff = maxp - mMin; mScaleInv.set(0,0,0); if (diff[0] != 0) mScaleInv[0] = 2047.0/diff[0]; if (diff[1] != 0) mScaleInv[1] = 2047.0/diff[1]; if (diff[2] != 0) mScaleInv[2] = 1023.0/diff[2]; mScale[0] = diff[0] / 2047; mScale[1] = diff[1] / 2047; mScale[2] = diff[2] / 1023; } void compress(const std::vector& src) { mVecCompressed.resize(src.size()); // save all core keyframes for(int i = 0; i < (int)src.size(); i++) mVecCompressed[i].compress(src[i], mMin, mScaleInv); } }; } #endif