File Coverage

blib/lib/Rinchi/CIGIPP/CollisionDetectionVolumeDefinition.pm
Criterion Covered Total %
statement 85 123 69.1
branch 17 44 38.6
condition 3 9 33.3
subroutine 22 24 91.6
pod 20 20 100.0
total 147 220 66.8


line stmt bran cond sub pod time code
1             #
2             # Rinchi Common Image Generator Interface for Perl
3             # Class Identifier: f78af006-200e-11de-bdb7-001c25551abc
4             # Author: Brian M. Ames
5             #
6              
7             package Rinchi::CIGIPP::CollisionDetectionVolumeDefinition;
8              
9 1     1   22 use 5.006;
  1         4  
  1         34  
10 1     1   5 use strict;
  1         2  
  1         29  
11 1     1   4 use warnings;
  1         2  
  1         100  
12 1     1   6 use Carp;
  1         2  
  1         2205  
13              
14             require Exporter;
15              
16             our @ISA = qw(Exporter);
17              
18             # Items to export into callers namespace by default. Note: do not export
19             # names by default without a very good reason. Use EXPORT_OK instead.
20             # Do not simply export all your public functions/methods/constants.
21              
22             # This allows declaration use Rinchi::CIGI::AtmosphereControl ':all';
23             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
24             # will save memory.
25             our %EXPORT_TAGS = ( 'all' => [ qw(
26            
27             ) ] );
28              
29             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
30              
31             our @EXPORT = qw(
32            
33             );
34              
35             our $VERSION = '0.02';
36              
37             # Preloaded methods go here.
38              
39             =head1 NAME
40              
41             Rinchi::CIGIPP::CollisionDetectionVolumeDefinition - Perl extension for the
42             Common Image Generator Interface - Collision Detection Volume Definition data packet.
43             data packet.
44             =head1 SYNOPSIS
45              
46             use Rinchi::CIGIPP::CollisionDetectionVolumeDefinition;
47             my $cdv_def = Rinchi::CIGIPP::CollisionDetectionVolumeDefinition->new();
48              
49             $packet_type = $cdv_def->packet_type();
50             $packet_size = $cdv_def->packet_size();
51             $entity_ident = $cdv_def->entity_ident(56515);
52             $volume_ident = $cdv_def->volume_ident(33);
53             $volume_type = $cdv_def->volume_type(Rinchi::CIGIPP->Sphere);
54             $volume_enable = $cdv_def->volume_enable(Rinchi::CIGIPP->Enable);
55             $x = $cdv_def->x(42.227);
56             $y = $cdv_def->y(17.683);
57             $z = $cdv_def->z(61.995);
58             $radius = $cdv_def->radius(42.354);
59             $height = $cdv_def->height(82.136);
60             $width = $cdv_def->width(62.861);
61             $depth = $cdv_def->depth(56.607);
62             $roll = $cdv_def->roll(72.09);
63             $pitch = $cdv_def->pitch(50.275);
64             $yaw = $cdv_def->yaw(10.898);
65              
66             =head1 DESCRIPTION
67              
68             The Collision Detection Volume Definition packet enables the Host to define one
69             or more collision detection volumes for an entity. A collision detection volume
70             is a sphere or a cuboid through which collision testing is performed by the IG.
71             When a collision detection volume passes through another collision detection
72             volume, the IG registers a collision by sending a Collision Detection Volume
73             Notification packet to the Host identifying the collided volumes.
74              
75             Note that collision detection testing is performed every frame by the IG.
76              
77             A volume is defined by specifying its location, size, and orientation with
78             respect to the associated entity's body coordinate system. A sphere's size is
79             specified as a radius; a cuboid's size is specified by its width, height, and
80             depth.
81             Unlike collision detection segments, which are tested segment-to-polygon,
82             collision detection volumes are tested volume-to-volume. Volumes associated
83             with the same entity are not tested against each other.
84              
85             Since collision tests are conducted at discrete moments in time, it is possible
86             that two volumes could pass completely through one another between successive
87             tests, causing a missed collision. It may therefore be necessary for the IG to
88             use volume sweeping or some other mechanism to avoid this situation.
89              
90             If the state of an entity is set to Inactive/Standby (0) via the Entity State
91             attribute of an Entity Control packet, no collision detection volume testing
92             will be performed for that entity.
93              
94             If the Collision Detection Enable attribute of the Entity Control packet is set
95             to Disabled (0), no volumes defined for the entity will be used as "source"
96             volumes for collision testing.
97              
98             If collision detection is enabled for two entities, two tests will be performed
99             between each pair of volumes. This is because each volume will be used as both
100             source and destination in each pair-wise test.
101              
102             If an entity is destroyed, any collision detection volumes defined for that
103             entity will also be destroyed.
104              
105             Although non-entity collision detection volumes may be defined by the IG
106             configuration, the Host can only create collision detection volumes by
107             referencing an entity. If a volume must be defined about a non-entity object,
108             the Host must first create an entity with no geometry (entity type zero) to
109             represent that object.
110              
111             =head2 EXPORT
112              
113             None by default.
114              
115             #==============================================================================
116              
117             =item new $cdv_def = Rinchi::CIGIPP::CollisionDetectionVolumeDefinition->new()
118              
119             Constructor for Rinchi::CollisionDetectionVolumeDefinition.
120              
121             =cut
122              
123             sub new {
124 1     1 1 1250 my $class = shift;
125 1   33     13 $class = ref($class) || $class;
126              
127 1         22 my $self = {
128             '_Buffer' => '',
129             '_ClassIdent' => 'f78af006-200e-11de-bdb7-001c25551abc',
130             '_Pack' => 'CCSCCSfffffffffI',
131             '_Swap1' => 'CCvCCvVVVVVVVVVV',
132             '_Swap2' => 'CCnCCnNNNNNNNNNN',
133             'packetType' => 23,
134             'packetSize' => 48,
135             'entityIdent' => 0,
136             'volumeIdent' => 0,
137             '_bitfields1' => 0, # Includes bitfields unused38, volumeType, and volumeEnable.
138             'volumeType' => 0,
139             'volumeEnable' => 0,
140             '_unused39' => 0,
141             'x' => 0,
142             'y' => 0,
143             'z' => 0,
144             'height_radius' => 0,
145             'width' => 0,
146             'depth' => 0,
147             'roll' => 0,
148             'pitch' => 0,
149             'yaw' => 0,
150             '_unused40' => 0,
151             };
152              
153 1 50       5 if (@_) {
154 0 0       0 if (ref($_[0]) eq 'ARRAY') {
    0          
155 0         0 $self->{'_Buffer'} = $_[0][0];
156             } elsif (ref($_[0]) eq 'HASH') {
157 0         0 foreach my $attr (keys %{$_[0]}) {
  0         0  
158 0 0       0 $self->{"_$attr"} = $_[0]->{$attr} unless ($attr =~ /^_/);
159             }
160             }
161             }
162              
163 1         3 bless($self,$class);
164 1         4 return $self;
165             }
166              
167             #==============================================================================
168              
169             =item sub packet_type()
170              
171             $value = $cdv_def->packet_type();
172              
173             Data Packet Identifier.
174              
175             This attribute identifies this data packet as the Collision Detection Volume
176             Definition packet. The value of this attribute must be 23.
177              
178             =cut
179              
180             sub packet_type() {
181 1     1 1 9 my ($self) = @_;
182 1         9 return $self->{'packetType'};
183             }
184              
185             #==============================================================================
186              
187             =item sub packet_size()
188              
189             $value = $cdv_def->packet_size();
190              
191             Data Packet Size.
192              
193             This attribute indicates the number of bytes in this data packet. The value of
194             this attribute must be 48.
195              
196             =cut
197              
198             sub packet_size() {
199 1     1 1 6 my ($self) = @_;
200 1         3 return $self->{'packetSize'};
201             }
202              
203             #==============================================================================
204              
205             =item sub entity_ident([$newValue])
206              
207             $value = $cdv_def->entity_ident($newValue);
208              
209             Entity ID.
210              
211             This attribute specifies the entity for which the volume is defined.
212              
213             =cut
214              
215             sub entity_ident() {
216 1     1 1 5 my ($self,$nv) = @_;
217 1 50       4 if (defined($nv)) {
218 1         3 $self->{'entityIdent'} = $nv;
219             }
220 1         4 return $self->{'entityIdent'};
221             }
222              
223             #==============================================================================
224              
225             =item sub volume_ident([$newValue])
226              
227             $value = $cdv_def->volume_ident($newValue);
228              
229             Volume ID.
230              
231             This attribute specifies the ID of the volume. If an ID is specified for which
232             a volume is already defined, that volume will be overwritten.
233              
234             =cut
235              
236             sub volume_ident() {
237 1     1 1 6 my ($self,$nv) = @_;
238 1 50       7 if (defined($nv)) {
239 1         3 $self->{'volumeIdent'} = $nv;
240             }
241 1         3 return $self->{'volumeIdent'};
242             }
243              
244             #==============================================================================
245              
246             =item sub volume_type([$newValue])
247              
248             $value = $cdv_def->volume_type($newValue);
249              
250             Volume Type.
251              
252             This attribute specified whether the volume is spherical or cuboid.
253              
254             Sphere 0
255             Cuboid 1
256              
257             =cut
258              
259             sub volume_type() {
260 1     1 1 13 my ($self,$nv) = @_;
261 1 50       5 if (defined($nv)) {
262 1 50 33     12 if (($nv==0) or ($nv==1)) {
263 1         3 $self->{'volumeType'} = $nv;
264 1         3 $self->{'_bitfields1'} |= ($nv << 1) &0x02;
265             } else {
266 0         0 carp "volume_type must be 0 (Sphere), or 1 (Cuboid).";
267             }
268             }
269 1         4 return (($self->{'_bitfields1'} & 0x02) >> 1);
270             }
271              
272             #==============================================================================
273              
274             =item sub volume_enable([$newValue])
275              
276             $value = $cdv_def->volume_enable($newValue);
277              
278             Volume Enable.
279              
280             This attribute specifies whether the volume is enabled or disabled. If it is
281             set to Disable (0), the specified volume is ignored during collision testing.
282              
283             Disable 0
284             Enable 1
285              
286             =cut
287              
288             sub volume_enable() {
289 1     1 1 3 my ($self,$nv) = @_;
290 1 50       5 if (defined($nv)) {
291 1 50 33     15 if (($nv==0) or ($nv==1)) {
292 1         3 $self->{'volumeEnable'} = $nv;
293 1         3 $self->{'_bitfields1'} |= $nv &0x01;
294             } else {
295 0         0 carp "volume_enable must be 0 (Disable), or 1 (Enable).";
296             }
297             }
298 1         4 return ($self->{'_bitfields1'} & 0x01);
299             }
300              
301             #==============================================================================
302              
303             =item sub x([$newValue])
304              
305             $value = $cdv_def->x($newValue);
306              
307             X.
308              
309             This attribute specifies the X offset of the center of the volume. This offset
310             is measured with respect to the coordinate system of the entity specified by
311             the Entity ID attribute.
312              
313             =cut
314              
315             sub x() {
316 1     1 1 6 my ($self,$nv) = @_;
317 1 50       4 if (defined($nv)) {
318 1         3 $self->{'x'} = $nv;
319             }
320 1         4 return $self->{'x'};
321             }
322              
323             #==============================================================================
324              
325             =item sub y([$newValue])
326              
327             $value = $cdv_def->y($newValue);
328              
329             Y.
330              
331             This attribute specifies the Y offset of the center of the volume. This offset
332             is measured with respect to the coordinate system of the entity specified by
333             the Entity ID attribute.
334              
335             =cut
336              
337             sub y() {
338 1     1 1 6 my ($self,$nv) = @_;
339 1 50       4 if (defined($nv)) {
340 1         3 $self->{'y'} = $nv;
341             }
342 1         4 return $self->{'y'};
343             }
344              
345             #==============================================================================
346              
347             =item sub z([$newValue])
348              
349             $value = $cdv_def->z($newValue);
350              
351             Z.
352              
353             This attribute specifies the Z offset of the center of the volume. This offset
354             is measured with respect to the coordinate system of the entity specified by
355             the Entity ID attribute.
356              
357             =cut
358              
359             sub z() {
360 1     1 1 5 my ($self,$nv) = @_;
361 1 50       5 if (defined($nv)) {
362 1         3 $self->{'z'} = $nv;
363             }
364 1         3 return $self->{'z'};
365             }
366              
367             #==============================================================================
368              
369             =item sub radius([$newValue])
370              
371             $value = $cdv_def->radius($newValue);
372              
373             Radius.
374              
375             For spherical collision detection volumes, this attribute specifies the radius
376             of the sphere.
377              
378             =cut
379              
380             sub radius() {
381 1     1 1 7 my ($self,$nv) = @_;
382 1 50       5 if (defined($nv)) {
383 1         2 $self->{'height_radius'} = $nv;
384             }
385 1         4 return $self->{'height_radius'};
386             }
387              
388             #==============================================================================
389              
390             =item sub height([$newValue])
391              
392             $value = $cdv_def->height($newValue);
393              
394             Height.
395              
396             For cuboid collision detection volumes, this attribute specifies the length of
397             the cuboid along its Z axis.
398              
399             =cut
400              
401             sub height() {
402 1     1 1 5 my ($self,$nv) = @_;
403 1 50       10 if (defined($nv)) {
404 1         3 $self->{'height_radius'} = $nv;
405             }
406 1         3 return $self->{'height_radius'};
407             }
408              
409             #==============================================================================
410              
411             =item sub width([$newValue])
412              
413             $value = $cdv_def->width($newValue);
414              
415             Width.
416              
417             For cuboid collision detection volumes, this attribute specifies the length of
418             the cuboid along its Y axis. This attribute is ignored if Volume Type is set to
419             Sphere (0).
420              
421             =cut
422              
423             sub width() {
424 1     1 1 6 my ($self,$nv) = @_;
425 1 50       5 if (defined($nv)) {
426 1         3 $self->{'width'} = $nv;
427             }
428 1         3 return $self->{'width'};
429             }
430              
431             #==============================================================================
432              
433             =item sub depth([$newValue])
434              
435             $value = $cdv_def->depth($newValue);
436              
437             Depth.
438              
439             For cuboid collision detection volumes, this attribute specifies the length of
440             the cuboid along its X axis. This attribute is ignored if Volume Type is set to
441             Sphere (0).
442              
443             =cut
444              
445             sub depth() {
446 1     1 1 7 my ($self,$nv) = @_;
447 1 50       5 if (defined($nv)) {
448 1         3 $self->{'depth'} = $nv;
449             }
450 1         4 return $self->{'depth'};
451             }
452              
453             #==============================================================================
454              
455             =item sub roll([$newValue])
456              
457             $value = $cdv_def->roll($newValue);
458              
459             Roll.
460              
461             For cuboid collision detection volumes, this attribute specifies the roll of
462             the cuboid with respect to the entity's coordinate system. This attribute is
463             ignored if Volume Type is set to Sphere (0).
464              
465             =cut
466              
467             sub roll() {
468 1     1 1 6 my ($self,$nv) = @_;
469 1 50       5 if (defined($nv)) {
470 1         2 $self->{'roll'} = $nv;
471             }
472 1         5 return $self->{'roll'};
473             }
474              
475             #==============================================================================
476              
477             =item sub pitch([$newValue])
478              
479             $value = $cdv_def->pitch($newValue);
480              
481             Pitch.
482              
483             For cuboid collision detection volumes, this attribute specifies the pitch of
484             the cuboid with respect to the entity's coordinate system. This attribute is
485             ignored if Volume Type is set to Sphere (0).
486              
487             =cut
488              
489             sub pitch() {
490 1     1 1 5 my ($self,$nv) = @_;
491 1 50       3 if (defined($nv)) {
492 1         3 $self->{'pitch'} = $nv;
493             }
494 1         2 return $self->{'pitch'};
495             }
496              
497             #==============================================================================
498              
499             =item sub yaw([$newValue])
500              
501             $value = $cdv_def->yaw($newValue);
502              
503             Yaw.
504              
505             For cuboid collision detection volumes, this attribute specifies the yaw of the
506             cuboid with respect to the entity's coordinate system. This attribute is
507             ignored if Volume Type is set to Sphere (0).
508              
509             =cut
510              
511             sub yaw() {
512 1     1 1 6 my ($self,$nv) = @_;
513 1 50       4 if (defined($nv)) {
514 1         3 $self->{'yaw'} = $nv;
515             }
516 1         3 return $self->{'yaw'};
517             }
518              
519             #==========================================================================
520              
521             =item sub pack()
522              
523             $value = $cdv_def->pack();
524              
525             Returns the packed data packet.
526              
527             =cut
528              
529             sub pack($) {
530 1     1 1 7 my $self = shift ;
531            
532 1         10 $self->{'_Buffer'} = CORE::pack($self->{'_Pack'},
533             $self->{'packetType'},
534             $self->{'packetSize'},
535             $self->{'entityIdent'},
536             $self->{'volumeIdent'},
537             $self->{'_bitfields1'}, # Includes bitfields unused38, volumeType, and volumeEnable.
538             $self->{'_unused39'},
539             $self->{'x'},
540             $self->{'y'},
541             $self->{'z'},
542             $self->{'height_radius'},
543             $self->{'width'},
544             $self->{'depth'},
545             $self->{'roll'},
546             $self->{'pitch'},
547             $self->{'yaw'},
548             $self->{'_unused40'},
549             );
550              
551 1         3 return $self->{'_Buffer'};
552             }
553              
554             #==========================================================================
555              
556             =item sub unpack()
557              
558             $value = $cdv_def->unpack();
559              
560             Unpacks the packed data packet.
561              
562             =cut
563              
564             sub unpack($) {
565 0     0 1   my $self = shift @_;
566            
567 0 0         if (@_) {
568 0           $self->{'_Buffer'} = shift @_;
569             }
570 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p) = CORE::unpack($self->{'_Pack'},$self->{'_Buffer'});
571 0           $self->{'packetType'} = $a;
572 0           $self->{'packetSize'} = $b;
573 0           $self->{'entityIdent'} = $c;
574 0           $self->{'volumeIdent'} = $d;
575 0           $self->{'_bitfields1'} = $e; # Includes bitfields unused38, volumeType, and volumeEnable.
576 0           $self->{'_unused39'} = $f;
577 0           $self->{'x'} = $g;
578 0           $self->{'y'} = $h;
579 0           $self->{'z'} = $i;
580 0           $self->{'height_radius'} = $j;
581 0           $self->{'width'} = $k;
582 0           $self->{'depth'} = $l;
583 0           $self->{'roll'} = $m;
584 0           $self->{'pitch'} = $n;
585 0           $self->{'yaw'} = $o;
586 0           $self->{'_unused40'} = $p;
587              
588 0           $self->{'volumeType'} = $self->volume_type();
589 0           $self->{'volumeEnable'} = $self->volume_enable();
590              
591 0           return $self->{'_Buffer'};
592             }
593              
594             #==========================================================================
595              
596             =item sub byte_swap()
597              
598             $obj_name->byte_swap();
599              
600             Byte swaps the packed data packet.
601              
602             =cut
603              
604             sub byte_swap($) {
605 0     0 1   my $self = shift @_;
606            
607 0 0         if (@_) {
608 0           $self->{'_Buffer'} = shift @_;
609             } else {
610 0           $self->pack();
611             }
612 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p) = CORE::unpack($self->{'_Swap1'},$self->{'_Buffer'});
613              
614 0           $self->{'_Buffer'} = CORE::pack($self->{'_Swap2'},$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p);
615 0           $self->unpack();
616              
617 0           return $self->{'_Buffer'};
618             }
619              
620             1;
621             __END__