| 1 | /* -*-c++-*- |
|---|
| 2 | */ |
|---|
| 3 | //****************************************************************************// |
|---|
| 4 | // loader.cpp // |
|---|
| 5 | // Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger // |
|---|
| 6 | //****************************************************************************// |
|---|
| 7 | // This library is free software; you can redistribute it and/or modify it // |
|---|
| 8 | // under the terms of the GNU Lesser General Public License as published by // |
|---|
| 9 | // the Free Software Foundation; either version 2.1 of the License, or (at // |
|---|
| 10 | // your option) any later version. // |
|---|
| 11 | //****************************************************************************// |
|---|
| 12 | |
|---|
| 13 | /*****************************************************************************/ |
|---|
| 14 | /* Loads a core compressed keyframe instance. |
|---|
| 15 | * |
|---|
| 16 | * This function loads a core compressed keyframe instance from a data source. |
|---|
| 17 | * |
|---|
| 18 | * @param dataSrc The data source to load the core compressed keyframe instance from. |
|---|
| 19 | * |
|---|
| 20 | * @return One of the following values: |
|---|
| 21 | * \li a pointer to the core keyframe |
|---|
| 22 | * \li \b 0 if an error happened |
|---|
| 23 | * Authors |
|---|
| 24 | * Igor Kravchenko |
|---|
| 25 | * Cedric Pinson <mornifle@plopbyte.net> |
|---|
| 26 | *****************************************************************************/ |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | #ifndef OSGANIMATION_PACKED_H |
|---|
| 30 | #define OSGANIMATION_PACKED_H |
|---|
| 31 | |
|---|
| 32 | #include <float.h> |
|---|
| 33 | #include <vector> |
|---|
| 34 | #include <osg/Vec3> |
|---|
| 35 | #include <osg/Math> |
|---|
| 36 | |
|---|
| 37 | namespace osgAnimation |
|---|
| 38 | { |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | struct Vec3Packed |
|---|
| 42 | { |
|---|
| 43 | typedef unsigned int uint32_t; |
|---|
| 44 | uint32_t m32bits; |
|---|
| 45 | Vec3Packed(uint32_t val): m32bits(val) {} |
|---|
| 46 | Vec3Packed(): m32bits(0) {} |
|---|
| 47 | |
|---|
| 48 | void uncompress(const osg::Vec3& scale, const osg::Vec3& min, osg::Vec3& result) const |
|---|
| 49 | { |
|---|
| 50 | uint32_t pt[3]; |
|---|
| 51 | pt[0] = m32bits & 0x7ff; |
|---|
| 52 | pt[1] = (m32bits >> 11) & 0x7ff; |
|---|
| 53 | pt[2] = m32bits >> 22; |
|---|
| 54 | result[0] = scale[0] * pt[0] + min[0]; |
|---|
| 55 | result[1] = scale[1] * pt[1] + min[1]; |
|---|
| 56 | result[2] = scale[2] * pt[2] + min[2]; |
|---|
| 57 | } |
|---|
| 58 | |
|---|
| 59 | void compress(const osg::Vec3f& src, const osg::Vec3f& min, const osg::Vec3f& scaleInv) |
|---|
| 60 | { |
|---|
| 61 | uint32_t srci[3]; |
|---|
| 62 | srci[0] = osg::minimum(static_cast<uint32_t>(((src[0] - min[0] )*scaleInv[0])), uint32_t(2047)); |
|---|
| 63 | srci[1] = osg::minimum(static_cast<uint32_t>(((src[1] - min[1] )*scaleInv[1])), uint32_t(2047)); |
|---|
| 64 | srci[2] = osg::minimum(static_cast<uint32_t>(((src[2] - min[2] )*scaleInv[2])), uint32_t(1023)); |
|---|
| 65 | m32bits = srci[0] + (srci[1] << 11) + (srci[2] << 22); |
|---|
| 66 | } |
|---|
| 67 | }; |
|---|
| 68 | |
|---|
| 69 | struct Vec3ArrayPacked |
|---|
| 70 | { |
|---|
| 71 | std::vector<Vec3Packed> mVecCompressed; |
|---|
| 72 | osg::Vec3 mMin; |
|---|
| 73 | osg::Vec3 mScale; |
|---|
| 74 | osg::Vec3 mScaleInv; |
|---|
| 75 | |
|---|
| 76 | void analyze(const std::vector<osg::Vec3>& src) |
|---|
| 77 | { |
|---|
| 78 | //analyze the keys |
|---|
| 79 | mMin.set(FLT_MAX, FLT_MAX, FLT_MAX); |
|---|
| 80 | osg::Vec3 maxp(-FLT_MAX, -FLT_MAX, -FLT_MAX); |
|---|
| 81 | int nb = (int)src.size(); |
|---|
| 82 | for(int i = 0; i < nb; i++) |
|---|
| 83 | { |
|---|
| 84 | const osg::Vec3 &pos = src[i]; |
|---|
| 85 | for(int j = 0; j < 3; j++) |
|---|
| 86 | { |
|---|
| 87 | maxp[j] = osg::maximum(pos[j],maxp[j]); |
|---|
| 88 | mMin[j] = osg::minimum(pos[j],mMin[j]); |
|---|
| 89 | } |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | osg::Vec3 diff = maxp - mMin; |
|---|
| 93 | mScaleInv.set(0,0,0); |
|---|
| 94 | if (diff[0] != 0) |
|---|
| 95 | mScaleInv[0] = 2047.0/diff[0]; |
|---|
| 96 | |
|---|
| 97 | if (diff[1] != 0) |
|---|
| 98 | mScaleInv[1] = 2047.0/diff[1]; |
|---|
| 99 | |
|---|
| 100 | if (diff[2] != 0) |
|---|
| 101 | mScaleInv[2] = 1023.0/diff[2]; |
|---|
| 102 | |
|---|
| 103 | mScale[0] = diff[0] / 2047; |
|---|
| 104 | mScale[1] = diff[1] / 2047; |
|---|
| 105 | mScale[2] = diff[2] / 1023; |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | void compress(const std::vector<osg::Vec3>& src) |
|---|
| 109 | { |
|---|
| 110 | mVecCompressed.resize(src.size()); |
|---|
| 111 | // save all core keyframes |
|---|
| 112 | for(int i = 0; i < (int)src.size(); i++) |
|---|
| 113 | mVecCompressed[i].compress(src[i], mMin, mScaleInv); |
|---|
| 114 | } |
|---|
| 115 | }; |
|---|
| 116 | |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | #endif |
|---|