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