*** empty log message ***

This commit is contained in:
David Rose 2000-12-16 01:39:48 +00:00
parent 61070fad26
commit ba2608b7b4
3 changed files with 102 additions and 40 deletions

View File

@ -263,9 +263,9 @@ write_datagram(BamWriter *manager, Datagram &me)
max(max(_tables[3].size(), _tables[4].size()), _tables[5].size());
hprs.reserve(hprs_length);
for (i = 0; i < hprs_length; i++) {
float h = (i < (int)_tables[3].size()) ? _tables[3][i] : 0.0f;
float p = (i < (int)_tables[4].size()) ? _tables[4][i] : 0.0f;
float r = (i < (int)_tables[5].size()) ? _tables[5][i] : 0.0f;
float h = _tables[3].empty() ? 0.0f : _tables[3][i % _tables[3].size()];
float p = _tables[4].empty() ? 0.0f : _tables[4][i % _tables[4].size()];
float r = _tables[5].empty() ? 0.0f : _tables[5][i % _tables[5].size()];
hprs.push_back(LVecBase3f(h, p, r));
}
compressor.write_hprs(me, &hprs[0], hprs_length);

View File

@ -65,10 +65,15 @@ is_compression_available() {
// how aggressively the reals are compressed; lower
// numbers mean smaller output, and more data loss.
//
// As a special case, a negative quality indicates that
// the individual parameters should be separately
// controlled via config variables, and a quality
// greater than 100 indicates lossless output.
// There are a few special cases. Quality -1 means to
// use whatever individual parameters are set in the
// user's Configrc file, rather than the single quality
// dial. Quality 101 or higher means to generate
// lossless output (this is the default if libfftw is
// not available). Quality 102 writes all four
// components of quaternions to the output file, rather
// than just three, and quality 103 doesn't even convert
// hpr to quat.
////////////////////////////////////////////////////////////////////
void FFTCompressor::
set_quality(int quality) {
@ -84,11 +89,12 @@ set_quality(int quality) {
_quality = quality;
if (_quality < 0) {
// A negative quality indicates to read the important parameters
// from config variables.
// A negative quality indicates we should read the various
// parameters from individual config variables.
_fft_offset = fft_offset;
_fft_factor = fft_factor;
_fft_exponent = fft_exponent;
} else if (_quality < 40) {
// 0 - 40 :
// fft-offset 1.0 - 0.001
@ -191,29 +197,17 @@ write_reals(Datagram &datagram, const float *array, int length) {
}
// Normal case: FFT the array, and write that out.
double data[length];
double *data = (double *)alloca(length * sizeof(double));
int i;
for (i = 0; i < length; i++) {
data[i] = array[i];
}
double half_complex[length];
double *half_complex = (double *)alloca(length * sizeof(double));
rfftw_plan plan = get_real_compress_plan(length);
rfftw_one(plan, data, half_complex);
if (mathutil_cat.is_debug()) {
mathutil_cat.debug()
<< "write_reals :";
for (int i = 0; i < length; i++) {
double scale_factor = get_scale_factor(i, length);
mathutil_cat.debug(false)
// << " " << data[i];
<< " " << floor(half_complex[i] / scale_factor + 0.5);
}
mathutil_cat.debug(false) << "\n";
}
// Now encode the numbers, run-length encoded by size, so we only
// write out the number of bits we need for each number.
@ -281,6 +275,22 @@ write_reals(Datagram &datagram, const float *array, int length) {
////////////////////////////////////////////////////////////////////
void FFTCompressor::
write_hprs(Datagram &datagram, const LVecBase3f *array, int length) {
if (_quality >= 103) {
// If quality level is at least 103, we don't even convert hpr to
// quat.
vector_float h, p, r;
for (int i = 0; i < length; i++) {
h.push_back(array[i][0]);
p.push_back(array[i][1]);
r.push_back(array[i][2]);
}
write_reals(datagram, &h[0], length);
write_reals(datagram, &p[0], length);
write_reals(datagram, &r[0], length);
return;
}
// First, convert the HPR's to quats. We expect quats to have
// better FFT consistency, and therefore compress better, even
// though they have an extra component.
@ -289,11 +299,12 @@ write_hprs(Datagram &datagram, const LVecBase3f *array, int length) {
// have to write out all three components; any three can be used to
// determine the fourth (provided we ensure consistency of sign).
vector_float qi, qj, qk;
vector_float qr, qi, qj, qk;
for (int i = 0; i < length; i++) {
LMatrix3f mat;
compose_matrix(mat, LVecBase3f(1.0, 1.0, 1.0), array[i]);
LOrientationf rot;
rot.set(mat);
rot.normalize();
@ -312,11 +323,30 @@ write_hprs(Datagram &datagram, const LVecBase3f *array, int length) {
rot.set(-rot.get_r(), -rot.get_i(), -rot.get_j(), -rot.get_k());
}
/*
{
LMatrix3f mat2;
rot.extract_to_matrix(mat2);
LVecBase3f scale, hpr;
bool success = decompose_matrix(mat2, scale, hpr);
nassertv(success);
if (!array[i].almost_equal(hpr, 0.001)) {
cerr << "array " << array[i] << " hpr " << hpr << "\n";
}
}
*/
qr.push_back(rot.get_r());
qi.push_back(rot.get_i());
qj.push_back(rot.get_j());
qk.push_back(rot.get_k());
}
// If quality is at least 102, we write all four quat components,
// instead of just the three.
if (_quality >= 102) {
write_reals(datagram, &qr[0], length);
}
write_reals(datagram, &qi[0], length);
write_reals(datagram, &qj[0], length);
write_reals(datagram, &qk[0], length);
@ -336,6 +366,11 @@ bool FFTCompressor::
read_header(DatagramIterator &di) {
_quality = di.get_int8();
if (mathutil_cat.is_debug()) {
mathutil_cat.debug()
<< "Found compressed data at quality level " << _quality << "\n";
}
#ifndef HAVE_FFTW
if (_quality <= 100) {
mathutil_cat.error()
@ -410,7 +445,7 @@ read_reals(DatagramIterator &di, vector_float &array) {
half_complex[i] *= get_scale_factor(i, length);
}
double data[length];
double *data = (double *)alloca(length * sizeof(double));
rfftw_plan plan = get_real_decompress_plan(length);
rfftw_one(plan, &half_complex[0], data);
@ -420,16 +455,6 @@ read_reals(DatagramIterator &di, vector_float &array) {
array.push_back(data[i] * scale);
}
if (mathutil_cat.is_debug()) {
mathutil_cat.debug()
<< "read_reals :";
for (int i = 0; i < length; i++) {
mathutil_cat.debug(false)
<< " " << data[i] * scale;
}
mathutil_cat.debug(false) << "\n";
}
return true;
#endif
}
@ -444,11 +469,36 @@ read_reals(DatagramIterator &di, vector_float &array) {
////////////////////////////////////////////////////////////////////
bool FFTCompressor::
read_hprs(DatagramIterator &di, vector_LVecBase3f &array) {
vector_float qi, qj, qk;
if (_quality >= 103) {
// If quality level is at least 103, we don't even convert hpr to
// quat.
vector_float h, p, r;
bool okflag = true;
okflag =
read_reals(di, h) &&
read_reals(di, p) &&
read_reals(di, r);
if (okflag) {
nassertr(h.size() == p.size() && p.size() == r.size(), false);
for (int i = 0; i < (int)h.size(); i++) {
array.push_back(LVecBase3f(h[i], p[i], r[i]));
}
}
return okflag;
}
vector_float qr, qi, qj, qk;
bool okflag = true;
if (_quality >= 102) {
okflag = read_reals(di, qr);
}
okflag =
okflag &&
read_reals(di, qi) &&
read_reals(di, qj) &&
read_reals(di, qk);
@ -458,10 +508,20 @@ read_hprs(DatagramIterator &di, vector_LVecBase3f &array) {
array.reserve(array.size() + qi.size());
for (int i = 0; i < (int)qi.size(); i++) {
float qr2 = 1.0 - (qi[i] * qi[i] + qj[i] * qj[i] + qk[i] * qk[i]);
float qr = qr2 < 0.0 ? 0.0 : sqrtf(qr2);
LOrientationf rot;
if (_quality >= 102) {
// If we have written out all four components, use them.
rot.set(qr[i], qi[i], qj[i], qj[i]);
} else {
// Otherwise, infer the real component from the remaining
// three.
float qr2 = 1.0 - (qi[i] * qi[i] + qj[i] * qj[i] + qk[i] * qk[i]);
float qr1 = qr2 < 0.0 ? 0.0 : sqrtf(qr2);
rot.set(qr1, qi[i], qj[i], qk[i]);
}
LOrientationf rot(qr, qi[i], qj[i], qk[i]);
rot.normalize(); // Just for good measure.
LMatrix3f mat;

View File

@ -19,7 +19,9 @@ static const unsigned short _bam_major_ver = 3;
// Bumped to major version 2 on 7/6/00 due to major changes in Character.
// Bumped to major version 3 on 12/8/00 to change float64's to float32's.
static const unsigned short _bam_minor_ver = 0;
static const unsigned short _bam_minor_ver = 1;
// Bumped to minor version 1 on 12/15/00 to add FFT-style channel
// compression.
#endif