00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fltTransformRotateScale.h"
00016 #include "fltRecordReader.h"
00017 #include "fltRecordWriter.h"
00018
00019 #include "mathNumbers.h"
00020 #include "look_at.h"
00021
00022 TypeHandle FltTransformRotateScale::_type_handle;
00023
00024
00025
00026
00027
00028
00029 FltTransformRotateScale::
00030 FltTransformRotateScale(FltHeader *header) : FltTransformRecord(header) {
00031 _center.set(0.0, 0.0, 0.0);
00032 _reference_point.set(0.0, 0.0, 0.0);
00033 _to_point.set(0.0, 0.0, 0.0);
00034 _overall_scale = 1.0;
00035 _axis_scale = 1.0;
00036 _angle = 0.0;
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 void FltTransformRotateScale::
00052 set(const LPoint3d ¢er, const LPoint3d &reference_point,
00053 const LPoint3d &to_point, bool axis_scale) {
00054 _center = center;
00055 _reference_point = reference_point;
00056 _to_point = to_point;
00057
00058 LVector3d v1 = _reference_point - _center;
00059 LVector3d v2 = _to_point - _center;
00060
00061 _angle =
00062 acos(dot(normalize(v1), normalize(v2))) * 180.0 / MathNumbers::pi;
00063
00064 if (axis_scale) {
00065 _axis_scale = length(v1);
00066 _overall_scale = 1.0;
00067 } else {
00068 _overall_scale = length(v1);
00069 _axis_scale = 1.0;
00070 }
00071
00072 recompute_matrix();
00073 }
00074
00075
00076
00077
00078
00079
00080 const LPoint3d &FltTransformRotateScale::
00081 get_center() const {
00082 return _center;
00083 }
00084
00085
00086
00087
00088
00089
00090 const LPoint3d &FltTransformRotateScale::
00091 get_reference_point() const {
00092 return _reference_point;
00093 }
00094
00095
00096
00097
00098
00099
00100 const LPoint3d &FltTransformRotateScale::
00101 get_to_point() const {
00102 return _to_point;
00103 }
00104
00105
00106
00107
00108
00109
00110 PN_stdfloat FltTransformRotateScale::
00111 get_overall_scale() const {
00112 return _overall_scale;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 PN_stdfloat FltTransformRotateScale::
00122 get_axis_scale() const {
00123 return _axis_scale;
00124 }
00125
00126
00127
00128
00129
00130
00131 PN_stdfloat FltTransformRotateScale::
00132 get_angle() const {
00133 return _angle;
00134 }
00135
00136
00137
00138
00139
00140
00141 void FltTransformRotateScale::
00142 recompute_matrix() {
00143 LVector3d v1 = _reference_point - _center;
00144 LVector3d v2 = _to_point - _center;
00145 LVector3d rotate_axis = normalize(cross(v1, v2));
00146
00147
00148
00149
00150 LMatrix4d r1;
00151 look_at(r1, v1, rotate_axis, CS_zup_right);
00152
00153 _matrix =
00154 LMatrix4d::translate_mat(-_center) *
00155 r1 *
00156 LMatrix4d::scale_mat(1.0, _axis_scale, 1.0) *
00157 LMatrix4d::scale_mat(_overall_scale) *
00158 invert(r1) *
00159 LMatrix4d::rotate_mat(_angle, rotate_axis, CS_zup_right) *
00160 LMatrix4d::translate_mat(_center);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 bool FltTransformRotateScale::
00172 extract_record(FltRecordReader &reader) {
00173 if (!FltTransformRecord::extract_record(reader)) {
00174 return false;
00175 }
00176
00177 nassertr(reader.get_opcode() == FO_rotate_and_scale, false);
00178 DatagramIterator &iterator = reader.get_iterator();
00179
00180 iterator.skip_bytes(4);
00181
00182 _center[0] = iterator.get_be_float64();
00183 _center[1] = iterator.get_be_float64();
00184 _center[2] = iterator.get_be_float64();
00185 _reference_point[0] = iterator.get_be_float64();
00186 _reference_point[1] = iterator.get_be_float64();
00187 _reference_point[2] = iterator.get_be_float64();
00188 _to_point[0] = iterator.get_be_float64();
00189 _to_point[1] = iterator.get_be_float64();
00190 _to_point[2] = iterator.get_be_float64();
00191 _overall_scale = iterator.get_be_float32();
00192 _axis_scale = iterator.get_be_float32();
00193 _angle = iterator.get_be_float32();
00194
00195 iterator.skip_bytes(4);
00196
00197 recompute_matrix();
00198
00199 check_remaining_size(iterator);
00200 return true;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 bool FltTransformRotateScale::
00212 build_record(FltRecordWriter &writer) const {
00213 if (!FltTransformRecord::build_record(writer)) {
00214 return false;
00215 }
00216
00217 writer.set_opcode(FO_put);
00218 Datagram &datagram = writer.update_datagram();
00219
00220 datagram.pad_bytes(4);
00221
00222 datagram.add_be_float64(_center[0]);
00223 datagram.add_be_float64(_center[1]);
00224 datagram.add_be_float64(_center[2]);
00225 datagram.add_be_float64(_reference_point[0]);
00226 datagram.add_be_float64(_reference_point[1]);
00227 datagram.add_be_float64(_reference_point[2]);
00228 datagram.add_be_float64(_to_point[0]);
00229 datagram.add_be_float64(_to_point[1]);
00230 datagram.add_be_float64(_to_point[2]);
00231 datagram.add_be_float32(_overall_scale);
00232 datagram.add_be_float32(_axis_scale);
00233 datagram.add_be_float32(_angle);
00234
00235 datagram.pad_bytes(4);
00236
00237 return true;
00238 }
00239