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