34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../vrml_parser/CRoutes.h"
38#include "../main/headers.h"
40#include "../world_script/fieldSet.h"
41#include "../x3d_parser/Bindable.h"
43#include "quaternion.h"
45#include "../opengl/Frustum.h"
46#include "../opengl/Material.h"
47#include "../opengl/OpenGL_Utils.h"
48#include "../input/EAIHelpers.h"
51#include "LinearAlgebra.h"
54#include "Component_Geospatial.h"
55#include "Component_DIS.h"
56#include "Component_Grouping.h"
57#include "RenderFuncs.h"
60void add_node_to_broto_context(
struct X3D_Proto *currentContext,
struct X3D_Node *node);
64#include <sys/socket.h>
65#include <netinet/in.h>
201#include "../DIS/DIS.h"
235static int allow_DIS = 0;
240int fwl_get_allow_DIS(){
243void fwl_set_allow_DIS(
int allow){
244 allow_DIS = allow ? 1 : 0;
324 PDU_ENTITY_STATE = 1,
328 PDU_SERVICE_REQUEST = 5,
329 PDU_RESUPPLY_OFFER = 6,
330 PDU_RESUPPLY_RECEIVED = 7,
331 PDU_RESUPPLY_CANCEL = 8,
332 PDU_REPAIR_COMPLETE = 9,
333 PDU_REPAIR_RESPONSE = 10,
334 PDU_CREATE_ENTITY = 11,
335 PDU_REMOVE_ENTITY = 12,
336 PDU_START_RESUME = 13,
337 PDU_STOP_FREEZE = 14,
338 PDU_ACKNOWLEDGE = 15,
339 PDU_ACTION_REQUEST = 16,
340 PDU_ACTION_RESPONSE = 17,
344 PDU_EVENT_REPORT = 21,
346 PDU_ELECTROMAGNETIC_EMISSION = 23,
348 PDU_TRANSMITTER = 25,
351 PDU_IFF_ATC_NAVAIDS = 28,
352 PDU_UNDERWATER_ACOUSTIC = 29,
353 PDU_SUPPLEMENTAL_EMISSION_ENTITY_STATE = 30,
354 PDU_INTERCOM_SIGNAL = 31,
355 PDU_INTERCOM_CONTROL = 32,
356 PDU_AGGREGATE_STATE = 33,
358 PDU_TRANSFER_CONTROL = 35,
360 PDU_MINEFIELD_STATE =37,
361 PDU_MINEFIELD_QUERY = 38,
362 PDU_MINEFIELD_DATA = 39,
363 PDU_MINEFIELD_RESPONSE_NAK = 40,
364 PDU_ENVIRONMENTAL_PROCESS = 41,
365 PDU_GRIDDED_DATA = 42,
366 PDU_POINT_OBJECT_STATE = 43,
367 PDU_LINEAR_OBJECT_STATE = 44,
368 PDU_AREAL_OBJECT_STATE = 45,
371 PDU_ARTICULATED_PARTS = 48,
373 PDU_LE_DETONATION = 50,
374 PDU_CREATE_ENTITY_R = 51,
375 PDU_REMOVE_ENTITY_R = 52,
376 PDU_START_RESUME_R = 53,
377 PDU_STOP_FREEZE_R = 54,
378 PDU_ACKNOWLEDGE_R = 55,
379 PDU_ACTION_REQUEST_R = 56,
380 PDU_ACTION_RESPONSE_R = 57,
381 PDU_DATA_QUERY_R = 58,
384 PDU_EVENT_REPORT_R = 61,
386 PDU_RECORD_QUERY_R = 63,
387 PDU_SET_RECORD_R = 64,
389 PDU_COLLISION_ELASTIC = 66,
390 PDU_ENTITY_STATE_UPDATE = 67,
391 PDU_ANNOUNCE_OBJECT = 129,
392 PDU_DELETE_OBJECT = 130,
393 PDU_DESCRIBE_APPLICATION = 131,
394 PDU_DESCRIBE_EVENT = 132,
395 PDU_DESCRIBE_OBJECT = 133,
396 PDU_REQUEST_EVENT = 134,
397 PDU_REQUEST_OBJECT = 135,
400void axisangle2ypr(
float *xyza,
float *ypr)
406 float yaw, pitch, roll, x,y,z,a, xyz[3], flen;
407 vecnormalize3f(xyz,xyza);
408 x = xyz[0]; y = xyz[1], z=xyz[2], a=xyza[3];
409 flen = veclength2f(xyz);
412 pitch = acos(-1.0) * .5;
415 pitch = atan(z/flen);
422void ypr2axisangle(
float *ypr,
float *xyza)
428 float yaw, pitch, roll, x,y,z,a, xyz[3];
433 x = cos(pitch)*cos(yaw);
434 y = cos(pitch)*sin(yaw);
439 vecnormalize3f(xyza,xyz);
449float *vector3float2vec3f(
float *b,
struct Vector3Float *a){
461double *vector3double2vec3d(
double *b,
struct Vector3Double *a){
477void TickTime2DISTime(
double ticktime,
int iabs,
unsigned int *hours,
unsigned int *hourfraction ){
478 double hours1970, fraction;
479 unsigned int bitmask;
480 hours1970 = floor(ticktime / 3600.0);
481 *hours = (
unsigned int)hours1970;
482 fraction = (ticktime / 3600.0) - hours1970;
483 *hourfraction = ((
unsigned int)(fraction * pow(2.0,31.0)))<<1;
487 bitmask = bitmask << 1;
488 *hourfraction = *hourfraction & bitmask;
489 if(iabs) *hourfraction |= 1;
491double DISTime2TickTime(
unsigned int hours,
unsigned int hourfraction){
493 double fraction, mantissa;
495 unsigned int bitmask;
497 iabs = (hourfraction & bitmask) != 0 ? TRUE : FALSE;
498 hourfraction = hourfraction >> 1;
499 fraction = hourfraction;
500 fraction /= pow(2.0,31.0);
504 mantissa = floor(TickTime() / 3600.0);
505 mantissa += fraction;
517 struct sockaddr_in saddr;
518 int multicastRelayPort;
519 char *multicastRelayHost;
521 struct Vector *registered;
526void print_stream(
unsigned char *buf,
int nbytes){
528 for(i=0;i<min(210,nbytes);i+=10){
532 printf(
"%5d",(
int)buf[i+j]);
539double *tcs2localswizzled(
double *local,
double *tcs){
545double *local2tcsswizzled(
double *tcs,
double *local){
551void node2pdu_entityType(
int *entityKind,
struct EntityType *entityType){
554 entityType->
entityKind = (
unsigned char) entityKind[0];
555 entityType->
domain = (
unsigned char) entityKind[1];
556 entityType->
country = (
unsigned short) entityKind[2];
557 entityType->
category = (
unsigned char) entityKind[3];
558 entityType->
subcategory = (
unsigned char) entityKind[4];
559 entityType->
specific = (
unsigned char) entityKind[5];
560 entityType->extra = (
unsigned char) entityKind[6];
562void pdu2node_entityType(
struct EntityType *entityType,
int *entityKind){
566 entityKind[1] = entityType->
domain;
567 entityKind[2] = entityType->
country;
568 entityKind[3] = entityType->
category;
570 entityKind[5] = entityType->
specific;
571 entityKind[6] = entityType->extra;
573static int dis_event_number = 0;
574int dis_next_event_number(){
576 return dis_event_number;
578static int dis_fire_mission_index = 0;
579int dis_next_fire_mission_index(){
580 dis_fire_mission_index++;
581 return dis_fire_mission_index;
583struct X3D_Node * dis_find_registered_node_by_entityid(
int entityid,
int sendlist,
int recvlist);
584struct Vector * dis_node2pdus_espdu(
struct X3D_Node *node,
int isHeartbeat){
593 pdus = newVector(
struct Pdu *, 6);
597 printf(
"es pduchange %d heartbeat %d\n",pnode->_pduchange_es,isHeartbeat);
598 if(pnode->_pduchange_es || isHeartbeat){
608 if(pnode->__geoSystem){
611 struct SFVec3d gd, gc, translate;
613 double localxyz[3], tcsxyz[3], tcs2bodyxyz[3], world2bodyxyz[3];
616 gs = GEOSYS(pnode->__geoSystem);
617 user2gc(gs,&pnode->geoCoords,1,&gc);
620 gc2tcsB_transform(gs,&gc,&translate,&rotate);
625 vrmlrot4d_to_quaternion(&qgc2tcs,rotate.c);
626 vrmlrot4f_to_quaternion(&qtcs2body,pnode->rotation.c);
627 quaternion_multiply(&qgc2body,&qgc2tcs,&qtcs2body);
628 quaternion_to_vrmlrot4f(&qgc2body,xyza);
631 axisangle2ypr(xyza,ypr);
641 float2double(tcs.c,pnode->translation.c,3);
643 tcs2gcB(gs,&gc,&tcs,1,&world);
648 if(pnode->deadReckoning < 6){
652 pnode->_change_count++;
653 if(pnode->_change_count > 1){
655 float v1[3], tmp[3], a1[3];
656 dtime = TickTime() - pnode->_lastp0time;
657 vecscale3f(v1,vecdif3f(tmp,pnode->translation.c,pnode->_lastp0.c),1.0f/dtime);
659 if(pnode->_change_count > 2){
661 vecscale3f(a1,vecdif3f(tmp,v1,pnode->linearVelocity.c),1.0f/dtime);
662 veccopy3f(pnode->linearAcceleration.c,a1);
666 vecset3f(pnode->linearAcceleration.c,0.0,0.0,0.0);
668 veccopy3f(pnode->linearVelocity.c,v1);
672 vrmlrot4f_to_quaternion(&qlast,pnode->_lastr0.c);
673 vrmlrot4f_to_quaternion(&q,pnode->rotation.c);
674 quaternion_inverse(&qinv,&qlast);
675 quaternion_multiply(&qdif,&q,&qinv);
676 quaternion_to_vrmlrot4f(&qdif,pnode->_angularVelocity.c);
677 pnode->_angularVelocity.c[3] *= 1.0f/dtime;
681 veccopy3f(pnode->_lastp0.c,pnode->translation.c);
682 veccopy4f(pnode->_lastr0.c,pnode->rotation.c);
683 pnode->_lastp0time = TickTime();
689 veccopy3f(V,pnode->linearVelocity.c);
690 veccopy3f(A,pnode->linearAcceleration.c);
695 if(pnode->deadReckoning < 6){
699 vrmlrot4d_to_quaternion(&q,rotate.c);
700 quaternion_inverse(&q,&q);
701 quaternion_rotation3f(V,&q,V);
702 quaternion_rotation3f(A,&q,A);
708 vrmlrot4f_to_quaternion(&q,pnode->rotation.c);
709 quaternion_inverse(&q,&q);
710 quaternion_rotation3f(V,&q,V);
711 quaternion_rotation3f(A,&q,A);
724 vecnormalize3f(axis,pnode->_angularVelocity.c);
725 vecscale3f(axis,axis,pnode->_angularVelocity.c[3]);
729 switch(pnode->deadReckoning){
739 if(pnode->__geoSystem){
740 axisangle2ypr(pnode->rotation.c,ypr);
742 vecset3f(ypr,0.0f,0.0f,0.0f);
758 unsigned short iquat16;
760 if(pnode->__geoSystem){
766 struct SFVec3d gc, gd, translate;
769 gs = GEOSYS(pnode->__geoSystem);
770 user2gc(gs,&pnode->geoCoords,1,&gc);
773 gc2tcsB_transform(gs,&gc,&translate,&rotate);
774 vrmlrot4d_to_quaternion(&qtcs,rotate.c);
775 vrmlrot4f_to_quaternion(&qlocal,pnode->rotation.c);
776 quaternion_multiply(&qglobal,&qlocal,&qtcs);
778 vrmlrot_to_quaternion(&qglobal,0.0,1.0,0.0,0.0);
780 quat2double(quat4d,&qglobal);
781 double2float(&quat4f[1],quat4d,3);
782 quat4f[0] = quat4d[3];
784 vecscale4f(quat4f,quat4f,-1.0f);
786 iquat0 = (
unsigned int)(quat4f[0] * 65536);
787 if(quat4f[0] > 65536) iquat0 = 65535;
806 double local2bodyxyz[3], localxyz[3];
807 float2double(local2bodyxyz,pnode->translation.c,3);
808 tcs2localswizzled(localxyz,local2bodyxyz);
829 float *c = pnode->rotation.c;
830 vrmlrot_to_quaternion(&qA,c[0],c[1],c[2],c[3]);
831 quat2euler(ypr,0,&qA);
837 axisangle2ypr(pnode->rotation.c,ypr);
846 pnode->_change_count++;
847 if(pnode->_change_count > 1){
849 float v1[3], tmp[3], a1[3];
850 dtime = TickTime() - pnode->_lastp0time;
851 vecscale3f(v1,vecdif3f(tmp,pnode->translation.c,pnode->_lastp0.c),1.0f/dtime);
853 if(pnode->_change_count > 2){
855 vecscale3f(a1,vecdif3f(tmp,v1,pnode->linearVelocity.c),1.0f/dtime);
856 veccopy3f(pnode->linearAcceleration.c,a1);
860 vecset3f(pnode->linearAcceleration.c,0.0,0.0,0.0);
862 veccopy3f(pnode->linearVelocity.c,v1);
866 vrmlrot4f_to_quaternion(&qlast,pnode->_lastr0.c);
867 vrmlrot4f_to_quaternion(&q,pnode->rotation.c);
868 quaternion_inverse(&qinv,&qlast);
869 quaternion_multiply(&qdif,&q,&qinv);
870 quaternion_to_vrmlrot4f(&qdif,pnode->_angularVelocity.c);
871 pnode->_angularVelocity.c[3] *= 1.0f/dtime;
874 veccopy3f(pnode->_lastp0.c,pnode->translation.c);
875 veccopy4f(pnode->_lastr0.c,pnode->rotation.c);
876 pnode->_lastp0time = TickTime();
886 vecnormalize3f(axis,pnode->_angularVelocity.c);
887 vecscale3f(axis,axis,pnode->_angularVelocity.c[3]);
891 switch(pnode->deadReckoning){
901 if(pnode->__geoSystem){
902 axisangle2ypr(pnode->rotation.c,ypr);
904 vecset3f(ypr,0.0f,0.0f,0.0f);
920 unsigned short iquat16;
922 if(pnode->__geoSystem){
928 struct SFVec3d gc, gd, translate;
931 gs = GEOSYS(pnode->__geoSystem);
932 user2gc(gs,&pnode->geoCoords,1,&gc);
935 gc2tcsB_transform(gs,&gc,&translate,&rotate);
936 vrmlrot4d_to_quaternion(&qtcs,rotate.c);
937 vrmlrot4f_to_quaternion(&qlocal,pnode->rotation.c);
938 quaternion_multiply(&qglobal,&qlocal,&qtcs);
940 vrmlrot_to_quaternion(&qglobal,0.0,1.0,0.0,0.0);
942 quat2double(quat4d,&qglobal);
943 double2float(&quat4f[1],quat4d,3);
944 quat4f[0] = quat4d[3];
946 vecscale4f(quat4f,quat4f,-1.0f);
948 iquat0 = (
unsigned int)(quat4f[0] * 65536);
949 if(quat4f[0] > 65536) iquat0 = 65535;
963 if(pnode->articulationParameterArray.n){
965 int i, np = pnode->articulationParameterArray.n;
970 ap[i].parameterTypeDesignator = 0;
971 ap[i].parameterType = 1029;
972 ap[i].parameterValue = pnode->articulationParameterArray.p[i];
973 ap[i].partAttachedTo = 0;
978 node2pdu_entityType(&pnode->entityKind,&espdu->
entityType);
982 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)espdu);
987 if(pnode->_pduchange_fire){
989 fpdu = (
struct FirePdu *) dis_ctor(type_FirePdu);
996 if(pnode->fired1 || pnode->fired2){
997 pnode->firedTime = TickTime();
1019 fpdu->fireMissionIndex = dis_next_fire_mission_index();
1022 float2double(loc,pnode->munitionStartPoint.c,3);
1032 fpdu->
range = pnode->firingRange;
1035 vecdif3f(delta,pnode->munitionEndPoint.c,pnode->munitionStartPoint.c);
1037 vecscale3f(delta,delta,1.0f/3.0f);
1038 vec3f2vector3float(&fpdu->
velocity,delta);
1040 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)fpdu);
1043 if(pnode->_pduchange_collision){
1045 cpdu = (
struct CollisionPdu *) dis_ctor(type_CollisionPdu);
1057 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)cpdu);
1060 if(pnode->_pduchange_detonation){
1062 dpdu = (
struct DetonationPdu *) dis_ctor(type_DetonationPdu);
1071 pnode->detonateTime = TickTime();
1094 if(pnode->articulationParameterArray.n){
1096 int i, np = pnode->articulationParameterArray.n;
1101 ap[i].parameterTypeDesignator = 0;
1102 ap[i].parameterType = 1029;
1103 ap[i].parameterValue = pnode->articulationParameterArray.p[i];
1104 ap[i].partAttachedTo = 0;
1107 dpdu->articulationParameters = (
void*)ap;
1112 float2double(loc,pnode->detonationLocation.c,3);
1125 vecdif3f(delta,pnode->munitionEndPoint.c,pnode->munitionStartPoint.c);
1127 vecscale3f(delta,delta,1.0f/.5f);
1128 vec3f2vector3float(&dpdu->
velocity,delta);
1132 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)dpdu);
1139struct Vector * dis_node2pdus_receiver(
struct X3D_Node *node,
int isHeartbeat){
1142 pdus = newVector(
struct Pdu *, 6);
1145 if(pnode->_pduchange_receiver){
1147 rpdu = (
struct ReceiverPdu *) dis_ctor(type_ReceiverPdu);
1155 rpdu->myRadioCommunicationsFamilyPdu.
radioId = pnode->radioID;
1162 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)rpdu);
1166struct Vector * dis_node2pdus_transmitter(
struct X3D_Node *node,
int isHeartbeat){
1169 pdus = newVector(
struct Pdu *, 6);
1173 if(pnode->_pduchange_transmitter){
1202 float2double(loc,pnode->antennaLocation.c,3);
1218 tpdu->
power = pnode->power;
1223 tpdu->
radioEntityType.nomenclature = pnode->radioEntityTypeNomenclature;
1225 tpdu->myRadioCommunicationsFamilyPdu.
radioId = pnode->radioID;
1229 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)tpdu);
1233#define ONE_INT32_PER_SIGNAL_DATA_BYTE TRUE
1234struct Vector * dis_node2pdus_signal(
struct X3D_Node *node,
int isHeartbeat){
1237 pdus = newVector(
struct Pdu *, 6);
1241 if(pnode->_pduchange_signal){
1243 spdu = (
struct SignalPdu *) dis_ctor(type_SignalPdu);
1252 spdu->
data = realloc(spdu->
data,pnode->dataLength*
sizeof(
unsigned char));
1253 if(ONE_INT32_PER_SIGNAL_DATA_BYTE){
1255 unsigned char *cdata = (
unsigned char *)spdu->
data;
1257 cdata[k] = (
unsigned char)((
unsigned int)pnode->data.p[k] % 256);
1260 memcpy(spdu->
data,pnode->data.p,pnode->dataLength);
1265 spdu->
samples = pnode->samples;
1266 spdu->
tdlType = pnode->tdlType;
1267 spdu->myRadioCommunicationsFamilyPdu.
radioId = pnode->radioID;
1268 spdu->myRadioCommunicationsFamilyPdu.
entityId.
entity = pnode->entityID;
1269 spdu->myRadioCommunicationsFamilyPdu.
entityId.
site = pnode->siteID;
1271 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)spdu);
1275struct X3D_Node *dis_find_or_create_espdu_by_category(
int kind,
int domain,
int country,
int category,
int subcategory,
int specific,
int extra);
1276int dis_pdus2node_espdu(
struct X3D_Node *node,
struct Vector *pdus){
1282 if(!pdus)
return ihit;
1283 for(i=0;i<pdus->n;i++)
1285 pdu = vector_get(
struct Pdu*,pdus,i);
1287 case PDU_ENTITY_STATE:
1297 pnode->timestamp = TickTime();
1299 if(pnode->__geoSystem){
1301 struct SFVec3d gd, gc, translate;
1303 double localxyz[3], tcsxyz[3], tcs2bodyxyz[3], world2bodyxyz[3];
1306 gs = GEOSYS(pnode->__geoSystem);
1307 user2gc(gs,&pnode->geoCoords,1,&gc);
1310 gc2tcsB_transform(gs,&gc,&translate,&rotate);
1322 float ypr[3], xyza[4];
1326 ypr2axisangle(ypr,xyza);
1330 vrmlrot4f_to_quaternion(&qgc2body,xyza);
1331 vrmlrot4d_to_quaternion(&qgc2tcs,rotate.c);
1332 quaternion_inverse(&qtcs2gc,&qgc2tcs);
1333 quaternion_multiply(&qtcs2body,&qtcs2gc,&qgc2body);
1334 quaternion_set(&q,&qtcs2body);
1335 quaternion_to_vrmlrot4f(&q,pnode->rotation.c);
1341 TRANS_LOCATION_MINUS_GEOCOORD = 2
1344 static int transmethod = TRANS_ZERO;
1347 if(transmethod == TRANS_LOCATION_MINUS_GEOCOORD){
1350 veccopyd(world.c,world2bodyxyz);
1352 gc2tcsB(gs,&gc,&world,1,&tcs);
1353 double2float(pnode->translation.c,tcs.c,3);
1358 struct SFVec3d world, tcs2, tcs1;
1361 static int want_smoothing = 1;
1364 gc2tcsB(gs,&gc,&gc,1,&tcs1);
1365 veccopyd(world.c,world2bodyxyz);
1366 gc2tcs(gs,&gd,&world,1,&tcs2);
1367 gc2tcsB(gs,&gc,&world,1,&tcs2);
1368 vecdifd(deltatcs,tcs1.c,tcs2.c);
1369 double2float(deltap,deltatcs,3);
1370 vecadd3f(pnode->_p0.c,pnode->_p0.c,deltap);
1372 gc2user(gs,&world,1,&pnode->geoCoords);
1374 vecset3f(pnode->translation.c,0.0f,0.0f,0.0f);
1389 if(pnode->deadReckoning < 6){
1393 vrmlrot4d_to_quaternion(&q,rotate.c);
1394 quaternion_rotation3f(V,&q,V);
1395 quaternion_rotation3f(A,&q,A);
1401 vrmlrot4f_to_quaternion(&q,pnode->rotation.c);
1402 quaternion_rotation3f(V,&q,V);
1403 quaternion_rotation3f(A,&q,A);
1409 veccopy3f(pnode->linearAcceleration.c,A);
1410 veccopy3f(pnode->linearVelocity.c,V);
1415 float axis[3], angle;
1417 angle = veclength3f(axis);
1418 vecnormalize3f(pnode->_angularVelocity.c,axis);
1419 pnode->_angularVelocity.c[3] = angle;
1436 float *c = pnode->rotation.c;
1440 euler2quat(&qA,ypr[0],ypr[1],ypr[2]);
1443 quaternion_to_vrmlrot(&qA,&r[0],&r[1],&r[2],&r[3]);
1454 ypr2axisangle(ypr,pnode->rotation.c);
1462 float axis[3], angle;
1464 angle = veclength3f(axis);
1465 vecnormalize3f(pnode->_angularVelocity.c,axis);
1466 pnode->_angularVelocity.c[3] = angle;
1473 if(pnode->articulationParameterArray.n){
1476 int i, np = pnode->articulationParameterArray.n;
1478 pp = malloc(np *
sizeof(
float));
1483 pp[i] = (float)ap[i].parameterValue;
1487 case 0: pnode->articulationParameterValue0_changed = pp[i];
break;
1488 case 1: pnode->articulationParameterValue1_changed = pp[i];
break;
1489 case 2: pnode->articulationParameterValue2_changed = pp[i];
break;
1490 case 3: pnode->articulationParameterValue3_changed = pp[i];
break;
1491 case 4: pnode->articulationParameterValue4_changed = pp[i];
break;
1492 case 5: pnode->articulationParameterValue5_changed = pp[i];
break;
1493 case 6: pnode->articulationParameterValue6_changed = pp[i];
break;
1494 case 7: pnode->articulationParameterValue7_changed = pp[i];
break;
1499 if(pnode->articulationParameterArray.p) free(pnode->articulationParameterArray.p);
1500 pnode->articulationParameterArray.p = pp;
1503 pdu2node_entityType(&espdu->
entityType,&pnode->entityKind);
1504 pnode->_pduchange_es = TRUE;
1530 pnode->timestamp = TickTime();
1533 pnode->firedTime = TickTime();
1535 pnode->fired1 = TRUE;
1551 if(!muni) printf(
"no muni\n");
1553 printf(
"got muni\n");
1554 pnode->munitionEntityID = muni->entityID;
1555 pnode->munitionSiteID = muni->siteID;
1556 pnode->munitionApplicationID = muni->applicationID;
1566 pnode->fireMissionIndex = fpdu->fireMissionIndex;
1572 double2float(pnode->munitionStartPoint.c,loc,3);
1582 pnode->firingRange = fpdu->
range;
1585 vector3float2vec3f(delta,&fpdu->
velocity);
1587 vecscale3f(delta,delta,3.0f/1.0f);
1588 vecadd3f(pnode->munitionEndPoint.c,pnode->munitionStartPoint.c,delta);
1590 pnode->_pduchange_fire = TRUE;
1606 if(pnode->collisionType) pnode->isCollided = TRUE;
1607 else pnode->isCollided = FALSE;
1613 pnode->_pduchange_collision = TRUE;
1616 case PDU_DETONATION:
1627 pnode->timestamp = TickTime();
1629 pnode->detonateTime = TickTime();
1644 if(!muni) printf(
"no muni\n");
1646 printf(
"got muni\n");
1647 pnode->munitionEntityID = muni->entityID;
1648 pnode->munitionSiteID = muni->siteID;
1649 pnode->munitionApplicationID = muni->applicationID;
1664 double2float(pnode->detonationLocation.c,loc,3);
1671 vector3float2vec3f(delta,&dpdu->
velocity);
1673 vecscale3f(delta,delta,.5f/1.0f);
1674 veccopy3f(pnode->munitionStartPoint.c,pnode->detonationRelativeLocation.c);
1675 vecadd3f(pnode->munitionEndPoint.c,pnode->munitionStartPoint.c,delta);
1680 if(pnode->articulationParameterArray.n){
1683 int i, np = pnode->articulationParameterArray.n;
1684 ap = dpdu->articulationParameters;
1685 pp = malloc(np *
sizeof(
float));
1690 pp[i] = (float)ap[i].parameterValue;
1694 case 0: pnode->articulationParameterValue0_changed = pp[i];
break;
1695 case 1: pnode->articulationParameterValue1_changed = pp[i];
break;
1696 case 2: pnode->articulationParameterValue2_changed = pp[i];
break;
1697 case 3: pnode->articulationParameterValue3_changed = pp[i];
break;
1698 case 4: pnode->articulationParameterValue4_changed = pp[i];
break;
1699 case 5: pnode->articulationParameterValue5_changed = pp[i];
break;
1700 case 6: pnode->articulationParameterValue6_changed = pp[i];
break;
1701 case 7: pnode->articulationParameterValue7_changed = pp[i];
break;
1706 if(pnode->articulationParameterArray.p) free(pnode->articulationParameterArray.p);
1707 pnode->articulationParameterArray.p = pp;
1710 pnode->_pduchange_detonation = TRUE;
1721int dis_pdus2node_receiver(
struct X3D_Node *node,
struct Vector *pdus){
1727 if(!pdus)
return ihit;
1728 for(i=0;i<pdus->n;i++)
1730 pdu = vector_get(
struct Pdu*,pdus,i);
1737 if(pnode->radioID != rpdu->myRadioCommunicationsFamilyPdu.
radioId)
break;
1740 pnode->timestamp = TickTime();
1748 pnode->_pduchange_receiver = TRUE;
1757int dis_pdus2node_transmitter(
struct X3D_Node *node,
struct Vector *pdus){
1763 if(!pdus)
return ihit;
1764 for(i=0;i<pdus->n;i++)
1766 pdu = vector_get(
struct Pdu*,pdus,i);
1768 case PDU_TRANSMITTER:
1773 if(pnode->radioID != tpdu->myRadioCommunicationsFamilyPdu.
radioId)
break;
1774 if(tpdu->myRadioCommunicationsFamilyPdu.
entityId.
entity != pnode->entityID)
break;
1775 if(tpdu->myRadioCommunicationsFamilyPdu.
entityId.
site != pnode->siteID)
break;
1776 if(tpdu->myRadioCommunicationsFamilyPdu.
entityId.
application != pnode->applicationID)
break;
1780 pnode->timestamp = TickTime();
1784 double2float(pnode->antennaLocation.c,loc,3);
1799 pnode->power = tpdu->
power;
1804 pnode->radioEntityTypeNomenclature = tpdu->
radioEntityType.nomenclature;
1806 pnode->radioID = tpdu->myRadioCommunicationsFamilyPdu.
radioId;
1809 pnode->_pduchange_transmitter = TRUE;
1820int dis_pdus2node_signal(
struct X3D_Node *node,
struct Vector *pdus){
1826 if(!pdus)
return ihit;
1827 for(i=0;i<pdus->n;i++)
1829 pdu = vector_get(
struct Pdu*,pdus,i);
1836 if(pnode->radioID != spdu->myRadioCommunicationsFamilyPdu.
radioId)
break;
1837 if(spdu->myRadioCommunicationsFamilyPdu.
entityId.
entity != pnode->entityID)
break;
1838 if(spdu->myRadioCommunicationsFamilyPdu.
entityId.
site != pnode->siteID)
break;
1839 if(spdu->myRadioCommunicationsFamilyPdu.
entityId.
application != pnode->applicationID)
break;
1843 pnode->timestamp = TickTime();
1844 if(ONE_INT32_PER_SIGNAL_DATA_BYTE){
1846 unsigned char *cdata = (
unsigned char *)spdu->
data;
1847 pnode->data.p = realloc(pnode->data.p,spdu->
dataLength*
sizeof(
int));
1849 pnode->data.p[k] = (int)(cdata[k]);
1852 memcpy(pnode->data.p,spdu->
data,pnode->dataLength);
1858 pnode->samples = spdu->
samples;
1859 pnode->tdlType = spdu->
tdlType;
1860 pnode->_pduchange_signal = TRUE;
1887struct Vector * dis_node2pdus_sm(
struct X3D_Node *node,
int isHeartbeat){
1891 pdus = newVector(
struct Pdu *, 6);
1895 printf(
"em pduchange create %d remove %d heartbeat %d ticktime %lf\n",pnode->_pduchange_create, pnode->_pduchange_remove, isHeartbeat,TickTime());
1901 struct SimulationManagementPdu *simanpdu;
1904 if(pnode->_pduchange_create){
1912 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)crpdu);
1915 if(pnode->_pduchange_remove){
1919 vector_pushBack(
struct Pdu*,pdus,(
struct Pdu*)rmpdu);
1930 if(!pdus)
return ihit;
1931 for(i=0;i<pdus->n;i++)
1933 pdu = vector_get(
struct Pdu*,pdus,i);
1935 case PDU_CREATE_ENTITY:
1940 printf(
"hi from pdu2node create_entity\n");
1941 pnode->_pduchange_create = TRUE;
1944 case PDU_REMOVE_ENTITY:
1948 printf(
"hi from pdu2node remove_entity\n");
1949 pnode->_pduchange_remove = TRUE;
1959void dis_set_node_lasttime(
struct X3D_Node *node,
double lasttime){
1961 switch(node->_nodeType){
1962 case NODE_ReceiverPdu:
1963 case NODE_TransmitterPdu:
1964 case NODE_SignalPdu:
1965 case NODE_EspduTransform:
1966 case NODE_DISEntityManager:
1969 pnode->_lasttime = lasttime;
1984 for(i=0;i<pdus->n;i++) {
1985 pdu = vector_get(
struct Pdu*,pdus,i);
1987 case PDU_ENTITY_STATE:
1989 case PDU_TRANSMITTER:
1992 int j, already_done;
1993 int entityID, siteID, applicationID;
2004 already_done = FALSE;
2005 for(j=0;j<pnode->addEntities.n;j++){
2007 if(candi->_nodeType == NODE_DISEntityTypeMapping){
2010 }
else if(candi->_nodeType == NODE_EspduTransform) {
2017 et->siteID == espdu->
entityID.
site) already_done = TRUE;
2018 if(already_done)
break;
2029 et = createNewX3DNode0(NODE_EspduTransform);
2032 case PDU_ENTITY_STATE: nodetype = NODE_EspduTransform;
break;
2033 case PDU_RECEIVER: nodetype = NODE_ReceiverPdu;
break;
2034 case PDU_TRANSMITTER: nodetype = NODE_TransmitterPdu;
break;
2035 case PDU_SIGNAL: nodetype = NODE_SignalPdu;
break;
2041 et->_nodeType = nodetype;
2045 et->address = newASCIIString(dsock->address);
2046 et->port = dsock->port;
2047 et->multicastRelayHost = newASCIIString(dsock->multicastRelayHost);
2048 et->multicastRelayPort = dsock->multicastRelayPort;
2058 void * pp = pnode->addEntities.p;
2059 pnode->addEntities.p = realloc(pp,
sizeof(
struct X3D_Node*)*upper_power_of_two(pnode->addEntities.n + 1));
2060 pnode->addEntities.p[pnode->addEntities.n] = (
struct X3D_Node*)et;
2061 pnode->addEntities.n++;
2080 if(node->_nodeType == NODE_EspduTransform){
2081 if(pnode && pnode->_nodeType == NODE_DISEntityManager){
2083 static int ADD = 1, REMOVE = 2;
2085 for(i=0;i<pnode->entities.n;i++){
2086 if(pnode->entities.p[i] == node){
2088 AddRemoveChildren(X3D_NODE(pnode), &pnode->entities, (
struct X3D_Node * *)&node, 1, REMOVE,__FILE__,__LINE__);
2089 AddRemoveChildren(X3D_NODE(pnode), &pnode->removedEntities, (
struct X3D_Node * *)&node, 1, ADD,__FILE__,__LINE__);
2099struct Vector * dis_node2pdus(
struct X3D_Node *node,
int isHeartbeat){
2100 struct Vector *pdus = NULL;
2101 switch(node->_nodeType){
2102 case NODE_EspduTransform:
2103 pdus = dis_node2pdus_espdu(node, isHeartbeat);
2105 case NODE_DISEntityManager:
2106 pdus = dis_node2pdus_sm(node,isHeartbeat);
2108 case NODE_ReceiverPdu:
2109 pdus = dis_node2pdus_receiver(node,isHeartbeat);
2111 case NODE_TransmitterPdu:
2112 pdus = dis_node2pdus_transmitter(node,isHeartbeat);
2114 case NODE_SignalPdu:
2115 pdus = dis_node2pdus_signal(node,isHeartbeat);
2121static struct Vector *sockets_send = NULL;
2122static struct Vector *sockets_recv = NULL;
2124struct X3D_Node * dis_find_registered_node_by_entityid(
int entityid,
int sendlist,
int recvlist){
2126 struct X3D_Node *node, *pnode = NULL;
2128 for(i=0;i<sockets_send->n;i++){
2130 if(dsock->registered){
2131 for(j=0;j<dsock->registered->n;j++){
2134 if(node->_nodeType == NODE_EspduTransform){
2136 if(espdu->entityID == entityid){
2145 for(i=0;i<sockets_recv->n;i++){
2147 if(dsock->registered){
2148 for(j=0;j<dsock->registered->n;j++){
2151 if(node->_nodeType == NODE_EspduTransform){
2153 if(espdu->entityID == entityid){
2166struct X3D_Node *dis_find_or_create_espdu_by_category(
int kind,
int domain,
int country,
int category,
int subcategory,
int specific,
int extra){
2167 int i,j,k, ibest, iscore;
2172 for(i=0;i<sockets_recv->n;i++){
2174 if(dsock->registered){
2175 for(j=0;j<dsock->registered->n;j++){
2178 if(node->_nodeType == NODE_DISEntityManager){
2181 for(k=0;k<em->entities.n;k++){
2183 if(bnode->_nodeType == NODE_EspduTransform){
2185 if(domain == bnode->entityDomain) jscore++;
2186 if(category == bnode->entityCategory) jscore++;
2187 if(country == bnode->entityCountry) jscore++;
2188 if(kind == bnode->entityKind) jscore++;
2189 if(extra == bnode->entityExtra) jscore++;
2190 if(subcategory == bnode->entitySubCategory) jscore++;
2191 if(specific == bnode->entitySpecific) jscore++;
2192 if(jscore > iscore){
2209unsigned char buf2[32767];
2211void dis_get_node_lasttime(
struct X3D_Node *node,
double *lasttime,
double *readInterval,
double *writeInterval){
2213 switch(node->_nodeType){
2214 case NODE_ReceiverPdu:
2215 case NODE_TransmitterPdu:
2216 case NODE_SignalPdu:
2217 case NODE_EspduTransform:
2218 case NODE_DISEntityManager:
2221 *lasttime = pnode->_lasttime;
2222 *writeInterval = pnode->writeInterval;
2223 *readInterval = pnode->readInterval;
2230int node_only_transform_changed(
struct X3D_Node *node){
2231 int changed, onlytransform = FALSE;
2233 if( node->_nodeType == NODE_EspduTransform)
2236 changed += pnode->_pduchange_es ? 1 : 0;
2237 changed += pnode->_pduchange_collision ? 2:0;
2238 changed += pnode->_pduchange_fire ? 4:0;
2239 changed += pnode->_pduchange_detonation ? 8:0;
2241 onlytransform = changed == 1;
2242 return onlytransform;
2246int node_pdus_changed_by_scene(
struct X3D_Node *node){
2247 int changed = FALSE;
2248 switch(node->_nodeType){
2249 case NODE_EspduTransform:
2252 changed = pnode->_pduchange_es;
2253 changed |= pnode->_pduchange_collision;
2254 changed |= pnode->_pduchange_fire;
2255 changed |= pnode->_pduchange_detonation;
2258 case NODE_DISEntityManager:
2261 changed = pnode->_pduchange_create;
2262 changed |= pnode->_pduchange_remove;
2265 case NODE_TransmitterPdu:
2268 changed = pnode->_pduchange_transmitter;
2271 case NODE_SignalPdu:
2274 changed = pnode->_pduchange_signal;
2277 case NODE_ReceiverPdu:
2280 changed = pnode->_pduchange_receiver;
2288void reset_node_pduchanged(
struct X3D_Node *node){
2289 switch(node->_nodeType){
2290 case NODE_EspduTransform:
2293 pnode->_pduchange_es = FALSE;
2294 pnode->_pduchange_collision = FALSE;
2295 pnode->_pduchange_fire = FALSE;
2296 pnode->_pduchange_detonation = FALSE;
2299 case NODE_DISEntityManager:
2302 pnode->_pduchange_em_info = FALSE;
2303 pnode->_pduchange_create = FALSE;
2304 pnode->_pduchange_remove = FALSE;
2307 case NODE_TransmitterPdu:
2310 pnode->_pduchange_transmitter = FALSE;
2313 case NODE_SignalPdu:
2316 pnode->_pduchange_signal = FALSE;
2319 case NODE_ReceiverPdu:
2322 pnode->_pduchange_receiver = FALSE;
2331int sockwrite(SOCKET s,
const char *buf,
int len);
2332int sockread(SOCKET s,
const char *buf,
int len);
2333int sockrecvfrom(
struct dis_socket *dsock,
const char *buf,
int len);
2334int socksendto(
struct dis_socket *dsock,
const char *buf,
int len);
2336int write_rtp(
unsigned char *buf,
struct X3D_Node *node);
2339 int i,j, nbytes, nb;
2340 if(!sockets_send || sockets_send->n == 0)
return;
2341 thistime = TickTime();
2342 for(i=0;i<sockets_send->n;i++){
2344 if(dsock->registered){
2346 for(j=0;j<dsock->registered->n;j++){
2351 double lasttime, dtime, readInterval, writeInterval, isHeartbeat;
2355 dis_get_node_lasttime(node,&lasttime,&readInterval,&writeInterval);
2356 if(writeInterval == 0.0)
continue;
2359 dtime = thistime - lasttime;
2360 isHeartbeat = dtime > writeInterval ? TRUE: FALSE;
2361 if(!isHeartbeat && !node_pdus_changed_by_scene(node))
continue;
2367 lasttime = thistime;
2368 dsock->lasttime = thistime;
2370 nb = write_rtp(&buf2[nbytes],node);
2375 pdus = dis_node2pdus(node,isHeartbeat);
2377 dis_set_node_lasttime(node,lasttime);
2379 if(pdus && pdus->n) {
2380 struct Pdu* pdu = vector_get(
struct Pdu*,pdus,0);
2383 nb = dis_write_stream(&buf2[nbytes],pdus);
2386 printf(
"sendloop >>>>\n");
2387 print_stream(&buf2[nbytes], nb);
2388 printf(
"<<<< sendloop\n");
2391 reset_node_pduchanged(node);
2393 if(nbytes) socksendto(dsock,(
const char *)buf2,nbytes);
2410 unsigned char toprow[2];
2411 unsigned short sequence;
2412 unsigned int timestamp;
2415unsigned char * rtp_strip_header(
unsigned char *buf,
int *heard){
2416 unsigned char *carat = buf;
2420 if(carat[0] > 127) {
2422 struct rtp_header rtph;
2425 memcpy(&rtph.toprow,carat,2);
2427 memcpy(&rtph.sequence,carat,2);
2429 memcpy(&rtph.timestamp,carat,4);
2431 memcpy(&rtph.ssrc,carat,4);
2433 cc = rtph.toprow[0] << 4 >> 4;
2434 x = rtph.toprow[0] & 1 << 4;
2446unsigned char * rtp_add_header(
unsigned char *buf,
unsigned int timestamp){
2447 struct rtp_header rtph;
2448 unsigned char PayloadType;
2449 unsigned char *carat = buf;
2451 memset(&rtph,0,
sizeof(
struct rtp_header));
2452 rtph.toprow[0] = 2 << 7 | 0 << 6 | 0 << 5 | 0;
2453 rtph.toprow[1] = 0 << 7 | PayloadType;
2454 rtph.sequence = htons(0);
2455 rtph.timestamp = htonl(timestamp);
2457 memcpy(carat,&rtph.toprow,2);
2459 memcpy(carat,&rtph.sequence,2);
2461 memcpy(carat,&rtph.timestamp,4);
2463 memcpy(carat,&rtph.ssrc,4);
2467int write_rtp(
unsigned char *buf,
struct X3D_Node *node){
2470 switch(node->_nodeType){
2471 case NODE_EspduTransform:
2474 case NODE_DISEntityManager:
2477 case NODE_ReceiverPdu:
2480 case NODE_TransmitterPdu:
2483 case NODE_SignalPdu:
2490 unsigned char *carat;
2491 unsigned int hours, timestamp;
2492 TickTime2DISTime(TickTime(),1,&hours,×tamp);
2493 carat = rtp_add_header(buf,timestamp);
2498void set_rtp_heard(
struct X3D_Node *node){
2502 switch(node->_nodeType){
2503 case NODE_EspduTransform:
2506 case NODE_DISEntityManager:
2509 case NODE_ReceiverPdu:
2512 case NODE_TransmitterPdu:
2515 case NODE_SignalPdu:
2522void dis_set_isActive(
struct X3D_Node*node,
int ival){
2523 switch(node->_nodeType){
2524 case NODE_EspduTransform:
2527 if(pnode->isActive != ival){
2528 pnode->isActive = ival;
2533 case NODE_DISEntityManager:
2536 if(pnode->isActive != ival){
2537 pnode->isActive = ival;
2542 case NODE_ReceiverPdu:
2545 if(pnode->isActive != ival){
2546 pnode->isActive = ival;
2551 case NODE_TransmitterPdu:
2554 if(pnode->isActive != ival){
2555 pnode->isActive = ival;
2560 case NODE_SignalPdu:
2563 if(pnode->isActive != ival){
2564 pnode->isActive = ival;
2574void dis_set_isNetworkMode(
struct X3D_Node*node,
int networkMode){
2575 int isStandAlone, isNetworkReader, isNetworkWriter;
2576 isStandAlone = isNetworkReader = isNetworkWriter = 0;
2577 switch(networkMode){
2578 case 0: isStandAlone = TRUE;
break;
2579 case 1: isNetworkReader = TRUE;
break;
2580 case 2: isNetworkWriter = TRUE;
break;
2583 switch(node->_nodeType){
2584 case NODE_EspduTransform:
2587 if(pnode->isStandAlone != isStandAlone){
2588 pnode->isStandAlone = isStandAlone;
2591 if(pnode->isNetworkReader != isNetworkReader){
2592 pnode->isNetworkReader = isNetworkReader;
2595 if(pnode->isNetworkWriter != isNetworkWriter){
2596 pnode->isNetworkWriter = isNetworkWriter;
2601 case NODE_DISEntityManager:
2604 if(pnode->isStandAlone != isStandAlone){
2605 pnode->isStandAlone = isStandAlone;
2608 if(pnode->isNetworkReader != isNetworkReader){
2609 pnode->isNetworkReader = isNetworkReader;
2612 if(pnode->isNetworkWriter != isNetworkWriter){
2613 pnode->isNetworkWriter = isNetworkWriter;
2618 case NODE_ReceiverPdu:
2621 if(pnode->isStandAlone != isStandAlone){
2622 pnode->isStandAlone = isStandAlone;
2625 if(pnode->isNetworkReader != isNetworkReader){
2626 pnode->isNetworkReader = isNetworkReader;
2629 if(pnode->isNetworkWriter != isNetworkWriter){
2630 pnode->isNetworkWriter = isNetworkWriter;
2635 case NODE_TransmitterPdu:
2638 if(pnode->isStandAlone != isStandAlone){
2639 pnode->isStandAlone = isStandAlone;
2642 if(pnode->isNetworkReader != isNetworkReader){
2643 pnode->isNetworkReader = isNetworkReader;
2646 if(pnode->isNetworkWriter != isNetworkWriter){
2647 pnode->isNetworkWriter = isNetworkWriter;
2652 case NODE_SignalPdu:
2655 if(pnode->isStandAlone != isStandAlone){
2656 pnode->isStandAlone = isStandAlone;
2659 if(pnode->isNetworkReader != isNetworkReader){
2660 pnode->isNetworkReader = isNetworkReader;
2663 if(pnode->isNetworkWriter != isNetworkWriter){
2664 pnode->isNetworkWriter = isNetworkWriter;
2673int dis_read_stream(
unsigned char * datastream,
int streamsize,
struct Vector *pdus,
int *heard)
2675 int pdutype, bytesread;
2676 unsigned char *carat, *carat2;
2677 static char pdubuffer[10000];
2678 unsigned char *pdubuf;
2681 carat = &datastream[0];
2682 carat = rtp_strip_header(carat,heard);
2683 while(bytesread < streamsize){
2684 int i, distype, nbytes;
2685 if(0)
for(i=0;i<210;i+=10){
2689 printf(
"%5d",(
int)carat[i+j]);
2693 pdutype = (int)(carat[2]);
2694 distype = pduToDis(pdutype);
2697 pdubuf = dis_ctor(distype);
2698 carat2 = dis_unmarshal(carat,pdubuf,distype);
2699 nbytes = (carat2 - carat);
2700 pdu = (
struct Pdu*)pdubuf;
2702 vector_pushBack(
struct Pdu*,pdus,pdu);
2707 unsigned char buf3[32000];
2708 unsigned char *carat3;
2710 carat3 = dis_marshal(buf3,pdubuf,distype);
2711 b3size = carat3 - buf3;
2712 printf(
"marshed bits %d bytes %d\n",b3size*8,b3size);
2714 if(memcmp(carat,buf3,b3size) == 0)
2718 for(i=0;i<210;i+=10){
2722 printf(
"%5d",(
int)buf3[i+j]);
2731 if(0)
if(pdutype == 1){
2734 printf(
"loc %lf %lf %lf rot %f %f %f\n",
2738 n = p->numberOfVariableParameters;
2755 struct ArticulatedParts *v;
2756 v = (
struct ArticulatedParts*)p->variableParameters;
2757 printf(
"v address = %p\n",v);
2760 printf(
"%d %d %d %d %d %lf\n",
2762 (
int)v[i].recordType,
2763 (
int)v[i].changeIndicator,
2764 (
int)v[i].partAttachedTo,
2765 (
int)v[i].parameterType,
2772 printf(
"v address = %p\n",v);
2775 printf(
"%d %d %d %d %d %lf\n",
2777 (
int)v[i].parameterTypeDesignator,
2778 (
int)v[i].changeIndicator,
2779 (
int)v[i].partAttachedTo,
2780 (
int)v[i].parameterType,
2788 bytesread += nbytes;
2804int dis_write_stream(
unsigned char * datastream,
struct Vector *pdus)
2808 unsigned char *carat;
2811 if(pdus && pdus->n){
2812 for(i=0;i<pdus->n;i++){
2813 struct Pdu *pdu = vector_get(
struct Pdu*,pdus,i);
2815 int distype = pduToDis(pdu->
pduType);
2816 carat = dis_marshal(carat,(
unsigned char*)pdu,distype);
2820 nbytes = (int)(carat - datastream);
2827static double lasttime;
2828static char buf[32768];
2829static struct Vector *pdus = NULL;
2837 int i,j,nbytes, more, heard;
2838 static int count = 0;
2839 double thistime, dtime;
2840 if(!sockets_recv || sockets_recv->n == 0)
return;
2841 thistime = TickTime();
2842 dtime = thistime - lasttime;
2843 if(!pdus) pdus = newVector(
struct Pdu*,20);
2847 for(i=0;i<sockets_recv->n;i++){
2854 nbytes = sockrecvfrom(dsock,buf,32000);
2858 dsock->lasttime = thistime;
2861 for(j=0;j<pdus->n;j++){
2862 struct Pdu* pdu = vector_get(
struct Pdu*,pdus,j);
2863 dis_dtor((
unsigned char *)pdu,pduToDis(pdu->pduType));
2866 dis_read_stream((
unsigned char *)buf,nbytes,pdus,&heard);
2872 if(dsock->registered){
2873 for(j=0;j<dsock->registered->n;j++){
2879 switch(node->_nodeType){
2880 case NODE_EspduTransform:
2881 ihit = dis_pdus2node_espdu(node, pdus);
2883 case NODE_DISEntityManager:
2885 ihit = dis_pdus2node_sm(node, pdus);
2887 case NODE_ReceiverPdu:
2888 ihit = dis_pdus2node_receiver(node, pdus);
2890 case NODE_TransmitterPdu:
2891 ihit = dis_pdus2node_transmitter(node, pdus);
2893 case NODE_SignalPdu:
2894 ihit = dis_pdus2node_signal(node, pdus);
2900 if(heard) set_rtp_heard(node);
2901 dis_set_isActive(node,TRUE);
2902 dis_set_node_lasttime(node,thistime);
2909 printf(
"leftovers ...");
2910 nhit = dis_pdus2newnode(dsock,sockem, pdus);
2911 printf(
" %d used\n",nhit);
2915 if(dsock->registered){
2918 for(j=0;j<dsock->registered->n;j++){
2920 if(node->_nodeType == NODE_DISEntityManager){
2925 for(j=0;j<dsock->registered->n;j++){
2927 double readinterval, writeinterval, lasttime;
2929 dis_get_node_lasttime(node,&lasttime,&readinterval,&writeinterval);
2930 if(thistime - lasttime > 5.0) {
2932 dis_set_isActive(node,FALSE);
2936 if(thistime - lasttime > (5.0 * 3) ){
2939 if(sockem && node->_nodeType == NODE_EspduTransform ){
2940 ihit = dis_entity_retire(sockem,node);
2943 printf(
" retired one\n");
2949 if(sockem && sockem->removedEntities.n) {
2959void dis_open_socket(
struct dis_socket* dsock){
2960 if(dsock->multicastRelayHost && strlen(dsock->multicastRelayHost)){
2961 printf(
"[%s]\n",dsock->multicastRelayHost);
2969void *dis_register(
struct X3D_Node* node,
char *address,
int applicationID,
int entityID,
char *multicastRelayHost,
2970 int multicastRelayPort,
2971 char *networkMode,
int port,
double readInterval,
int rtpHeaderExpected,
int siteID,
double writeInterval){
2973 int inetworkmode = 0;
2974 if(!strcmp(networkMode,
"standAlone")) inetworkmode = 0;
2975 else if(!strcmp(networkMode,
"networkReader")) inetworkmode = 1;
2976 else if(!strcmp(networkMode,
"networkWriter")) inetworkmode = 2;
2978 if(inetworkmode == 0) preg = NULL;
2979 if(inetworkmode == 1){
2982 if(!sockets_recv) sockets_recv = newVector(
struct dis_socket,10);
2986 for(i=0;i<sockets_recv->n;i++){
2987 dsock = vector_get_ptr(
struct dis_socket,sockets_recv,i);
2988 if(!strcmp(dsock->address,address) && dsock->port == port){
3002 vector_pushBack(
struct dis_socket,sockets_recv,asock);
3003 dsock = vector_get_ptr(
struct dis_socket,sockets_recv,sockets_recv->n-1);
3004 dsock->address = address;
3006 dsock->multicastRelayHost = multicastRelayHost;
3007 dsock->multicastRelayPort = multicastRelayPort;
3008 dsock->idir = inetworkmode;
3010 dis_open_socket(dsock);
3013 if(!dsock->registered) dsock->registered = newVector(
struct X3D_Node*,20);
3014 vector_pushBack(
struct X3D_Node*,dsock->registered,node);
3015 preg = (
void*)dsock;
3017 if(inetworkmode==2){
3020 if(!sockets_send) sockets_send = newVector(
struct dis_socket,10);
3024 for(i=0;i<sockets_send->n;i++){
3025 dsock = vector_get_ptr(
struct dis_socket,sockets_send,i);
3026 if(!strcmp(dsock->address,address) && dsock->port == port){
3040 vector_pushBack(
struct dis_socket,sockets_send,asock);
3041 dsock = vector_get_ptr(
struct dis_socket,sockets_send,sockets_send->n-1);
3042 dsock->address = address;
3044 dsock->multicastRelayHost = multicastRelayHost;
3045 dsock->multicastRelayPort = multicastRelayPort;
3046 dsock->idir = inetworkmode;
3048 dis_open_socket(dsock);
3051 if(!dsock->registered) dsock->registered = newVector(
struct X3D_Node*,20);
3052 vector_pushBack(
struct X3D_Node*,dsock->registered,node);
3053 preg = (
void*)dsock;
3055 dis_set_isNetworkMode(node, inetworkmode);
3061 if(dsock->registered){
3062 for(j=0;j<dsock->registered->n;j++){
3063 if(vector_get(
struct X3D_Node*,dsock->registered,j)==node){
3064 vector_remove_elem(
struct X3D_Node*,dsock->registered,j);
3070int dis_check_socket_change(
struct dis_socket* dsock,
char *address,
int port,
3071 char *multicastRelayHost,
int multicastRelayPort,
char *networkMode){
3080 int inetworkmode = 0;
3081 if(!strcmp(networkMode,
"standAlone")) inetworkmode = 0;
3082 else if(!strcmp(networkMode,
"networkReader")) inetworkmode = 1;
3083 else if(!strcmp(networkMode,
"networkWriter")) inetworkmode = 2;
3084 if(inetworkmode == 0 && dsock == NULL)
return FALSE;
3085 if(dsock == NULL)
return TRUE;
3086 if(inetworkmode != dsock->idir)
return TRUE;
3087 if(strcmp(address,dsock->address))
return TRUE;
3088 if(port != dsock->port)
return TRUE;
3089 if(strcmp(multicastRelayHost,dsock->multicastRelayHost))
return TRUE;
3090 if(multicastRelayPort != dsock->multicastRelayPort)
return TRUE;
3125 unsigned char *src, *dest;
3126 src = (
unsigned char *)original;
3127 dest = (
unsigned char *)copy;
3129 offset = NODE_OFFSETS[original->_nodeType];
3130 while(offset[0] > -1){
3134 union anyVrml *anysrc, *anydest;
3135 anysrc = (
union anyVrml*)(src + offset[1]);
3136 anydest = (
union anyVrml*)(dest + offset[1]);
3137 shallow_copy_field(offset[2],anysrc,anydest);
3142int shallow_compare_field(
int typeIndex,
union anyVrml* source,
union anyVrml* dest)
3144 int i, isize, has_changed;
3147 has_changed = FALSE;
3149 isMF = typeIndex % 2;
3150 sftype = typeIndex - isMF;
3153 isize = sizeofSForMF(sftype);
3161 if(mfs->n != mfd->n){
3164 ps = (
char *)mfs->p;
3165 pd = (
char *)mfd->p;
3166 for(i=0;i<mfs->n;i++)
3168 has_changed = shallow_compare_field(sftype,(
union anyVrml*)ps,(
union anyVrml*)pd);
3177 case FIELDTYPE_SFString:
3187 has_changed = memcmp(*sd,*ss,
sizeof(
struct Uni_String)) ? TRUE : FALSE;
3194 has_changed = memcmp(dest,source,isize) ? TRUE : FALSE;
3201int shallow_compare_node_fields(
struct X3D_Node *node,
struct X3D_Node *old,
const int *PFIELDS){
3202 const int *fname, *offset;
3203 unsigned char *src, *dest;
3206 src = (
unsigned char *)old;
3207 dest = (
unsigned char *)node;
3211 while(fname[k] > -1){
3212 offset = NODE_OFFSETS[node->_nodeType];
3213 while(offset[0] > -1){
3214 if(offset[0] == fname[k]){
3215 union anyVrml *anysrc, *anydest;
3216 anysrc = (
union anyVrml*)(src + offset[1]);
3217 anydest = (
union anyVrml*)(dest + offset[1]);
3218 has_changed += shallow_compare_field(offset[2],anysrc,anydest);
3225 return has_changed ? TRUE : FALSE;
3228int mark_changed_node_fields(
struct X3D_Node *node,
struct X3D_Node *old,
const int *PFIELDS){
3229 const int *fname, *offset;
3230 unsigned char *src, *dest;
3233 src = (
unsigned char *)old;
3234 dest = (
unsigned char *)node;
3238 while(fname[k] > -1){
3239 offset = NODE_OFFSETS[node->_nodeType];
3240 while(offset[0] > -1){
3241 if(offset[0] == fname[k]){
3242 union anyVrml *anysrc, *anydest;
3243 anysrc = (
union anyVrml*)(src + offset[1]);
3244 anydest = (
union anyVrml*)(dest + offset[1]);
3245 if(shallow_compare_field(offset[2],anysrc,anydest)){
3246 MARK_EVENT(node,offset[1]);
3260const int FIELDS_networksensor [] = {
3262 FIELDNAMES_isActive,
3263 FIELDNAMES_timestamp,
3266 FIELDNAMES_multicastRelayHost,
3267 FIELDNAMES_multicastRelayPort,
3268 FIELDNAMES_networkMode,
3269 FIELDNAMES_isNetworkReader,
3270 FIELDNAMES_isNetworkWriter,
3271 FIELDNAMES_isStandAlone,
3272 FIELDNAMES_readInterval,
3273 FIELDNAMES_writeInterval,
3274 FIELDNAMES_rtpHeaderExpected,
3275 FIELDNAMES_isRtpHeaderHeard,
3282const int FIELDS_entity [] = {
3283 FIELDNAMES_entityID,
3284 FIELDNAMES_applicationID,
3289const int FIELDS_geo [] = {
3290 FIELDNAMES_geoSystem,
3291 FIELDNAMES_geoCoords,
3294const int FIELDS_geosys [] = {
3295 FIELDNAMES_geoSystem,
3298const int FIELDS_geocoord [] = {
3299 FIELDNAMES_geoCoords,
3304const int FIELDS_em_info [] = {
3305 FIELDNAMES_entityCategory,
3306 FIELDNAMES_entityCountry,
3307 FIELDNAMES_entityDomain,
3308 FIELDNAMES_entityExtra,
3309 FIELDNAMES_entityKind,
3310 FIELDNAMES_entitySpecific,
3311 FIELDNAMES_entitySubCategory,
3314const int FIELDS_create [] = {
3315 FIELDNAMES_addedEntities,
3318const int FIELDS_remove [] = {
3319 FIELDNAMES_removedEntities,
3323const int FIELDS_es_force [] = {
3329const int FIELDS_es_transform [] = {
3331 FIELDNAMES_children,
3332 FIELDNAMES_rotation,
3334 FIELDNAMES_scaleOrientation,
3335 FIELDNAMES_translation,
3342const int FIELDS_es_deadreckoning [] = {
3343 FIELDNAMES_deadReckoning,
3344 FIELDNAMES_linearVelocity,
3345 FIELDNAMES_linearAcceleration,
3349const int FIELDS_es_articulation [] = {
3350 FIELDNAMES_set_articulationParameterValue0,
3351 FIELDNAMES_set_articulationParameterValue1,
3352 FIELDNAMES_set_articulationParameterValue2,
3353 FIELDNAMES_set_articulationParameterValue3,
3354 FIELDNAMES_set_articulationParameterValue4,
3355 FIELDNAMES_set_articulationParameterValue5,
3356 FIELDNAMES_set_articulationParameterValue6,
3357 FIELDNAMES_set_articulationParameterValue7,
3358 FIELDNAMES_articulationParameterCount,
3359 FIELDNAMES_articulationParameterDesignatorArray,
3360 FIELDNAMES_articulationParameterChangeIndicatorArr,
3361 FIELDNAMES_articulationParameterIdPartAttachedToAr,
3362 FIELDNAMES_articulationParameterTypeArray,
3363 FIELDNAMES_articulationParameterArray,
3364 FIELDNAMES_articulationParameterValue0_changed,
3365 FIELDNAMES_articulationParameterValue1_changed,
3366 FIELDNAMES_articulationParameterValue2_changed,
3367 FIELDNAMES_articulationParameterValue3_changed,
3368 FIELDNAMES_articulationParameterValue4_changed,
3369 FIELDNAMES_articulationParameterValue5_changed,
3370 FIELDNAMES_articulationParameterValue6_changed,
3371 FIELDNAMES_articulationParameterValue7_changed,
3375const int FIELDS_collision [] = {
3376 FIELDNAMES_collisionType,
3377 FIELDNAMES_collideTime,
3378 FIELDNAMES_isCollided,
3382const int FIELDS_events [] = {
3383 FIELDNAMES_eventEntityID,
3384 FIELDNAMES_eventApplicationID,
3385 FIELDNAMES_eventSiteID,
3386 FIELDNAMES_eventNumber,
3390const int FIELDS_fire [] = {
3393 FIELDNAMES_fireMissionIndex,
3394 FIELDNAMES_firingRange,
3395 FIELDNAMES_firedTime,
3399const int FIELDS_detonation [] = {
3400 FIELDNAMES_detonationLocation,
3401 FIELDNAMES_detonationRelativeLocation,
3402 FIELDNAMES_detonationResult,
3403 FIELDNAMES_detonateTime,
3404 FIELDNAMES_isDetonated,
3408const int FIELDS_munition [] = {
3409 FIELDNAMES_munitionEntityID,
3410 FIELDNAMES_munitionApplicationID,
3411 FIELDNAMES_munitionSiteID,
3412 FIELDNAMES_munitionStartPoint,
3413 FIELDNAMES_munitionEndPoint,
3414 FIELDNAMES_munitionQuantity,
3417const int FIELDS_rate [] = {
3418 FIELDNAMES_firingRate,
3424const int FIELDS_receiver [] = {
3426 FIELDNAMES_whichGeometry,
3427 FIELDNAMES_receiverState,
3428 FIELDNAMES_receivedPower,
3429 FIELDNAMES_transmitterEntityID,
3430 FIELDNAMES_transmitterApplicationID,
3431 FIELDNAMES_transmitterSiteID,
3432 FIELDNAMES_transmitterRadioID,
3436const int FIELDS_signal [] = {
3438 FIELDNAMES_whichGeometry,
3440 FIELDNAMES_dataLength,
3441 FIELDNAMES_encodingScheme,
3442 FIELDNAMES_sampleRate,
3448const int FIELDS_transmitter [] = {
3450 FIELDNAMES_whichGeometry,
3451 FIELDNAMES_radioEntityTypeCategory,
3452 FIELDNAMES_radioEntityTypeCountry,
3453 FIELDNAMES_radioEntityTypeDomain,
3454 FIELDNAMES_radioEntityTypeKind,
3455 FIELDNAMES_radioEntityTypeNomenclature,
3456 FIELDNAMES_radioEntityTypeNomenclatureVersion,
3457 FIELDNAMES_antennaLocation,
3458 FIELDNAMES_antennaPatternLength,
3459 FIELDNAMES_antennaPatternType,
3460 FIELDNAMES_relativeAntennaLocation,
3461 FIELDNAMES_inputSource,
3462 FIELDNAMES_transmitState,
3464 FIELDNAMES_frequency,
3465 FIELDNAMES_transmitFrequencyBandwidth,
3466 FIELDNAMES_lengthOfModulationParameters,
3467 FIELDNAMES_modulationTypeDetail,
3468 FIELDNAMES_modulationTypeMajor,
3469 FIELDNAMES_modulationTypeMajor,
3470 FIELDNAMES_modulationTypeSpreadSpectrum,
3471 FIELDNAMES_modulationTypeSystem,
3472 FIELDNAMES_cryptoSystem,
3473 FIELDNAMES_cryptoKeyID,
3478 if(node->_oldState == NULL){
3482 old = createNewX3DNode0(node->_nodeType);
3484 node->_oldState = old;
3486 if(!node->_registered){
3488 psock = dis_register(X3D_NODE(node),node->address->strptr,node->applicationID,node->entityID,node->multicastRelayHost->strptr,
3489 node->multicastRelayPort,
3490 node->networkMode->strptr, node->port,node->readInterval,node->rtpHeaderExpected,node->siteID,node->writeInterval);
3491 node->_registered = TRUE;
3492 node->_dsock = psock;
3494 if(node->_registered){
3497 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_networksensor)){
3499 changed = dis_check_socket_change((
struct dis_socket*)node->_dsock,node->address->strptr, node->port,
3500 node->multicastRelayHost->strptr,node->multicastRelayPort, node->networkMode->strptr);
3502 dis_unregister((
struct dis_socket*)node->_dsock,X3D_NODE(node));
3503 node->_registered = FALSE;
3504 node->_dsock = NULL;
3518 if(!node->__geoSystem || shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_geosys)){
3519 compile_geoSystem(X3D_NODE(node),node->_nodeType,&node->geoSystem,&node->__geoSystem);
3520 update_origin(GEOSYS(node->__geoSystem), X3D_NODE(node), &node->geoCoords, NULL);
3526 compile_DIS_network(node);
3527 compile_DIS_geo(node);
3530 if(node->_oldState == NULL){
3534 old = createNewX3DNode0(node->_nodeType);
3536 node->_oldState = old;
3538 if(!node->_registered){
3540 psock = dis_register(X3D_NODE(node),node->address->strptr,node->applicationID,node->entityID,node->multicastRelayHost->strptr,
3541 node->multicastRelayPort,
3542 node->networkMode->strptr, node->port,node->readInterval,node->rtpHeaderExpected,node->siteID,node->writeInterval);
3543 node->_registered = TRUE;
3544 node->_dsock = psock;
3546 if(node->_registered){
3549 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_networksensor)){
3551 changed = dis_check_socket_change((
struct dis_socket*)node->_dsock,node->address->strptr, node->port,
3552 node->multicastRelayHost->strptr,node->multicastRelayPort, node->networkMode->strptr);
3554 dis_unregister((
struct dis_socket*)node->_dsock,X3D_NODE(node));
3555 node->_registered = FALSE;
3556 node->_dsock = NULL;
3568 if(!node->__geoSystem || shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_geosys)){
3569 compile_geoSystem(X3D_NODE(node),node->_nodeType,&node->geoSystem,&node->__geoSystem);
3570 update_origin(GEOSYS(node->__geoSystem), X3D_NODE(node), &node->geoCoords, NULL);
3576 if(node->isNetworkReader){
3577 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_transmitter);
3578 }
else if(node->isNetworkWriter){
3579 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_transmitter)){
3580 node->_pduchange_transmitter = TRUE;
3583 freeMallocedNodeFields(node->_oldState);
3584 shallow_copy_node(node->_oldState,X3D_NODE(node));
3587 if(node->isNetworkReader){
3588 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_signal);
3589 }
else if(node->isNetworkWriter){
3590 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_signal)){
3591 node->_pduchange_signal = TRUE;
3594 freeMallocedNodeFields(node->_oldState);
3595 shallow_copy_node(node->_oldState,X3D_NODE(node));
3598 if(node->isNetworkReader){
3599 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_receiver);
3600 }
else if(node->isNetworkWriter){
3601 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_receiver)){
3602 node->_pduchange_receiver = TRUE;
3605 freeMallocedNodeFields(node->_oldState);
3606 shallow_copy_node(node->_oldState,X3D_NODE(node));
3613 if(node->isNetworkReader){
3614 if(node->_pduchange_es){
3615 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_em_info);
3616 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_es_force);
3617 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_es_deadreckoning);
3618 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_es_articulation);
3621 if(node->_pduchange_collision){
3622 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_collision);
3624 if(node->_pduchange_fire){
3625 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_fire);
3627 if(node->_pduchange_fire || node->_pduchange_collision){
3630 if(node->_pduchange_detonation){
3631 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_detonation);
3633 if(node->_pduchange_fire || node->_pduchange_detonation){
3634 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_munition);
3635 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_rate);
3638 reset_node_pduchanged(X3D_NODE(node));
3640 }
else if(node->isNetworkWriter){
3641 int es_info, es_force, es_deadreckoning, es_articulation;
3642 es_info = es_force = es_deadreckoning = es_articulation = FALSE;
3643 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_em_info)){
3646 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_es_force)){
3649 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_es_deadreckoning)){
3650 es_deadreckoning = FALSE;
3652 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_es_articulation)){
3655 es_articulation = TRUE;
3656 node->articulationParameterArray.p = realloc(node->articulationParameterArray.p,16*
sizeof(
float));
3657 n = node->articulationParameterArray.n;
3661 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue0)
3662 node->articulationParameterArray.p[i] = node->set_articulationParameterValue0;
3666 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue1)
3667 node->articulationParameterArray.p[i] = node->set_articulationParameterValue1;
3671 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue2)
3672 node->articulationParameterArray.p[i] = node->set_articulationParameterValue2;
3676 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue3)
3677 node->articulationParameterArray.p[i] = node->set_articulationParameterValue3;
3681 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue4)
3682 node->articulationParameterArray.p[i] = node->set_articulationParameterValue4;
3686 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue5)
3687 node->articulationParameterArray.p[i] = node->set_articulationParameterValue5;
3691 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue6)
3692 node->articulationParameterArray.p[i] = node->set_articulationParameterValue6;
3696 if(node->set_articulationParameterValue0 != old->set_articulationParameterValue7)
3697 node->articulationParameterArray.p[i] = node->set_articulationParameterValue7;
3704 node->articulationParameterCount = node->articulationParameterArray.n;
3707 node->_pduchange_es = node->_pduchange_es || es_info || es_force || es_deadreckoning || es_articulation ? TRUE : FALSE;
3708 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_collision)){
3709 node->_pduchange_collision = TRUE;
3711 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_events)){
3715 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_fire)){
3716 node->_pduchange_fire = TRUE;
3718 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_detonation)){
3719 node->_pduchange_detonation = TRUE;
3721 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_munition)){
3722 node->_pduchange_fire = TRUE;
3723 node->_pduchange_detonation = TRUE;
3725 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_rate)){
3726 node->_pduchange_fire = TRUE;
3727 node->_pduchange_detonation = TRUE;
3730 freeMallocedNodeFields(node->_oldState);
3731 shallow_copy_node(node->_oldState,X3D_NODE(node));
3750 if(node->isNetworkReader){
3751 if(node->_pduchange_em_info){
3752 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_em_info);
3754 if(node->_pduchange_create){
3755 if(node->addedEntities.n > 0)
3756 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_create);
3758 if(node->_pduchange_remove){
3759 if(node->removedEntities.n > 0)
3760 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_remove);
3762 reset_node_pduchanged(X3D_NODE(node));
3764 }
else if(node->isNetworkWriter){
3765 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_em_info)){
3766 node->_pduchange_em_info = TRUE;
3768 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_create)){
3769 if(node->addedEntities.n > 0)
3770 node->_pduchange_create = TRUE;
3772 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_remove)){
3773 if(node->removedEntities.n > 0)
3774 node->_pduchange_remove = TRUE;
3777 freeMallocedNodeFields(node->_oldState);
3778 shallow_copy_node(node->_oldState,X3D_NODE(node));
3802void dead_reckon(
int drmethod,
double dtime,
float *p1,
float *R1xyza,
float *p0,
float *v0,
float *a0,
float *R0xyza,
float *RVxyza){
3823 veccopy4f(R1xyza,R0xyza);
3830 vecadd3f(p1,p0,vecscale3f(tmp,v0,dtime));
3831 veccopy4f(R1xyza,R0xyza);
3841 vecadd3f(p1,p0,vecscale3f(tmp,v0,dtime));
3844 vrmlrot4f_to_quaternion(&q0,R0xyza);
3845 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3846 quaternion_multiply(&q1,&q0,&qv);
3847 quaternion_to_vrmlrot4f(&q1,R1xyza);
3855 float tmp3[3],tmp2[3],tmp1[3];
3858 vecadd3f(p1,p0,vecadd3f(tmp3,vecscale3f(tmp2,v0,dtime),vecscale3f(tmp1,a0,.5f*dtime*dtime)));
3861 vrmlrot4f_to_quaternion(&q0,R0xyza);
3862 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3863 quaternion_multiply(&q1,&q0,&qv);
3864 quaternion_to_vrmlrot4f(&q1,R1xyza);
3875 float tmp3[3],tmp2[3],tmp1[3];
3876 vecadd3f(p1,p0,vecadd3f(tmp3,vecscale3f(tmp2,v0,dtime),vecscale3f(tmp1,a0,.5f*dtime*dtime)));
3878 veccopy4f(R1xyza,R0xyza);
3886 float deltap[3], att[3], tmp[3], tmp1[3], tmp2[3], tmp3[3];
3888 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3889 vrmlrot4f_to_quaternion(&qbw,R0xyza);
3890 vecscale3f(tmp3,v0,dtime);
3891 quaternion_rotation3f(deltap,&qv,tmp3);
3892 quaternion_rotation3f(tmp2,&qbw,deltap);
3893 vecadd3f(p1,p0,tmp2);
3896 veccopy4f(R1xyza,R0xyza);
3903 float deltap[3], att[3], tmp[3], tmp1[3], tmp2[3], tmp3[3];
3905 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3906 vrmlrot4f_to_quaternion(&qbw,R0xyza);
3907 vecscale3f(tmp3,v0,dtime);
3908 quaternion_rotation3f(deltap,&qv,tmp3);
3909 quaternion_rotation3f(tmp2,&qbw,deltap);
3910 vecadd3f(p1,p0,tmp2);
3914 quaternion_multiply(&q1,&qbw,&qv);
3915 quaternion_to_vrmlrot4f(&q1,R1xyza);
3933 float deltap[3], att[3], tmp[3], tmp1[3], tmp2[3], tmp3[3];
3935 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3936 vrmlrot4f_to_quaternion(&qbw,R0xyza);
3937 vecadd3f(tmp3,vecscale3f(tmp2,v0,dtime),vecscale3f(tmp1,a0,.5f*dtime*dtime));
3938 quaternion_rotation3f(deltap,&qv,tmp3);
3939 quaternion_rotation3f(tmp2,&qbw,deltap);
3940 vecadd3f(p1,p0,tmp2);
3944 quaternion_multiply(&q1,&qbw,&qv);
3945 quaternion_to_vrmlrot4f(&q1,R1xyza);
3953 float deltap[3], att[3], tmp[3], tmp1[3], tmp2[3], tmp3[3];
3955 vrmlrot_to_quaternion(&qv,RVxyza[0],RVxyza[1],RVxyza[2],RVxyza[3]*dtime);
3956 vrmlrot4f_to_quaternion(&qbw,R0xyza);
3957 vecadd3f(tmp3,vecscale3f(tmp2,v0,dtime),vecscale3f(tmp1,a0,.5f*dtime*dtime));
3958 quaternion_rotation3f(deltap,&qv,tmp3);
3959 quaternion_rotation3f(tmp2,&qbw,deltap);
3960 vecadd3f(p1,p0,tmp2);
3963 veccopy4f(R1xyza,R0xyza);
3972 veccopy4f(R1xyza,R0xyza);
3977#define DRA_POS_THRSH 1.5
3978#define DRA_ORIENT_THRSH .175
3981 int withintol = TRUE;
3982 float p0[3], gap[3];
3984 veccopy3f(p0,node->_p0.c);
3986 vecdif3f(gap,p0,node->translation.c);
3987 if(veclength3f(gap) > DRA_POS_THRSH)
3993 if(node->isNetworkReader){
3994 if(node->_pduchange_es){
3995 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_es_transform);
3996 mark_changed_node_fields(X3D_NODE(node), node->_oldState, FIELDS_geo);
3998 }
else if(node->isNetworkWriter){
3999 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_es_transform)
4000 || shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_geo)) {
4002 if(!transform_within_DeadReckoningTolerance1(node)) {
4003 node->_pduchange_es = TRUE;
4008 if(shallow_compare_node_fields(X3D_NODE(node),node->_oldState,FIELDS_es_transform)){
4013 node->__do_center = verify_translate ((GLfloat *)node->center.c);
4014 node->__do_trans = verify_translate ((GLfloat *)node->translation.c);
4015 node->__do_scale = verify_scale ((GLfloat *)node->scale.c);
4016 node->__do_rotation = verify_rotate ((GLfloat *)node->rotation.c);
4017 node->__do_scaleO = verify_rotate ((GLfloat *)node->scaleOrientation.c);
4019 node->__do_anything = (node->__do_center ||
4022 node->__do_rotation ||
4025 REINITIALIZE_SORTED_NODES_FIELD(node->children,node->_sortedChildren);
4031 compile_DIS_common(node);
4032 compile_EspduTransform1(node);
4033 compile_EspduTransform0(node);
4038 int drmethod, wasTransmitted;
4039 float p1[3],v1[3],a1[3], RVxyza[4], R0xyza[4], R1xyza[4];
4040 float p0[3],v0[3],a0[3];
4042 static int smoothing_frames = 230;
4043 static int want_smoothing = 1;
4046 wasTransmitted = FALSE;
4047 if(node->isNetworkReader){
4048 if(node->_lasttime == 0.0)
4050 if(node->_pduchange_es){
4052 node->_change_count++;
4053 wasTransmitted = TRUE;
4054 if(want_smoothing && node->_change_count){
4055 vecdif3f(node->_smoothingDelta.c,node->translation.c,node->_p0.c);
4056 node->_smoothingCount = smoothing_frames;
4057 if(node->_change_count > 1)
4058 node->_smoothingCount = 0;
4060 veccopy3f(node->_p0.c,node->translation.c);
4061 veccopy4f(node->_r0.c,node->rotation.c);
4063 veccopy3f(p0,node->_p0.c);
4065 veccopy3f(v0,node->linearVelocity.c);
4066 veccopy3f(a0,node->linearAcceleration.c);
4067 veccopy4f(RVxyza,node->_angularVelocity.c);
4068 veccopy4f(R0xyza,node->_r0.c);
4071 if(node->isStandAlone){
4072 veccopy3f(p0,node->translation.c);
4073 veccopy3f(v0,node->linearVelocity.c);
4074 veccopy3f(a0,node->linearAcceleration.c);
4075 veccopy4f(RVxyza,node->_angularVelocity.c);
4076 veccopy4f(R0xyza,node->rotation.c);
4078 if(node->isNetworkWriter){
4081 wasTransmitted = TRUE;
4082 node->_sent = FALSE;
4083 veccopy3f(node->_p0.c,node->translation.c);
4084 veccopy4f(node->_r0.c,node->rotation.c);
4086 veccopy3f(p0,node->_p0.c);
4087 veccopy3f(v0,node->linearVelocity.c);
4088 veccopy3f(a0,node->linearAcceleration.c);
4089 veccopy4f(RVxyza,node->_angularVelocity.c);
4090 veccopy4f(R0xyza,node->_r0.c);
4092 if(node->_lastframetime == 0.0)
4093 veccopy3f(node->_p0.c,p0);
4094 if(node->_lastframetime > 0.0){
4095 dtime = TickTime() - node->_lastframetime;
4096 drmethod = node->deadReckoning;
4099 dead_reckon(drmethod, dtime, p1, R1xyza, p0, v0, a0, R0xyza, RVxyza);
4100 veccopy3f(node->_p0.c,p1);
4101 veccopy4f(node->_r0.c,R1xyza);
4104 node->_lastframetime = TickTime();
4105 if(node->isNetworkReader){
4110 float psmooth[3], pzero[3], alpha;
4113 i = node->_smoothingCount;
4114 n = smoothing_frames;
4115 alpha = 1.0f - (float)min(i,n)/(float)n;
4116 vecset3f(pzero,0.0f,0.0f,0.0f);
4117 veclerp3f(psmooth,pzero,node->_smoothingDelta.c,alpha);
4118 vecdif3f(node->translation.c,node->_p0.c,psmooth);
4119 node->_smoothingCount++;
4121 veccopy3f(node->translation.c,node->_p0.c);
4123 veccopy4f(node->rotation.c,node->_r0.c);
4129 if(node->isNetworkReader) espdu_update_by_dead_reckoning(node);
4131 if(node->__geoSystem)
4132 geoprep(GEOSYS(node->__geoSystem),&node->geoCoords);
4133 if(!node->isNetworkReader) espdu_update_by_dead_reckoning(node);
4144 if(!renderstate()->render_vp) {
4148 if (node->__do_anything) {
4150 FW_GL_PUSH_MATRIX();
4153 if (node->__do_trans)
4154 FW_GL_TRANSLATE_F(node->translation.c[0],node->translation.c[1],node->translation.c[2]);
4157 if (node->__do_center)
4158 FW_GL_TRANSLATE_F(node->center.c[0],node->center.c[1],node->center.c[2]);
4161 if (node->__do_rotation) {
4162 FW_GL_ROTATE_RADIANS(node->rotation.c[3], node->rotation.c[0],node->rotation.c[1],node->rotation.c[2]);
4166 if (node->__do_scaleO) {
4167 FW_GL_ROTATE_RADIANS(node->scaleOrientation.c[3], node->scaleOrientation.c[0], node->scaleOrientation.c[1],node->scaleOrientation.c[2]);
4172 if (node->__do_scale)
4173 FW_GL_SCALE_F(node->scale.c[0],node->scale.c[1],node->scale.c[2]);
4176 if (node->__do_scaleO)
4177 FW_GL_ROTATE_RADIANS(-node->scaleOrientation.c[3], node->scaleOrientation.c[0], node->scaleOrientation.c[1],node->scaleOrientation.c[2]);
4180 if (node->__do_center)
4181 FW_GL_TRANSLATE_F(-node->center.c[0],-node->center.c[1],-node->center.c[2]);
4185 if(renderstate()->render_boxes) extent6f_draw(node->_extent);
4194 if(!renderstate()->render_vp) {
4195 if (node->__do_anything) {
4200 if((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) {
4201 FW_GL_TRANSLATE_F(((node->center).c[0]),((node->center).c[1]),((node->center).c[2])
4203 FW_GL_ROTATE_RADIANS(((node->scaleOrientation).c[3]),((node->scaleOrientation).c[0]),((node->scaleOrientation).c[1]),((node->scaleOrientation).c[2])
4205 FW_GL_SCALE_F((
float)1.0/(((node->scale).c[0])),(
float)1.0/(((node->scale).c[1])),(
float)1.0/(((node->scale).c[2]))
4207 FW_GL_ROTATE_RADIANS(-(((node->scaleOrientation).c[3])),((node->scaleOrientation).c[0]),((node->scaleOrientation).c[1]),((node->scaleOrientation).c[2])
4209 FW_GL_ROTATE_RADIANS(-(((node->rotation).c[3])),((node->rotation).c[0]),((node->rotation).c[1]),((node->rotation).c[2])
4211 FW_GL_TRANSLATE_F(-(((node->center).c[0])),-(((node->center).c[1])),-(((node->center).c[2]))
4213 FW_GL_TRANSLATE_F(-(((node->translation).c[0])),-(((node->translation).c[1])),-(((node->translation).c[2]))
4217 if(node->__geoSystem)
4218 geofin(GEOSYS(node->__geoSystem),&node->geoCoords);
4225 if(!renderstate()->render_vp) {
4230 static int eventNumber = 0;
4231 if(node->eventNumber > eventNumber){
4232 node->firedTime = TickTime();
4233 eventNumber = node->eventNumber;
4235 double dtime = TickTime() - (double)node->munitionQuantity/(
double)max(1,node->firingRate) - node->firedTime ;
4236 if(dtime > 5.0)
return;
4237 mnode = (
struct X3D_EspduTransform*)dis_find_registered_node_by_entityid(node->munitionEntityID,TRUE,TRUE);
4239 for(i=0;i<node->munitionQuantity;i++){
4241 dtime = max(0.0,TickTime() - (
double)i/(
double)max(1,node->firingRate) - node->firedTime);
4242 dtime = min(5.0,dtime);
4243 float delta[3], velocity[3], progress[3], loc[3];
4244 vecdif3f(delta,node->munitionEndPoint.c,node->munitionStartPoint.c);
4245 vecscale3f(velocity,delta,1.0f/3.0f);
4246 vecscale3f(progress,velocity,(
float)dtime);
4247 if(veclength3f(progress) > veclength3f(delta)) {
4249 veccopy3f(loc,node->munitionEndPoint.c);
4250 if(i==(node->munitionQuantity-1)){
4251 node->fired1 = FALSE;
4252 node->detonateTime = TickTime();
4255 vecadd3f(loc,node->munitionStartPoint.c,progress);
4258 FW_GL_PUSH_MATRIX();
4259 FW_GL_TRANSLATE_F(loc[0],loc[1],loc[2]);
4264 normalChildren(mnode->children);
4275 if(!renderstate()->render_vp) {
4276 double dtime = TickTime() - node->detonateTime;
4277 if( dtime > 0.0 && dtime < .5){
4280 mnode = (
struct X3D_EspduTransform*)dis_find_registered_node_by_entityid(node->munitionEntityID,TRUE,TRUE);
4282 for(i=0;i<node->munitionQuantity;i++){
4283 float loc[3], fscale;
4285 veccopy3f(loc,node->detonationRelativeLocation.c);
4286 FW_GL_PUSH_MATRIX();
4287 FW_GL_TRANSLATE_F(loc[0],loc[1],loc[2]);
4288 fscale = dtime * 10.0f;
4289 FW_GL_SCALE_F(fscale,fscale,fscale);
4290 normalChildren(mnode->children);
4297void dis_register_collide(
struct X3D_Node* node,
double *transform);
4303 RETURN_FROM_CHILD_IF_NOT_FOR_ME
4308 double modelviewMatrix[16];
4309 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
4310 dis_register_collide(X3D_NODE(node),modelviewMatrix);
4314 prep_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
4327 printf (
"transform - doing normalChildren\n");
4330 normalChildren(node->_sortedChildren);
4333 render_munitions(node);
4335 render_detonation(node);
4340 printf (
"transform - done normalChildren\n");
4344 fin_sibAffectors((
struct X3D_Node*)node,&node->__sibAffectors);
4353 compile_TransmitterPdu0(node);
4358 compile_SignalPdu0(node);
4363 compile_ReceiverPdu0(node);
4369 geoprep(GEOSYS(node->__geoSystem),&node->geoCoords);
4371 geofin(GEOSYS(node->__geoSystem),&node->geoCoords);
4372 if(renderstate()->render_boxes) extent6f_draw(node->_extent);
4376 geoprep(GEOSYS(node->__geoSystem),&node->geoCoords);
4378 geofin(GEOSYS(node->__geoSystem),&node->geoCoords);
4379 if(renderstate()->render_boxes) extent6f_draw(node->_extent);
4383 geoprep(GEOSYS(node->__geoSystem),&node->geoCoords);
4385 geofin(GEOSYS(node->__geoSystem),&node->geoCoords);
4386 if(renderstate()->render_boxes) extent6f_draw(node->_extent);
4392 ConsoleMessage(
"domain %d category %d country %d kind %d extra %d subcat %d spec %d\n",
4393 anode->domain, anode->category,anode->country, anode->kind, anode->extra, anode->subcategory, anode->specific);
4397 compile_DISEntityManager0(node);
4400static int app_entity_last_id = 0;
4403 app_entity_last_id++;
4404 return app_entity_last_id;
4406#define GEOEL_WE_A (double)6378137
4414 static int ADD = 1, REMOVE = 2;
4417 if(node->addEntities.n){
4420 node->addedEntities.n = 0;
4421 for(j=0;j<node->addEntities.n;j++){
4422 int ibest,iscore,jscore;
4423 int entityID, applicationID, siteID;
4424 int port, multicastRelayPort;
4425 struct Uni_String *address, *networkMode, *multicastRelayHost;
4434 candi = node->addEntities.p[j];
4435 if(candi->_nodeType == NODE_DISEntityTypeMapping)
4445 for(i=0;i<node->mapping.n;i++){
4450 if(anode->domain == bnode->domain) jscore++;
4451 if(anode->category == bnode->category) jscore++;
4452 if(anode->country == bnode->country) jscore++;
4453 if(anode->kind == bnode->kind) jscore++;
4454 if(anode->extra == bnode->extra) jscore++;
4455 if(anode->subcategory == bnode->subcategory) jscore++;
4456 if(anode->specific == bnode->specific) jscore++;
4457 if(jscore > iscore){
4464 applicationID = node->applicationID;
4465 siteID = node->siteID;
4466 entityID = newEntityID();
4467 address = node->address;
4469 networkMode = newASCIIString (
"networkWriter");
4470 multicastRelayHost = node->multicastRelayHost;
4471 multicastRelayPort = node->multicastRelayPort;
4474 }
else if(candi->_nodeType == NODE_EspduTransform) {
4479 for(i=0;i<node->mapping.n;i++){
4484 if(anode->entityDomain == bnode->domain) jscore++;
4485 if(anode->entityCategory == bnode->category) jscore++;
4486 if(anode->entityCountry == bnode->country) jscore++;
4487 if(anode->entityKind == bnode->kind) jscore++;
4488 if(anode->entityExtra == bnode->extra) jscore++;
4489 if(anode->entitySubCategory == bnode->subcategory) jscore++;
4490 if(anode->entitySpecific == bnode->specific) jscore++;
4491 if(jscore > iscore){
4498 applicationID = anode->applicationID;
4499 siteID = anode->siteID;
4500 entityID = anode->entityID;
4501 address = anode->address;
4503 networkMode = newASCIIString (
"networkReader");
4504 multicastRelayHost = anode->multicastRelayHost;
4505 multicastRelayPort = anode->multicastRelayPort;
4506 if(veclengthd(anode->geoCoords.c) < GEOEL_WE_A/2.0) use_GC = TRUE;
4517 iline = createNewX3DNode(NODE_Inline);
4519 iline->_parentResource = X3D_PROTO(node->_executionContext)->_parentResource;
4524 espdu = createNewX3DNode(NODE_EspduTransform);
4526 espdu->geoSystem.p[0] = newASCIIString(
"GC");
4527 espdu->geoSystem.n = 1;
4530 espdu->enabled = TRUE;
4531 espdu->isActive = TRUE;
4532 espdu->entityID = entityID;
4533 espdu->applicationID = applicationID;
4534 espdu->siteID = siteID;
4536 espdu->address = address;
4537 espdu->multicastRelayHost = multicastRelayHost;
4538 espdu->multicastRelayPort = multicastRelayPort;
4539 espdu->networkMode = networkMode;
4540 dis_set_node_lasttime(X3D_NODE(espdu),TickTime());
4547 dis_register(X3D_NODE(espdu),address->strptr,applicationID,entityID,multicastRelayHost->strptr,multicastRelayPort,
4548 networkMode->strptr,port,5.0,FALSE,siteID,5.0);
4551 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(iline));
4555 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(espdu));
4563 AddRemoveChildren(X3D_NODE(espdu), &espdu->children, (
struct X3D_Node * *)&iline, 1, ADD,__FILE__,__LINE__);
4565 shallow_copy_field(FIELDTYPE_MFString,(
union anyVrml*)&best->url,(
union anyVrml*)&iline->url);
4569 AddRemoveChildren(X3D_NODE(node), mfn, (
struct X3D_Node * *)&espdu, 1, ADD,__FILE__,__LINE__);
4571 AddRemoveChildren(X3D_NODE(node), &node->addedEntities, (
struct X3D_Node * *)&espdu, 1, ADD,__FILE__,__LINE__);
4576 if(node->addedEntities.n) MARK_EVENT(X3D_NODE(node),offsetof(
struct X3D_DISEntityManager,addedEntities));
4577 node->addEntities.n = 0;
4578 FREE_IF_NZ(node->addEntities.p);
4580 if(node->removeEntities.n){
4583 node->removedEntities.n = 0;
4584 for(j=0;j<node->removeEntities.n;j++){
4585 if(node->removeEntities.p[j]->_nodeType == NODE_DISEntityTypeMapping){
4586 int ibest,iscore,jscore;
4591 for(i=0;i<node->mapping.n;i++){
4592 if(node->mapping.p[i]->_nodeType == NODE_DISEntityTypeMapping){
4595 if(anode->domain == bnode->domain) jscore++;
4596 if(anode->category == bnode->category) jscore++;
4597 if(anode->country == bnode->country) jscore++;
4598 if(anode->kind == bnode->kind) jscore++;
4599 if(anode->extra == bnode->extra) jscore++;
4600 if(anode->subcategory == bnode->subcategory) jscore++;
4601 if(anode->specific == bnode->specific) jscore++;
4602 if(jscore > iscore){
4611 AddRemoveChildren(X3D_NODE(node), mfn, (
struct X3D_Node * *)&best, 1, REMOVE,__FILE__,__LINE__);
4613 AddRemoveChildren(X3D_NODE(node), &node->removedEntities, (
struct X3D_Node * *)&best->_child, 1, ADD,__FILE__,__LINE__);
4619 if(node->removedEntities.n) {
4623 node->removeEntities.n = 0;
4626Stack *dis_collide_stack = NULL;
4629 if(dis_collide_stack){
4630 for(i=0;i<dis_collide_stack->n;i++){
4633 double mvmInverse[16], m2m[16];
4636 usehit *uhit = vector_get_ptr(
usehit,dis_collide_stack,i);
4638 if(espdu->isNetworkReader)
continue;
4641 matinverseAFFINE(mvmInverse,uhit->mvm);
4642 extent6f_copy(ee,uhit->node->_extent);
4643 for(j=0;j<dis_collide_stack->n;j++){
4645 float eeb[6],eeba[6],eaXb[6];
4646 usehit *uhitb = vector_get_ptr(
usehit,dis_collide_stack,j);
4647 extent6f_copy(eeb,uhitb->node->_extent);
4648 if(extent6f_isSet(eeb)){
4650 matmultiplyAFFINE(m2m,mvmInverse,uhitb->mvm);
4652 extent6f_mattransform4d(eeba,eeb,m2m);
4654 extent6f_intersect_extent6f(eaXb,ee,eeba);
4655 if(extent6f_isSet(eaXb)){
4663 if(espdu->isCollided == FALSE){
4664 espdu->collideTime = TickTime();
4665 espdu->eventNumber = dis_next_event_number();
4667 espdu->collisionType = 33;
4668 espdu->isCollided = TRUE;
4669 espdu->eventSiteID = espdub->siteID;
4670 espdu->eventApplicationID = espdub->applicationID;
4671 espdu->eventEntityID = espdub->entityID;
4681 if(espdu->isCollided){
4682 espdu->isCollided = FALSE;
4683 espdu->collideTime = 0.0;
4684 espdu->collisionType = 0;
4685 espdu->eventSiteID = 0;
4686 espdu->eventApplicationID = 0;
4687 espdu->eventEntityID = 0;
4694void dis_clear_collide(){
4695 if(dis_collide_stack) dis_collide_stack->n = 0;
4697void dis_register_collide(
struct X3D_Node* node,
double *transform){
4700 if(!dis_collide_stack) dis_collide_stack = newStack(
usehit);
4702 for(i=0;i<dis_collide_stack->n;i++){
4703 usehit *uhit = vector_get_ptr(
usehit,dis_collide_stack,i);
4704 if(uhit->node == node){
4712 memcpy(uhit.mvm,transform,16*
sizeof(
double));
4713 uhit.userdata = NULL;
4714 vector_pushBack(
usehit,dis_collide_stack,uhit);
4735void fwl_sendreceive_DIS(){
4767 dis_clear_collide();
unsigned short quantity
how many of the munition were fired
unsigned short rate
rate at which the munition was fired
struct EntityType munition
What munition was used in the burst.
unsigned short warhead
type of warhead
unsigned short fuse
type of fuse used
unsigned char collisionType
ID of event.
struct EventID eventID
ID of event.
struct EntityID issuingEntityID
ID of the entity that issued the collision PDU.
struct EntityID collidingEntityID
ID of entity that has collided with the issuing entity ID.
struct Vector3Float entityAngularVelocity
angular velocity of the entity
struct Vector3Float entityLinearAcceleration
Linear acceleration of the entity.
unsigned char deadReckoningAlgorithm
enumeration of what dead reckoning algorighm to use
char otherParameters[15]
other parameters to use in the dead reckoning algorithm
struct Vector3Float locationInEntityCoordinates
location of the detonation or impact in the target entity's coordinate system.
struct BurstDescriptor burstDescriptor
Describes munition used.
struct Vector3Double locationInWorldCoordinates
where the detonation is, in world coordinates
unsigned char detonationResult
result of the explosion
struct EventID eventID
ID firing event.
unsigned char numberOfArticulationParameters
How many articulation parameters we have.
struct EntityID munitionID
ID of muntion that was fired.
struct Vector3Float velocity
ID firing event.
unsigned short application
The application ID.
unsigned short site
The site ID.
unsigned short entity
the entity ID
struct Vector3Float entityLinearVelocity
Describes the speed of the entity in the world.
struct EntityType entityType
Describes the type of entity in the world.
struct EntityID entityID
Unique ID for an entity that is tied to this state information.
void * articulationParameters
variable length list of articulation parameters
struct Orientation entityOrientation
describes the orientation of the entity, in euler angles
int entityAppearance
a series of bit flags that are used to help draw the entity, such as smoking, on fire,...
struct Vector3Double entityLocation
describes the location of the entity in the world
struct DeadReckoningParameter deadReckoningParameters
parameters used for dead reckoning
char numberOfArticulationParameters
How many articulation parameters are in the variable length list.
unsigned char domain
Domain of entity (air, surface, subsurface, space, etc)
unsigned short country
country to which the design of the entity is attributed
unsigned char entityKind
Kind of entity.
unsigned char specific
specific info based on subcategory field
unsigned char category
category of entity
unsigned char subcategory
subcategory of entity
unsigned short application
The application ID.
unsigned short eventNumber
the number of the event
unsigned short site
The site ID.
struct BurstDescriptor burstDescriptor
Describes munitions used in the firing event.
struct EntityID munitionID
ID of the munition that is being shot.
struct Vector3Float velocity
Velocity of the ammunition.
struct EventID eventID
ID of event.
struct Vector3Double locationInWorldCoordinates
location of the firing event
float range
range to the target
unsigned short system
system
unsigned short detail
detail
unsigned short spreadSpectrum
spread spectrum, 16 bit boolean array
unsigned short major
major
unsigned char pduType
Type of pdu, unique for each PDU class.
unsigned short radioId
particular radio within an entity
struct EntityID entityId
ID of the entitythat is the source of the communication.
unsigned short country
country to which the design of the entity is attributed
unsigned char domain
Domain of entity (air, surface, subsurface, space, etc)
unsigned char entityKind
Kind of entity.
unsigned char category
category of entity
unsigned char nomenclatureVersion
specific info based on subcategory field
struct EntityID transmitterEntityId
ID of transmitter.
unsigned short transmitterRadioId
ID of transmitting radio.
unsigned short receiverState
encoding scheme used, and enumeration
float receivedPoser
received power
void * data
list of eight bit values
unsigned int sampleRate
sample rate
unsigned short encodingScheme
encoding scheme used, and enumeration
short dataLength
length od data
unsigned short tdlType
tdl type
short samples
number of samples
struct EntityID originatingEntityID
Entity that is sending message.
unsigned char modulationParameterCount
how many modulation parameters we have
unsigned short antennaPatternType
antenna pattern type
unsigned char transmitState
transmit state
float power
transmission power
unsigned short cryptoSystem
crypto system enumeration
float transmitFrequencyBandwidth
transmit frequency Bandwidth
struct RadioEntityType radioEntityType
linear accelleration of entity
struct Vector3Double antennaLocation
Location of antenna.
struct Vector3Float relativeAntennaLocation
relative location of antenna
unsigned short cryptoKeyId
crypto system key identifer
unsigned char inputSource
input source
unsigned short antennaPatternCount
atenna pattern length
unsigned long long frequency
frequency
struct ModulationType modulationType
modulation
struct EntityID firingEntityID
ID of the entity that shot.