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