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::decode(&mut buffer);
93 if pdu_header.pdu_type == PduType::CollisionElastic {
94 let issuing_entity_id = EntityId::decode(&mut buffer);
95 let colliding_entity_id = EntityId::decode(&mut buffer);
96 let event_id = EventId::decode(&mut buffer);
97 let padding = buffer.get_u16();
98 let contact_velocity = LinearVelocity::decode(&mut buffer);
99 let mass = buffer.get_f32();
100 let location_of_impact = EntityCoordinateVector::decode(&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::decode(&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::InvalidDISHeader)
129 }
130 }
131
132 fn as_any(&self) -> &dyn Any {
133 self
134 }
135
136 #[allow(clippy::similar_names)]
137 fn deserialize_without_header(
138 mut buffer: BytesMut,
139 pdu_header: PduHeader,
140 ) -> Result<Self, DISError>
141 where
142 Self: Sized,
143 {
144 let issuing_entity_id = EntityId::decode(&mut buffer);
145 let colliding_entity_id = EntityId::decode(&mut buffer);
146 let event_id = EventId::decode(&mut buffer);
147 let padding = buffer.get_u16();
148 let contact_velocity = LinearVelocity::decode(&mut buffer);
149 let mass = buffer.get_f32();
150 let location_of_impact = EntityCoordinateVector::decode(&mut buffer);
151 let collision_intermediate_result_xx = buffer.get_f32();
152 let collision_intermediate_result_xy = buffer.get_f32();
153 let collision_intermediate_result_xz = buffer.get_f32();
154 let collision_intermediate_result_yy = buffer.get_f32();
155 let collision_intermediate_result_yz = buffer.get_f32();
156 let collision_intermediate_result_zz = buffer.get_f32();
157 let unit_surface_normal = EntityCoordinateVector::decode(&mut buffer);
158 let coefficient_of_restitution = buffer.get_f32();
159 Ok(CollisionElasticPdu {
160 pdu_header,
161 issuing_entity_id,
162 colliding_entity_id,
163 event_id,
164 padding,
165 contact_velocity,
166 mass,
167 location_of_impact,
168 collision_intermediate_result_xx,
169 collision_intermediate_result_xy,
170 collision_intermediate_result_xz,
171 collision_intermediate_result_yy,
172 collision_intermediate_result_yz,
173 collision_intermediate_result_zz,
174 unit_surface_normal,
175 coefficient_of_restitution,
176 })
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::CollisionElasticPdu;
183 use crate::common::{
184 pdu::Pdu,
185 pdu_header::{PduHeader, PduType, ProtocolFamily},
186 };
187 use bytes::BytesMut;
188
189 #[test]
190 fn create_header() {
191 let collision_elastic_pdu = CollisionElasticPdu::default();
192 let header = PduHeader::default(
193 PduType::CollisionElastic,
194 ProtocolFamily::EntityInformation,
195 100,
196 );
197 assert_eq!(
198 header.protocol_version,
199 collision_elastic_pdu.pdu_header.protocol_version
200 );
201 assert_eq!(
202 header.exercise_id,
203 collision_elastic_pdu.pdu_header.exercise_id
204 );
205 assert_eq!(header.pdu_type, collision_elastic_pdu.pdu_header.pdu_type);
206 assert_eq!(
207 header.protocol_family,
208 collision_elastic_pdu.pdu_header.protocol_family
209 );
210 assert_eq!(header.length, collision_elastic_pdu.pdu_header.length);
211 assert_eq!(header.padding, collision_elastic_pdu.pdu_header.padding);
212 }
213
214 #[test]
215 fn deserialize_header() {
216 let mut collision_elastic_pdu = CollisionElasticPdu::default();
217 let mut buffer = BytesMut::new();
218 collision_elastic_pdu.serialize(&mut buffer);
219
220 let new_collision_elastic_pdu = CollisionElasticPdu::deserialize(buffer).unwrap();
221 assert_eq!(
222 new_collision_elastic_pdu.pdu_header,
223 collision_elastic_pdu.pdu_header
224 );
225 }
226}