convert flt files with componentwise transforms

This commit is contained in:
David Rose 2002-06-23 00:02:27 +00:00
parent 0a0f53ffda
commit 3ab477ccbf
6 changed files with 152 additions and 33 deletions

View File

@ -129,6 +129,20 @@ get_transform_step(int n) {
return _transform_steps[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::get_transform_step
// Access: Public
// Description: Returns the nth individual step that defines
// the net transform on this bead. See
// get_num_transform_steps().
////////////////////////////////////////////////////////////////////
const FltTransformRecord *FltBead::
get_transform_step(int n) const {
nassertr(n >= 0 && n < (int)_transform_steps.size(),
(const FltTransformRecord *)NULL);
return _transform_steps[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::add_transform_step
// Access: Public

View File

@ -45,6 +45,7 @@ public:
int get_num_transform_steps() const;
FltTransformRecord *get_transform_step(int n);
const FltTransformRecord *get_transform_step(int n) const;
void add_transform_step(FltTransformRecord *record);
int get_replicate_count() const;

View File

@ -251,7 +251,7 @@ convert_lod(const FltLOD *flt_lod, FltToEggLevelState &state) {
flt_lod->_transition_range);
egg_group->set_lod(lod);
set_transform(flt_lod, egg_group);
state.set_transform(flt_lod, egg_group);
parse_comment(flt_lod, egg_group);
FltToEggLevelState next_state(state);
@ -275,7 +275,7 @@ convert_group(const FltGroup *flt_group, FltToEggLevelState &state) {
egg_group->set_switch_fps(24.0);
}
set_transform(flt_group, egg_group);
state.set_transform(flt_group, egg_group);
parse_comment(flt_group, egg_group);
///*** replicate count.
@ -295,7 +295,7 @@ convert_object(const FltObject *flt_object, FltToEggLevelState &state) {
EggGroup *egg_group = new EggGroup(flt_object->get_id());
state._egg_parent->add_child(egg_group);
set_transform(flt_object, egg_group);
state.set_transform(flt_object, egg_group);
parse_comment(flt_object, egg_group);
FltToEggLevelState next_state(state);
@ -317,7 +317,7 @@ convert_bead_id(const FltBeadID *flt_bead, FltToEggLevelState &state) {
EggGroup *egg_group = new EggGroup(flt_bead->get_id());
state._egg_parent->add_child(egg_group);
set_transform(flt_bead, egg_group);
state.set_transform(flt_bead, egg_group);
parse_comment(flt_bead, egg_group);
FltToEggLevelState next_state(state);
@ -338,7 +338,7 @@ convert_bead(const FltBead *flt_bead, FltToEggLevelState &state) {
EggGroup *egg_group = new EggGroup;
state._egg_parent->add_child(egg_group);
set_transform(flt_bead, egg_group);
state.set_transform(flt_bead, egg_group);
parse_comment(flt_bead, egg_group);
FltToEggLevelState next_state(state);
@ -404,7 +404,7 @@ void FltToEggConverter::
convert_ext_ref(const FltExternalReference *flt_ext, FltToEggLevelState &state) {
// Get a group node to put the reference into.
EggGroupNode *egg_parent =
state.get_synthetic_group("", flt_ext->get_transform());
state.get_synthetic_group("", flt_ext);
handle_external_reference(egg_parent,
flt_ext->_filename, _flt_header->get_model_path());
@ -426,7 +426,7 @@ setup_geometry(const FltGeometry *flt_geom, FltToEggLevelState &state,
// Determine what the appropriate parent will be.
EggGroupNode *egg_parent =
state.get_synthetic_group(flt_geom->get_id(), flt_geom->get_transform(),
state.get_synthetic_group(flt_geom->get_id(), flt_geom,
flt_geom->_billboard_type);
// Create a new state to reflect the new parent.
@ -579,20 +579,6 @@ convert_subfaces(const FltRecord *flt_record, FltToEggLevelState &state) {
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::set_transform
// Access: Private
// Description: Sets up the group to reflect the transform indicated
// by the given record, if any.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
if (flt_bead->has_transform()) {
egg_group->set_transform(flt_bead->get_transform());
egg_group->set_group_type(EggGroup::GT_instance);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::parse_comment
// Access: Private

View File

@ -88,7 +88,6 @@ private:
void convert_subfaces(const FltRecord *flt_record, FltToEggLevelState &state);
void set_transform(const FltBead *flt_bead, EggGroup *egg_group);
bool parse_comment(const FltBeadID *flt_bead, EggNode *egg_node);
bool parse_comment(const FltBead *flt_bead, EggNode *egg_node);
bool parse_comment(const FltTexture *flt_texture, EggNode *egg_node);

View File

@ -17,8 +17,14 @@
////////////////////////////////////////////////////////////////////
#include "fltToEggLevelState.h"
#include <eggGroup.h>
#include "fltTransformTranslate.h"
#include "fltTransformRotateAboutPoint.h"
#include "fltTransformRotateAboutEdge.h"
#include "fltTransformScale.h"
#include "fltTransformPut.h"
#include "eggGroup.h"
#include "dcast.h"
#include "look_at.h"
////////////////////////////////////////////////////////////////////
@ -63,9 +69,9 @@ ParentNodes() {
////////////////////////////////////////////////////////////////////
EggGroupNode *FltToEggLevelState::
get_synthetic_group(const string &name,
const LMatrix4d &transform,
const FltBead *transform_bead,
FltGeometry::BillboardType type) {
LMatrix4d transform = transform_bead->get_transform();
bool is_identity = transform.almost_equal(LMatrix4d::ident_mat());
if (is_identity &&
(type != FltGeometry::BT_axial &&
@ -94,7 +100,7 @@ get_synthetic_group(const string &name,
_egg_parent->add_child(nodes->_axial_billboard);
nodes->_axial_billboard->set_billboard_type(EggGroup::BT_axis);
if (!is_identity) {
nodes->_axial_billboard->set_transform(transform);
set_transform(transform_bead, nodes->_axial_billboard);
nodes->_axial_billboard->set_group_type(EggGroup::GT_instance);
}
}
@ -106,7 +112,7 @@ get_synthetic_group(const string &name,
_egg_parent->add_child(nodes->_point_billboard);
nodes->_point_billboard->set_billboard_type(EggGroup::BT_point_world_relative);
if (!is_identity) {
nodes->_point_billboard->set_transform(transform);
set_transform(transform_bead, nodes->_point_billboard);
nodes->_point_billboard->set_group_type(EggGroup::GT_instance);
}
}
@ -118,10 +124,121 @@ get_synthetic_group(const string &name,
nodes->_plain = new EggGroup(name);
_egg_parent->add_child(nodes->_plain);
if (!is_identity) {
nodes->_plain->set_transform(transform);
set_transform(transform_bead, nodes->_plain);
nodes->_plain->set_group_type(EggGroup::GT_instance);
}
}
return nodes->_plain;
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggLevelState::set_transform
// Access: Public, Static
// Description: Sets up the group to reflect the transform indicated
// by the given record, if any.
////////////////////////////////////////////////////////////////////
void FltToEggLevelState::
set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
if (flt_bead->has_transform()) {
egg_group->set_group_type(EggGroup::GT_instance);
int num_steps = flt_bead->get_num_transform_steps();
bool componentwise_ok = true;
if (num_steps == 0) {
componentwise_ok = false;
} else {
// Walk through each transform step and store the individual
// components in the egg file. If we come across a step we
// don't know how to interpret, just store the whole transform
// matrix in the egg file.
egg_group->clear_transform();
for (int i = 0; i < num_steps && componentwise_ok; i++) {
const FltTransformRecord *step = flt_bead->get_transform_step(i);
if (step->is_exact_type(FltTransformTranslate::get_class_type())) {
const FltTransformTranslate *trans;
DCAST_INTO_V(trans, step);
if (!trans->get_delta().almost_equal(LVector3d::zero())) {
egg_group->add_translate(trans->get_delta());
}
} else if (step->is_exact_type(FltTransformRotateAboutPoint::get_class_type())) {
const FltTransformRotateAboutPoint *rap;
DCAST_INTO_V(rap, step);
if (!IS_NEARLY_ZERO(rap->get_angle())) {
if (!rap->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-rap->get_center());
}
LVector3d axis = LCAST(double, rap->get_axis());
egg_group->add_rotate(rap->get_angle(), axis);
if (!rap->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(rap->get_center());
}
}
} else if (step->is_exact_type(FltTransformRotateAboutEdge::get_class_type())) {
const FltTransformRotateAboutEdge *rae;
DCAST_INTO_V(rae, step);
if (!IS_NEARLY_ZERO(rae->get_angle())) {
if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-rae->get_point_a());
}
LVector3d axis = rae->get_point_b() - rae->get_point_a();
egg_group->add_rotate(rae->get_angle(), axis);
if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
egg_group->add_translate(rae->get_point_a());
}
}
} else if (step->is_exact_type(FltTransformScale::get_class_type())) {
const FltTransformScale *scale;
DCAST_INTO_V(scale, step);
if (!scale->get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) {
if (!scale->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-scale->get_center());
}
egg_group->add_scale(LCAST(double, scale->get_scale()));
if (!scale->get_center().almost_equal(LVector3d::zero())) {
egg_group->add_translate(scale->get_center());
}
}
} else if (step->is_exact_type(FltTransformPut::get_class_type())) {
const FltTransformPut *put;
DCAST_INTO_V(put, step);
if (!put->get_from_origin().almost_equal(LVector3d::zero())) {
egg_group->add_translate(-put->get_from_origin());
}
LQuaterniond q1, q2;
look_at(q1, put->get_from_align() - put->get_from_origin(),
put->get_from_track() - put->get_from_origin(),
CS_zup_right);
look_at(q2, put->get_to_align() - put->get_to_origin(),
put->get_to_track() - put->get_to_origin(),
CS_zup_right);
LQuaterniond q = invert(q1) * q2;
if (!q.is_identity()) {
egg_group->add_rotate(q);
}
if (!put->get_to_origin().almost_equal(LVector3d::zero())) {
egg_group->add_translate(put->get_to_origin());
}
} else {
// Here's a transform component we haven't implemented here.
// Give up on storing the componentwise transform.
componentwise_ok = false;
}
}
}
if (!componentwise_ok) {
egg_group->set_transform(flt_bead->get_transform());
}
}
}

View File

@ -19,11 +19,11 @@
#ifndef FLTTOEGGLEVELSTATE_H
#define FLTTOEGGLEVELSTATE_H
#include <pandatoolbase.h>
#include <fltGeometry.h>
#include "pandatoolbase.h"
#include "fltGeometry.h"
class FltObject;
class FltBead;
class EggGroupNode;
class EggGroup;
@ -40,9 +40,11 @@ public:
~FltToEggLevelState();
EggGroupNode *get_synthetic_group(const string &name,
const LMatrix4d &transform,
const FltBead *transform_bead,
FltGeometry::BillboardType type = FltGeometry::BT_none);
static void set_transform(const FltBead *flt_bead, EggGroup *egg_group);
const FltObject *_flt_object;
EggGroupNode *_egg_parent;