Panda3D
fltTransformRotateScale.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file fltTransformRotateScale.cxx
10  * @author drose
11  * @date 2000-08-30
12  */
13 
15 #include "fltRecordReader.h"
16 #include "fltRecordWriter.h"
17 
18 #include "mathNumbers.h"
19 #include "look_at.h"
20 
21 TypeHandle FltTransformRotateScale::_type_handle;
22 
23 /**
24  *
25  */
26 FltTransformRotateScale::
27 FltTransformRotateScale(FltHeader *header) : FltTransformRecord(header) {
28  _center.set(0.0, 0.0, 0.0);
29  _reference_point.set(0.0, 0.0, 0.0);
30  _to_point.set(0.0, 0.0, 0.0);
31  _overall_scale = 1.0;
32  _axis_scale = 1.0;
33  _angle = 0.0;
34 }
35 
36 /**
37  * Defines the transform explicitly. The angle of rotation is determined by
38  * the angle between the reference point and the to point (relative to the
39  * center), and the scale factor is determined by the distance between the
40  * reference point and the center point. If axis_scale is true, the scale is
41  * along reference point axis only; otherwise, it is a uniform scale.
42  */
44 set(const LPoint3d &center, const LPoint3d &reference_point,
45  const LPoint3d &to_point, bool axis_scale) {
46  _center = center;
47  _reference_point = reference_point;
48  _to_point = to_point;
49 
50  LVector3d v1 = _reference_point - _center;
51  LVector3d v2 = _to_point - _center;
52 
53  _angle =
54  acos(dot(normalize(v1), normalize(v2))) * 180.0 / MathNumbers::pi;
55 
56  if (axis_scale) {
57  _axis_scale = length(v1);
58  _overall_scale = 1.0;
59  } else {
60  _overall_scale = length(v1);
61  _axis_scale = 1.0;
62  }
63 
64  recompute_matrix();
65 }
66 
67 /**
68  *
69  */
70 const LPoint3d &FltTransformRotateScale::
71 get_center() const {
72  return _center;
73 }
74 
75 /**
76  *
77  */
78 const LPoint3d &FltTransformRotateScale::
79 get_reference_point() const {
80  return _reference_point;
81 }
82 
83 /**
84  *
85  */
86 const LPoint3d &FltTransformRotateScale::
87 get_to_point() const {
88  return _to_point;
89 }
90 
91 /**
92  * Returns the overall scale factor.
93  */
95 get_overall_scale() const {
96  return _overall_scale;
97 }
98 
99 /**
100  * Returns the scale factor in the direction of the axis.
101  */
103 get_axis_scale() const {
104  return _axis_scale;
105 }
106 
107 /**
108  * Returns the angle of rotation in degrees.
109  */
111 get_angle() const {
112  return _angle;
113 }
114 
115 /**
116  *
117  */
118 void FltTransformRotateScale::
119 recompute_matrix() {
120  LVector3d v1 = _reference_point - _center;
121  LVector3d v2 = _to_point - _center;
122  LVector3d rotate_axis = normalize(cross(v1, v2));
123 
124  // To scale along an axis, we have to do a bit of work. First determine the
125  // matrices to rotate and unrotate the rotate axis to the y-forward axis.
126  LMatrix4d r1;
127  look_at(r1, v1, rotate_axis, CS_zup_right);
128 
129  _matrix =
130  LMatrix4d::translate_mat(-_center) *
131  r1 *
132  LMatrix4d::scale_mat(1.0, _axis_scale, 1.0) *
133  LMatrix4d::scale_mat(_overall_scale) *
134  invert(r1) *
135  LMatrix4d::rotate_mat(_angle, rotate_axis, CS_zup_right) *
136  LMatrix4d::translate_mat(_center);
137 }
138 
139 /**
140  * Fills in the information in this record based on the information given in
141  * the indicated datagram, whose opcode has already been read. Returns true
142  * on success, false if the datagram is invalid.
143  */
144 bool FltTransformRotateScale::
145 extract_record(FltRecordReader &reader) {
146  if (!FltTransformRecord::extract_record(reader)) {
147  return false;
148  }
149 
150  nassertr(reader.get_opcode() == FO_rotate_and_scale, false);
151  DatagramIterator &iterator = reader.get_iterator();
152 
153  iterator.skip_bytes(4); // Undocumented additional padding.
154 
155  _center[0] = iterator.get_be_float64();
156  _center[1] = iterator.get_be_float64();
157  _center[2] = iterator.get_be_float64();
158  _reference_point[0] = iterator.get_be_float64();
159  _reference_point[1] = iterator.get_be_float64();
160  _reference_point[2] = iterator.get_be_float64();
161  _to_point[0] = iterator.get_be_float64();
162  _to_point[1] = iterator.get_be_float64();
163  _to_point[2] = iterator.get_be_float64();
164  _overall_scale = iterator.get_be_float32();
165  _axis_scale = iterator.get_be_float32();
166  _angle = iterator.get_be_float32();
167 
168  iterator.skip_bytes(4); // Undocumented additional padding.
169 
170  recompute_matrix();
171 
172  check_remaining_size(iterator);
173  return true;
174 }
175 
176 /**
177  * Fills up the current record on the FltRecordWriter with data for this
178  * record, but does not advance the writer. Returns true on success, false if
179  * there is some error.
180  */
181 bool FltTransformRotateScale::
182 build_record(FltRecordWriter &writer) const {
183  if (!FltTransformRecord::build_record(writer)) {
184  return false;
185  }
186 
187  writer.set_opcode(FO_put);
188  Datagram &datagram = writer.update_datagram();
189 
190  datagram.pad_bytes(4); // Undocumented additional padding.
191 
192  datagram.add_be_float64(_center[0]);
193  datagram.add_be_float64(_center[1]);
194  datagram.add_be_float64(_center[2]);
195  datagram.add_be_float64(_reference_point[0]);
196  datagram.add_be_float64(_reference_point[1]);
197  datagram.add_be_float64(_reference_point[2]);
198  datagram.add_be_float64(_to_point[0]);
199  datagram.add_be_float64(_to_point[1]);
200  datagram.add_be_float64(_to_point[2]);
201  datagram.add_be_float32(_overall_scale);
202  datagram.add_be_float32(_axis_scale);
203  datagram.add_be_float32(_angle);
204 
205  datagram.pad_bytes(4); // Undocumented additional padding.
206 
207  return true;
208 }
A class to retrieve the individual data elements previously stored in a Datagram.
void skip_bytes(size_t size)
Skips over the indicated number of bytes in the datagram.
PN_float32 get_be_float32()
Extracts a 32-bit big-endian single-precision floating-point number.
PN_float64 get_be_float64()
Extracts a 64-bit big-endian floating-point number.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_be_float32(PN_float32 value)
Adds a 32-bit single-precision big-endian floating-point number to the datagram.
Definition: datagram.I:200
void add_be_float64(PN_float64 value)
Adds a 64-bit big-endian floating-point number to the datagram.
Definition: datagram.I:209
void pad_bytes(size_t size)
Adds the indicated number of zero bytes to the datagram.
Definition: datagram.cxx:99
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:44
This class turns an istream into a sequence of FltRecords by reading a sequence of Datagrams and extr...
FltOpcode get_opcode() const
Returns the opcode associated with the current record.
DatagramIterator & get_iterator()
Returns an iterator suitable for extracting data from the current record.
This class writes a sequence of FltRecords to an ostream, handling opcode and size counts properly.
void set_opcode(FltOpcode opcode)
Sets the opcode associated with the current record.
Datagram & update_datagram()
Returns a modifiable reference to the datagram associated with the current record.
void check_remaining_size(const DatagramIterator &di, const std::string &name=std::string()) const
Checks that the iterator has no bytes left, as it should at the end of a successfully read record.
Definition: fltRecord.cxx:254
A base class for a number of types of ancillary records that follow beads and indicate some kind of a...
PN_stdfloat get_axis_scale() const
Returns the scale factor in the direction of the axis.
PN_stdfloat get_angle() const
Returns the angle of rotation in degrees.
void set(const LPoint3d &center, const LPoint3d &reference_point, const LPoint3d &to_point, bool axis_scale)
Defines the transform explicitly.
PN_stdfloat get_overall_scale() const
Returns the overall scale factor.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.