00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fltToEggLevelState.h"
00016 #include "fltToEggConverter.h"
00017 #include "fltTransformTranslate.h"
00018 #include "fltTransformRotateAboutPoint.h"
00019 #include "fltTransformRotateAboutEdge.h"
00020 #include "fltTransformScale.h"
00021 #include "fltTransformPut.h"
00022 #include "eggGroup.h"
00023 #include "dcast.h"
00024 #include "look_at.h"
00025
00026
00027
00028
00029
00030
00031
00032 FltToEggLevelState::
00033 ~FltToEggLevelState() {
00034 Parents::iterator pi;
00035 for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
00036 delete (*pi).second;
00037 }
00038 }
00039
00040
00041
00042
00043
00044
00045 FltToEggLevelState::ParentNodes::
00046 ParentNodes() {
00047 _axial_billboard = (EggGroup *)NULL;
00048 _point_billboard = (EggGroup *)NULL;
00049 _plain = (EggGroup *)NULL;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 EggGroupNode *FltToEggLevelState::
00068 get_synthetic_group(const string &name,
00069 const FltBead *transform_bead,
00070 FltGeometry::BillboardType type) {
00071 LMatrix4d transform = transform_bead->get_transform();
00072 bool is_identity = transform.almost_equal(LMatrix4d::ident_mat());
00073 if (is_identity &&
00074 (type != FltGeometry::BT_axial &&
00075 type != FltGeometry::BT_point)) {
00076
00077
00078 return _egg_parent;
00079 }
00080
00081
00082
00083 Parents::iterator pi;
00084 pi = _parents.find(transform);
00085 ParentNodes *nodes;
00086 if (pi != _parents.end()) {
00087 nodes = (*pi).second;
00088 } else {
00089 nodes = new ParentNodes;
00090 _parents.insert(Parents::value_type(transform, nodes));
00091 }
00092
00093 switch (type) {
00094 case FltGeometry::BT_axial:
00095 if (nodes->_axial_billboard == (EggGroupNode *)NULL) {
00096 nodes->_axial_billboard = new EggGroup(name);
00097 _egg_parent->add_child(nodes->_axial_billboard);
00098 nodes->_axial_billboard->set_billboard_type(EggGroup::BT_axis);
00099 if (!is_identity) {
00100 set_transform(transform_bead, nodes->_axial_billboard);
00101 nodes->_axial_billboard->set_group_type(EggGroup::GT_instance);
00102 }
00103 }
00104 return nodes->_axial_billboard;
00105
00106 case FltGeometry::BT_point:
00107 if (nodes->_point_billboard == (EggGroupNode *)NULL) {
00108 nodes->_point_billboard = new EggGroup(name);
00109 _egg_parent->add_child(nodes->_point_billboard);
00110 nodes->_point_billboard->set_billboard_type(EggGroup::BT_point_world_relative);
00111 if (!is_identity) {
00112 set_transform(transform_bead, nodes->_point_billboard);
00113 nodes->_point_billboard->set_group_type(EggGroup::GT_instance);
00114 }
00115 }
00116 return nodes->_point_billboard;
00117
00118 default:
00119
00120 if (nodes->_plain == (EggGroupNode *)NULL) {
00121 nodes->_plain = new EggGroup(name);
00122 _egg_parent->add_child(nodes->_plain);
00123 if (!is_identity) {
00124 set_transform(transform_bead, nodes->_plain);
00125 nodes->_plain->set_group_type(EggGroup::GT_instance);
00126 }
00127 }
00128 return nodes->_plain;
00129 }
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 void FltToEggLevelState::
00139 set_transform(const FltBead *flt_bead, EggGroup *egg_group) {
00140 if (flt_bead->has_transform()) {
00141 egg_group->set_group_type(EggGroup::GT_instance);
00142
00143 int num_steps = flt_bead->get_num_transform_steps();
00144 bool componentwise_ok = !_converter->_compose_transforms;
00145
00146 if (num_steps == 0) {
00147 componentwise_ok = false;
00148 } else {
00149
00150
00151
00152
00153 egg_group->clear_transform();
00154 for (int i = num_steps -1; i >= 0 && componentwise_ok; i--) {
00155 const FltTransformRecord *step = flt_bead->get_transform_step(i);
00156 if (step->is_exact_type(FltTransformTranslate::get_class_type())) {
00157 const FltTransformTranslate *trans;
00158 DCAST_INTO_V(trans, step);
00159 if (!trans->get_delta().almost_equal(LVector3d::zero())) {
00160 egg_group->add_translate3d(trans->get_delta());
00161 }
00162
00163 } else if (step->is_exact_type(FltTransformRotateAboutPoint::get_class_type())) {
00164 const FltTransformRotateAboutPoint *rap;
00165 DCAST_INTO_V(rap, step);
00166 if (!IS_NEARLY_ZERO(rap->get_angle())) {
00167 if (!rap->get_center().almost_equal(LVector3d::zero())) {
00168 egg_group->add_translate3d(-rap->get_center());
00169 }
00170 LVector3d axis = LCAST(double, rap->get_axis());
00171 egg_group->add_rotate3d(rap->get_angle(), axis);
00172 if (!rap->get_center().almost_equal(LVector3d::zero())) {
00173 egg_group->add_translate3d(rap->get_center());
00174 }
00175 }
00176
00177 } else if (step->is_exact_type(FltTransformRotateAboutEdge::get_class_type())) {
00178 const FltTransformRotateAboutEdge *rae;
00179 DCAST_INTO_V(rae, step);
00180 if (!IS_NEARLY_ZERO(rae->get_angle())) {
00181 if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
00182 egg_group->add_translate3d(-rae->get_point_a());
00183 }
00184 LVector3d axis = rae->get_point_b() - rae->get_point_a();
00185 egg_group->add_rotate3d(rae->get_angle(), axis);
00186 if (!rae->get_point_a().almost_equal(LVector3d::zero())) {
00187 egg_group->add_translate3d(rae->get_point_a());
00188 }
00189 }
00190
00191 } else if (step->is_exact_type(FltTransformScale::get_class_type())) {
00192 const FltTransformScale *scale;
00193 DCAST_INTO_V(scale, step);
00194 if (!scale->get_scale().almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
00195 if (scale->has_center() &&
00196 !scale->get_center().almost_equal(LVector3d::zero())) {
00197 egg_group->add_translate3d(-scale->get_center());
00198 }
00199 egg_group->add_scale3d(LCAST(double, scale->get_scale()));
00200 if (scale->has_center() &&
00201 !scale->get_center().almost_equal(LVector3d::zero())) {
00202 egg_group->add_translate3d(scale->get_center());
00203 }
00204 }
00205
00206 } else if (step->is_exact_type(FltTransformPut::get_class_type())) {
00207 const FltTransformPut *put;
00208 DCAST_INTO_V(put, step);
00209
00210 if (!put->get_from_origin().almost_equal(LVector3d::zero())) {
00211 egg_group->add_translate3d(-put->get_from_origin());
00212 }
00213 LQuaterniond q1, q2;
00214 look_at(q1, put->get_from_align() - put->get_from_origin(),
00215 put->get_from_track() - put->get_from_origin(),
00216 CS_zup_right);
00217 look_at(q2, put->get_to_align() - put->get_to_origin(),
00218 put->get_to_track() - put->get_to_origin(),
00219 CS_zup_right);
00220
00221 LQuaterniond q = invert(q1) * q2;
00222
00223 if (!q.is_identity()) {
00224 egg_group->add_rotate3d(q);
00225 }
00226 if (!put->get_to_origin().almost_equal(LVector3d::zero())) {
00227 egg_group->add_translate3d(put->get_to_origin());
00228 }
00229
00230 } else {
00231
00232
00233 componentwise_ok = false;
00234 }
00235 }
00236 }
00237
00238 if (!componentwise_ok) {
00239 egg_group->set_transform3d(flt_bead->get_transform());
00240 }
00241 }
00242 }