open_dis_rust/entity_information/
collision_elastic_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_coordinate_vector::EntityCoordinateVector,
13 entity_id::EntityId,
14 event_id::EventId,
15 linear_velocity::LinearVelocity,
16 pdu::Pdu,
17 pdu_header::{PduHeader, PduType, ProtocolFamily},
18};
19
20#[derive(Clone, Debug)]
21pub struct CollisionElasticPdu {
23 pub pdu_header: PduHeader,
24 pub issuing_entity_id: EntityId,
25 pub colliding_entity_id: EntityId,
26 pub event_id: EventId,
27 pub padding: u16,
28 pub contact_velocity: LinearVelocity,
29 pub mass: f32,
30 pub location_of_impact: EntityCoordinateVector,
31 pub collision_intermediate_result_xx: f32,
32 pub collision_intermediate_result_xy: f32,
33 pub collision_intermediate_result_xz: f32,
34 pub collision_intermediate_result_yy: f32,
35 pub collision_intermediate_result_yz: f32,
36 pub collision_intermediate_result_zz: f32,
37 pub unit_surface_normal: EntityCoordinateVector,
38 pub coefficient_of_restitution: f32,
39}
40
41impl Default for CollisionElasticPdu {
42 fn default() -> Self {
43 CollisionElasticPdu {
44 pdu_header: PduHeader::default(
45 PduType::CollisionElastic,
46 ProtocolFamily::EntityInformation,
47 100,
48 ),
49 issuing_entity_id: EntityId::default(1),
50 colliding_entity_id: EntityId::default(2),
51 event_id: EventId::default(1),
52 padding: 0,
53 contact_velocity: LinearVelocity::default(),
54 mass: 0.0,
55 location_of_impact: EntityCoordinateVector::default(),
56 collision_intermediate_result_xx: 0.0,
57 collision_intermediate_result_xy: 0.0,
58 collision_intermediate_result_xz: 0.0,
59 collision_intermediate_result_yy: 0.0,
60 collision_intermediate_result_yz: 0.0,
61 collision_intermediate_result_zz: 0.0,
62 unit_surface_normal: EntityCoordinateVector::default(),
63 coefficient_of_restitution: 0.0,
64 }
65 }
66}
67
68impl Pdu for CollisionElasticPdu {
69 fn serialize(&mut self, buf: &mut BytesMut) {
70 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
71 .expect("The length of the PDU should fit in a u16.");
72 self.pdu_header.serialize(buf);
73 self.issuing_entity_id.serialize(buf);
74 self.colliding_entity_id.serialize(buf);
75 self.event_id.serialize(buf);
76 buf.put_u16(self.padding);
77 self.contact_velocity.serialize(buf);
78 buf.put_f32(self.mass);
79 self.location_of_impact.serialize(buf);
80 buf.put_f32(self.collision_intermediate_result_xx);
81 buf.put_f32(self.collision_intermediate_result_xy);
82 buf.put_f32(self.collision_intermediate_result_xz);
83 buf.put_f32(self.collision_intermediate_result_yy);
84 buf.put_f32(self.collision_intermediate_result_yz);
85 buf.put_f32(self.collision_intermediate_result_zz);
86 self.unit_surface_normal.serialize(buf);
87 buf.put_f32(self.coefficient_of_restitution);
88 }
89
90 #[allow(clippy::similar_names)]
91 fn deserialize(mut buffer: BytesMut) -> Result<CollisionElasticPdu, DISError> {
92 let pdu_header = PduHeader::deserialize(&mut buffer);
93 if pdu_header.pdu_type == PduType::CollisionElastic {
94 let issuing_entity_id = EntityId::deserialize(&mut buffer);
95 let colliding_entity_id = EntityId::deserialize(&mut buffer);
96 let event_id = EventId::deserialize(&mut buffer);
97 let padding = buffer.get_u16();
98 let contact_velocity = LinearVelocity::deserialize(&mut buffer);
99 let mass = buffer.get_f32();
100 let location_of_impact = EntityCoordinateVector::deserialize(&mut buffer);
101 let collision_intermediate_result_xx = buffer.get_f32();
102 let collision_intermediate_result_xy = buffer.get_f32();
103 let collision_intermediate_result_xz = buffer.get_f32();
104 let collision_intermediate_result_yy = buffer.get_f32();
105 let collision_intermediate_result_yz = buffer.get_f32();
106 let collision_intermediate_result_zz = buffer.get_f32();
107 let unit_surface_normal = EntityCoordinateVector::deserialize(&mut buffer);
108 let coefficient_of_restitution = buffer.get_f32();
109 Ok(CollisionElasticPdu {
110 pdu_header,
111 issuing_entity_id,
112 colliding_entity_id,
113 event_id,
114 padding,
115 contact_velocity,
116 mass,
117 location_of_impact,
118 collision_intermediate_result_xx,
119 collision_intermediate_result_xy,
120 collision_intermediate_result_xz,
121 collision_intermediate_result_yy,
122 collision_intermediate_result_yz,
123 collision_intermediate_result_zz,
124 unit_surface_normal,
125 coefficient_of_restitution,
126 })
127 } else {
128 Err(DISError::invalid_header(
129 format!(
130 "Expected PDU type CollisionElastic, got {:?}",
131 pdu_header.pdu_type
132 ),
133 None,
134 ))
135 }
136 }
137
138 fn as_any(&self) -> &dyn Any {
139 self
140 }
141
142 #[allow(clippy::similar_names)]
143 fn deserialize_without_header(
144 mut buffer: BytesMut,
145 pdu_header: PduHeader,
146 ) -> Result<Self, DISError>
147 where
148 Self: Sized,
149 {
150 let issuing_entity_id = EntityId::deserialize(&mut buffer);
151 let colliding_entity_id = EntityId::deserialize(&mut buffer);
152 let event_id = EventId::deserialize(&mut buffer);
153 let padding = buffer.get_u16();
154 let contact_velocity = LinearVelocity::deserialize(&mut buffer);
155 let mass = buffer.get_f32();
156 let location_of_impact = EntityCoordinateVector::deserialize(&mut buffer);
157 let collision_intermediate_result_xx = buffer.get_f32();
158 let collision_intermediate_result_xy = buffer.get_f32();
159 let collision_intermediate_result_xz = buffer.get_f32();
160 let collision_intermediate_result_yy = buffer.get_f32();
161 let collision_intermediate_result_yz = buffer.get_f32();
162 let collision_intermediate_result_zz = buffer.get_f32();
163 let unit_surface_normal = EntityCoordinateVector::deserialize(&mut buffer);
164 let coefficient_of_restitution = buffer.get_f32();
165 Ok(CollisionElasticPdu {
166 pdu_header,
167 issuing_entity_id,
168 colliding_entity_id,
169 event_id,
170 padding,
171 contact_velocity,
172 mass,
173 location_of_impact,
174 collision_intermediate_result_xx,
175 collision_intermediate_result_xy,
176 collision_intermediate_result_xz,
177 collision_intermediate_result_yy,
178 collision_intermediate_result_yz,
179 collision_intermediate_result_zz,
180 unit_surface_normal,
181 coefficient_of_restitution,
182 })
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::CollisionElasticPdu;
189 use crate::common::{
190 pdu::Pdu,
191 pdu_header::{PduHeader, PduType, ProtocolFamily},
192 };
193 use bytes::BytesMut;
194
195 #[test]
196 fn create_header() {
197 let collision_elastic_pdu = CollisionElasticPdu::default();
198 let header = PduHeader::default(
199 PduType::CollisionElastic,
200 ProtocolFamily::EntityInformation,
201 100,
202 );
203 assert_eq!(
204 header.protocol_version,
205 collision_elastic_pdu.pdu_header.protocol_version
206 );
207 assert_eq!(
208 header.exercise_id,
209 collision_elastic_pdu.pdu_header.exercise_id
210 );
211 assert_eq!(header.pdu_type, collision_elastic_pdu.pdu_header.pdu_type);
212 assert_eq!(
213 header.protocol_family,
214 collision_elastic_pdu.pdu_header.protocol_family
215 );
216 assert_eq!(header.length, collision_elastic_pdu.pdu_header.length);
217 assert_eq!(
218 header.status_record,
219 collision_elastic_pdu.pdu_header.status_record
220 );
221 }
222
223 #[test]
224 fn deserialize_header() {
225 let mut collision_elastic_pdu = CollisionElasticPdu::default();
226 let mut buffer = BytesMut::new();
227 collision_elastic_pdu.serialize(&mut buffer);
228
229 let new_collision_elastic_pdu = CollisionElasticPdu::deserialize(buffer).unwrap();
230 assert_eq!(
231 new_collision_elastic_pdu.pdu_header,
232 collision_elastic_pdu.pdu_header
233 );
234 }
235}