161 lines
5.2 KiB
C++
161 lines
5.2 KiB
C++
// Filename: movingPartMatrix.cxx
|
|
// Created by: drose (23Feb99)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://www.panda3d.org/license.txt .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d@yahoogroups.com .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include "movingPartMatrix.h"
|
|
|
|
#include <compose_matrix.h>
|
|
#include <datagram.h>
|
|
#include <datagramIterator.h>
|
|
#include <bamReader.h>
|
|
#include <bamWriter.h>
|
|
|
|
// Tell GCC that we'll take care of the instantiation explicitly here.
|
|
#ifdef __GNUC__
|
|
#pragma implementation
|
|
#endif
|
|
|
|
TypeHandle MovingPartMatrix::_type_handle;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: MovingPartMatrix::get_blend_value
|
|
// Access: Public
|
|
// Description: Attempts to blend the various matrix values
|
|
// indicated, and sets the _value member to the
|
|
// resulting matrix.
|
|
////////////////////////////////////////////////////////////////////
|
|
void MovingPartMatrix::
|
|
get_blend_value(const PartBundle *root) {
|
|
const PartBundle::ChannelBlend &blend = root->get_blend_map();
|
|
|
|
if (blend.empty()) {
|
|
// No channel is bound; supply the default value.
|
|
_value = _initial_value;
|
|
|
|
} else if (blend.size() == 1) {
|
|
// A single value, the normal case.
|
|
AnimControl *control = (*blend.begin()).first;
|
|
|
|
int channel_index = control->get_channel_index();
|
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
|
nassertv(channel != NULL);
|
|
|
|
channel->get_value(control->get_frame(), _value);
|
|
|
|
} else {
|
|
// A blend of two or more values.
|
|
|
|
if (root->get_blend_type() == PartBundle::BT_linear) {
|
|
// An ordinary, linear blend.
|
|
_value = 0.0;
|
|
float net = 0.0;
|
|
|
|
PartBundle::ChannelBlend::const_iterator cbi;
|
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
|
AnimControl *control = (*cbi).first;
|
|
float effect = (*cbi).second;
|
|
nassertv(effect != 0.0);
|
|
|
|
int channel_index = control->get_channel_index();
|
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
|
nassertv(channel != NULL);
|
|
|
|
ValueType v;
|
|
channel->get_value(control->get_frame(), v);
|
|
|
|
_value += v * effect;
|
|
net += effect;
|
|
}
|
|
|
|
nassertv(net != 0.0);
|
|
_value /= net;
|
|
|
|
} else if (root->get_blend_type() == PartBundle::BT_normalized_linear) {
|
|
// A normalized linear blend. This means we do a linear blend
|
|
// without scales, normalize the scale components of the
|
|
// resulting matrix to eliminate artificially-introduced scales,
|
|
// and then reapply the scales.
|
|
|
|
_value = 0.0;
|
|
LVector3f scale(0.0, 0.0, 0.0);
|
|
float net = 0.0;
|
|
|
|
PartBundle::ChannelBlend::const_iterator cbi;
|
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
|
AnimControl *control = (*cbi).first;
|
|
float effect = (*cbi).second;
|
|
nassertv(effect != 0.0);
|
|
|
|
int channel_index = control->get_channel_index();
|
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
|
nassertv(channel != NULL);
|
|
|
|
ValueType v;
|
|
channel->get_value_no_scale(control->get_frame(), v);
|
|
LVector3f s;
|
|
channel->get_scale(control->get_frame(), &s[0]);
|
|
|
|
_value += v * effect;
|
|
scale += s * effect;
|
|
net += effect;
|
|
}
|
|
|
|
nassertv(net != 0.0);
|
|
_value /= net;
|
|
scale /= net;
|
|
|
|
// Now rebuild the matrix with the correct scale values.
|
|
|
|
LVector3f false_scale, hpr, translate;
|
|
decompose_matrix(_value, false_scale, hpr, translate);
|
|
compose_matrix(_value, scale, hpr, translate);
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: MovingPartMatrix::make_MovingPartMatrix
|
|
// Access: Protected
|
|
// Description: Factory method to generate a MovingPartMatrix object
|
|
////////////////////////////////////////////////////////////////////
|
|
TypedWritable* MovingPartMatrix::
|
|
make_MovingPartMatrix(const FactoryParams ¶ms)
|
|
{
|
|
MovingPartMatrix *me = new MovingPartMatrix;
|
|
DatagramIterator scan;
|
|
BamReader *manager;
|
|
|
|
parse_params(params, scan, manager);
|
|
me->fillin(scan, manager);
|
|
return me;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: MovingPartMatrix::register_with_factory
|
|
// Access: Public, Static
|
|
// Description: Factory method to generate a MovingPartMatrix object
|
|
////////////////////////////////////////////////////////////////////
|
|
void MovingPartMatrix::
|
|
register_with_read_factory(void)
|
|
{
|
|
BamReader::get_factory()->register_factory(get_class_type(), make_MovingPartMatrix);
|
|
}
|